xpath.c revision 42596ad20cdf1925dd79ea801cbe598b6e7b7aec
13473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
23473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xpath.c: XML Path Language implementation
33473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *          XPath is a language for addressing parts of an XML document,
43473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *          designed to be used by both XSLT and XPointer
53473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
63473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Reference: W3C Recommendation 16 November 1999
73473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     http://www.w3.org/TR/1999/REC-xpath-19991116
83473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Public reference:
93473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     http://www.w3.org/TR/xpath
103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * See COPYRIGHT for the status of this software
123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Author: Daniel.Veillard@w3.org
143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 14 Nov 2000 ht - truncated declaration of xmlXPathEvalRelativeLocationPath
163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * for VMS
173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese#include "libxml.h"
203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPATH_ENABLED
213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <string.h>
233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_SYS_TYPES_H
253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <sys/types.h>
263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_MATH_H
283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <math.h>
293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_FLOAT_H
313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <float.h>
323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_IEEEFP_H
343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <ieeefp.h>
353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_NAN_H
373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <nan.h>
383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_CTYPE_H
403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <ctype.h>
413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
425792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef HAVE_SIGNAL_H
43b45c43be206b8c824558269731128c6a64599a54Daniel Veillard#include <signal.h>
44b45c43be206b8c824558269731128c6a64599a54Daniel Veillard#endif
453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlmemory.h>
473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/tree.h>
483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/valid.h>
493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpath.h>
503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpathInternals.h>
513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/parserInternals.h>
523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/hash.h>
533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xpointer.h>
553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED
573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/debugXML.h>
583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <libxml/xmlerror.h>
603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* #define DEBUG */
623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* #define DEBUG_STEP */
633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* #define DEBUG_EXPR */
643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid xmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs);
663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathStringEvalNumber(const xmlChar *str);
675792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillarddouble xmlXPathDivideBy(double f, double fzero);
683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 									*
719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 			Floating point stuff				*
729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 									*
739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lack of portability of this section of the libc is annoying !
773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNAN = 0;
793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathPINF = 1;
803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble xmlXPathNINF = -1;
813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifndef isinf
833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifndef HAVE_ISINF
843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if HAVE_FPCLASS
863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint isinf(double d) {
883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    fpclass_t	type = fpclass(d);
893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (type) {
903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case FP_NINF:
913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(-1);
923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case FP_PINF:
933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(1);
943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#elif defined(HAVE_FP_CLASS) || defined(HAVE_FP_CLASS_D)
993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if HAVE_FP_CLASS_H
1013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#include <fp_class.h>
1023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
1033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint isinf(double d) {
1053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if HAVE_FP_CLASS
1063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int	fpclass = fp_class(d);
1073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else
1083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int	fpclass = fp_class_d(d);
1093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
1103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (fpclass == FP_POS_INF)
1113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
1123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (fpclass == FP_NEG_INF)
1133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
1143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
1153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
1163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#elif defined(HAVE_CLASS)
1183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint isinf(double d) {
1203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int	fpclass = class(d);
1213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (fpclass == FP_PLUS_INF)
1223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
1233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (fpclass == FP_MINUS_INF)
1243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
1253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
1263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
1273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#elif defined(finite) || defined(HAVE_FINITE)
1283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint isinf(double x) { return !finite(x) && x==x; }
1293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#elif defined(HUGE_VAL)
1303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint isinf(double x)
1313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{
1323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (x == HUGE_VAL)
1333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(1);
1343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (x == -HUGE_VAL)
1353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(-1);
1363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
1373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
1383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
1393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* ! HAVE_ISINF */
1413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* ! defined(isinf) */
1423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifndef isnan
1443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifndef HAVE_ISNAN
1453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef HAVE_ISNAND
1473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define isnan(f) isnand(f)
1483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* HAVE_iSNAND */
1493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* ! HAVE_iSNAN */
1513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* ! defined(isnan) */
1523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1535792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard
1545792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard/**
1555792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard * xmlXPathDivideBy:
1565792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard *
1575792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard * The best way found so far to generate the NAN, +-INF
1585792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard * without hitting a compiler bug or optimization :-\
1595792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard *
1605792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard * Returns the double resulting from the division
1615792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard */
1625792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillarddouble
1635792e16f0562d206e1ef4e611f7b43ec53c92149Daniel VeillardxmlXPathDivideBy(double f, double fzero) {
16481418e38c80cf1ddac6fe1426d8037a3da39853fDaniel Veillard    double ret;
1655792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef HAVE_SIGNAL
1665792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef SIGFPE
1675792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef SIG_IGN
1685792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard    void (*sighandler)(int);
1695792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard    sighandler = signal(SIGFPE, SIG_IGN);
1705792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#endif
1715792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#endif
1725792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#endif
1735792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard    ret = f / fzero;
1745792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef HAVE_SIGNAL
1755792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef SIGFPE
1765792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#ifdef SIG_IGN
1775792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard    signal(SIGFPE, sighandler);
1785792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#endif
1795792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#endif
1805792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard#endif
1815792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard    return(ret);
1825792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard}
1835792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard
1843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
1853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathInit:
1863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
1873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initialize the XPath environment
1883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
1893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
1903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathInit(void) {
1913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    static int initialized = 0;
1923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (initialized) return;
1943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1955792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard    xmlXPathNAN = xmlXPathDivideBy(0.0, 0.0);
1965792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard    xmlXPathPINF = xmlXPathDivideBy(1.0, 0.0);
1975792e16f0562d206e1ef4e611f7b43ec53c92149Daniel Veillard    xmlXPathPINF = xmlXPathDivideBy(-1.0, 0.0);
1983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    initialized = 1;
2003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
2013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
2023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
2039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 									*
2049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 			Parser Types					*
2059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 									*
2069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
2079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/*
2099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Types are private:
2109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
2119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
2139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_END=0,
2149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_AND,
2159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_OR,
2169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_EQUAL,
2179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_CMP,
2189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_PLUS,
2199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_MULT,
2209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_UNION,
2219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_ROOT,
2229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_NODE,
2239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_RESET,
2249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_COLLECT,
2259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_VALUE,
2269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_VARIABLE,
2279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_FUNCTION,
2289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_ARG,
2299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_PREDICATE,
230d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    XPATH_OP_FILTER,
2319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    XPATH_OP_SORT
2329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED
2339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ,XPATH_OP_RANGETO
2349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif
2359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathOp;
2369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
2389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ANCESTOR = 1,
2399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ANCESTOR_OR_SELF,
2409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_ATTRIBUTE,
2419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_CHILD,
2429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_DESCENDANT,
2439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_DESCENDANT_OR_SELF,
2449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_FOLLOWING,
2459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_FOLLOWING_SIBLING,
2469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_NAMESPACE,
2479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PARENT,
2489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PRECEDING,
2499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_PRECEDING_SIBLING,
2509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    AXIS_SELF
2519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathAxisVal;
2529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
2549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NONE = 0,
2559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_TYPE = 1,
2569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_PI = 2,
2579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_ALL = 3,
2589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NS = 4,
2599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TEST_NAME = 5
2609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTestVal;
2619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef enum {
2639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_NODE = 0,
2649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_COMMENT = XML_COMMENT_NODE,
2659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_TEXT = XML_TEXT_NODE,
2669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NODE_TYPE_PI = XML_PI_NODE
2679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard} xmlXPathTypeVal;
2689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef struct _xmlXPathStepOp xmlXPathStepOp;
2719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardtypedef xmlXPathStepOp *xmlXPathStepOpPtr;
2729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathStepOp {
2739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathOp op;
2749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int ch1;
2759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int ch2;
2769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value;
2779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value2;
2789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int value3;
2799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    void *value4;
2809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    void *value5;
281e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard    void *cache;
28242596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard    void *cacheURI;
2839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard};
2849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardstruct _xmlXPathCompExpr {
2869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int nbStep;
2879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int maxStep;
2889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathStepOp *steps;        /* ops for computation */
2899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int last;
2909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard};
2919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
2939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 									*
2949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 			Parser Type functions 				*
2959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 									*
2969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
2979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
2999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathNewCompExpr:
3009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
3019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new Xpath component
3029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
3039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the newly allocated xmlXPathCompExprPtr or NULL in case of error
3049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
30556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathCompExprPtr
3069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathNewCompExpr(void) {
3079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprPtr cur;
3089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
3099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur = (xmlXPathCompExprPtr) xmlMalloc(sizeof(xmlXPathCompExpr));
3109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (cur == NULL) {
3119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        xmlGenericError(xmlGenericErrorContext,
3129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		"xmlXPathNewCompExpr : malloc failed\n");
3139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
3149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
3159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(cur, 0, sizeof(xmlXPathCompExpr));
3169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->maxStep = 10;
3179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->nbStep = 0;
3189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->steps = (xmlXPathStepOp *) xmlMalloc(cur->maxStep *
3199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                                   sizeof(xmlXPathStepOp));
3209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (cur->steps == NULL) {
3219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        xmlGenericError(xmlGenericErrorContext,
3229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		"xmlXPathNewCompExpr : malloc failed\n");
3239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(cur);
3249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
3259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
3269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(cur->steps, 0, cur->maxStep * sizeof(xmlXPathStepOp));
3279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    cur->last = -1;
3289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(cur);
3299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
3309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
3319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
3329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathFreeCompExpr:
3339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  an XPATH comp
3349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
3359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Free up the memory allocated by @comp
3369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
3379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardvoid
3389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathFreeCompExpr(xmlXPathCompExprPtr comp) {
3399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathStepOpPtr op;
3409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int i;
3419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
3429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp == NULL)
3439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return;
3449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    for (i = 0;i < comp->nbStep;i++) {
3459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	op = &comp->steps[i];
3469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (op->value4 != NULL) {
3479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->op == XPATH_OP_VALUE)
3489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathFreeObject(op->value4);
3499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else
3509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlFree(op->value4);
3519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
3529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (op->value5 != NULL)
3539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlFree(op->value5);
3549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
3559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp->steps != NULL) {
3569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(comp->steps);
3579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
3589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlFree(comp);
3599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
3609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
3619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
3629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompExprAdd:
3639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the compiled expression
3649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch1: first child index
3659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ch2: second child index
3669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @op:  an op
3679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value:  the first int value
3689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value2:  the second int value
3699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value3:  the third int value
3709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value4:  the first string value
3719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @value5:  the second string value
3729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
3739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Add an step to an XPath Compiled Expression
3749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
3759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns -1 in case of failure, the index otherwise
3769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
37756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
3789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(xmlXPathCompExprPtr comp, int ch1, int ch2,
3799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard   xmlXPathOp op, int value,
3809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard   int value2, int value3, void *value4, void *value5) {
3819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp->nbStep >= comp->maxStep) {
3829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathStepOp *real;
3839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
3849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	comp->maxStep *= 2;
3859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	real = (xmlXPathStepOp *) xmlRealloc(comp->steps,
3869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		                      comp->maxStep * sizeof(xmlXPathStepOp));
3879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (real == NULL) {
3889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    comp->maxStep /= 2;
3899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
3909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    "xmlXPathCompExprAdd : realloc failed\n");
3919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return(-1);
3929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
3939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	comp->steps = real;
3949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
3959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->last = comp->nbStep;
3969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].ch1 = ch1;
3979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].ch2 = ch2;
3989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].op = op;
3999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value = value;
4009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value2 = value2;
4019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value3 = value3;
4029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value4 = value4;
4039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp->steps[comp->nbStep].value5 = value5;
404e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard    comp->steps[comp->nbStep].cache = NULL;
4059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(comp->nbStep++);
4069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
4079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
408d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#define PUSH_FULL_EXPR(op, op1, op2, val, val2, val3, val4, val5)	\
409d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathCompExprAdd(ctxt->comp, (op1), (op2),			\
410d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	                (op), (val), (val2), (val3), (val4), (val5))
4119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LONG_EXPR(op, val, val2, val3, val4, val5)			\
4129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprAdd(ctxt->comp, ctxt->comp->last, -1,		\
4139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                (op), (val), (val2), (val3), (val4), (val5))
4149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
4159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_LEAVE_EXPR(op, val, val2) 					\
4169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, -1, -1, (op), (val), (val2), 0 ,NULL ,NULL)
4179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
4189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_UNARY_EXPR(op, ch, val, val2) 				\
4199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch), -1, (op), (val), (val2), 0 ,NULL ,NULL)
4209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
4219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#define PUSH_BINARY_EXPR(op, ch1, ch2, val, val2) 			\
4229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompExprAdd(ctxt->comp, (ch1), (ch2), (op), (val), (val2), 0 ,NULL ,NULL)
4239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
4249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
4253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
4263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 		Debugging related functions				*
4273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
4283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
4293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define TODO 								\
4313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext,				\
4323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    "Unimplemented block at %s:%d\n",				\
4333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            __FILE__, __LINE__);
4343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define STRANGE 							\
4363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext,				\
4373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    "Internal error at %s:%d\n",				\
4383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            __FILE__, __LINE__);
4393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_DEBUG_ENABLED
44156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
44256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNode(FILE *output, xmlNodePtr cur, int depth) {
4433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
4443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
4453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
4473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
4483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
4493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
4503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
4513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "Node is NULL !\n");
4523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
4533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
4553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur->type == XML_DOCUMENT_NODE) ||
4573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     (cur->type == XML_HTML_DOCUMENT_NODE)) {
4583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
4593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, " /\n");
4603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->type == XML_ATTRIBUTE_NODE)
4613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlDebugDumpAttr(output, (xmlAttrPtr)cur, depth);
4623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
4633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlDebugDumpOneNode(output, cur, depth);
4643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
46556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
46656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeList(FILE *output, xmlNodePtr cur, int depth) {
467f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    xmlNodePtr tmp;
468f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    int i;
469f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    char shift[100];
470f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
471f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
472f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
473f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
474f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    if (cur == NULL) {
475f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, shift);
476f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, "Node is NULL !\n");
477f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	return;
478f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
479f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
480f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
481f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    while (cur != NULL) {
482f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	tmp = cur;
483f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	cur = cur->next;
484f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	xmlDebugDumpOneNode(output, tmp, depth);
485f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
486f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard}
4873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
48956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpNodeSet(FILE *output, xmlNodeSetPtr cur, int depth) {
4903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
4913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
4923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
4943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
4953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
4963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
4983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
4993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "NodeSet is NULL !\n");
5003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
5013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
504911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (cur != NULL) {
505911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	fprintf(output, "Set contains %d nodes:\n", cur->nodeNr);
506911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < cur->nodeNr;i++) {
507911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    fprintf(output, shift);
508911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    fprintf(output, "%d", i + 1);
509911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    xmlXPathDebugDumpNode(output, cur->nodeTab[i], depth + 1);
510911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
5113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
5133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
51556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpValueTree(FILE *output, xmlNodeSetPtr cur, int depth) {
516f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    int i;
517f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    char shift[100];
518f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
519f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
520f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
521f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
522f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
523f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    if ((cur == NULL) || (cur->nodeNr == 0) || (cur->nodeTab[0] == NULL)) {
524f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, shift);
525f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	fprintf(output, "Value Tree is NULL !\n");
526f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	return;
527f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
528f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    }
529f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard
530f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    fprintf(output, shift);
531f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    fprintf(output, "%d", i + 1);
532f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard    xmlXPathDebugDumpNodeList(output, cur->nodeTab[0]->children, depth + 1);
533f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard}
5343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED)
5353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid xmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth);
53656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
53756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpLocationSet(FILE *output, xmlLocationSetPtr cur, int depth) {
5383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
5393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
5403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
5423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
5433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
5443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
5463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
5473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, "LocationSet is NULL !\n");
5483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
5493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->locNr;i++) {
5533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, shift);
5543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "%d : ", i + 1);
5553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathDebugDumpObject(output, cur->locTab[i], depth + 1);
5563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
5583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
5593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
560afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
561afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathDebugDumpObject:
562afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @output:  the FILE * to dump the output
563afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @cur:  the object to inspect
564afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @depth:  indentation level
565afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
566afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Dump the content of the object for debugging purposes
567afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
568afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid
569afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathDebugDumpObject(FILE *output, xmlXPathObjectPtr cur, int depth) {
5703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
5713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char shift[100];
5723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;((i < depth) && (i < 25));i++)
5743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        shift[2 * i] = shift[2 * i + 1] = ' ';
5753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    shift[2 * i] = shift[2 * i + 1] = 0;
5763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    fprintf(output, shift);
5783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
5803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "Object is empty (NULL)\n");
5813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
5823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch(cur->type) {
5843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_UNDEFINED:
5853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is uninitialized\n");
5863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
5873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NODESET:
5883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Node Set :\n");
5893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpNodeSet(output, cur->nodesetval, depth);
5903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
5913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_XSLT_TREE:
5923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is an XSLT value tree :\n");
593f7cd48176c8333c0d487b7b4a12ff24f2db81aceDaniel Veillard	    xmlXPathDebugDumpValueTree(output, cur->nodesetval, depth);
5943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
5953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
5963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Boolean : ");
5973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (cur->boolval) fprintf(output, "true\n");
5983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else fprintf(output, "false\n");
5993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
6003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
601357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    switch (isinf(cur->floatval)) {
602357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    case 1:
603357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		fprintf(output, "Object is a number : +Infinity\n");
604357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		break;
605357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    case -1:
606357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		fprintf(output, "Object is a number : -Infinity\n");
607357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		break;
608357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    default:
609357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		if (isnan(cur->floatval)) {
610357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		    fprintf(output, "Object is a number : NaN\n");
611357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		} else {
612357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		    fprintf(output, "Object is a number : %0g\n", cur->floatval);
613357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard		}
614357c960e4035ee2fb40d0072bb7bde4533be76f8Daniel Veillard	    }
6153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
6163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
6173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a string : ");
6183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlDebugDumpString(output, cur->stringval);
6193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "\n");
6203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
6213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
6223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a point : index %d in node", cur->index);
6233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user, depth + 1);
6243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "\n");
6253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
6263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
6273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((cur->user2 == NULL) ||
6283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		((cur->user2 == cur->user) && (cur->index == cur->index2))) {
6293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "Object is a collapsed range :\n");
6303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, shift);
6313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index >= 0)
6323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index);
6333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
6343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
6353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
6363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else  {
6373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "Object is a range :\n");
6383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, shift);
6393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "From ");
6403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index >= 0)
6413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index);
6423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
6433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user,
6443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
6453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, shift);
6463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "To ");
6473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (cur->index2 >= 0)
6483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    fprintf(output, "index %d in ", cur->index2);
6493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "node\n");
6503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlXPathDebugDumpNode(output, (xmlNodePtr) cur->user2,
6513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			              depth + 1);
6523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		fprintf(output, "\n");
6533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
6543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
6553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
6563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(LIBXML_XPTR_ENABLED)
6573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is a Location Set:\n");
6583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathDebugDumpLocationSet(output,
6593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    (xmlLocationSetPtr) cur->user, depth);
6603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
6613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
6623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_USERS:
6633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, "Object is user defined\n");
6643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
6653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
6663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
6679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
66856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
66956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpStepOp(FILE *output, xmlXPathCompExprPtr comp,
6709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	                     xmlXPathStepOpPtr op, int depth) {
6719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int i;
6729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    char shift[100];
6739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
6759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
6769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
6779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    fprintf(output, shift);
6799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (op == NULL) {
6809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	fprintf(output, "Step is NULL\n");
6819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return;
6829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
6839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    switch (op->op) {
6849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_END:
6859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "END"); break;
6869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_AND:
6879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "AND"); break;
6889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_OR:
6899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "OR"); break;
6909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_EQUAL:
6919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value)
6929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "EQUAL =");
6939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
6949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "EQUAL !=");
6959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
6969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_CMP:
6979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value)
6989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "CMP <");
6999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
7009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "CMP >");
7019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (!op->value2)
7029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "=");
7039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
7049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_PLUS:
7059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value == 0)
7069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS -");
7079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 1)
7089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS +");
7099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 2)
7109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS unary -");
7119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 3)
7129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "PLUS unary - -");
7139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
7149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_MULT:
7159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     if (op->value == 0)
7169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT *");
7179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else if (op->value == 1)
7189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT div");
7199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     else
7209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 fprintf(output, "MULT mod");
7219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     break;
7229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_UNION:
7239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "UNION"); break;
7249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_ROOT:
7259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "ROOT"); break;
7269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_NODE:
7279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "NODE"); break;
7289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_RESET:
7299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "RESET"); break;
7309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_SORT:
7319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     fprintf(output, "SORT"); break;
7329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_COLLECT: {
7339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathAxisVal axis = op->value;
7349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathTestVal test = op->value2;
7359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathTypeVal type = op->value3;
7369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value4;
7379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value5;
7389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
7399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "COLLECT ");
7409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (axis) {
7419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ANCESTOR:
7429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'ancestors' "); break;
7439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ANCESTOR_OR_SELF:
7449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'ancestors-or-self' "); break;
7459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_ATTRIBUTE:
7469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'attributes' "); break;
7479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_CHILD:
7489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'child' "); break;
7499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_DESCENDANT:
7509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'descendant' "); break;
7519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_DESCENDANT_OR_SELF:
7529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'descendant-or-self' "); break;
7539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_FOLLOWING:
7549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'following' "); break;
7559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_FOLLOWING_SIBLING:
7569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'following-siblings' "); break;
7579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_NAMESPACE:
7589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'namespace' "); break;
7599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PARENT:
7609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'parent' "); break;
7619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PRECEDING:
7629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'preceding' "); break;
7639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_PRECEDING_SIBLING:
7649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'preceding-sibling' "); break;
7659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		case AXIS_SELF:
7669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, " 'self' "); break;
7679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
7689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (test) {
7699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NONE:
7709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'none' "); break;
7719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_TYPE:
7729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'type' "); break;
7739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_PI:
7749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'PI' "); break;
7759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_ALL:
7769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'all' "); break;
7779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NS:
7789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'namespace' "); break;
7799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TEST_NAME:
7809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'name' "); break;
7819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
7829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    switch (type) {
7839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_NODE:
7849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'node' "); break;
7859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_COMMENT:
7869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'comment' "); break;
7879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_TEXT:
7889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'text' "); break;
7899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard                case NODE_TYPE_PI:
7909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    fprintf(output, "'PI' "); break;
7919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
7929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
7939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "%s:", prefix);
7949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (name != NULL)
7959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "%s", name);
7969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
7979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
7989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        }
7999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_VALUE: {
8009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathObjectPtr object = (xmlXPathObjectPtr) op->value4;
8019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    fprintf(output, "ELEM ");
8039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathDebugDumpObject(output, object, 0);
8049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    goto finish;
8059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
8069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_VARIABLE: {
8079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value5;
8089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value4;
8099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
8119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "VARIABLE %s:%s", prefix, name);
8129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else
8139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "VARIABLE %s", name);
8149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
8159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
8169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_FUNCTION: {
8179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    int nbargs = op->value;
8189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *prefix = op->value5;
8199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    const xmlChar *name = op->value4;
8209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (prefix != NULL)
8229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "FUNCTION %s:%s(%d args)",
8239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			prefix, name, nbargs);
8249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else
8259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		fprintf(output, "FUNCTION %s(%d args)", name, nbargs);
8269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    break;
8279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
8289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_ARG: fprintf(output, "ARG"); break;
8299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        case XPATH_OP_PREDICATE: fprintf(output, "PREDICATE"); break;
830d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case XPATH_OP_FILTER: fprintf(output, "FILTER"); break;
831fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
832fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard        case XPATH_OP_RANGETO: fprintf(output, "RANGETO"); break;
833fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
8349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	default:
8359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        fprintf(output, "UNKNOWN %d\n", op->op); return;
8369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
8379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    fprintf(output, "\n");
8389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillardfinish:
8399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (op->ch1 >= 0)
8409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch1], depth + 1);
8419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (op->ch2 >= 0)
8429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathDebugDumpStepOp(output, comp, &comp->steps[op->ch2], depth + 1);
8439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
84456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard
84556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardvoid
84656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathDebugDumpCompExpr(FILE *output, xmlXPathCompExprPtr comp,
84756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard	                  int depth) {
8489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int i;
8499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    char shift[100];
8509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    for (i = 0;((i < depth) && (i < 25));i++)
8529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        shift[2 * i] = shift[2 * i + 1] = ' ';
8539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    shift[2 * i] = shift[2 * i + 1] = 0;
8549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    fprintf(output, shift);
8569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (comp == NULL) {
8589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	fprintf(output, "Compiled Expression is NULL\n");
8599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return;
8609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
8619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    fprintf(output, "Compiled Expression : %d elements\n",
8629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    comp->nbStep);
8639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    i = comp->last;
8649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathDebugDumpStepOp(output, comp, &comp->steps[i], depth + 1);
8659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
8663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
8673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
8693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
8703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * 		Parser stacks related functions and macros		*
8713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
8723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
8733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
8753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Generic function for accessing stacks in the Parser Context
8763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
8773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
8783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define PUSH_AND_POP(type, name)					\
8793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorextern int name##Push(xmlXPathParserContextPtr ctxt, type value) {	\
8803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->name##Nr >= ctxt->name##Max) {				\
8813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->name##Max *= 2;						\
8823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ctxt->name##Tab = (type *) xmlRealloc(ctxt->name##Tab,		\
8833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	             ctxt->name##Max * sizeof(ctxt->name##Tab[0]));	\
8843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (ctxt->name##Tab == NULL) {					\
8853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,			\
8863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "realloc failed !\n");				\
8873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(0);							\
8883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}								\
8893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }									\
8903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->name##Tab[ctxt->name##Nr] = value;				\
8913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->name = value;							\
8923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ctxt->name##Nr++);						\
8933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}									\
8943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorextern type name##Pop(xmlXPathParserContextPtr ctxt) {			\
8953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    type ret;								\
8963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->name##Nr <= 0) return(0);					\
8973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->name##Nr--;							\
8983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->name##Nr > 0)						\
8993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->name = ctxt->name##Tab[ctxt->name##Nr - 1];		\
9003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else								\
9013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ctxt->name = NULL;						\
9023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = ctxt->name##Tab[ctxt->name##Nr];				\
9033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->name##Tab[ctxt->name##Nr] = 0;				\
9043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);							\
9053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}									\
9063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorPUSH_AND_POP(xmlXPathObjectPtr, value)
9083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
9103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Macros for accessing the content. Those should be used only by the parser,
9113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and not exported.
9123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
9133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Dirty macros, i.e. one need to make assumption on the context to use them
9143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
9153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CUR_PTR return the current pointer to the xmlChar to be parsed.
9163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CUR     returns the current xmlChar value, i.e. a 8 bit value
9173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           in ISO-Latin or UTF-8.
9183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           This should be used internally by the parser
9193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           only to compare to ASCII values otherwise it would break when
9203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           running with UTF-8 encoding.
9213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
9223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           to compare on ASCII based substring.
9233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
9243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           strings within the parser.
9253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   CURRENT Returns the current char value, with the full decoding of
9263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           UTF-8 if we are using this mode. It returns an int.
9273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   NEXT    Skip to the next character, this does the proper decoding
9283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
9293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *           It returns the pointer to the current xmlChar.
9303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
9313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR (*ctxt->cur)
9333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP(val) ctxt->cur += (val)
9343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NXT(val) ctxt->cur[(val)]
9353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CUR_PTR ctxt->cur
93661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define CUR_CHAR(l) xmlXPathCurrentChar(ctxt, &l)
93761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
93861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define COPY_BUF(l,b,i,v)                                              \
93961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (l == 1) b[i++] = (xmlChar) v;                                  \
94061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    else i += xmlCopyChar(l,&b[i],v)
94161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
94261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard#define NEXTL(l)  ctxt->cur += l
9433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define SKIP_BLANKS 							\
9453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (IS_BLANK(*(ctxt->cur))) NEXT
9463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
9473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CURRENT (*ctxt->cur)
9483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
9493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
950e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
951e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_DIG
952e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_DIG 16
953e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif
954e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#ifndef DBL_EPSILON
955e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define DBL_EPSILON 1E-9
956e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#endif
957e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
958e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define UPPER_DOUBLE 1E9
959e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define LOWER_DOUBLE 1E-5
960e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
961e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define INTEGER_DIGITS DBL_DIG
962e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define FRACTION_DIGITS (DBL_DIG + 1)
963e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese#define EXPONENT_DIGITS (3 + 2)
964e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
965e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese/**
966e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * xmlXPathFormatNumber:
967e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @number:     number to format
968e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffer:     output buffer
969e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * @buffersize: size of output buffer
970e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese *
971e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese * Convert the number into a string representation.
972e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese */
973e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reesestatic void
974e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn ReesexmlXPathFormatNumber(double number, char buffer[], int buffersize)
975e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese{
976e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    switch (isinf(number)) {
977e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    case 1:
978e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	if (buffersize > (int)sizeof("+Infinity"))
979e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    sprintf(buffer, "+Infinity");
980e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
981e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    case -1:
982e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	if (buffersize > (int)sizeof("-Infinity"))
983e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    sprintf(buffer, "-Infinity");
984e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
985e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    default:
986e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	if (isnan(number)) {
987e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    if (buffersize > (int)sizeof("NaN"))
988e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese		sprintf(buffer, "NaN");
989e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	} else {
99070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /* 3 is sign, decimal point, and terminating zero */
99170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    char work[DBL_DIG + EXPONENT_DIGITS + 3];
99270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    int integer_place, fraction_place;
99370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    char *ptr;
99470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    char *after_fraction;
99570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    double absolute_value;
99670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    int size;
99770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
99870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    absolute_value = fabs(number);
99970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
100070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /*
100170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * First choose format - scientific or regular floating point.
100270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * In either case, result is in work, and after_fraction points
100370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	     * just past the fractional part.
100470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    */
100570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if ( ((absolute_value > UPPER_DOUBLE) ||
100670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		  (absolute_value < LOWER_DOUBLE)) &&
100770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		 (absolute_value != 0.0) ) {
100870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		/* Use scientific notation */
100970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		integer_place = DBL_DIG + EXPONENT_DIGITS + 1;
101070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		fraction_place = DBL_DIG - 1;
101170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		snprintf(work, sizeof(work),"%*.*e",
101270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese			 integer_place, fraction_place, number);
101370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		after_fraction = strchr(work + DBL_DIG, 'e');
1014e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    }
101570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    else {
101670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		/* Use regular notation */
101770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		integer_place = 1 + (int)log10(absolute_value);
101870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		fraction_place = (integer_place > 0)
101970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		    ? DBL_DIG - integer_place
102070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		    : DBL_DIG;
102170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		size = snprintf(work, sizeof(work), "%0.*f",
102270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese				fraction_place, number);
102370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		after_fraction = work + size;
1024e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	    }
1025e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
102670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /* Remove fractional trailing zeroes */
102770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    ptr = after_fraction;
102870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    while (*(--ptr) == '0')
102970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		;
103070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if (*ptr != '.')
103170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	        ptr++;
103270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    strcpy(ptr, after_fraction);
103370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
103470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    /* Finally copy result back to caller */
103570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    size = strlen(work) + 1;
103670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    if (size > buffersize) {
103770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		work[buffersize - 1] = 0;
103870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese		size = buffersize;
103970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    }
104070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	    memcpy(buffer, work, size);
1041e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	}
1042e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese	break;
1043e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    }
1044e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese}
1045e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese
10463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
10473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
10483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			Error handling routines				*
10493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
10503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
10513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst char *xmlXPathErrorMessages[] = {
10543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Ok",
10553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Number encoding",
10563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Unfinished litteral",
10573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Start of litteral",
10583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Expected $ for variable reference",
10593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Undefined variable",
10603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Invalid predicate",
10613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Invalid expression",
10623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Missing closing curly brace",
10633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Unregistered function",
10643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Invalid operand",
10653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Invalid type",
10663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Invalid number of arguments",
10673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Invalid context size",
10683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Invalid context position",
10693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Memory allocation error",
10703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Syntax error",
10713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Resource error",
10723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    "Sub resource error",
107361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    "Undefined namespace prefix",
107461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    "Encoding error",
107561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    "Char out of XML range"
10763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor};
10773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
10793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathError:
10803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
10813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @file:  the file name
10823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @line:  the line number
10833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @no:  the error number
10843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlNodeSetPtr of type double and of value @val
10863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
10873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
10883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
10893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
10903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPatherror(xmlXPathParserContextPtr ctxt, const char *file,
10913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor              int line, int no) {
10923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int n;
10933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *cur;
10943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *base;
10953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
10963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext,
10973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    "Error %s:%d: %s\n", file, line,
10983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            xmlXPathErrorMessages[no]);
10993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = ctxt->cur;
11013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    base = ctxt->base;
1102d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if ((cur == NULL) || (base == NULL))
1103d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	return;
1104d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
11053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((cur > base) && ((*cur == '\n') || (*cur == '\r'))) {
11063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur--;
11073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    n = 0;
11093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((n++ < 80) && (cur > base) && (*cur != '\n') && (*cur != '\r'))
11103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur--;
11113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((*cur == '\n') || (*cur == '\r')) cur++;
11123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    base = cur;
11133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    n = 0;
11143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((*cur != 0) && (*cur != '\n') && (*cur != '\r') && (n < 79)) {
11153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext, "%c", (unsigned char) *cur++);
11163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	n++;
11173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext, "\n");
11193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = ctxt->cur;
11203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((*cur == '\n') || (*cur == '\r'))
11213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur--;
11223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    n = 0;
11233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((cur != base) && (n++ < 80)) {
11243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext, " ");
11253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        base++;
11263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext,"^\n");
11283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
11293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
11323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
11333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			Routines to handle NodeSets			*
11343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
11353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
11363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
11383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCmpNodes:
11393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node1:  the first node
11403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node2:  the second node
11413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Compare two nodes w.r.t document order
11433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
11443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns -2 in case of error 1 if first point < second point, 0 if
11453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *         that's the same node, -1 otherwise
11463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
11473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
11483473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCmpNodes(xmlNodePtr node1, xmlNodePtr node2) {
11493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int depth1, depth2;
11503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodePtr cur, root;
11513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((node1 == NULL) || (node2 == NULL))
11533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-2);
11543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
11553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * a couple of optimizations which will avoid computations in most cases
11563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
11573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node1 == node2)
11583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
1159b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard    if ((node1->type == XML_NAMESPACE_DECL) ||
1160b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard        (node2->type == XML_NAMESPACE_DECL))
1161b33c201978ed1c434877cdc6e2000b7012cc26f9Daniel Veillard	return(1);
11623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node1 == node2->prev)
11633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
11643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node1 == node2->next)
11653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
11663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
11673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
11683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * compute depth to root
11693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
11703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (depth2 = 0, cur = node2;cur->parent != NULL;cur = cur->parent) {
11713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == node1)
11723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(1);
11733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	depth2++;
11743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    root = cur;
11763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (depth1 = 0, cur = node1;cur->parent != NULL;cur = cur->parent) {
11773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == node2)
11783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(-1);
11793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	depth1++;
11803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
11823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Distinct document (or distinct entities :-( ) case.
11833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
11843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (root != cur) {
11853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-2);
11863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
11883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * get the nearest common ancestor.
11893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
11903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (depth1 > depth2) {
11913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	depth1--;
11923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node1 = node1->parent;
11933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (depth2 > depth1) {
11953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	depth2--;
11963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node2 = node2->parent;
11973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
11983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (node1->parent != node2->parent) {
11993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node1 = node1->parent;
12003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node2 = node2->parent;
12013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* should not happen but just in case ... */
12023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((node1 == NULL) || (node2 == NULL))
12033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(-2);
12043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
12053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
12063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Find who's first.
12073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
12083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node1 == node2->next)
12093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
12103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (cur = node1->next;cur != NULL;cur = cur->next)
12113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == node2)
12123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(1);
12133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(-1); /* assume there is no sibling list corruption */
12143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
12153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
12173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetSort:
12183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @set:  the node set
12193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
12203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Sort the node set in document order
12213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
12223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
12233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetSort(xmlNodeSetPtr set) {
1224e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    int i, j, incr, len;
12253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodePtr tmp;
12263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (set == NULL)
12283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
12293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Use Shell's sort to sort the node-set */
12313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    len = set->nodeNr;
12323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (incr = len / 2; incr > 0; incr /= 2) {
12333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (i = incr; i < len; i++) {
12343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    j = i - incr;
12353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    while (j >= 0) {
1236e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese		if (xmlXPathCmpNodes(set->nodeTab[j],
1237e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese				     set->nodeTab[j + incr]) == -1) {
12383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    tmp = set->nodeTab[j];
12393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    set->nodeTab[j] = set->nodeTab[j + incr];
12403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    set->nodeTab[j + incr] = tmp;
12413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    j -= incr;
12423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else
12433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
12443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
12453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
12463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
12473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
12483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define XML_NODESET_DEFAULT	10
12503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
12513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetCreate:
12523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an initial xmlNodePtr, or NULL
12533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
12543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlNodeSetPtr of type double and of value @val
12553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
12563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
12573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
12583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr
12593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetCreate(xmlNodePtr val) {
12603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ret;
12613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlNodeSetPtr) xmlMalloc(sizeof(xmlNodeSet));
12633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
12643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
12653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewNodeSet: out of memory\n");
12663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
12673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
12683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlNodeSet));
12693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val != NULL) {
12703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
12713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
12723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret->nodeTab == NULL) {
12733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
12743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "xmlXPathNewNodeSet: out of memory\n");
12753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
12763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
12773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(ret->nodeTab, 0 ,
12783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
12793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret->nodeMax = XML_NODESET_DEFAULT;
12803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret->nodeTab[ret->nodeNr++] = val;
12813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
12823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
12833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
12843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
12863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAdd:
12873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
12883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  a new xmlNodePtr
12893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
12903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * add a new xmlNodePtr ot an existing NodeSet
12913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
12923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
12933473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAdd(xmlNodeSetPtr cur, xmlNodePtr val) {
12943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
12953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL) return;
12973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
12983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
12993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * check against doublons
13003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
13013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->nodeNr;i++)
13023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->nodeTab[i] == val) return;
13033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
13053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * grow the nodeTab if needed
13063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
13073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->nodeMax == 0) {
13083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
13093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
13103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->nodeTab == NULL) {
13113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
13123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "xmlXPathNodeSetAdd: out of memory\n");
13133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
13143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
13153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(cur->nodeTab, 0 ,
13163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
13173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax = XML_NODESET_DEFAULT;
13183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->nodeNr == cur->nodeMax) {
13193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlNodePtr *temp;
13203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax *= 2;
13223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
13233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				      sizeof(xmlNodePtr));
13243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (temp == NULL) {
13253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
13263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "xmlXPathNodeSetAdd: out of memory\n");
13273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
13283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
13293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->nodeTab = temp;
13303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
13313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeTab[cur->nodeNr++] = val;
13323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
13333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
13353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetAddUnique:
13363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
13373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  a new xmlNodePtr
13383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
13393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * add a new xmlNodePtr ot an existing NodeSet, optimized version
13403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * when we are sure the node is not already in the set.
13413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
13423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
13433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetAddUnique(xmlNodeSetPtr cur, xmlNodePtr val) {
13443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL) return;
13453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
13473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * grow the nodeTab if needed
13483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
13493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->nodeMax == 0) {
13503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
13513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
13523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->nodeTab == NULL) {
13533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
13543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "xmlXPathNodeSetAddUnique: out of memory\n");
13553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
13563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
13573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	memset(cur->nodeTab, 0 ,
13583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
13593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax = XML_NODESET_DEFAULT;
13603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (cur->nodeNr == cur->nodeMax) {
13613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlNodePtr *temp;
13623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeMax *= 2;
13643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	temp = (xmlNodePtr *) xmlRealloc(cur->nodeTab, cur->nodeMax *
13653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				      sizeof(xmlNodePtr));
13663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (temp == NULL) {
13673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
13683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "xmlXPathNodeSetAddUnique: out of memory\n");
13693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
13703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
13713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->nodeTab = temp;
13723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
13733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeTab[cur->nodeNr++] = val;
13743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
13753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
13773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetMerge:
13783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val1:  the first NodeSet or NULL
13793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val2:  the second NodeSet
13803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
13813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Merges two nodesets, all nodes from @val2 are added to @val1
13823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if @val1 is NULL, a new set is created and copied from @val2
13833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
13843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns val1 once extended or NULL in case of error.
13853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
13863473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodeSetPtr
13873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetMerge(xmlNodeSetPtr val1, xmlNodeSetPtr val2) {
1388d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    int i, j, initNr, skip;
13893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val2 == NULL) return(val1);
13913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val1 == NULL) {
13923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	val1 = xmlXPathNodeSetCreate(NULL);
13933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
13943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    initNr = val1->nodeNr;
13963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
13973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < val2->nodeNr;i++) {
13983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
13993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * check against doublons
14003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
1401d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	skip = 0;
1402d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	for (j = 0; j < initNr; j++) {
1403d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    if (val1->nodeTab[j] == val2->nodeTab[i]) {
1404d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		skip = 1;
1405d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		break;
1406d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    }
1407d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	}
1408d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	if (skip)
1409d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    continue;
14103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
14123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * grow the nodeTab if needed
14133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
14143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (val1->nodeMax == 0) {
14153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeTab = (xmlNodePtr *) xmlMalloc(XML_NODESET_DEFAULT *
14163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor						    sizeof(xmlNodePtr));
14173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (val1->nodeTab == NULL) {
14183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlGenericError(xmlGenericErrorContext,
14193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				"xmlXPathNodeSetMerge: out of memory\n");
14203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
14213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
14223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    memset(val1->nodeTab, 0 ,
14233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   XML_NODESET_DEFAULT * (size_t) sizeof(xmlNodePtr));
14243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeMax = XML_NODESET_DEFAULT;
14253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (val1->nodeNr == val1->nodeMax) {
14263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlNodePtr *temp;
14273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeMax *= 2;
14293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    temp = (xmlNodePtr *) xmlRealloc(val1->nodeTab, val1->nodeMax *
14303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor					     sizeof(xmlNodePtr));
14313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (temp == NULL) {
14323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlGenericError(xmlGenericErrorContext,
14333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				"xmlXPathNodeSetMerge: out of memory\n");
14343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
14353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
14363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    val1->nodeTab = temp;
14373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
14383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	val1->nodeTab[val1->nodeNr++] = val2->nodeTab[i];
14393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
14403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(val1);
14423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
14433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
14453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetDel:
14463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
14473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an xmlNodePtr
14483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
14493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an xmlNodePtr from an existing NodeSet
14503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
14513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
14523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetDel(xmlNodeSetPtr cur, xmlNodePtr val) {
14533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
14543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return;
14563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL) return;
14573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
14593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * check against doublons
14603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
14613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < cur->nodeNr;i++)
14623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->nodeTab[i] == val) break;
14633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (i >= cur->nodeNr) {
14653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG
14663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
14673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        "xmlXPathNodeSetDel: Node %s wasn't found in NodeList\n",
14683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		val->name);
14693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
14703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return;
14713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
14723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeNr--;
14733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (;i < cur->nodeNr;i++)
14743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab[i] = cur->nodeTab[i + 1];
14753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeTab[cur->nodeNr] = NULL;
14763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
14773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
14793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNodeSetRemove:
14803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the initial node set
14813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the index to remove
14823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
14833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Removes an entry from an existing NodeSet list.
14843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
14853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
14863473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNodeSetRemove(xmlNodeSetPtr cur, int val) {
14873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return;
14883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val >= cur->nodeNr) return;
14893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeNr--;
14903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (;val < cur->nodeNr;val++)
14913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur->nodeTab[val] = cur->nodeTab[val + 1];
14923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur->nodeTab[cur->nodeNr] = NULL;
14933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
14943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
14953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
14963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSet:
14973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the xmlNodeSetPtr to free
14983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
14993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound (not the actual nodes !).
15003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
15013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
15023473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSet(xmlNodeSetPtr obj) {
15033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
15043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab != NULL) {
15053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(obj->nodeTab);
15063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
15073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
15083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
15093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
15113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeValueTree:
15123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the xmlNodeSetPtr to free
15133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
15143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free the NodeSet compound and the actual tree, this is different
15153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * from xmlXPathFreeNodeSet()
15163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
151756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
15183473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeValueTree(xmlNodeSetPtr obj) {
15193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
15203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
15223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < obj->nodeNr;i++)
15233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (obj->nodeTab[i] != NULL)
1524bbd51d512bdffad6d54fb45cbbb9843e787f448aDaniel Veillard	    xmlFreeNodeList(obj->nodeTab[i]);
15253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab != NULL) {
15273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(obj->nodeTab);
15283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
15293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
15303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
15313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if defined(DEBUG) || defined(DEBUG_STEP)
15333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
15343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlGenericErrorContextNodeSet:
15353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @output:  a FILE * for the output
15363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the xmlNodeSetPtr to free
15373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
15383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Quick display of a NodeSet
15393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
15403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
15413473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlGenericErrorContextNodeSet(FILE *output, xmlNodeSetPtr obj) {
15423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
15433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (output == NULL) output = xmlGenericErrorContext;
15453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL)  {
15463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "NodeSet == NULL !\n");
15473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
15483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
15493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeNr == 0) {
15503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        fprintf(output, "NodeSet is empty\n");
15513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
15523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
15533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->nodeTab == NULL) {
15543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	fprintf(output, " nodeTab == NULL !\n");
15553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
15563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
15573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0; i < obj->nodeNr; i++) {
15583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (obj->nodeTab[i] == NULL) {
15593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " NULL !\n");
15603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
15613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
15623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((obj->nodeTab[i]->type == XML_DOCUMENT_NODE) ||
15633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (obj->nodeTab[i]->type == XML_HTML_DOCUMENT_NODE))
15643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " /");
15653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (obj->nodeTab[i]->name == NULL)
15663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    fprintf(output, " noname!");
15673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else fprintf(output, " %s", obj->nodeTab[i]->name);
15683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
15693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    fprintf(output, "\n");
15703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
15713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
15723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
15743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSet:
15753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
15763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
15773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize
15783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the single Node @val
15793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
15803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
15813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
15823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
15833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewNodeSet(xmlNodePtr val) {
15843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
15853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
15873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
15883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
15893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewNodeSet: out of memory\n");
15903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
15913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
15923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
15933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NODESET;
159477851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard    ret->boolval = 0;
15953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = xmlXPathNodeSetCreate(val);
15963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
15973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
15983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
15993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
16003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewValueTree:
16013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
16023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
16033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type Value Tree (XSLT) and initialize
16043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the tree root @val
16053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
16063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
16073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
16083473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
16093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewValueTree(xmlNodePtr val) {
16103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
16113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
16133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
16143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
16153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewNodeSet: out of memory\n");
16163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
16173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
16183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
16193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_XSLT_TREE;
16203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = xmlXPathNodeSetCreate(val);
16213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
16223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
16233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
16253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewNodeSetList:
16263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  an existing NodeSet
16273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
16283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type NodeSet and initialize
16293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * it with the Nodeset @val
16303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
16313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
16323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
16333473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
16343473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewNodeSetList(xmlNodeSetPtr val) {
16353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
16363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
16373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL)
16393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    	ret = NULL;
16403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (val->nodeTab == NULL)
16413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlXPathNewNodeSet(NULL);
16423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
16433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    	{
16443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlXPathNewNodeSet(val->nodeTab[0]);
16453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    for (i = 1; i < val->nodeNr; ++i)
16463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    	xmlXPathNodeSetAddUnique(ret->nodesetval, val->nodeTab[i]);
16473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
16483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
16503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
16513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
16533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathWrapNodeSet:
16543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the NodePtr value
16553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
16563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Wrap the Nodeset @val in a new xmlXPathObjectPtr
16573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
16583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
16593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
16603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
16613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathWrapNodeSet(xmlNodeSetPtr val) {
16623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
16633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
16653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
16663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
16673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathWrapNodeSet: out of memory\n");
16683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
16693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
16703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
16713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NODESET;
16723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nodesetval = val;
16733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
16743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
16753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
16773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeNodeSetList:
16783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  an existing NodeSetList object
16793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
16803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up the xmlXPathObjectPtr @obj but don't deallocate the objects in
16813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the list contrary to xmlXPathFreeObject().
16823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
16833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
16843473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeNodeSetList(xmlXPathObjectPtr obj) {
16853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
16863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
16873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
16883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
16903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
16913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle extra functions			*
16923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
16933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
16943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
16953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
16963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFunc:
16973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
16983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
16993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the function implementation or NULL
17003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function
17023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
17043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
17053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
17063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFunc(xmlXPathContextPtr ctxt, const xmlChar *name,
17073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		     xmlXPathFunction f) {
17083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathRegisterFuncNS(ctxt, name, NULL, f));
17093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
17103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
17123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterFuncNS:
17133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
17143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
17153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the function namespace URI
17163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the function implementation or NULL
17173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new function. If @f is NULL it unregisters the function
17193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
17213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
17223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
17233473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterFuncNS(xmlXPathContextPtr ctxt, const xmlChar *name,
17243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		       const xmlChar *ns_uri, xmlXPathFunction f) {
17253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
17263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
17273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
17283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
17293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->funcHash == NULL)
17313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->funcHash = xmlHashCreate(0);
17323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->funcHash == NULL)
17333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
17343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlHashAddEntry2(ctxt->funcHash, name, ns_uri, (void *) f));
17353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
17363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
17383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookup:
17393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
17403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
17413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given
17433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function.
17443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found
17463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
17473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction
17483473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
17493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathFunctionLookupNS(ctxt, name, NULL));
17503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
17513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
17533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFunctionLookupNS:
17543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
17553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the function name
17563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the function namespace URI
17573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Function array of the context for the given
17593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * function.
17603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathFunction or NULL if not found
17623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
17633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunction
17643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFunctionLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
17653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 const xmlChar *ns_uri) {
17663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
17673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
17683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->funcHash == NULL)
17693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
17703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
17713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
17723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((xmlXPathFunction) xmlHashLookup2(ctxt->funcHash, name, ns_uri));
17743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
17753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
17773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredFuncsCleanup:
17783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
17793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
17803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered functions
17813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
17823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
17833473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredFuncsCleanup(xmlXPathContextPtr ctxt) {
17843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
17853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
17863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlHashFree(ctxt->funcHash, NULL);
17883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->funcHash = NULL;
17893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
17903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
17923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
17933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			Routines to handle Variable			*
17943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
17953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
17963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
17973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
17983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariable:
17993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
18003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
18013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value:  the variable value or NULL
18023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters
18043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable
18053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
18073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
18083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
18093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariable(xmlXPathContextPtr ctxt, const xmlChar *name,
18103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 xmlXPathObjectPtr value) {
18113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathRegisterVariableNS(ctxt, name, NULL, value));
18123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
18133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
18143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
18153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableNS:
18163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
18173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
18183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the variable namespace URI
18193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @value:  the variable value or NULL
18203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new variable value. If @value is NULL it unregisters
18223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the variable
18233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
18253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
18263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
18273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableNS(xmlXPathContextPtr ctxt, const xmlChar *name,
18283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   const xmlChar *ns_uri,
18293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   xmlXPathObjectPtr value) {
18303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
18313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
18323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
18333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
18343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
18353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
18363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->varHash = xmlHashCreate(0);
18373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
18383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
18393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlHashUpdateEntry2(ctxt->varHash, name, ns_uri,
18403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			       (void *) value,
18413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			       (xmlHashDeallocator)xmlXPathFreeObject));
18423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
18433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
18443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
18453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterVariableLookup:
18463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
18473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the lookup function
18483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @data:  the lookup data
18493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * register an external mechanism to do variable lookup
18513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
18523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
18533473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterVariableLookup(xmlXPathContextPtr ctxt,
18543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 xmlXPathVariableLookupFunc f, void *data) {
18553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
18563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
18573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->varLookupFunc = (void *) f;
18583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->varLookupData = data;
18593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
18603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
18613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
18623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookup:
18633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
18643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
18653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given
18673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * variable value.
18683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found
18703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
18713473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
18723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookup(xmlXPathContextPtr ctxt, const xmlChar *name) {
18733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
18743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
18753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
18763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varLookupFunc != NULL) {
18773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathObjectPtr ret;
18783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
18793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
18803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        (ctxt->varLookupData, name, NULL);
18813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret != NULL) return(ret);
18823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
18833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathVariableLookupNS(ctxt, name, NULL));
18843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
18853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
18863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
18873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathVariableLookupNS:
18883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
18893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  the variable name
18903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the variable namespace URI
18913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the Variable array of the context for the given
18933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * variable value.
18943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
18953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found
18963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
18973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
18983473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathVariableLookupNS(xmlXPathContextPtr ctxt, const xmlChar *name,
18993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 const xmlChar *ns_uri) {
19003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
19013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
19023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varLookupFunc != NULL) {
19043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathObjectPtr ret;
19053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = ((xmlXPathVariableLookupFunc)ctxt->varLookupFunc)
19073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        (ctxt->varLookupData, name, ns_uri);
19083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret != NULL) return(ret);
19093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
19103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->varHash == NULL)
19123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
19133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
19143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
19153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((xmlXPathObjectPtr) xmlHashLookup2(ctxt->varHash, name, ns_uri));
19173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
19183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
19203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredVariablesCleanup:
19213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
19223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
19233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables
19243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
19253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
19263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredVariablesCleanup(xmlXPathContextPtr ctxt) {
19273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
19283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
19293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
193076d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard    xmlHashFree(ctxt->varHash, (xmlHashDeallocator)xmlXPathFreeObject);
19313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->varHash = NULL;
19323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
19333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
19353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterNs:
19363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
19373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix:  the namespace prefix
19383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ns_uri:  the namespace name
19393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
19403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Register a new namespace. If @ns_uri is NULL it unregisters
19413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace
19423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
19433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 in case of success, -1 in case of error
19443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
19453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
19463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterNs(xmlXPathContextPtr ctxt, const xmlChar *prefix,
19473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   const xmlChar *ns_uri) {
19483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
19493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
19503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
19513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
19523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->nsHash == NULL)
19543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->nsHash = xmlHashCreate(10);
19553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->nsHash == NULL)
19563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(-1);
19573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlHashUpdateEntry(ctxt->nsHash, prefix, (void *) ns_uri,
19583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			      (xmlHashDeallocator)xmlFree));
19593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
19603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
19623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNsLookup:
19633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
19643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix:  the namespace prefix value
19653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
19663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Search in the namespace declaration array of the context for the given
19673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace name associated to the given prefix
19683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
19693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the value or NULL if not found
19703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
19713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorconst xmlChar *
19723473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNsLookup(xmlXPathContextPtr ctxt, const xmlChar *prefix) {
19733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
19743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
19753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
19763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
19773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef XML_XML_NAMESPACE
19793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(prefix, (const xmlChar *) "xml"))
19803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(XML_XML_NAMESPACE);
19813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
19823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
1983c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard    if (ctxt->namespaces != NULL) {
1984c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	int i;
1985c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard
1986c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	for (i = 0;i < ctxt->nsNr;i++) {
1987c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	    if ((ctxt->namespaces[i] != NULL) &&
1988c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard		(xmlStrEqual(ctxt->namespaces[i]->prefix, prefix)))
1989c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard		return(ctxt->namespaces[i]->href);
1990c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard	}
1991c8f620ba7f95b3ceb687699e140eeaa33343e41aDaniel Veillard    }
19923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((const xmlChar *) xmlHashLookup(ctxt->nsHash, prefix));
19943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
19953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
19963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
19973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisteredVariablesCleanup:
19983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
19993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
20003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Cleanup the XPath context data associated to registered variables
20013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
20023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
20033473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisteredNsCleanup(xmlXPathContextPtr ctxt) {
20043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL)
20053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
20063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlHashFree(ctxt->nsHash, NULL);
20083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->nsHash = NULL;
20093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
20103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
20123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
20133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			Routines to handle Values			*
20143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
20153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
20163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/* Allocations are terrible, one need to optimize all this !!! */
20183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
20203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewFloat:
20213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the double value
20223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
20233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type double and of value @val
20243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
20253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
20263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
20273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
20283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewFloat(double val) {
20293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
20303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
20323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
20333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
20343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewFloat: out of memory\n");
20353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
20363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
20373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
20383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_NUMBER;
20393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->floatval = val;
20403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
20413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
20423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
20443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewBoolean:
20453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the boolean value
20463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
20473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type boolean and of value @val
20483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
20493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
20503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
20513473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
20523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewBoolean(int val) {
20533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
20543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
20563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
20573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
20583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewBoolean: out of memory\n");
20593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
20603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
20613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
20623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_BOOLEAN;
20633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->boolval = (val != 0);
20643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
20653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
20663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
20683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewString:
20693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the xmlChar * value
20703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
20713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val
20723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
20733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
20743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
20753473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
20763473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewString(const xmlChar *val) {
20773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
20783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
20803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
20813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
20823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewString: out of memory\n");
20833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
20843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
20853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
20863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_STRING;
20873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val != NULL)
20883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret->stringval = xmlStrdup(val);
20893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
20903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret->stringval = xmlStrdup((const xmlChar *)"");
20913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
20923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
20933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
20943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
2095ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapString:
2096ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  the xmlChar * value
2097ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2098ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps the @val string into an XPath object.
2099ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2100ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object.
2101ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2102ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
2103ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapString (xmlChar *val) {
2104ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
2105ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2106ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
2107ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (ret == NULL) {
2108ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        xmlGenericError(xmlGenericErrorContext,
2109ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		"xmlXPathWrapString: out of memory\n");
2110ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(NULL);
2111ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
2112ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
2113ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret->type = XPATH_STRING;
2114ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret->stringval = val;
2115ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2116ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2117ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2118ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
21193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewCString:
21203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the char * value
21213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
21223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathObjectPtr of type string and of value @val
21233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
21243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
21253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
21263473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
21273473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewCString(const char *val) {
21283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
21293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
21303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
21313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
21323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
21333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewCString: out of memory\n");
21343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
21353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
21363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
21373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->type = XPATH_STRING;
21383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->stringval = xmlStrdup(BAD_CAST val);
21393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
21403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
21413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
21423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
2143ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathWrapCString:
2144ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  the char * value
2145ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2146ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Wraps a string into an XPath object.
2147ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2148ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the newly created object.
2149ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2150ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
2151ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathWrapCString (char * val) {
2152ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathWrapString((xmlChar *)(val)));
2153ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2154ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2155ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
21563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathObjectCopy:
21573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the original object
21583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
21593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * allocate a new copy of a given object
21603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
21613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the newly created object.
21623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
21633473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
21643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectCopy(xmlXPathObjectPtr val) {
21653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr ret;
21663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
21673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (val == NULL)
21683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
21693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
21703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
21713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
21723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
21733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathObjectCopy: out of memory\n");
21743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
21753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
21763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memcpy(ret, val , (size_t) sizeof(xmlXPathObject));
21773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (val->type) {
21783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_BOOLEAN:
21793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_NUMBER:
21803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
21813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
21823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
21833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_STRING:
21843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->stringval = xmlStrdup(val->stringval);
21853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
21863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_XSLT_TREE:
21873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((val->nodesetval != NULL) &&
21883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		(val->nodesetval->nodeTab != NULL))
21893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret->nodesetval = xmlXPathNodeSetCreate(
21903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			xmlCopyNode(val->nodesetval->nodeTab[0], 1));
21913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else
21923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret->nodesetval = xmlXPathNodeSetCreate(NULL);
21933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
21943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_NODESET:
21953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->nodesetval = xmlXPathNodeSetMerge(NULL, val->nodesetval);
21963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
21973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
21983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
21993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	{
22003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlLocationSetPtr loc = val->user;
22013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret->user = (void *) xmlXPtrLocationSetMerge(NULL, loc);
22023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
22033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
22043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
22053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_UNDEFINED:
22063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_USERS:
22073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
22083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "xmlXPathObjectCopy: unsupported type %d\n",
22093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    val->type);
22103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
22113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
22123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
22133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
22143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
22153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
22163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeObject:
22173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @obj:  the object to free
22183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
22193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathObjectPtr object.
22203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
22213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
22223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeObject(xmlXPathObjectPtr obj) {
22233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) return;
22243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->type == XPATH_NODESET) {
222577851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	if (obj->boolval) {
222677851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	    obj->type = XPATH_XSLT_TREE;
222777851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	    if (obj->nodesetval != NULL)
222877851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard		xmlXPathFreeValueTree(obj->nodesetval);
222977851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	} else {
223077851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	    if (obj->nodesetval != NULL)
223177851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard		xmlXPathFreeNodeSet(obj->nodesetval);
223277851710aba3a0effdc6af67ea4caf212307420cDaniel Veillard	}
22333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
22343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (obj->type == XPATH_LOCATIONSET) {
22353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (obj->user != NULL)
22363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPtrFreeLocationSet(obj->user);
22373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
22383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (obj->type == XPATH_STRING) {
22393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (obj->stringval != NULL)
22403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(obj->stringval);
22413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (obj->type == XPATH_XSLT_TREE) {
22423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (obj->nodesetval != NULL)
22433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathFreeValueTree(obj->nodesetval);
22443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
22453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
22463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(obj);
22473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
22483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
2249ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2250ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/************************************************************************
2251ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *									*
2252ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *			Type Casting Routines				*
2253ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *									*
2254ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard ************************************************************************/
2255ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2256ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2257ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToString:
2258ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a boolean
2259ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2260ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its string value.
2261ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2262ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
2263ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2264ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
2265ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToString (int val) {
2266ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret;
2267ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val)
2268ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "true");
2269ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    else
2270ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "false");
2271ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2272ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2273ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2274ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2275ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToString:
2276ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a number
2277ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2278ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its string value.
2279ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2280ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
2281ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2282ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
2283ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToString (double val) {
2284ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret;
2285ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (isinf(val)) {
2286ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case 1:
2287ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "+Infinity");
2288ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2289ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case -1:
2290ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlStrdup((const xmlChar *) "-Infinity");
2291ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2292ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    default:
2293ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	if (isnan(val)) {
2294ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "NaN");
2295ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	} else {
2296ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    /* could be improved */
2297ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    char buf[100];
2298ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    xmlXPathFormatNumber(val, buf, 100);
2299ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) buf);
2300ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	}
2301ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
2302ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2303ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2304ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2305ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2306ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToString:
2307ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node:  a node
2308ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2309ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its string value.
2310ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2311ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
2312ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2313ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
2314ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToString (xmlNodePtr node) {
2315ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlNodeGetContent(node));
2316ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2317ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2318ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2319ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToString:
2320ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
2321ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2322ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its string value.
2323ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2324ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a newly allocated string.
2325ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2326ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
2327ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToString (xmlNodeSetPtr ns) {
2328ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((ns == NULL) || (ns->nodeNr == 0) || (ns->nodeTab == NULL))
2329ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlStrdup((const xmlChar *) ""));
2330ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2331ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathNodeSetSort(ns);
2332ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathCastNodeToString(ns->nodeTab[0]));
2333ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2334ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2335ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2336ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToString:
2337ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
2338ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2339ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent
2340ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2341ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the string value of the object, NULL in case of error.
2342ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         A new string is allocated only if needed (val isn't a
2343ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         string object).
2344ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2345ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlChar *
2346ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToString(xmlXPathObjectPtr val) {
2347ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ret = NULL;
2348ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2349ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
2350ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlStrdup((const xmlChar *) ""));
2351ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
2352ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_UNDEFINED:
2353ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
2354ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "String: undefined\n");
2355ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
2356ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "");
2357ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
2358ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        case XPATH_XSLT_TREE:
2359ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        case XPATH_NODESET:
2360ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastNodeSetToString(val->nodesetval);
2361ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
2362ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_STRING:
2363ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    return(val->stringval);
2364ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        case XPATH_BOOLEAN:
2365ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastBooleanToString(val->boolval);
2366ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
2367ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_NUMBER: {
2368ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlXPathCastNumberToString(val->floatval);
2369ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
2370ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	}
2371ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_USERS:
2372ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_POINT:
2373ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_RANGE:
2374ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	case XPATH_LOCATIONSET:
2375ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    TODO
2376ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    ret = xmlStrdup((const xmlChar *) "");
2377ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    break;
2378ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
2379ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2380ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2381ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2382ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2383ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertString:
2384ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
2385ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2386ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its string() equivalent
2387ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2388ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
2389ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
2390ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2391ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
2392ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertString(xmlXPathObjectPtr val) {
2393ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *res = NULL;
2394ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2395ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
2396ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewCString(""));
2397ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2398ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
2399ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
2400ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
2401ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "STRING: undefined\n");
2402ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
2403ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2404ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_XSLT_TREE:
2405ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
2406ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastNodeSetToString(val->nodesetval);
2407ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2408ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
2409ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
2410ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
2411ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastBooleanToString(val->boolval);
2412ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2413ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
2414ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	res = xmlXPathCastNumberToString(val->floatval);
2415ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2416ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
2417ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
2418ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
2419ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
2420ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
2421ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2422ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
2423ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
2424ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (res == NULL)
2425ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewCString(""));
2426ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathWrapString(res));
2427ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2428ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2429ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2430ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastBooleanToNumber:
2431ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a boolean
2432ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2433ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a boolean to its number value
2434ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2435ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
2436ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2437ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
2438ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastBooleanToNumber(int val) {
2439ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val)
2440ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(1.0);
2441ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(0.0);
2442ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2443ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2444ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2445ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToNumber:
2446ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a string
2447ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2448ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its number value
2449ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2450ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
2451ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2452ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
2453ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToNumber(const xmlChar * val) {
2454ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(xmlXPathStringEvalNumber(val));
2455ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2456ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2457ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2458ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeToNumber:
2459ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @node:  a node
2460ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2461ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node to its number value
2462ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2463ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
2464ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2465ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
2466ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeToNumber (xmlNodePtr node) {
2467ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *strval;
2468ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret;
2469ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2470ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (node == NULL)
2471ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
2472ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    strval = xmlXPathCastNodeToString(node);
2473ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (strval == NULL)
2474ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
2475ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathCastStringToNumber(strval);
2476ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlFree(strval);
2477ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2478ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2479ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2480ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2481ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2482ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToNumber:
2483ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
2484ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2485ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its number value
2486ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2487ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
2488ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2489ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
2490ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToNumber (xmlNodeSetPtr ns) {
2491ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *str;
2492ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret;
2493ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2494ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (ns == NULL)
2495ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
2496ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    str = xmlXPathCastNodeSetToString(ns);
2497ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathCastStringToNumber(str);
2498ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlFree(str);
2499ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2500ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2501ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2502ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2503ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastToNumber:
2504ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
2505ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2506ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its number value
2507ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2508ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the number value
2509ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2510ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillarddouble
2511ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToNumber(xmlXPathObjectPtr val) {
2512ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double ret = 0.0;
2513ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2514ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
2515ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNAN);
2516ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
2517ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
2518ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEGUB_EXPR
2519ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "NUMBER: undefined\n");
2520ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
2521ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNAN;
2522ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2523ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_XSLT_TREE:
2524ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
2525ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNodeSetToNumber(val->nodesetval);
2526ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2527ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
2528ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastStringToNumber(val->stringval);
2529ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2530ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
2531ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = val->floatval;
2532ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2533ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
2534ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastBooleanToNumber(val->boolval);
2535ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2536ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
2537ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
2538ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
2539ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
2540ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
2541ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNAN;
2542ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2543ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
2544ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2545ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2546ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2547ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2548ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertNumber:
2549ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
2550ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2551ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its number() equivalent
2552ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2553ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
2554ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
2555ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2556ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
2557ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertNumber(xmlXPathObjectPtr val) {
2558ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
2559ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2560ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
2561ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewFloat(0.0));
2562ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val->type == XPATH_NUMBER)
2563ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
2564ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNewFloat(xmlXPathCastToNumber(val));
2565ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
2566ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2567ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2568ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2569ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2570ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNumberToBoolean:
2571ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a number
2572ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2573ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a number to its boolean value
2574ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2575ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
2576ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2577ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
2578ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNumberToBoolean (double val) {
2579ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard     if (isnan(val) || (val == 0.0))
2580ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	 return(0);
2581ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard     return(1);
2582ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2583ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2584ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2585ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastStringToBoolean:
2586ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  a string
2587ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2588ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a string to its boolean value
2589ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2590ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
2591ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2592ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
2593ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastStringToBoolean (const xmlChar *val) {
2594ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((val == NULL) || (xmlStrlen(val) == 0))
2595ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
2596ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(1);
2597ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2598ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2599ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2600ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathCastNodeSetToBoolean:
2601ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ns:  a node-set
2602ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2603ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts a node-set to its boolean value
2604ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2605ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
2606ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2607ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
2608ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastNodeSetToBoolean (xmlNodeSetPtr ns) {
2609ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if ((ns == NULL) || (ns->nodeNr == 0))
2610ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
2611ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(1);
2612ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2613ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2614ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2615ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXpathCastToBoolean:
2616ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
2617ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2618ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an XPath object to its boolean value
2619ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2620ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the boolean value
2621ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2622ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardint
2623ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathCastToBoolean (xmlXPathObjectPtr val) {
2624ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    int ret = 0;
2625ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2626ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
2627ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(0);
2628ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    switch (val->type) {
2629ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_UNDEFINED:
2630ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#ifdef DEBUG_EXPR
2631ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "BOOLEAN: undefined\n");
2632ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard#endif
2633ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = 0;
2634ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2635ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_XSLT_TREE:
2636ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NODESET:
2637ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNodeSetToBoolean(val->nodesetval);
2638ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2639ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_STRING:
2640ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastStringToBoolean(val->stringval);
2641ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2642ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_NUMBER:
2643ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathCastNumberToBoolean(val->floatval);
2644ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2645ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_BOOLEAN:
2646ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = val->boolval;
2647ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2648ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_USERS:
2649ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_POINT:
2650ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_RANGE:
2651ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    case XPATH_LOCATIONSET:
2652ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	TODO;
2653ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = 0;
2654ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	break;
2655ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
2656ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2657ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2658ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2659ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2660ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
2661ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathConvertBoolean:
2662ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @val:  an XPath object
2663ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2664ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Converts an existing object to its boolean() equivalent
2665ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
2666ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns the new object, the old one is freed (or the operation
2667ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *         is done directly on @val)
2668ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
2669ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathObjectPtr
2670ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathConvertBoolean(xmlXPathObjectPtr val) {
2671ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr ret;
2672ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
2673ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val == NULL)
2674ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(xmlXPathNewBoolean(0));
2675ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (val->type == XPATH_BOOLEAN)
2676ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return(val);
2677ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNewBoolean(xmlXPathCastToBoolean(val));
2678ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathFreeObject(val);
2679ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
2680ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
2681ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
26823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
26833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
26843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle XPath contexts			*
26853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
26863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
26873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
26883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
26893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewContext:
26903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @doc:  the XML document
26913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
26923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathContext
26933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
26943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathContext just allocated.
26953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
26963473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContextPtr
26973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewContext(xmlDocPtr doc) {
26983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathContextPtr ret;
26993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathContextPtr) xmlMalloc(sizeof(xmlXPathContext));
27013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
27023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
27033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewContext: out of memory\n");
27043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
27053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
27063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathContext));
27073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->doc = doc;
27083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->node = NULL;
27093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->varHash = NULL;
27113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nb_types = 0;
27133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->max_types = 0;
27143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->types = NULL;
27153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->funcHash = xmlHashCreate(0);
27173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nb_axis = 0;
27193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->max_axis = 0;
27203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->axis = NULL;
27213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->nsHash = NULL;
27233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->user = NULL;
27243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->contextSize = -1;
27263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->proximityPosition = -1;
27273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterAllFunctions(ret);
27293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
27313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
27323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
27343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeContext:
27353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the context to free
27363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
27373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathContext
27383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
27393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
27403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeContext(xmlXPathContextPtr ctxt) {
27413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredNsCleanup(ctxt);
27423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredFuncsCleanup(ctxt);
27433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisteredVariablesCleanup(ctxt);
27443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ctxt);
27453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
27463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
27483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
27493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		Routines to handle XPath parser contexts		*
27503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
27513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
27523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CTXT(ctxt)						\
27543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL) { 						\
27553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,				\
27563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"%s:%d Internal error: ctxt == NULL\n",			\
27573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        __FILE__, __LINE__);					\
27583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }									\
27593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define CHECK_CONTEXT(ctxt)						\
27623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt == NULL) { 						\
27633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,				\
27643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"%s:%d Internal error: no context\n",			\
27653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        __FILE__, __LINE__);					\
27663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }									\
27673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (ctxt->doc == NULL) { 					\
27683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,				\
27693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"%s:%d Internal error: no document\n",			\
27703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        __FILE__, __LINE__);					\
27713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }									\
27723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (ctxt->doc->children == NULL) { 				\
27733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,				\
27743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        "%s:%d Internal error: document without root\n",	\
27753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        __FILE__, __LINE__);					\
27763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }									\
27773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
27803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNewParserContext:
27813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
27823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
27833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
27843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Create a new xmlXPathParserContext
27853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
27863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathParserContext just allocated.
27873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
27883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParserContextPtr
27893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNewParserContext(const xmlChar *str, xmlXPathContextPtr ctxt) {
27903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr ret;
27913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
27923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
27933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) {
27943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
27953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathNewParserContext: out of memory\n");
27963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
27973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
27983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
27993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->cur = ret->base = str;
28003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->context = ctxt;
28013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
28029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret->comp = xmlXPathNewCompExpr();
28039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret->comp == NULL) {
28049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret->valueTab);
28059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret);
28069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
28079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
28089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
28099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(ret);
28109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
28119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
28129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
28139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompParserContext:
28149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the XPath compiled expression
28159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt:  the XPath context
28169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
28179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Create a new xmlXPathParserContext when processing a compiled expression
28189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
28199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the xmlXPathParserContext just allocated.
28209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
282156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathParserContextPtr
28229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompParserContext(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctxt) {
28239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathParserContextPtr ret;
28249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
28259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret = (xmlXPathParserContextPtr) xmlMalloc(sizeof(xmlXPathParserContext));
28269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret == NULL) {
28279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        xmlGenericError(xmlGenericErrorContext,
28289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		"xmlXPathNewParserContext: out of memory\n");
28299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
28309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
28319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    memset(ret, 0 , (size_t) sizeof(xmlXPathParserContext));
28329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
28333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Allocate the value stack */
28343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->valueTab = (xmlXPathObjectPtr *)
28353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                     xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
28369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ret->valueTab == NULL) {
28379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlFree(ret);
28389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        xmlGenericError(xmlGenericErrorContext,
28399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		"xmlXPathNewParserContext: out of memory\n");
28409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
28419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
28423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->valueNr = 0;
28433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->valueMax = 10;
28443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret->value = NULL;
28459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
2846fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    ret->context = ctxt;
28479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ret->comp = comp;
28489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
28493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
28503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
28513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
28523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
28533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFreeParserContext:
28543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the context to free
28553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
28563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Free up an xmlXPathParserContext
28573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
28583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
28593473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFreeParserContext(xmlXPathParserContextPtr ctxt) {
28603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->valueTab != NULL) {
28613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlFree(ctxt->valueTab);
28623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
28639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ctxt->comp)
28649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathFreeCompExpr(ctxt->comp);
28653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ctxt);
28663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
28673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
28683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
28693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
28703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		The implicit core function library			*
28713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
28723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
28733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
28743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
28753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetFloat:
28763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
28773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
28783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
28793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
28803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the value
28813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
28823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a number
28833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
28843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
28853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
28863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
28873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
28883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number,
28893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in the
28903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set such that the result of performing the comparison on the number
28913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be compared and on the result of converting the string-value of that
28923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node to a number using the number function is true.
28933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
28943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
28953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
289656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
28973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetFloat(xmlXPathParserContextPtr ctxt, int inf, int strict,
28983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr f) {
28993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, ret = 0;
29003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
29013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
29023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
29033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((f == NULL) || (arg == NULL) ||
29043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
29053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg);
29063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(f);
29073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
29083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
2910911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (ns != NULL) {
2911911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < ns->nodeNr;i++) {
2912ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	     str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
2913911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     if (str2 != NULL) {
2914911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 valuePush(ctxt,
2915911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard			   xmlXPathNewString(str2));
2916911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlFree(str2);
2917911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlXPathNumberFunction(ctxt, 1);
2918911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 valuePush(ctxt, xmlXPathObjectCopy(f));
2919911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 ret = xmlXPathCompareValues(ctxt, inf, strict);
2920911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 if (ret)
2921911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		     break;
2922911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     }
2923911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
29243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg);
29263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(f);
29273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
29283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
29293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
29303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
29313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetString:
29323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
29333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
29343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
29353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
29363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @s:  the value
29373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
29383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a string
29393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
29403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
29413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
29423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
29433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
29443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string,
29453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
29463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
29473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true.
29483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
29493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
29503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
295156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
29523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetString(xmlXPathParserContextPtr ctxt, int inf, int strict,
29533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr s) {
29543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, ret = 0;
29553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
29563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
29573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
29583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((s == NULL) || (arg == NULL) ||
29593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE))) {
29603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg);
29613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(s);
29623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
29633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
2965911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if (ns != NULL) {
2966911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	for (i = 0;i < ns->nodeNr;i++) {
2967ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	     str2 = xmlXPathCastNodeToString(ns->nodeTab[i]);
2968911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     if (str2 != NULL) {
2969911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 valuePush(ctxt,
2970911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard			   xmlXPathNewString(str2));
2971911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 xmlFree(str2);
2972911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 valuePush(ctxt, xmlXPathObjectCopy(s));
2973911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 ret = xmlXPathCompareValues(ctxt, inf, strict);
2974911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		 if (ret)
2975911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		     break;
2976911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	     }
2977911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	}
29783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
29793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg);
29803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(s);
29813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
29823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
29833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
29843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
29853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSets:
2986ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @inf:  less than (1) or greater than (0)
29873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
29883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1:  the fist node set object
29893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2:  the second node set object
29903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
29913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on nodesets:
29923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
29933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison
29943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set
29953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a node in the second node-set such that the result of performing
29963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the string-values of the two nodes is true.
29973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ....
29983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator
29993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is <=, <, >= or >, then the objects are compared by converting both
30003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * objects to numbers and comparing the numbers according to IEEE 754.
30013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ....
30023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The number function converts its argument to a number as follows:
30033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - a string that consists of optional whitespace followed by an
30043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    optional minus sign followed by a Number followed by whitespace
30053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    is converted to the IEEE 754 number that is nearest (according
30063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    to the IEEE 754 round-to-nearest rule) to the mathematical value
30073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    represented by the string; any other string is converted to NaN
30083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
30093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Conclusion all nodes need to be converted first to their string value
30103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and then the comparison must be done when possible
30113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
301256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
301356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel VeillardxmlXPathCompareNodeSets(int inf, int strict,
30143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
30153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, j, init = 0;
30163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val1;
30173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double *values2;
30183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
30193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns1;
30203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns2;
30213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
30223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg1 == NULL) ||
30234dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE))) {
30244dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
30253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
30264dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
30273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg2 == NULL) ||
30284dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE))) {
30294dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
30304dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
30313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
30324dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
30333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
30343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns1 = arg1->nodesetval;
30353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns2 = arg2->nodesetval;
30363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3037d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if ((ns1 == NULL) || (ns1->nodeNr <= 0)) {
30384dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
30394dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
30403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
30414dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
3042d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if ((ns2 == NULL) || (ns2->nodeNr <= 0)) {
30434dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
30444dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
30453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
30464dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    }
30473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
30483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values2 = (double *) xmlMalloc(ns2->nodeNr * sizeof(double));
30493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (values2 == NULL) {
30504dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg1);
30514dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard	xmlXPathFreeObject(arg2);
30523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
30533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
30543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++) {
3055ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	val1 = xmlXPathCastNodeToNumber(ns1->nodeTab[i]);
30563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (isnan(val1))
30573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    continue;
30583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (j = 0;j < ns2->nodeNr;j++) {
30593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (init == 0) {
3060ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		values2[j] = xmlXPathCastNodeToNumber(ns2->nodeTab[j]);
30613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
30623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (isnan(values2[j]))
30633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		continue;
30643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (inf && strict)
30653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 < values2[j]);
30663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (inf && !strict)
30673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 <= values2[j]);
30683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (!inf && strict)
30693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 > values2[j]);
30703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else if (!inf && !strict)
30713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = (val1 >= values2[j]);
30723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (ret)
30733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		break;
30743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
30753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret)
30763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
30773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	init = 1;
30783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
30793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values2);
30804dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    xmlXPathFreeObject(arg1);
30814dd9346df228ff478e8cbe38bee270d56a609676Daniel Veillard    xmlXPathFreeObject(arg2);
30823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
30833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
30843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
30853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
30863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareNodeSetValue:
30873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
30883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
30893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
30903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the node set
30913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @val:  the value
30923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
30933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation between a nodeset and a value
30943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns < @val    (1, 1, ...
30953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns <= @val   (1, 0, ...
30963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns > @val    (0, 1, ...
30973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @ns >= @val   (0, 0, ...
30983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
30993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a boolean,
31003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if the result of performing
31013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the comparison on the boolean and on the result of converting
31023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set to a boolean using the boolean function is true.
31033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
31043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
31053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
310656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
31073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareNodeSetValue(xmlXPathParserContextPtr ctxt, int inf, int strict,
31083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	                    xmlXPathObjectPtr arg, xmlXPathObjectPtr val) {
31093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((val == NULL) || (arg == NULL) ||
31103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
31113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
31123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
31133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch(val->type) {
31143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
31153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareNodeSetFloat(ctxt, inf, strict, arg, val));
31163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NODESET:
31173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_XSLT_TREE:
311856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard	    return(xmlXPathCompareNodeSets(inf, strict, arg, val));
31193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
31203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareNodeSetString(ctxt, inf, strict, arg, val));
31213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
31223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, arg);
31233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathBooleanFunction(ctxt, 1);
31243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, val);
31253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathCompareValues(ctxt, inf, strict));
31263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
31273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    TODO
31283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(0);
31293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
31303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
31313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
31323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
31333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
31343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEqualNodeSetString
31353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the nodeset object argument
31363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the string to compare to.
31373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
31383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2
31393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a string,
31403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
31413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
31423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string-value of the node and the other string is true.
31433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
31443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
31453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
314656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
31473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEqualNodeSetString(xmlXPathObjectPtr arg, const xmlChar *str) {
31483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
31493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns;
31503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *str2;
31513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
31523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((str == NULL) || (arg == NULL) ||
31533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
31543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
31553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns = arg->nodesetval;
3156d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (ns == NULL)
3157d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	return(0);
31583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ns->nodeNr <= 0)
31593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
31603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns->nodeNr;i++) {
31613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor         str2 = xmlNodeGetContent(ns->nodeTab[i]);
31623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 if ((str2 != NULL) && (xmlStrEqual(str, str2))) {
31633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     xmlFree(str2);
31643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     return(1);
31653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 }
31663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 if (str2 != NULL)
31673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     xmlFree(str2);
31683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
31693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
31703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
31713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
31723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
31733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEqualNodeSetFloat
31743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg:  the nodeset object argument
31753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @f:  the float to compare to
31763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
31773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2
31783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If one object to be compared is a node-set and the other is a number,
31793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the comparison will be true if and only if there is a node in
31803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the node-set such that the result of performing the comparison on the
31813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number to be compared and on the result of converting the string-value
31823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of that node to a number using the number function is true.
31833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
31843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
31853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
318656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
31873473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEqualNodeSetFloat(xmlXPathObjectPtr arg, double f) {
31883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    char buf[100] = "";
31893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
31903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg == NULL) ||
31913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg->type != XPATH_NODESET) && (arg->type != XPATH_XSLT_TREE)))
31923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
31933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3194e1dc0114ac95b4d86c61a05169a3d8eb80fccff3Bjorn Reese    xmlXPathFormatNumber(f, buf, sizeof(buf));
31953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathEqualNodeSetString(arg, BAD_CAST buf));
31963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
31973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
31983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
31993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
32003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEqualNodeSets
32013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg1:  first nodeset object argument
32023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @arg2:  second nodeset object argument
32033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
32043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath nodesets: @arg1 == @arg2
32053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If both objects to be compared are node-sets, then the comparison
32063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if there is a node in the first node-set and
32073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a node in the second node-set such that the result of performing the
32083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison on the string-values of the two nodes is true.
32093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
32103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (needless to say, this is a costly operation)
32113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
32123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
32133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
321456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic int
32153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEqualNodeSets(xmlXPathObjectPtr arg1, xmlXPathObjectPtr arg2) {
32163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, j;
32173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar **values1;
32183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar **values2;
32193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
32203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns1;
32213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlNodeSetPtr ns2;
32223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg1 == NULL) ||
32243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg1->type != XPATH_NODESET) && (arg1->type != XPATH_XSLT_TREE)))
32253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
32263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg2 == NULL) ||
32273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((arg2->type != XPATH_NODESET) && (arg2->type != XPATH_XSLT_TREE)))
32283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(0);
32293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns1 = arg1->nodesetval;
32313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ns2 = arg2->nodesetval;
32323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3233911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((ns1 == NULL) || (ns1->nodeNr <= 0))
32343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
3235911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((ns2 == NULL) || (ns2->nodeNr <= 0))
32363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
32373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
32393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * check if there is a node pertaining to both sets
32403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
32413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++)
32423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (j = 0;j < ns2->nodeNr;j++)
32433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (ns1->nodeTab[i] == ns2->nodeTab[j])
32443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(1);
32453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values1 = (xmlChar **) xmlMalloc(ns1->nodeNr * sizeof(xmlChar *));
32473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (values1 == NULL)
32483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
32493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(values1, 0, ns1->nodeNr * sizeof(xmlChar *));
32503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    values2 = (xmlChar **) xmlMalloc(ns2->nodeNr * sizeof(xmlChar *));
32513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (values2 == NULL) {
32523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(values1);
32533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
32543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
32553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    memset(values2, 0, ns2->nodeNr * sizeof(xmlChar *));
32563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++) {
32573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	values1[i] = xmlNodeGetContent(ns1->nodeTab[i]);
32583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	for (j = 0;j < ns2->nodeNr;j++) {
32593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (i == 0)
32603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		values2[j] = xmlNodeGetContent(ns2->nodeTab[j]);
32613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlStrEqual(values1[i], values2[j]);
32623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (ret)
32633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		break;
32643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
32653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ret)
32663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
32673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
32683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (i = 0;i < ns1->nodeNr;i++)
32693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (values1[i] != NULL)
32703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(values1[i]);
32713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    for (j = 0;j < ns2->nodeNr;j++)
32723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (values2[j] != NULL)
32733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(values2[j]);
32743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values1);
32753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(values2);
32763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
32773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
32783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
32803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEqualValues:
32813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
32823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
32833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the equal operation on XPath objects content: @arg1 == @arg2
32843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
32853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 0 or 1 depending on the results of the test.
32863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
32873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
32883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEqualValues(xmlXPathParserContextPtr ctxt) {
32893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg1, arg2;
32903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
32913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    arg1 = valuePop(ctxt);
32933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1 == NULL)
32943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
32953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
32963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    arg2 = valuePop(ctxt);
32973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg2 == NULL) {
32983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg1);
32993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
33003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
33013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
33023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1 == arg2) {
33033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
33043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlGenericError(xmlGenericErrorContext,
33053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"Equal: by pointer\n");
33063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
33073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(1);
33083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
33093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
33103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (arg1->type) {
33113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_UNDEFINED:
33123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
33133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
33143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "Equal: undefined\n");
33153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
33163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
33173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_XSLT_TREE:
33183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NODESET:
33193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
33203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
33213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
33223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
33233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
33243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
33253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_XSLT_TREE:
33273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NODESET:
33283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = xmlXPathEqualNodeSets(arg1, arg2);
33293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
33313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if ((arg1->nodesetval == NULL) ||
33323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			(arg1->nodesetval->nodeNr == 0)) ret = 0;
33333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    else
33343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			ret = 1;
33353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (ret == arg2->boolval);
33363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
33383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = xmlXPathEqualNodeSetFloat(arg1, arg2->floatval);
33393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
33413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = xmlXPathEqualNodeSetString(arg1, arg2->stringval);
33423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
33443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
33453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
33463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
33473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
33483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
33503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
33513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_BOOLEAN:
33523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
33533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
33543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
33553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
33563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
33573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
33583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NODESET:
33603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_XSLT_TREE:
33613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if ((arg2->nodesetval == NULL) ||
33623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			(arg2->nodesetval->nodeNr == 0)) ret = 0;
33633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    else
33643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			ret = 1;
33653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
33673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
33683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
33693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: %d boolean %d \n",
33703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    arg1->boolval, arg2->boolval);
33713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
33723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->boolval == arg2->boolval);
33733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
33753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if (arg2->floatval) ret = 1;
33763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    else ret = 0;
33773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->boolval == ret);
33783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
33803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if ((arg2->stringval == NULL) ||
33813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			(arg2->stringval[0] == 0)) ret = 0;
33823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    else
33833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			ret = 1;
33843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->boolval == ret);
33853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
33873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
33883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
33893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
33903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
33913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
33923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
33933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
33943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_NUMBER:
33953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
33963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
33973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
33983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
33993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
34003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
34013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NODESET:
34033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_XSLT_TREE:
34043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = xmlXPathEqualNodeSetFloat(arg2, arg1->floatval);
34053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
34073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if (arg1->floatval) ret = 1;
34083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    else ret = 0;
34093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg2->boolval == ret);
34103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
34123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    valuePush(ctxt, arg2);
34133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlXPathNumberFunction(ctxt, 1);
34143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    arg2 = valuePop(ctxt);
34153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* no break on purpose */
34163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
34173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->floatval == arg2->floatval);
34183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
34203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
34213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
34223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
34233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
34243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
34263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
34273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_STRING:
34283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    switch (arg2->type) {
34293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        case XPATH_UNDEFINED:
34303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
34313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
34323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "Equal: undefined\n");
34333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
34343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NODESET:
34363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_XSLT_TREE:
34373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = xmlXPathEqualNodeSetString(arg2, arg1->stringval);
34383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_BOOLEAN:
34403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if ((arg1->stringval == NULL) ||
34413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			(arg1->stringval[0] == 0)) ret = 0;
34423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    else
34433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			ret = 1;
34443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg2->boolval == ret);
34453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_STRING:
34473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = xmlStrEqual(arg1->stringval, arg2->stringval);
34483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_NUMBER:
34503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    valuePush(ctxt, arg1);
34513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlXPathNumberFunction(ctxt, 1);
34523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    arg1 = valuePop(ctxt);
34533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    ret = (arg1->floatval == arg2->floatval);
34543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_USERS:
34563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_POINT:
34573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_RANGE:
34583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		case XPATH_LOCATIONSET:
34593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    TODO
34603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
34613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
34623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
34633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XPATH_USERS:
34643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_POINT:
34653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_RANGE:
34663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XPATH_LOCATIONSET:
34673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    TODO
34683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
34693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
34703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg1);
34713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg2);
34723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
34733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
34743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
34753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
34763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
34773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCompareValues:
34783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
34793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @inf:  less than (1) or greater than (0)
34803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @strict:  is the comparison strict
34813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
34823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the compare operation on XPath objects:
34833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 < @arg2    (1, 1, ...
34843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 <= @arg2   (1, 0, ...
34853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 > @arg2    (0, 1, ...
34863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *     @arg1 >= @arg2   (0, 0, ...
34873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
34883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * When neither object to be compared is a node-set and the operator is
34893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * <=, <, >=, >, then the objects are compared by converted both objects
34903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to numbers and comparing the numbers according to IEEE 754. The <
34913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * comparison will be true if and only if the first number is less than the
34923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * second number. The <= comparison will be true if and only if the first
34933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number is less than or equal to the second number. The > comparison
34943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * will be true if and only if the first number is greater than the second
34953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number. The >= comparison will be true if and only if the first number
34963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is greater than or equal to the second number.
34973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
34983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 1 if the comparaison succeeded, 0 if it failed
34993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
35003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
35013473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCompareValues(xmlXPathParserContextPtr ctxt, int inf, int strict) {
35023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
35033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg1, arg2;
35043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    arg2 = valuePop(ctxt);
35063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg2 == NULL) {
35073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
35083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    arg1 = valuePop(ctxt);
35113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1 == NULL) {
35123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg2);
35133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
35143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((arg2->type == XPATH_NODESET) || (arg1->type == XPATH_NODESET)) {
35173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((arg2->type == XPATH_NODESET) && (arg1->type == XPATH_NODESET)) {
351856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard	    ret = xmlXPathCompareNodeSets(inf, strict, arg1, arg2);
35193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
35203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (arg1->type == XPATH_NODESET) {
35214af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard		ret = xmlXPathCompareNodeSetValue(ctxt, inf, strict,
35224af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard			                          arg1, arg2);
35233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else {
35244af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard		ret = xmlXPathCompareNodeSetValue(ctxt, !inf, strict,
35254af6b6e801346d1c832cf19b7c3833a831871db2Daniel Veillard			                          arg2, arg1);
35263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
35273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
35283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(ret);
35293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1->type != XPATH_NUMBER) {
35323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, arg1);
35333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathNumberFunction(ctxt, 1);
35343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	arg1 = valuePop(ctxt);
35353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg1->type != XPATH_NUMBER) {
35373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg1);
35383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg2);
35393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
35403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg2->type != XPATH_NUMBER) {
35423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, arg2);
35433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathNumberFunction(ctxt, 1);
35443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	arg2 = valuePop(ctxt);
35453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (arg2->type != XPATH_NUMBER) {
35473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg1);
35483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(arg2);
35493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_INVALID_OPERAND);
35503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
35513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
35523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Add tests for infinity and nan
35533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * => feedback on 3.4 for Inf and NaN
35543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
35553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (inf && strict)
35563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret = (arg1->floatval < arg2->floatval);
35573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (inf && !strict)
35583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret = (arg1->floatval <= arg2->floatval);
35593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (!inf && strict)
35603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret = (arg1->floatval > arg2->floatval);
35613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (!inf && !strict)
35623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret = (arg1->floatval >= arg2->floatval);
35633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg1);
35643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg2);
35653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
35663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
35673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
35693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathValueFlipSign:
35703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
35713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
35723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the unary - operation on an XPath object
35733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
35743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
35753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
35763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
35773473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathValueFlipSign(xmlXPathParserContextPtr ctxt) {
3578ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
3579ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
3580ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval = - ctxt->value->floatval;
35813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
35823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
35833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
35843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathAddValues:
35853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
35863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
35873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the add operation on XPath objects:
35883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
35893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
35903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
35913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
35923473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathAddValues(xmlXPathParserContextPtr ctxt) {
35933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
35943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
35953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3596ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
3597ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
3598ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
3599ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
36003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg);
36013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3602ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
3603ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
3604ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval += val;
36053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
36063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
36073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
36083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubValues:
36093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
36103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
36113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substraction operation on XPath objects:
36123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
36133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
36143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
36153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
36163473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubValues(xmlXPathParserContextPtr ctxt) {
36173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
36183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
36193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3620ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
3621ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
3622ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
3623ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
36243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg);
36253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3626ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
3627ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
3628ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval -= val;
36293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
36303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
36313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
36323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathMultValues:
36333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
36343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
36353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the multiply operation on XPath objects:
36363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
36373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
36383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
36393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
36403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathMultValues(xmlXPathParserContextPtr ctxt) {
36413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
36423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
36433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3644ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
3645ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
3646ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
3647ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
36483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg);
36493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3650ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
3651ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
3652ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval *= val;
36533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
36543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
36553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
36563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathDivValues:
36573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
36583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
36593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the div operation on XPath objects @arg1 / @arg2:
36603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
36613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
36623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
36633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
36643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathDivValues(xmlXPathParserContextPtr ctxt) {
36653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
36663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double val;
36673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3668ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
3669ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
3670ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
3671ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    val = xmlXPathCastToNumber(arg);
36723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg);
36733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3674ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
3675ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
3676ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval /= val;
36773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
36783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
36793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
36803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathModValues:
36813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
36823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
36833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the mod operation on XPath objects: @arg1 / @arg2
36843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The numeric operators convert their operands to numbers as if
36853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by calling the number function.
36863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
36873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
36883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathModValues(xmlXPathParserContextPtr ctxt) {
36893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr arg;
36903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int arg1, arg2;
36913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3692ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg = valuePop(ctxt);
3693ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    if (arg == NULL)
3694ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	XP_ERROR(XPATH_INVALID_OPERAND);
3695ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg2 = (int) xmlXPathCastToNumber(arg);
36963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(arg);
36973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
3698ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CAST_TO_NUMBER;
3699ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    CHECK_TYPE(XPATH_NUMBER);
3700ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    arg1 = (int) ctxt->value->floatval;
3701ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ctxt->value->floatval = arg1 % arg2;
37023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
37033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
37053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
37063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		The traversal functions					*
37073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
37083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
37093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
37113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A traversal function enumerates nodes along an axis.
37123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Initially it must be called with NULL, and it indicates
37133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * termination on the axis by returning NULL.
37143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
37153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylortypedef xmlNodePtr (*xmlXPathTraversalFunction)
37163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                    (xmlXPathParserContextPtr ctxt, xmlNodePtr cur);
37173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
37193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextSelf:
37203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
37213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
37223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
37233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "self" direction
37243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The self axis contains just the context node itself
37253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
37263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
37273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
37283473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
37293473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
37303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
37313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
37323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
37333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
37343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
37363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextChild:
37373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
37383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
37393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
37403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "child" direction
37413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The child axis contains the children of the context node in document order.
37423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
37433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
37443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
37453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
37463473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextChild(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
37473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
37483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
37493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
37503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
37513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
37523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
37533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
37543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
37553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
37563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
37573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
37583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DTD_NODE:
37593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->children);
37603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
37613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
37623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
37633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
3764eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
3765eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
37663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
37673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(((xmlDocPtr) ctxt->context->node)->children);
37683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
37693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
37703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
37713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE:
37723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_NAMESPACE_DECL:
37733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
37743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
37753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(NULL);
37763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
37773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
37783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
37793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur->type == XML_DOCUMENT_NODE) ||
37803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        (cur->type == XML_HTML_DOCUMENT_NODE))
37813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
37823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->next);
37833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
37843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
37853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
37863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendant:
37873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
37883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
37893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
37903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant" direction
37913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant axis contains the descendants of the context node in document
37923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order; a descendant is a child or a child of a child and so on.
37933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
37943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
37953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
37963473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
37973473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendant(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
37983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
37993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL)
38003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
38013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
38023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
38033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
38043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
38063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(ctxt->context->doc->children);
38073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->children);
38083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
38093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->children != NULL)
38113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    	{
38123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    	if (cur->children->type != XML_ENTITY_DECL)
38133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   	return(cur->children);
38143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    	}
38153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->next != NULL) return(cur->next);
38163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
38183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
38193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == NULL) return(NULL);
38203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur == ctxt->context->node) return(NULL);
38213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (cur->next != NULL) {
38223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    cur = cur->next;
38233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(cur);
38243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
38253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (cur != NULL);
38263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur);
38273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
38283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
38303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextDescendantOrSelf:
38313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
38323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
38333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
38343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "descendant-or-self" direction
38353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the descendant-or-self axis contains the context node and the descendants
38363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node in document order; thus the context node is the first
38373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis, and the first child of the context node is the second node
38383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the axis
38393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
38403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
38413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
38423473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
38433473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextDescendantOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
38443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
38453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL)
38463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
38473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
38483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    (ctxt->context->node->type == XML_NAMESPACE_DECL))
38493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
38503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
38513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
38523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathNextDescendant(ctxt, cur));
38543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
38553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
38573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextParent:
38583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
38593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
38603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
38613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "parent" direction
38623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The parent axis contains the parent of the context node, if there is one.
38633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
38643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
38653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
38663473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
38673473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextParent(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
38683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
38693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * the parent of an attribute or namespace node is the element
38703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * to which the attribute or namespace node is attached
38713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * Namespace handling !!!
38723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
38733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
38743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
38753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
38763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
38773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
38783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
38793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
38803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
38813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
38823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
38833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
38843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DTD_NODE:
38853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
38863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
38873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
38883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
38893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
38903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (ctxt->context->node->parent == NULL)
38913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    return((xmlNodePtr) ctxt->context->doc);
38923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->parent);
38933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE: {
38943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
38953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
38963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(att->parent);
38973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
38983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
38993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
39003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
39013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
3902eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
3903eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
39043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
39053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
39063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_NAMESPACE_DECL:
39073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		/*
39083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 * TODO !!! may require extending struct _xmlNs with
39093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 * parent field
39103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 * C.f. Infoset case...
39113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 */
39123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
39133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
39143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
39153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
39163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
39173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
39183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
39193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestor:
39203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
39213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
39223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
39233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor" direction
39243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the ancestor axis contains the ancestors of the context node; the ancestors
39253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node consist of the parent of context node and the parent's
39263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent and so on; the nodes are ordered in reverse document order; thus the
39273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent is the first node on the axis, and the parent's parent is the second
39283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node on the axis
39293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
39303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
39313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
39323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
39333473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestor(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
39343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
39353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * the parent of an attribute or namespace node is the element
39363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * to which the attribute or namespace node is attached
39373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     * !!!!!!!!!!!!!
39383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
39393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
39403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) return(NULL);
39413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (ctxt->context->node->type) {
39423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ELEMENT_NODE:
39433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_TEXT_NODE:
39443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_CDATA_SECTION_NODE:
39453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_REF_NODE:
39463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ENTITY_NODE:
39473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_PI_NODE:
39483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_COMMENT_NODE:
39493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_DTD_NODE:
39503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ELEMENT_DECL:
39513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ATTRIBUTE_DECL:
39523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_ENTITY_DECL:
39533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_NOTATION_NODE:
39543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_START:
39553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_XINCLUDE_END:
39563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (ctxt->context->node->parent == NULL)
39573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    return((xmlNodePtr) ctxt->context->doc);
39583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		return(ctxt->context->node->parent);
39593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_ATTRIBUTE_NODE: {
396056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		xmlAttrPtr tmp = (xmlAttrPtr) ctxt->context->node;
39613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
396256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		return(tmp->parent);
39633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
39643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_NODE:
39653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_TYPE_NODE:
39663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_DOCUMENT_FRAG_NODE:
39673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            case XML_HTML_DOCUMENT_NODE:
3968eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
3969eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	    case XML_DOCB_DOCUMENT_NODE:
39703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
39713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
39723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    case XML_NAMESPACE_DECL:
39733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		/*
39743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 * TODO !!! may require extending struct _xmlNs with
39753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 * parent field
39763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 * C.f. Infoset case...
39773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 */
39783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                return(NULL);
39793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
39803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
39813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
39823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == ctxt->context->doc->children)
39833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return((xmlNodePtr) ctxt->context->doc);
39843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
39853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
39863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (cur->type) {
39873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
39883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_TEXT_NODE:
39893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_CDATA_SECTION_NODE:
39903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ENTITY_REF_NODE:
39913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ENTITY_NODE:
39923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_PI_NODE:
39933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_COMMENT_NODE:
39943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_NOTATION_NODE:
39953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DTD_NODE:
39963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ELEMENT_DECL:
39973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ATTRIBUTE_DECL:
39983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        case XML_ENTITY_DECL:
39993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_XINCLUDE_START:
40003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_XINCLUDE_END:
40013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(cur->parent);
40023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE: {
40033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlAttrPtr att = (xmlAttrPtr) ctxt->context->node;
40043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(att->parent);
40063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
40073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_NODE:
40083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_TYPE_NODE:
40093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_DOCUMENT_FRAG_NODE:
40103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_HTML_DOCUMENT_NODE:
4011eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard#ifdef LIBXML_DOCB_ENABLED
4012eae522a0d8aa9f830d2e447f29b504030dbb6bbdDaniel Veillard	case XML_DOCB_DOCUMENT_NODE:
40133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
40143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
40153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_NAMESPACE_DECL:
40163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    /*
40173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * TODO !!! may require extending struct _xmlNs with
40183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * parent field
40193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * C.f. Infoset case...
40203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     */
40213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
40223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
40233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(NULL);
40243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
40253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
40273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAncestorOrSelf:
40283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
40293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
40303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "ancestor-or-self" direction
40323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he ancestor-or-self axis contains the context node and ancestors of
40333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node in reverse document order; thus the context node is
40343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node on the axis, and the context node's parent the second;
40353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parent here is defined the same as with the parent axis.
40363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
40383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
40393473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
40403473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAncestorOrSelf(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
40413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
40423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node);
40433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlXPathNextAncestor(ctxt, cur));
40443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
40453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
40473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowingSibling:
40483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
40493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
40503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following-sibling" direction
40523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following-sibling axis contains the following siblings of the context
40533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in document order.
40543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
40563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
40573473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
40583473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
40593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
40603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->context->node->type == XML_NAMESPACE_DECL))
40613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
40623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
40633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(NULL);
40643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
40653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->next);
40663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->next);
40673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
40683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
40703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPrecedingSibling:
40713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
40723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
40733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding-sibling" direction
40753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The preceding-sibling axis contains the preceding siblings of the context
40763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node in reverse document order; the first preceding sibling is first on the
40773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * axis; the sibling preceding that node is the second on the axis and so on.
40783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
40803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
40813473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
40823473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextPrecedingSibling(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
40833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->context->node->type == XML_ATTRIBUTE_NODE) ||
40843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->context->node->type == XML_NAMESPACE_DECL))
40853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
40863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == (xmlNodePtr) ctxt->context->doc)
40873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(NULL);
40883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
40893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(ctxt->context->node->prev);
40903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur->prev);
40913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
40923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
40933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
40943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextFollowing:
40953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
40963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
40973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
40983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "following" direction
40993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The following axis contains all nodes in the same document as the context
41003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are after the context node in document order, excluding any
41013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * descendants and excluding attribute nodes and namespace nodes; the nodes
41023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * are ordered in document order
41033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
41053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
41063473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
41073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextFollowing(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
41083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur != NULL && cur->children != NULL)
41093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return cur->children ;
41103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) cur = ctxt->context->node;
41113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) return(NULL) ; /* ERROR */
41123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur->next != NULL) return(cur->next) ;
41133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
41143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
41153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur == NULL) return(NULL);
41163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur == (xmlNodePtr) ctxt->context->doc) return(NULL);
41173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->next != NULL) return(cur->next);
41183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (cur != NULL);
41193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur);
41203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
41213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
41233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAncestor:
41243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ancestor:  the ancestor node
41253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @node:  the current node
41263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Check that @ancestor is a @node's ancestor
41283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns 1 if @ancestor is a @node's ancestor, 0 otherwise.
41303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
41313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorstatic int
41323473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAncestor(xmlNodePtr ancestor, xmlNodePtr node) {
41333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ancestor == NULL) || (node == NULL)) return(0);
41343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* nodes need to be in the same document */
41353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ancestor->doc != node->doc) return(0);
41363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* avoid searching if ancestor or node is the root node */
41373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ancestor == (xmlNodePtr) node->doc) return(1);
41383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (node == (xmlNodePtr) ancestor->doc) return(0);
41393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (node->parent != NULL) {
41403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (node->parent == ancestor)
41413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            return(1);
41423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	node = node->parent;
41433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
41443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
41453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
41463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
41483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextPreceding:
41493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
41503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current node in the traversal
41513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "preceding" direction
41533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the preceding axis contains all nodes in the same document as the context
41543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node that are before the context node in document order, excluding any
41553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ancestors and excluding attribute nodes and namespace nodes; the nodes are
41563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * ordered in reverse document order
41573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
41593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
41603473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
41613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextPreceding(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
41623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL)
41633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = ctxt->context->node ;
41643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
41653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur->prev != NULL) {
41663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            for (cur = cur->prev ; cur->last != NULL ; cur = cur->last)
41673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                ;
41683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor            return(cur) ;
41693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
41703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur = cur->parent;
41723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur == NULL) return(NULL);
41733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (cur == ctxt->context->doc->children) return(NULL);
41743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (xmlXPathIsAncestor(cur, ctxt->context->node));
41753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(cur);
41763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
41773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
41783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
41793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextNamespace:
41803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
41813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current attribute in the traversal
41823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "namespace" direction
41843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the namespace axis contains the namespace nodes of the context node;
41853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the order of nodes on this axis is implementation-defined; the axis will
41863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be empty unless the context node is an element
41873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
41883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
41893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
41903473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
41913473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextNamespace(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
41923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->context->node->type != XML_ELEMENT_NODE) return(NULL);
41933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur == NULL) || (ctxt->context->namespaces == NULL)) {
41943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (ctxt->context->namespaces != NULL)
41953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(ctxt->context->namespaces);
41963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->context->namespaces =
41973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGetNsList(ctxt->context->doc, ctxt->context->node);
41983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->namespaces == NULL) return(NULL);
41993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->context->nsNr = 0;
42003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
42013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((xmlNodePtr)ctxt->context->namespaces[ctxt->context->nsNr++]);
42023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
42033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
42053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNextAttribute:
42063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
42073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @cur:  the current attribute in the traversal
42083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Traversal function for the "attribute" direction
42103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * TODO: support DTD inherited default attributes
42113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
42123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the next element following that axis
42133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
42143473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlNodePtr
42153473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNextAttribute(xmlXPathParserContextPtr ctxt, xmlNodePtr cur) {
4216e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard    if (ctxt->context->node == NULL)
4217e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard	return(NULL);
4218e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard    if (ctxt->context->node->type != XML_ELEMENT_NODE)
4219e470df7fdd3505c6232d6498f3b8834ebfce522dDaniel Veillard	return(NULL);
42203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) {
42213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (ctxt->context->node == (xmlNodePtr) ctxt->context->doc)
42223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
42233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return((xmlNodePtr)ctxt->context->node->properties);
42243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
42253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return((xmlNodePtr)cur->next);
42263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
42273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
42293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
42303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		NodeTest Functions					*
42313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
42323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
42333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
42343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#define IS_FUNCTION			200
42353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4236d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
4237d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************
4238d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
4239d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *		Implicit tree core function library			*
4240d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
4241d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/
4242d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
42433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
4244d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathRoot:
42453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
42463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
4247d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Initialize the context to the root of the document
42483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
4249d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
4250d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathRoot(xmlXPathParserContextPtr ctxt) {
4251d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    ctxt->context->node = (xmlNodePtr) ctxt->context->doc;
4252d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
4253d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
42543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4255d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/************************************************************************
4256d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
4257d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *		The explicit core function library			*
4258d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *http://www.w3.org/Style/XSL/Group/1999/07/xpath-19990705.html#corelib	*
4259d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *									*
4260d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard ************************************************************************/
42613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4262d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
4263d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/**
4264d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathLastFunction:
4265d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath Parser context
4266d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs:  the number of arguments
4267d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
4268d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the last() XPath function
4269d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *    number last()
4270d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The last function returns the number of nodes in the context node list.
4271d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
4272d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
4273d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathLastFunction(xmlXPathParserContextPtr ctxt, int nargs) {
4274d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    CHECK_ARITY(0);
4275d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (ctxt->context->contextSize >= 0) {
4276d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	valuePush(ctxt, xmlXPathNewFloat((double) ctxt->context->contextSize));
4277d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR
4278d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlGenericError(xmlGenericErrorContext,
4279d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		"last() : %d\n", ctxt->context->contextSize);
42803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
4281d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    } else {
4282d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	XP_ERROR(XPATH_INVALID_CTXT_SIZE);
42833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
4284d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
42853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4286d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/**
4287d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathPositionFunction:
4288d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath Parser context
4289d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @nargs:  the number of arguments
4290d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
4291d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Implement the position() XPath function
4292d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *    number position()
4293d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * The position function returns the position of the context node in the
4294d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * context node list. The first position is 1, and so the last positionr
4295d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * will be equal to last().
4296d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
4297d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardvoid
4298d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathPositionFunction(xmlXPathParserContextPtr ctxt, int nargs) {
4299d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    CHECK_ARITY(0);
4300d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (ctxt->context->proximityPosition >= 0) {
4301d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	valuePush(ctxt,
4302d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	      xmlXPathNewFloat((double) ctxt->context->proximityPosition));
4303d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_EXPR
4304d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "position() : %d\n",
4305d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		ctxt->context->proximityPosition);
43063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
4307d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    } else {
4308d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	XP_ERROR(XPATH_INVALID_CTXT_POSITION);
4309d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
4310d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
43113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
43133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCountFunction:
43143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
43153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
43163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the count() XPath function
43183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number count(node-set)
43193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
43203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
43213473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCountFunction(xmlXPathParserContextPtr ctxt, int nargs) {
43223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
43233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
43253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->value == NULL) ||
43263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
43273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
43283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
43293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
43303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4331911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur == NULL) || (cur->nodesetval == NULL))
4332911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	valuePush(ctxt, xmlXPathNewFloat((double) 0));
4333911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    else
4334911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	valuePush(ctxt, xmlXPathNewFloat((double) cur->nodesetval->nodeNr));
43353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(cur);
43363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
43373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
43383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
4339ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * xmlXPathGetElementsByIds:
4340ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @doc:  the document
4341ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * @ids:  a whitespace separated list of IDs
4342ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
4343ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Selects elements by their unique ID.
4344ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard *
4345ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard * Returns a node-set of selected elements.
4346ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard */
4347ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillardstatic xmlNodeSetPtr
4348ba0b8c94acad3f8e880002b3069f074be582e893Daniel VeillardxmlXPathGetElementsByIds (xmlDocPtr doc, const xmlChar *ids) {
4349ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodeSetPtr ret;
4350ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    const xmlChar *cur = ids;
4351ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *ID;
4352ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlAttrPtr attr;
4353ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodePtr elem = NULL;
4354ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
4355ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathNodeSetCreate(NULL);
4356ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
4357ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    while (IS_BLANK(*cur)) cur++;
4358ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    while (*cur != 0) {
4359ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	while ((IS_LETTER(*cur)) || (IS_DIGIT(*cur)) ||
4360ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	       (*cur == '.') || (*cur == '-') ||
4361ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	       (*cur == '_') || (*cur == ':') ||
4362ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	       (IS_COMBINING(*cur)) ||
4363ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	       (IS_EXTENDER(*cur)))
4364ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	       cur++;
4365ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
4366ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	if ((!IS_BLANK(*cur)) && (*cur != 0)) break;
4367ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
4368ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        ID = xmlStrndup(ids, cur - ids);
4369ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	attr = xmlGetID(doc, ID);
4370ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	if (attr != NULL) {
4371ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    elem = attr->parent;
4372ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard            xmlXPathNodeSetAdd(ret, elem);
4373ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard        }
4374ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	if (ID != NULL)
4375ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    xmlFree(ID);
4376ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
4377ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	while (IS_BLANK(*cur)) cur++;
4378ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ids = cur;
4379ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    }
4380ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    return(ret);
4381ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard}
4382ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard
4383ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard/**
43843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIdFunction:
43853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
43863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
43873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
43883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the id() XPath function
43893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    node-set id(object)
43903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The id function selects elements by their unique ID
43913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [5.2.1 Unique IDs]). When the argument to id is of type node-set,
43923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the result is the union of the result of applying id to the
43933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string value of each of the nodes in the argument node-set. When the
43943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument to id is of any other type, the argument is converted to a
43953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string as if by a call to the string function; the string is split
43963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * into a whitespace-separated list of tokens (whitespace is any sequence
43973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of characters matching the production S); the result is a node-set
43983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * containing the elements in the same document as the context node that
43993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * have a unique ID equal to any of the tokens in the list.
44003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
44013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
44023473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIdFunction(xmlXPathParserContextPtr ctxt, int nargs) {
4403ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlChar *tokens;
4404ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlNodeSetPtr ret;
4405ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    xmlXPathObjectPtr obj;
44063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
44083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    obj = valuePop(ctxt);
44093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
44103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (obj->type == XPATH_NODESET) {
4411ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	xmlNodeSetPtr ns;
44123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i;
44133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4414ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	ret = xmlXPathNodeSetCreate(NULL);
44153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4416911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	if (obj->nodesetval != NULL) {
4417911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    for (i = 0; i < obj->nodesetval->nodeNr; i++) {
4418ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		tokens =
4419ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		    xmlXPathCastNodeToString(obj->nodesetval->nodeTab[i]);
4420ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		ns = xmlXPathGetElementsByIds(ctxt->context->doc, tokens);
4421ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		ret = xmlXPathNodeSetMerge(ret, ns);
4422ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		xmlXPathFreeNodeSet(ns);
4423ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		if (tokens != NULL)
4424ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		    xmlFree(tokens);
4425911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    }
44263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
44273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(obj);
4429ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	valuePush(ctxt, xmlXPathWrapNodeSet(ret));
44303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
44313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
4432ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    obj = xmlXPathConvertString(obj);
44333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4434ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    ret = xmlXPathGetElementsByIds(ctxt->context->doc, obj->stringval);
4435ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    valuePush(ctxt, xmlXPathWrapNodeSet(ret));
44363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(obj);
44383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return;
44393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
44403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
44423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLocalNameFunction:
44433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
44443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
44453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
44463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the local-name() XPath function
44473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string local-name(node-set?)
44483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The local-name function returns a string containing the local part
44493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the name of the node in the argument node-set that is first in
44503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document order. If the node-set is empty or the first node has no
44513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * name, an empty string is returned. If the argument is omitted it
44523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
44533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
44543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
44553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLocalNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
44563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
44573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
44593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
44603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs = 1;
44613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
44623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
44643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->value == NULL) ||
44653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
44663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
44673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
44683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
44693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4470911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
44713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, xmlXPathNewCString(""));
44723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
44733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i = 0; /* Should be first in document order !!!!! */
44743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (cur->nodesetval->nodeTab[i]->type) {
44753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
44763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE:
44773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_PI_NODE:
44783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt,
44793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		      xmlXPathNewString(cur->nodesetval->nodeTab[i]->name));
44803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
44813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_NAMESPACE_DECL:
44823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, xmlXPathNewString(
44833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			((xmlNsPtr)cur->nodesetval->nodeTab[i])->prefix));
44843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
44853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
44863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, xmlXPathNewCString(""));
44873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
44883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
44893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(cur);
44903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
44913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
44923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
44933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNamespaceURIFunction:
44943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
44953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
44963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
44973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the namespace-uri() XPath function
44983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string namespace-uri(node-set?)
44993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The namespace-uri function returns a string containing the
45003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace URI of the expanded name of the node in the argument
45013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node-set that is first in document order. If the node-set is empty,
45023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the first node has no name, or the expanded name has no namespace
45033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * URI, an empty string is returned. If the argument is omitted it
45043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
45053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
45063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
45073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNamespaceURIFunction(xmlXPathParserContextPtr ctxt, int nargs) {
45083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
45093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
45103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
45113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
45123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs = 1;
45133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
45143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
45153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->value == NULL) ||
45163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
45173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
45183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
45193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
45203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4521911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
45223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, xmlXPathNewCString(""));
45233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
45243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i = 0; /* Should be first in document order !!!!! */
45253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (cur->nodesetval->nodeTab[i]->type) {
45263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
45273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE:
45283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (cur->nodesetval->nodeTab[i]->ns == NULL)
45293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		valuePush(ctxt, xmlXPathNewCString(""));
45303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else
45313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		valuePush(ctxt, xmlXPathNewString(
45323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			  cur->nodesetval->nodeTab[i]->ns->href));
45333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
45343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
45353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, xmlXPathNewCString(""));
45363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
45373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
45383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(cur);
45393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
45403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
45413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
45423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNameFunction:
45433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
45443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
45453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
45463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the name() XPath function
45473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string name(node-set?)
45483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The name function returns a string containing a QName representing
45493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the name of the node in the argument node-set that is first in documenti
45503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * order. The QName must represent the name with respect to the namespace
45513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * declarations in effect on the node whose name is being represented.
45523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Typically, this will be the form in which the name occurred in the XML
45533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * source. This need not be the case if there are namespace declarations
45543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in effect on the node that associate multiple prefixes with the same
45553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * namespace. However, an implementation may include information about
45563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the original prefix in its representation of nodes; in this case, an
45573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation can ensure that the returned string is always the same
45583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * as the QName used in the XML source. If the argument it omitted it
45593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * defaults to the context node.
45603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Libxml keep the original prefix so the "real qualified name" used is
45613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returned.
45623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
456356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic void
45643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNameFunction(xmlXPathParserContextPtr ctxt, int nargs) {
45653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
45663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
45673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
45683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
45693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs = 1;
45703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
45713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
45723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
45733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->value == NULL) ||
45743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
45753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
45763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
45773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
45783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4579911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
45803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, xmlXPathNewCString(""));
45813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
45823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int i = 0; /* Should be first in document order !!!!! */
45833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
45843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	switch (cur->nodesetval->nodeTab[i]->type) {
45853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ELEMENT_NODE:
45863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case XML_ATTRIBUTE_NODE:
45873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (cur->nodesetval->nodeTab[i]->ns == NULL)
45883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		valuePush(ctxt, xmlXPathNewString(
45893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    cur->nodesetval->nodeTab[i]->name));
45903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
45913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    else {
45923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		char name[2000];
45933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		snprintf(name, sizeof(name), "%s:%s",
45943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 (char *) cur->nodesetval->nodeTab[i]->ns->prefix,
45953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			 (char *) cur->nodesetval->nodeTab[i]->name);
45963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		name[sizeof(name) - 1] = 0;
45973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		valuePush(ctxt, xmlXPathNewCString(name));
45983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
45993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
46003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	default:
46013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt,
46023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		      xmlXPathNewNodeSet(cur->nodesetval->nodeTab[i]));
46033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathLocalNameFunction(ctxt, 1);
46043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
46053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
46063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(cur);
46073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
46083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4609fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
4610fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
46113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringFunction:
46123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
46133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
46143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
46153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string() XPath function
46163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string string(object?)
46173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * he string function converts an object to a string as follows:
46183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - A node-set is converted to a string by returning the value of
46193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      the node in the node-set that is first in document order.
46203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      If the node-set is empty, an empty string is returned.
46213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - A number is converted to a string as follows
46223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + NaN is converted to the string NaN
46233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + positive zero is converted to the string 0
46243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + negative zero is converted to the string 0
46253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + positive infinity is converted to the string Infinity
46263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + negative infinity is converted to the string -Infinity
46273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + if the number is an integer, the number is represented in
46283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        decimal form as a Number with no decimal point and no leading
46293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        zeros, preceded by a minus sign (-) if the number is negative
46303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      + otherwise, the number is represented in decimal form as a
46313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        Number including a decimal point with at least one digit
46323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        before the decimal point and at least one digit after the
46333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        decimal point, preceded by a minus sign (-) if the number
46343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        is negative; there must be no leading zeros before the decimal
46353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        point apart possibly from the one required digit immediatelyi
46363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        before the decimal point; beyond the one required digit
46373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        after the decimal point there must be as many, but only as
46383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        many, more digits as are needed to uniquely distinguish the
46393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *        number from all other IEEE 754 numeric values.
46403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    - The boolean false value is converted to the string false.
46413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *      The boolean true value is converted to the string true.
46423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
46433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * If the argument is omitted, it defaults to a node-set with the
46443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * context node as its only member.
46453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
46463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
46473473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
46483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
46493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
46503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
4651ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	valuePush(ctxt,
4652ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		  xmlXPathWrapString(
4653ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard			xmlXPathCastNodeToString(ctxt->context->node)));
4654ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	return;
46553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
46563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
46573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
46583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
46593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
4660fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    cur = xmlXPathConvertString(cur);
4661fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    valuePush(ctxt, cur);
46623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
46633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
46643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
46653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringLengthFunction:
46663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
46673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
46683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
46693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the string-length() XPath function
46703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number string-length(string?)
46713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The string-length returns the number of characters in the string
46723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (see [3.6 Strings]). If the argument is omitted, it defaults to
46733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node converted to a string, in other words the value
46743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the context node.
46753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
46763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
46773473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringLengthFunction(xmlXPathParserContextPtr ctxt, int nargs) {
46783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
46793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
46803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
46813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) {
46823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, xmlXPathNewFloat(0));
46833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
46843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlChar *content;
46853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
4686ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    content = xmlXPathCastNodeToString(ctxt->context->node);
4687e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	    valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(content)));
46883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(content);
46893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
46903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
46913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
46923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
46933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
46943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
46953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
4696e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    valuePush(ctxt, xmlXPathNewFloat(xmlUTF8Strlen(cur->stringval)));
46973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(cur);
46983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
46993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
47013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathConcatFunction:
47023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
47033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
47043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the concat() XPath function
47063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string concat(string, string, string*)
47073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The concat function returns the concatenation of its arguments.
47083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
47093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
47103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathConcatFunction(xmlXPathParserContextPtr ctxt, int nargs) {
47113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur, newobj;
47123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *tmp;
47133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs < 2) {
47153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(2);
47163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
47173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
47193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
47203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((cur == NULL) || (cur->type != XPATH_STRING)) {
47213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlXPathFreeObject(cur);
47223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
47233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
47243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    nargs--;
47253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (nargs > 0) {
47273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CAST_TO_STRING;
47283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	newobj = valuePop(ctxt);
47293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((newobj == NULL) || (newobj->type != XPATH_STRING)) {
47303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathFreeObject(newobj);
47313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathFreeObject(cur);
47323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_INVALID_TYPE);
47333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
47343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	tmp = xmlStrcat(newobj->stringval, cur->stringval);
47353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	newobj->stringval = cur->stringval;
47363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur->stringval = tmp;
47373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(newobj);
47393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nargs--;
47403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
47413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, cur);
47423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
47433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
47453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathContainsFunction:
47463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
47473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
47483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the contains() XPath function
47503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean contains(string, string)
47513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The contains function returns true if the first argument string
47523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * contains the second argument string, and otherwise returns false.
47533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
47543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
47553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathContainsFunction(xmlXPathParserContextPtr ctxt, int nargs) {
47563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr hay, needle;
47573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(2);
47593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
47603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
47613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    needle = valuePop(ctxt);
47623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
47633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    hay = valuePop(ctxt);
47643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
47653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlXPathFreeObject(hay);
47663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlXPathFreeObject(needle);
47673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
47683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
47693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrstr(hay->stringval, needle->stringval))
47703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        valuePush(ctxt, xmlXPathNewBoolean(1));
47713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
47723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        valuePush(ctxt, xmlXPathNewBoolean(0));
47733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(hay);
47743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(needle);
47753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
47763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
47783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStartsWithFunction:
47793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
47803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
47813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
47823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the starts-with() XPath function
47833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean starts-with(string, string)
47843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The starts-with function returns true if the first argument string
47853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starts with the second argument string, and otherwise returns false.
47863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
47873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
47883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStartsWithFunction(xmlXPathParserContextPtr ctxt, int nargs) {
47893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr hay, needle;
47903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int n;
47913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
47923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(2);
47933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
47943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
47953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    needle = valuePop(ctxt);
47963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
47973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    hay = valuePop(ctxt);
47983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((hay == NULL) || (hay->type != XPATH_STRING)) {
47993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlXPathFreeObject(hay);
48003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlXPathFreeObject(needle);
48013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
48023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
48033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    n = xmlStrlen(needle->stringval);
48043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrncmp(hay->stringval, needle->stringval, n))
48053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        valuePush(ctxt, xmlXPathNewBoolean(0));
48063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
48073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        valuePush(ctxt, xmlXPathNewBoolean(1));
48083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(hay);
48093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(needle);
48103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
48113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
48133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringFunction:
48143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
48153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
48163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
48173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring() XPath function
48183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring(string, number, number?)
48193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring function returns the substring of the first argument
48203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * starting at the position specified in the second argument with
48213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * length specified in the third argument. For example,
48223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * substring("12345",2,3) returns "234". If the third argument is not
48233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * specified, it returns the substring starting at the position specified
48243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in the second argument and continuing to the end of the string. For
48253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * example, substring("12345",2) returns "2345".  More precisely, each
48263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character in the string (see [3.6 Strings]) is considered to have a
48273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * numeric position: the position of the first character is 1, the position
48283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of the second character is 2 and so on. The returned substring contains
48293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * those characters for which the position of the character is greater than
48303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or equal to the second argument and, if the third argument is specified,
48313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * less than the sum of the second and third arguments; the comparisons
48323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and addition used for the above follow the standard IEEE 754 rules. Thus:
48333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - substring("12345", 1.5, 2.6) returns "234"
48343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - substring("12345", 0, 3) returns "12"
48353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - substring("12345", 0 div 0, 3) returns ""
48363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - substring("12345", 1, 0 div 0) returns ""
48373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - substring("12345", -42, 1 div 0) returns "12345"
48383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  - substring("12345", -1 div 0, 1 div 0) returns ""
48393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
48403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
48413473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringFunction(xmlXPathParserContextPtr ctxt, int nargs) {
48423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr str, start, len;
48433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double le, in;
48443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i, l;
48453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret;
48463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /*
4848e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard     * TODO: need to be converted to UTF8 strings
48493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor     */
48503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs < 2) {
48513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(2);
48523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
48533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs > 3) {
48543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ARITY(3);
48553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
48563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 3) {
48573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CAST_TO_NUMBER;
48583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_TYPE(XPATH_NUMBER);
48593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	len = valuePop(ctxt);
48603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	le = len->floatval;
48613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        xmlXPathFreeObject(len);
48623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
48633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	le = 2000000000;
48643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
48653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
48663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
48673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    start = valuePop(ctxt);
48683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    in = start->floatval;
48693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(start);
48703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
48713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
48723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    str = valuePop(ctxt);
48733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    le += in;
48743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* integer index of the first char */
48763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    i = (int) in;
48773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (((double)i) != in) i++;
48783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* integer index of the last char */
48803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    l = (int) le;
48813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (((double)l) != le) l++;
48823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* back to a zero based len */
48843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    i--;
48853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    l--;
48863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* check against the string len */
48883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (l > 1024) {
48893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        l = xmlStrlen(str->stringval);
48903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
48913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (i < 0) {
48923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        i = 0;
48933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
48943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* number of chars to copy */
48963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    l -= i;
48973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
48983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = xmlStrsub(str->stringval, i, l);
48993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL)
49003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, xmlXPathNewCString(""));
49013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else {
49023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, xmlXPathNewString(ret));
49033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlFree(ret);
49043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
49053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(str);
49063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringBeforeFunction:
49103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
49113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
49123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-before() XPath function
49143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring-before(string, string)
49153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-before function returns the substring of the first
49163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that precedes the first occurrence of the second
49173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty string
49183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument
49193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-before("1999/04/01","/") returns 1999.
49203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
49223473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringBeforeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
49233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr str;
49243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr find;
49253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlBufferPtr target;
49263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  const xmlChar *point;
49273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  int offset;
49283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(2);
49303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
49313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  find = valuePop(ctxt);
49323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
49333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  str = valuePop(ctxt);
49343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  target = xmlBufferCreate();
49363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target) {
49373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    point = xmlStrstr(str->stringval, find->stringval);
49383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (point) {
49393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      offset = (int)(point - str->stringval);
49403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      xmlBufferAdd(target, str->stringval, offset);
49413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
49423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
49433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlBufferFree(target);
49443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
49453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathFreeObject(str);
49473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathFreeObject(find);
49483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSubstringAfterFunction:
49523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
49533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
49543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the substring-after() XPath function
49563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string substring-after(string, string)
49573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The substring-after function returns the substring of the first
49583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string that follows the first occurrence of the second
49593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string in the first argument string, or the empty stringi
49603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * if the first argument string does not contain the second argument
49613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, substring-after("1999/04/01","/") returns 04/01,
49623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and substring-after("1999/04/01","19") returns 99/04/01.
49633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
49643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
49653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSubstringAfterFunction(xmlXPathParserContextPtr ctxt, int nargs) {
49663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr str;
49673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr find;
49683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlBufferPtr target;
49693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  const xmlChar *point;
49703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  int offset;
49713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(2);
49733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
49743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  find = valuePop(ctxt);
49753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
49763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  str = valuePop(ctxt);
49773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  target = xmlBufferCreate();
49793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target) {
49803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    point = xmlStrstr(str->stringval, find->stringval);
49813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (point) {
49823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      offset = (int)(point - str->stringval) + xmlStrlen(find->stringval);
49833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      xmlBufferAdd(target, &str->stringval[offset],
49843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   xmlStrlen(str->stringval) - offset);
49853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
49863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
49873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlBufferFree(target);
49883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
49893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathFreeObject(str);
49913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathFreeObject(find);
49923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
49933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
49943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
49953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNormalizeFunction:
49963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
49973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
49983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
49993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the normalize-space() XPath function
50003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string normalize-space(string?)
50013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The normalize-space function returns the argument string with white
50023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space normalized by stripping leading and trailing whitespace
50033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and replacing sequences of whitespace characters by a single
50043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * space. Whitespace characters are the same allowed by the S production
50053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * in XML. If the argument is omitted, it defaults to the context
50063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node converted to a string, in other words the value of the context node.
50073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
50093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNormalizeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
50103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathObjectPtr obj = NULL;
50113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlChar *source = NULL;
50123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlBufferPtr target;
50133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlChar blank;
50143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (nargs == 0) {
50163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Use current context node */
5017ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    valuePush(ctxt,
5018ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	      xmlXPathWrapString(
5019ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		  xmlXPathCastNodeToString(ctxt->context->node)));
50203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    nargs = 1;
50213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
50223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_ARITY(1);
50243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CAST_TO_STRING;
50253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  CHECK_TYPE(XPATH_STRING);
50263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  obj = valuePop(ctxt);
50273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  source = obj->stringval;
50283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  target = xmlBufferCreate();
50303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  if (target && source) {
50313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Skip leading whitespaces */
50333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (IS_BLANK(*source))
50343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      source++;
50353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* Collapse intermediate whitespaces, and skip trailing whitespaces */
50373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    blank = 0;
50383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (*source) {
50393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      if (IS_BLANK(*source)) {
50403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	blank = *source;
50413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      } else {
50423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (blank) {
50433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	  xmlBufferAdd(target, &blank, 1);
50443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	  blank = 0;
50453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
50463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlBufferAdd(target, source, 1);
50473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      }
50483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor      source++;
50493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
50503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
50523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlBufferFree(target);
50533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  }
50543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor  xmlXPathFreeObject(obj);
50553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
50563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
50573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
50583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTranslateFunction:
50593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
50603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
50613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
50623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the translate() XPath function
50633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    string translate(string, string, string)
50643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The translate function returns the first argument string with
50653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * occurrences of characters in the second argument string replaced
50663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the character at the corresponding position in the third argument
50673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string. For example, translate("bar","abc","ABC") returns the string
50683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * BAr. If there is a character in the second argument string with no
50693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character at a corresponding position in the third argument string
50703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * (because the second argument string is longer than the third argument
50713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string), then occurrences of that character in the first argument
50723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * string are removed. For example, translate("--aaa--","abc-","ABC")
50733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns "AAA". If a character occurs more than once in second
50743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then the first occurrence determines the replacement
50753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * character. If the third argument string is longer than the second
50763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument string, then excess characters are ignored.
50773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
50783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
50793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTranslateFunction(xmlXPathParserContextPtr ctxt, int nargs) {
5080e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr str;
5081e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr from;
5082e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathObjectPtr to;
5083e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlBufferPtr target;
5084e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    int i, offset, max;
5085e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlChar ch;
5086e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    const xmlChar *point;
50873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5088e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    /*
5089e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard     * TODO: need to be converted to UTF8 strings
5090e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard     */
5091e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CHECK_ARITY(3);
50923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5093e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
5094e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    to = valuePop(ctxt);
5095e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
5096e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    from = valuePop(ctxt);
5097e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    CAST_TO_STRING;
5098e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    str = valuePop(ctxt);
50993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5100e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    target = xmlBufferCreate();
5101e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    if (target) {
5102e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	max = xmlStrlen(to->stringval);
5103e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	for (i = 0; (ch = str->stringval[i]); i++) {
5104e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	    point = xmlStrchr(from->stringval, ch);
5105e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	    if (point) {
5106e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard		offset = (int)(point - from->stringval);
5107e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard		if (offset < max)
5108e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard		    xmlBufferAdd(target, &to->stringval[offset], 1);
5109e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard		} else
5110e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard		    xmlBufferAdd(target, &ch, 1);
5111e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	}
51123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5113e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    valuePush(ctxt, xmlXPathNewString(xmlBufferContent(target)));
5114e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlBufferFree(target);
5115e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathFreeObject(str);
5116e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathFreeObject(from);
5117e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    xmlXPathFreeObject(to);
51183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5121fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathBooleanFunction:
5122fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath Parser context
5123fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @nargs:  the number of arguments
5124fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
5125fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Implement the boolean() XPath function
5126fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    boolean boolean(object)
5127fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * he boolean function converts its argument to a boolean as follows:
5128fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a number is true if and only if it is neither positive or
5129fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *      negative zero nor NaN
5130fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a node-set is true if and only if it is non-empty
5131fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *    - a string is true if and only if its length is non-zero
5132fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
5133fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardvoid
5134fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathBooleanFunction(xmlXPathParserContextPtr ctxt, int nargs) {
5135fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    xmlXPathObjectPtr cur;
5136fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
5137fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    CHECK_ARITY(1);
5138fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    cur = valuePop(ctxt);
5139fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    if (cur == NULL) XP_ERROR(XPATH_INVALID_OPERAND);
5140fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    cur = xmlXPathConvertBoolean(cur);
5141fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    valuePush(ctxt, cur);
51423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNotFunction:
51463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
51473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
51483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the not() XPath function
51503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean not(boolean)
51513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The not function returns true if its argument is false,
51523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and false otherwise.
51533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
51553473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNotFunction(xmlXPathParserContextPtr ctxt, int nargs) {
51563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
51573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_BOOLEAN;
51583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_BOOLEAN);
51593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->value->boolval = ! ctxt->value->boolval;
51603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathTrueFunction:
51643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
51653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
51663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the true() XPath function
51683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean true()
51693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
51713473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathTrueFunction(xmlXPathParserContextPtr ctxt, int nargs) {
51723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(0);
51733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, xmlXPathNewBoolean(1));
51743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFalseFunction:
51783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
51793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
51803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the false() XPath function
51823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean false()
51833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
51843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
51853473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFalseFunction(xmlXPathParserContextPtr ctxt, int nargs) {
51863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(0);
51873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, xmlXPathNewBoolean(0));
51883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
51893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
51903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
51913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathLangFunction:
51923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
51933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
51943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
51953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the lang() XPath function
51963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    boolean lang(string)
51973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The lang function returns true or false depending on whether the
51983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * language of the context node as specified by xml:lang attributes
51993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * is the same as or is a sublanguage of the language specified by
52003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument string. The language of the context node is determined
52013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * by the value of the xml:lang attribute on the context node, or, if
52023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the context node has no xml:lang attribute, by the value of the
52033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xml:lang attribute on the nearest ancestor of the context node that
52043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * has an xml:lang attribute. If there is no such attribute, then lang
52053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * returns false. If there is such an attribute, then lang returns
52063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * true if the attribute value is equal to the argument ignoring case,
52073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * or if there is some suffix starting with - such that the attribute
52083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value is equal to the argument ignoring that suffix of the attribute
52093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * value and ignoring case.
52103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
52113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
52123473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathLangFunction(xmlXPathParserContextPtr ctxt, int nargs) {
52133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr val;
52143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *theLang;
52153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *lang;
52163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ret = 0;
52173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
52183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
52203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_STRING;
52213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_STRING);
52223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    val = valuePop(ctxt);
52233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    lang = val->stringval;
52243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    theLang = xmlNodeGetLang(ctxt->context->node);
52253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((theLang != NULL) && (lang != NULL)) {
52263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        for (i = 0;lang[i] != 0;i++)
52273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (toupper(lang[i]) != toupper(theLang[i]))
52283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        goto not_equal;
52293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret = 1;
52303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
52313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylornot_equal:
52323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(val);
52333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    valuePush(ctxt, xmlXPathNewBoolean(ret));
52343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
52353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
52373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathNumberFunction:
52383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
52393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
52403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the number() XPath function
52423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number number(object?)
52433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
52443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
52453473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathNumberFunction(xmlXPathParserContextPtr ctxt, int nargs) {
52463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
52473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double res;
52483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (nargs == 0) {
52503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (ctxt->context->node == NULL) {
52513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, xmlXPathNewFloat(0.0));
52523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
52533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlChar* content = xmlNodeGetContent(ctxt->context->node);
52543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    res = xmlXPathStringEvalNumber(content);
52563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    valuePush(ctxt, xmlXPathNewFloat(res));
52573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(content);
52583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
52593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
52603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
52613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
52633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
5264fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    cur = xmlXPathConvertNumber(cur);
5265fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    valuePush(ctxt, cur);
52663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
52673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
52693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathSumFunction:
52703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
52713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
52723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
52733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the sum() XPath function
52743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number sum(node-set)
52753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The sum function returns the sum of the values of the nodes in
52763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * the argument node-set.
52773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
52783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
52793473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathSumFunction(xmlXPathParserContextPtr ctxt, int nargs) {
52803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr cur;
52813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int i;
5282ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard    double res = 0.0;
52833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
52843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
52853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->value == NULL) ||
52863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	((ctxt->value->type != XPATH_NODESET) &&
52873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 (ctxt->value->type != XPATH_XSLT_TREE)))
52883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_INVALID_TYPE);
52893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    cur = valuePop(ctxt);
52903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
5291d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if ((cur->nodesetval == NULL) || (cur->nodesetval->nodeNr == 0)) {
52923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	valuePush(ctxt, xmlXPathNewFloat(0.0));
52933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
5294ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	for (i = 0; i < cur->nodesetval->nodeNr; i++) {
5295ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	    res += xmlXPathCastNodeToNumber(cur->nodesetval->nodeTab[i]);
52963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
5297ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard	valuePush(ctxt, xmlXPathNewFloat(res));
52983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
52993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeObject(cur);
53003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
53013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
53033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathFloorFunction:
53043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
53053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
53063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
53073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the floor() XPath function
53083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number floor(number)
53093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The floor function returns the largest (closest to positive infinity)
53103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not greater than the argument and that is an integer.
53113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
53123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
53133473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathFloorFunction(xmlXPathParserContextPtr ctxt, int nargs) {
53143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
53153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
53163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
53173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0
53183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->value->floatval = floor(ctxt->value->floatval);
53193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else
53203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    /* floor(0.999999999999) => 1.0 !!!!!!!!!!! */
53213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->value->floatval = (double)((int) ctxt->value->floatval);
53223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
53233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
53243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
53263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathCeilingFunction:
53273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
53283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
53293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
53303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the ceiling() XPath function
53313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number ceiling(number)
53323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The ceiling function returns the smallest (closest to negative infinity)
53333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * number that is not less than the argument and that is an integer.
53343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
53353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
53363473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathCeilingFunction(xmlXPathParserContextPtr ctxt, int nargs) {
53373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double f;
53383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
53403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
53413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
53423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0
53443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt->value->floatval = ceil(ctxt->value->floatval);
53453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else
53463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    f = (double)((int) ctxt->value->floatval);
53473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (f != ctxt->value->floatval)
53483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ctxt->value->floatval = f + 1;
53493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
53503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
53513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
53533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRoundFunction:
53543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
53553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @nargs:  the number of arguments
53563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
53573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Implement the round() XPath function
53583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *    number round(number)
53593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The round function returns the number that is closest to the
53603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * argument and that is an integer. If there are two such numbers,
53613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * then the one that is even is returned.
53623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
53633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
53643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRoundFunction(xmlXPathParserContextPtr ctxt, int nargs) {
53653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double f;
53663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ARITY(1);
53683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CAST_TO_NUMBER;
53693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_TYPE(XPATH_NUMBER);
53703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((ctxt->value->floatval == xmlXPathNAN) ||
53723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->value->floatval == xmlXPathPINF) ||
53733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->value->floatval == xmlXPathNINF) ||
53743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	(ctxt->value->floatval == 0.0))
53753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return;
53763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#if 0
53783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    f = floor(ctxt->value->floatval);
53793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else
53803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    f = (double)((int) ctxt->value->floatval);
53813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
53823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->value->floatval < f + 0.5)
53833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ctxt->value->floatval = f;
53843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
53853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ctxt->value->floatval = f + 1;
53863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
53873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/************************************************************************
53893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
53903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *			The Parser					*
53913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *									*
53923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor ************************************************************************/
53933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
53943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/*
53953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * a couple of forward declarations since we use a recursive call based
53963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * implementation.
53973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
5398afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompileExpr(xmlXPathParserContextPtr ctxt);
5399d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void xmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter);
5400afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt);
54013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef VMS
5402afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelLocationPath(xmlXPathParserContextPtr ctxt);
5403afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard#define xmlXPathCompRelativeLocationPath xmlXPathCompRelLocationPath
54043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else
5405afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void xmlXPathCompRelativeLocationPath(xmlXPathParserContextPtr ctxt);
54063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
54072156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillardstatic xmlChar * xmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt,
54082156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	                                  int qualified);
54093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
54103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
541161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * xmlXPathCurrentChar:
541261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @ctxt:  the XPath parser context
541361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @cur:  pointer to the beginning of the char
541461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * @len:  pointer to the length of the char read
541561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *
541661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * The current char value, if using UTF-8 this may actaully span multiple
541761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * bytes in the input buffer.
541861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard *
541961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard * Returns the current char value and its lenght
542061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard */
542161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
542261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic int
542361d80a2822b2678dee885ac2850295cc96277c63Daniel VeillardxmlXPathCurrentChar(xmlXPathParserContextPtr ctxt, int *len) {
542461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    unsigned char c;
542561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    unsigned int val;
542661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    const xmlChar *cur;
542761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
542861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (ctxt == NULL)
542961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(0);
543061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    cur = ctxt->cur;
543161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
543261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
543361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * We are supposed to handle UTF8, check it's valid
543461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * From rfc2044: encoding of the Unicode values on UTF-8:
543561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     *
543661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * UCS-4 range (hex.)           UTF-8 octet sequence (binary)
543761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * 0000 0000-0000 007F   0xxxxxxx
543861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * 0000 0080-0000 07FF   110xxxxx 10xxxxxx
543961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx
544061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     *
544161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Check for the 0x110000 limit too
544261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
544361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    c = *cur;
544461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (c & 0x80) {
544561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if ((cur[1] & 0xc0) != 0x80)
544661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    goto encoding_error;
544761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if ((c & 0xe0) == 0xe0) {
544861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
544961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if ((cur[2] & 0xc0) != 0x80)
545061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		goto encoding_error;
545161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if ((c & 0xf0) == 0xf0) {
545261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		if (((c & 0xf8) != 0xf0) ||
545361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    ((cur[3] & 0xc0) != 0x80))
545461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    goto encoding_error;
545561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		/* 4-byte code */
545661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		*len = 4;
545761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val = (cur[0] & 0x7) << 18;
545861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[1] & 0x3f) << 12;
545961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[2] & 0x3f) << 6;
546061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= cur[3] & 0x3f;
546161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    } else {
546261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	      /* 3-byte code */
546361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		*len = 3;
546461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val = (cur[0] & 0xf) << 12;
546561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= (cur[1] & 0x3f) << 6;
546661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		val |= cur[2] & 0x3f;
546761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
546861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	} else {
546961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	  /* 2-byte code */
547061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    *len = 2;
547161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    val = (cur[0] & 0x1f) << 6;
547261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    val |= cur[1] & 0x3f;
547361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
547461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if (!IS_CHAR(val)) {
547561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    XP_ERROR0(XPATH_INVALID_CHAR_ERROR);
547661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
547761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(val);
547861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    } else {
547961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	/* 1-byte code */
548061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	*len = 1;
548161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return((int) *cur);
548261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
548361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardencoding_error:
548461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
548561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * If we detect an UTF8 error that probably mean that the
548661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * input encoding didn't get properly advertized in the
548761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * declaration header. Report the error and switch the encoding
548861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * to ISO-Latin-1 (if you don't like this policy, just declare the
548961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * encoding !)
549061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
549142596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard    *len = 0;
549261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    XP_ERROR0(XPATH_ENCODING_ERROR);
549361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
549461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
549561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard/**
54963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseNCName:
54973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
54983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
54993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML namespace non qualified name.
55003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 3] NCName ::= (Letter | '_') (NCNameChar)*
55023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 4] NCNameChar ::= Letter | Digit | '.' | '-' | '_' |
55043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                       CombiningChar | Extender
55053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL
55073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
55083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
55093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar *
55103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseNCName(xmlXPathParserContextPtr ctxt) {
55112156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    const xmlChar *in;
55122156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    xmlChar *ret;
55132156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    int count = 0;
55143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
55152156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    /*
55162156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard     * Accelerator for simple ASCII names
55172156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard     */
55182156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    in = ctxt->cur;
55192156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    if (((*in >= 0x61) && (*in <= 0x7A)) ||
55202156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	((*in >= 0x41) && (*in <= 0x5A)) ||
55212156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	(*in == '_')) {
55222156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	in++;
55232156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	while (((*in >= 0x61) && (*in <= 0x7A)) ||
55242156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	       ((*in >= 0x41) && (*in <= 0x5A)) ||
55252156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	       ((*in >= 0x30) && (*in <= 0x39)) ||
55262156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	       (*in == '_'))
55272156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    in++;
55282156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	if ((*in == ' ') || (*in == '>') || (*in == '/') ||
55292156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard            (*in == '[') || (*in == ']') || (*in == ':') ||
55302156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard            (*in == '@') || (*in == '*')) {
55312156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    count = in - ctxt->cur;
55322156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (count == 0)
55332156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		return(NULL);
55342156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    ret = xmlStrndup(ctxt->cur, count);
55352156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    ctxt->cur = in;
55362156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    return(ret);
55372156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	}
55382156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    }
55392156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    return(xmlXPathParseNameComplex(ctxt, 0));
55403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
55413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
55422156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard
55433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
55443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseQName:
55453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
55463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix:  a xmlChar **
55473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML qualified name
55493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 5] QName ::= (Prefix ':')? LocalPart
55513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 6] Prefix ::= NCName
55533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [NS 7] LocalPart ::= NCName
55553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the function returns the local part, and prefix is updated
55573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *   to get the Prefix if any.
55583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
55593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
556056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
55613473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseQName(xmlXPathParserContextPtr ctxt, xmlChar **prefix) {
55623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret = NULL;
55633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
55643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *prefix = NULL;
55653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ret = xmlXPathParseNCName(ctxt);
55663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == ':') {
55673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        *prefix = ret;
55683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
55693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ret = xmlXPathParseNCName(ctxt);
55703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
55713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
55723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
55733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
55743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
55753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathParseName:
55763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
55773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * parse an XML name
55793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
55813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  CombiningChar | Extender
55823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)*
55843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
55853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the namespace name or NULL
55863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
55873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
55883473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlChar *
55893473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathParseName(xmlXPathParserContextPtr ctxt) {
559061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    const xmlChar *in;
559161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    xmlChar *ret;
559261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    int count = 0;
55933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
559461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
559561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Accelerator for simple ASCII names
559661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
559761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    in = ctxt->cur;
559861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if (((*in >= 0x61) && (*in <= 0x7A)) ||
559961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	((*in >= 0x41) && (*in <= 0x5A)) ||
560061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	(*in == '_') || (*in == ':')) {
560161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	in++;
560261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	while (((*in >= 0x61) && (*in <= 0x7A)) ||
560361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	       ((*in >= 0x41) && (*in <= 0x5A)) ||
560461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	       ((*in >= 0x30) && (*in <= 0x39)) ||
560576d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	       (*in == '_') || (*in == '-') ||
560676d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	       (*in == ':') || (*in == '.'))
560761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    in++;
560876d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	if ((*in > 0) && (*in < 0x80)) {
560961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    count = in - ctxt->cur;
561061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    ret = xmlStrndup(ctxt->cur, count);
561161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    ctxt->cur = in;
561261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    return(ret);
561361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
561461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
56152156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    return(xmlXPathParseNameComplex(ctxt, 1));
561661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
56173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
561861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillardstatic xmlChar *
56192156a56bcbf5d83fb3d694123be01beebf84d273Daniel VeillardxmlXPathParseNameComplex(xmlXPathParserContextPtr ctxt, int qualified) {
562061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    xmlChar buf[XML_MAX_NAMELEN + 5];
562161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    int len = 0, l;
562261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    int c;
56233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
562461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    /*
562561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     * Handler for more complex cases
562661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard     */
562761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    c = CUR_CHAR(l);
562861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    if ((c == ' ') || (c == '>') || (c == '/') || /* accelerators */
56292156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard        (c == '[') || (c == ']') || (c == '@') || /* accelerators */
56302156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard        (c == '*') || /* accelerators */
563161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	(!IS_LETTER(c) && (c != '_') &&
56322156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard         ((qualified) && (c != ':')))) {
563361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	return(NULL);
563461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
56353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
563661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    while ((c != ' ') && (c != '>') && (c != '/') && /* test bigname.xml */
563761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	   ((IS_LETTER(c)) || (IS_DIGIT(c)) ||
563861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard            (c == '.') || (c == '-') ||
56392156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    (c == '_') || ((qualified) && (c == ':')) ||
564061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    (IS_COMBINING(c)) ||
564161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    (IS_EXTENDER(c)))) {
564261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	COPY_BUF(l,buf,len,c);
564361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	NEXTL(l);
564461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	c = CUR_CHAR(l);
564561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	if (len >= XML_MAX_NAMELEN) {
564661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    /*
564761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     * Okay someone managed to make a huge name, so he's ready to pay
564861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     * for the processing speed.
564961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	     */
565061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    xmlChar *buffer;
565161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    int max = len * 2;
565261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard
565361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    buffer = (xmlChar *) xmlMalloc(max * sizeof(xmlChar));
565461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    if (buffer == NULL) {
565561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		XP_ERROR0(XPATH_MEMORY_ERROR);
565661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
565761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    memcpy(buffer, buf, len);
565861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    while ((IS_LETTER(c)) || (IS_DIGIT(c)) || /* test bigname.xml */
565961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (c == '.') || (c == '-') ||
56602156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		   (c == '_') || ((qualified) && (c == ':')) ||
566161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (IS_COMBINING(c)) ||
566261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		   (IS_EXTENDER(c))) {
566361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		if (len + 10 > max) {
566461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    max *= 2;
566561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    buffer = (xmlChar *) xmlRealloc(buffer,
566661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard			                            max * sizeof(xmlChar));
566761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    if (buffer == NULL) {
566861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard			XP_ERROR0(XPATH_MEMORY_ERROR);
566961d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		    }
567061d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		}
567161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		COPY_BUF(l,buffer,len,c);
567261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		NEXTL(l);
567361d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard		c = CUR_CHAR(l);
567461d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    }
567561d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    buffer[len] = 0;
567661d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	    return(buffer);
567761d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard	}
567861d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    }
56792156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard    if (len == 0)
56802156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	return(NULL);
568161d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard    return(xmlStrndup(buf, len));
568261d80a2822b2678dee885ac2850295cc96277c63Daniel Veillard}
56833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
56843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathStringEvalNumber:
56853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  A string to scan
56863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
568770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese *  [30a]  Float  ::= Number ('e' Digits?)?
568870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese *
56893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [30]   Number ::=   Digits ('.' Digits?)?
56903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | '.' Digits
56913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [31]   Digits ::=   [0-9]+
56923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
5693afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number in the string
56943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * In complement of the Number expression, this function also handles
56953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * negative values : '-' Number.
56963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
56973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the double value.
56983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
56993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylordouble
57003473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathStringEvalNumber(const xmlChar *str) {
57013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *cur = str;
57023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double ret = 0.0;
57033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double mult = 1;
57043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ok = 0;
57053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int isneg = 0;
570670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int exponent = 0;
570770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int is_exponent_negative = 0;
570870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese
57093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (IS_BLANK(*cur)) cur++;
57103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((*cur != '.') && ((*cur < '0') || (*cur > '9')) && (*cur != '-')) {
57113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        return(xmlXPathNAN);
57123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
57133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur == '-') {
57143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	isneg = 1;
57153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur++;
57163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
57173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((*cur >= '0') && (*cur <= '9')) {
57183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret = ret * 10 + (*cur - '0');
57193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ok = 1;
57203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	cur++;
57213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
57223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur == '.') {
57233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        cur++;
57243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (((*cur < '0') || (*cur > '9')) && (!ok)) {
57253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(xmlXPathNAN);
57263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
57273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while ((*cur >= '0') && (*cur <= '9')) {
57283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    mult /= 10;
57293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = ret  + (*cur - '0') * mult;
57303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    cur++;
57313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
57323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
573370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if ((*cur == 'e') || (*cur == 'E')) {
573470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      cur++;
573570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      if (*cur == '-') {
573670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	is_exponent_negative = 1;
573770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	cur++;
573870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      }
573970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      while ((*cur >= '0') && (*cur <= '9')) {
574070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	exponent = exponent * 10 + (*cur - '0');
574170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	cur++;
574270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      }
574370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    }
57443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (IS_BLANK(*cur)) cur++;
57453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*cur != 0) return(xmlXPathNAN);
57463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (isneg) ret = -ret;
574770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if (is_exponent_negative) exponent = -exponent;
574870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    ret *= pow(10.0, (double)exponent);
57493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
57503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
57513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
57523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5753afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNumber:
57543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
57553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
57563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [30]   Number ::=   Digits ('.' Digits?)?
57573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | '.' Digits
57583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [31]   Digits ::=   [0-9]+
57593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
5760afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Number, then push it on the stack
57613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
57623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
5763afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
5764afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompNumber(xmlXPathParserContextPtr ctxt) {
57653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double ret = 0.0;
57663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    double mult = 1;
57673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int ok = 0;
576870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int exponent = 0;
576970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    int is_exponent_negative = 0;
57703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
57713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
57723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR != '.') && ((CUR < '0') || (CUR > '9'))) {
57733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        XP_ERROR(XPATH_NUMBER_ERROR);
57743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
57753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR >= '0') && (CUR <= '9')) {
57763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        ret = ret * 10 + (CUR - '0');
57773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	ok = 1;
57783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
57793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
57803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '.') {
57813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
57823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (((CUR < '0') || (CUR > '9')) && (!ok)) {
57833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     XP_ERROR(XPATH_NUMBER_ERROR);
57843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
57853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while ((CUR >= '0') && (CUR <= '9')) {
57863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    mult /= 10;
57873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = ret  + (CUR - '0') * mult;
57883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
57893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
57903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
579170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if ((CUR == 'e') || (CUR == 'E')) {
579270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      NEXT;
579370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      if (CUR == '-') {
579470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	is_exponent_negative = 1;
579570a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	NEXT;
579670a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      }
579770a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      while ((CUR >= '0') && (CUR <= '9')) {
579870a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	exponent = exponent * 10 + (CUR - '0');
579970a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese	NEXT;
580070a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      }
580170a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    }
580270a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    if (is_exponent_negative)
580370a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese      exponent = -exponent;
580470a9da54eb200cd5c5ceafb72aff72c39021c94cBjorn Reese    ret *= pow(10.0, (double)exponent);
58059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_NUMBER, 0, 0,
58069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	           xmlXPathNewFloat(ret), NULL);
58073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
58083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
58093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5810fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathParseLiteral:
5811fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath Parser context
5812fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
5813fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Parse a Literal
5814fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
5815fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *  [29]   Literal ::=   '"' [^"]* '"'
5816fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *                    | "'" [^']* "'"
5817fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
5818fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Returns the value found or NULL in case of error
5819fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
5820fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic xmlChar *
5821fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathParseLiteral(xmlXPathParserContextPtr ctxt) {
5822fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    const xmlChar *q;
5823fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    xmlChar *ret = NULL;
5824fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
5825fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    if (CUR == '"') {
5826fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        NEXT;
5827fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	q = CUR_PTR;
5828fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	while ((IS_CHAR(CUR)) && (CUR != '"'))
5829fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
5830fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	if (!IS_CHAR(CUR)) {
5831fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR);
5832fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	} else {
5833fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    ret = xmlStrndup(q, CUR_PTR - q);
5834fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
5835fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        }
5836fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    } else if (CUR == '\'') {
5837fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        NEXT;
5838fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	q = CUR_PTR;
5839fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	while ((IS_CHAR(CUR)) && (CUR != '\''))
5840fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
5841fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	if (!IS_CHAR(CUR)) {
5842fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    XP_ERROR0(XPATH_UNFINISHED_LITERAL_ERROR);
5843fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	} else {
5844fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    ret = xmlStrndup(q, CUR_PTR - q);
5845fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    NEXT;
5846fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        }
5847fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    } else {
5848fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	XP_ERROR0(XPATH_START_LITERAL_ERROR);
5849fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    }
5850fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    return(ret);
5851fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard}
5852fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
5853fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
5854afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLiteral:
58553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
58563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
58573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a Literal and push it on the stack.
58583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
58593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [29]   Literal ::=   '"' [^"]* '"'
58603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | "'" [^']* "'"
58613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
5862afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * TODO: xmlXPathCompLiteral memory allocation could be improved.
58633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
5864afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
5865afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLiteral(xmlXPathParserContextPtr ctxt) {
58663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    const xmlChar *q;
58673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *ret = NULL;
58683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
58693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '"') {
58703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
58713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	q = CUR_PTR;
58723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while ((IS_CHAR(CUR)) && (CUR != '"'))
58733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
58743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (!IS_CHAR(CUR)) {
58753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
58763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
58773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlStrndup(q, CUR_PTR - q);
58783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
58793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
58803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '\'') {
58813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        NEXT;
58823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	q = CUR_PTR;
58833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while ((IS_CHAR(CUR)) && (CUR != '\''))
58843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
58853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (!IS_CHAR(CUR)) {
58863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_UNFINISHED_LITERAL_ERROR);
58873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
58883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    ret = xmlStrndup(q, CUR_PTR - q);
58893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
58903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
58913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
58923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_START_LITERAL_ERROR);
58933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
58943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ret == NULL) return;
58959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VALUE, XPATH_STRING, 0, 0,
58969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	           xmlXPathNewString(ret), NULL);
58973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlFree(ret);
58983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
58993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5901afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompVariableReference:
59023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
59033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Parse a VariableReference, evaluate it and push it on the stack.
59053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings consist of a mapping from variable names
59073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to variable values. The value of a variable is an object, which
59083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * of any of the types that are possible for the value of an expression,
59093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and may also be of additional types not specified here.
59103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Early evaluation is possible since:
59123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The variable bindings [...] used to evaluate a subexpression are
59133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * always the same as those used to evaluate the containing expression.
59143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [36]   VariableReference ::=   '$' QName
59163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
5917afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
5918afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompVariableReference(xmlXPathParserContextPtr ctxt) {
59193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name;
59203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *prefix;
59213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
59233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '$') {
59243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
59253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
59263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
59273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    name = xmlXPathParseQName(ctxt, &prefix);
59283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
59293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_VARIABLE_REF_ERROR);
59303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
5931fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    ctxt->comp->last = -1;
59329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_VARIABLE, 0, 0, 0,
59339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	           name, prefix);
59343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
59353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
59363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
59383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsNodeType:
59393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
59403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  a name string
59413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Is the name given a NodeType one.
59433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [38]   NodeType ::=   'comment'
59453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'text'
59463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'processing-instruction'
59473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                    | 'node'
59483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns 1 if true 0 otherwise
59503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
59513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorint
59523473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsNodeType(const xmlChar *name) {
59533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
59543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(0);
59553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(name, BAD_CAST "comment"))
59573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
59583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(name, BAD_CAST "text"))
59593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
59603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
59613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
59623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (xmlStrEqual(name, BAD_CAST "node"))
59633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(1);
59643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(0);
59653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
59663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
5968afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFunctionCall:
59693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
59703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
59713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [16]   FunctionCall ::=   FunctionName '(' ( Argument ( ',' Argument)*)? ')'
59723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [17]   Argument ::=   Expr
59733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
5974afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a function call, the evaluation of all arguments are
59753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * pushed on the stack
59763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
5977afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
5978afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFunctionCall(xmlXPathParserContextPtr ctxt) {
59793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name;
59803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *prefix;
59813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int nbargs = 0;
59823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    name = xmlXPathParseQName(ctxt, &prefix);
59843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
59853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_EXPR_ERROR);
59863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
59873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
59883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_EXPR
59893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (prefix == NULL)
59903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Calling function %s\n",
59913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			name);
59923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else
59933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Calling function %s:%s\n",
59943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			prefix, name);
59953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
59963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
59973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '(') {
59983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR(XPATH_EXPR_ERROR);
59993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
60003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
60013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
60023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ctxt->comp->last = -1;
60043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR != ')') {
60059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
60069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->comp->last = -1;
6007afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompileExpr(ctxt);
60089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_ARG, op1, ctxt->comp->last, 0, 0);
60093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	nbargs++;
60103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR == ')') break;
60113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR != ',') {
60123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_EXPR_ERROR);
60133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
60143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
60153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
60163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
60179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    PUSH_LONG_EXPR(XPATH_OP_FUNCTION, nbargs, 0, 0,
60189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	           name, prefix);
60193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    NEXT;
60203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
60213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
60223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6024afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPrimaryExpr:
60253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
60263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [15]   PrimaryExpr ::=   VariableReference
60283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                | '(' Expr ')'
60293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                | Literal
60303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                | Number
60313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                | FunctionCall
60323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6033afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a primary expression.
60343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
6035afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6036afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPrimaryExpr(xmlXPathParserContextPtr ctxt) {
60373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
6038afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    if (CUR == '$') xmlXPathCompVariableReference(ctxt);
60393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    else if (CUR == '(') {
60403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
60413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
6042afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompileExpr(ctxt);
60433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR != ')') {
60443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_EXPR_ERROR);
60453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
60463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
60473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
60483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (IS_DIGIT(CUR)) {
6049afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompNumber(ctxt);
60503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if ((CUR == '\'') || (CUR == '"')) {
6051afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompLiteral(ctxt);
60523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
6053afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompFunctionCall(ctxt);
60543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
60553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
60563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
60573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6059afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompFilterExpr:
60603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
60613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [20]   FilterExpr ::=   PrimaryExpr
60633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *               | FilterExpr Predicate
60643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6065afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a filter expression.
60663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Square brackets are used to filter expressions in the same way that
60673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * they are used in location paths. It is an error if the expression to
60683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * be filtered does not evaluate to a node-set. The context node list
60693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used for evaluating the expression in square brackets is the node-set
60703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * to be filtered listed in document order.
60713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
60723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6073afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6074afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompFilterExpr(xmlXPathParserContextPtr ctxt) {
6075afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompPrimaryExpr(ctxt);
60763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
60773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
60783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '[') {
6080d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlXPathCompPredicate(ctxt, 1);
60813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
60823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
60833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
60863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
60873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
60883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathScanName:
60893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
60903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Trickery: parse an XML name but without consuming the input flow
60923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Needed to avoid insanity in the parser state.
60933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | ':' |
60953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  CombiningChar | Extender
60963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] Name ::= (Letter | '_' | ':') (NameChar)*
60983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
60993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] Names ::= Name (S Name)*
61003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
61013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the Name parsed or NULL
61023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
61033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
610456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
61053473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathScanName(xmlXPathParserContextPtr ctxt) {
61063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar buf[XML_MAX_NAMELEN];
61073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int len = 0;
61083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
61103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (!IS_LETTER(CUR) && (CUR != '_') &&
61113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        (CUR != ':')) {
61123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
61133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
61143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
61163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           (NXT(len) == '.') || (NXT(len) == '-') ||
61173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	   (NXT(len) == '_') || (NXT(len) == ':') ||
61183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	   (IS_COMBINING(NXT(len))) ||
61193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	   (IS_EXTENDER(NXT(len)))) {
61203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	buf[len] = NXT(len);
61213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	len++;
61223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (len >= XML_MAX_NAMELEN) {
61233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
61243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	       "xmlScanName: reached XML_MAX_NAMELEN limit\n");
61253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    while ((IS_LETTER(NXT(len))) || (IS_DIGIT(NXT(len))) ||
61263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   (NXT(len) == '.') || (NXT(len) == '-') ||
61273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   (NXT(len) == '_') || (NXT(len) == ':') ||
61283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   (IS_COMBINING(NXT(len))) ||
61293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		   (IS_EXTENDER(NXT(len))))
61303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		 len++;
61313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
61323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
61333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
61343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(xmlStrndup(buf, len));
61353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
61363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6138afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPathExpr:
61393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
61403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
61413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [19]   PathExpr ::=   LocationPath
61423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *               | FilterExpr
61433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *               | FilterExpr '/' RelativeLocationPath
61443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *               | FilterExpr '//' RelativeLocationPath
61453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6146afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a path expression.
61473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator and // operators combine an arbitrary expression
61483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and a relative location path. It is an error if the expression
61493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * does not evaluate to a node-set.
61503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * The / operator does composition in the same way as when / is
61513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * used in a location path. As in location paths, // is short for
61523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * /descendant-or-self::node()/.
61533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
61543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6155afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6156afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompPathExpr(xmlXPathParserContextPtr ctxt) {
61573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int lc = 1;           /* Should we branch to LocationPath ?         */
61583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlChar *name = NULL; /* we may have to preparse a name to find out */
61593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
61603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
61613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR == '$') || (CUR == '(') || (IS_DIGIT(CUR)) ||
61623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        (CUR == '\'') || (CUR == '"')) {
61633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 0;
61643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '*') {
61653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative or absolute location path */
61663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
61673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '/') {
61683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative or absolute location path */
61693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
61703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '@') {
61713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative abbreviated attribute location path */
61723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
61733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '.') {
61743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/* relative abbreviated attribute location path */
61753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	lc = 1;
61763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
61773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
61783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * Problem is finding if we have a name here whether it's:
61793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a nodetype
61803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a function call in which case it's followed by '('
61813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - an axis in which case it's followed by ':'
61823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 *   - a element name
61833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * We do an a priori analysis here rather than having to
61843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * maintain parsed token content through the recursive function
61853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * calls. This looks uglier but makes the code quite easier to
61863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * read/write/debug.
61873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
61883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
61893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathScanName(ctxt);
61903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((name != NULL) && (xmlStrstr(name, (xmlChar *) "::") != NULL)) {
61913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
61923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlGenericError(xmlGenericErrorContext,
61933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    "PathExpr: Axis\n");
61943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
61953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    lc = 1;
61963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
61973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (name != NULL) {
61983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    int len =xmlStrlen(name);
61993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    int blank = 0;
62003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    while (NXT(len) != 0) {
62033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (NXT(len) == '/') {
62043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* element name */
62053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
62063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
62073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
62083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
62093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
62103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
62113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if (IS_BLANK(NXT(len))) {
62123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* skip to next */
62133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    blank = 1;
62143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if (NXT(len) == ':') {
62153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
62163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
62173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
62183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
62193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
62203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
62213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '(')) {
62223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* Note Type or Function */
62233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    if (xmlXPathIsNodeType(name)) {
62243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
62253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		        xmlGenericError(xmlGenericErrorContext,
62263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				"PathExpr: Type search\n");
62273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
62283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			lc = 1;
62293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    } else {
62303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
62313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		        xmlGenericError(xmlGenericErrorContext,
62323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor				"PathExpr: function call\n");
62333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
62343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			lc = 0;
62353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    }
62363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                    break;
62373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '[')) {
62383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    /* element name */
62393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
62403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    xmlGenericError(xmlGenericErrorContext,
62413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			    "PathExpr: AbbrRelLocation\n");
62423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
62433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
62443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
62453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else if ((NXT(len) == '<') || (NXT(len) == '>') ||
62463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			   (NXT(len) == '=')) {
62473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
62483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
62493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else {
62503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    lc = 1;
62513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    break;
62523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
62533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		len++;
62543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
62553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (NXT(len) == 0) {
62563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
62573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlGenericError(xmlGenericErrorContext,
62583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			"PathExpr: AbbrRelLocation\n");
62593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
62603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		/* element name */
62613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		lc = 1;
62623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
62633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
62643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else {
62653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    /* make sure all cases are covered explicitely */
62663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR(XPATH_EXPR_ERROR);
62673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
62683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
62693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (lc) {
62719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (CUR == '/') {
62729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LEAVE_EXPR(XPATH_OP_ROOT, 0, 0);
62739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	} else {
62749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
62753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
6276afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompLocationPath(ctxt);
62773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
6278afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompFilterExpr(ctxt);
62793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
62803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((CUR == '/') && (NXT(1) == '/')) {
62813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(2);
62823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
62839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
62849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
62859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
62869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_RESET, ctxt->comp->last, 1, 0);
62879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6288afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompRelativeLocationPath(ctxt);
62893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == '/') {
6290afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompRelativeLocationPath(ctxt);
62913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
62923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
62933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
62943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
62953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
62963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6297afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnionExpr:
62983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
62993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
63003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [18]   UnionExpr ::=   PathExpr
63013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *               | UnionExpr '|' PathExpr
63023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6303afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an union expression.
63043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
63053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6306afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6307afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnionExpr(xmlXPathParserContextPtr ctxt) {
6308afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompPathExpr(ctxt);
63093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
63103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
63113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '|') {
63129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
63139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LEAVE_EXPR(XPATH_OP_NODE, 0, 0);
63143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
63163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
6317afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	xmlXPathCompPathExpr(ctxt);
63183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_UNION, op1, ctxt->comp->last, 0, 0);
63209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
63213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
63223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
63233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
63243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6326afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompUnaryExpr:
63273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
63283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
63293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [27]   UnaryExpr ::=   UnionExpr
63303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                   | '-' UnaryExpr
63313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6332afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an unary expression.
63333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
63343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6335afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6336afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompUnaryExpr(xmlXPathParserContextPtr ctxt) {
63373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int minus = 0;
63389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int found = 0;
63393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
634168d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard    while (CUR == '-') {
634268d7b67ada0941ad7e1d02602f48de4015a67af3Daniel Veillard        minus = 1 - minus;
63439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	found = 1;
63443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
63453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
63463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
63479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6348afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompUnionExpr(ctxt);
63493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
63509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (found) {
63519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (minus)
63529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 2, 0);
63539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	else
63549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_UNARY_EXPR(XPATH_OP_PLUS, ctxt->comp->last, 3, 0);
63553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
63563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
63573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6359afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompMultiplicativeExpr:
63603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
63613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
63623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [26]   MultiplicativeExpr ::=   UnaryExpr
63633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                   | MultiplicativeExpr MultiplyOperator UnaryExpr
63643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                   | MultiplicativeExpr 'div' UnaryExpr
63653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                   | MultiplicativeExpr 'mod' UnaryExpr
63663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [34]   MultiplyOperator ::=   '*'
63673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6368afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression.
63693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
63703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6371afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6372afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompMultiplicativeExpr(xmlXPathParserContextPtr ctxt) {
6373afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompUnaryExpr(ctxt);
63743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
63753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
63763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '*') ||
63773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == 'd') && (NXT(1) == 'i') && (NXT(2) == 'v')) ||
63783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == 'm') && (NXT(1) == 'o') && (NXT(2) == 'd'))) {
63793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int op = -1;
63809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
63813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
63823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '*') {
63833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 0;
63843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
63853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == 'd') {
63863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 1;
63873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(3);
63883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == 'm') {
63893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    op = 2;
63903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(3);
63913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
63923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
6393afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompUnaryExpr(ctxt);
63943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
63959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_MULT, op1, ctxt->comp->last, op, 0);
63963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
63973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
63983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
63993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6401afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAdditiveExpr:
64023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
64033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [25]   AdditiveExpr ::=   MultiplicativeExpr
64053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                   | AdditiveExpr '+' MultiplicativeExpr
64063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                   | AdditiveExpr '-' MultiplicativeExpr
64073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6408afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Additive expression.
64093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
64103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6411afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6412afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAdditiveExpr(xmlXPathParserContextPtr ctxt) {
64139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6414afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompMultiplicativeExpr(ctxt);
64153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
64163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
64173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '+') || (CUR == '-')) {
64183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	int plus;
64199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
64203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '+') plus = 1;
64223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else plus = 0;
64233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
64243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
6425afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompMultiplicativeExpr(ctxt);
64263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
64279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_PLUS, op1, ctxt->comp->last, plus, 0);
64283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
64293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
64303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
64313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6433afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelationalExpr:
64343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
64353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [24]   RelationalExpr ::=   AdditiveExpr
64373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                 | RelationalExpr '<' AdditiveExpr
64383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                 | RelationalExpr '>' AdditiveExpr
64393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                 | RelationalExpr '<=' AdditiveExpr
64403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                 | RelationalExpr '>=' AdditiveExpr
64413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  A <= B > C is allowed ? Answer from James, yes with
64433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (AdditiveExpr <= AdditiveExpr) > AdditiveExpr
64443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  which is basically what got implemented.
64453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6446afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a Relational expression, then push the result
64473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * on the stack
64483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
64493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6450afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6451afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelationalExpr(xmlXPathParserContextPtr ctxt) {
6452afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompAdditiveExpr(ctxt);
64533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
64543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
64553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '<') ||
64563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           (CUR == '>') ||
64573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == '<') && (NXT(1) == '=')) ||
64583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor           ((CUR == '>') && (NXT(1) == '='))) {
64599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int inf, strict;
64609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
64613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '<') inf = 1;
64633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else inf = 0;
64643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (NXT(1) == '=') strict = 0;
64653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else strict = 1;
64663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
64673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (!strict) NEXT;
64683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
6469afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompAdditiveExpr(ctxt);
64703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
64719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_CMP, op1, ctxt->comp->last, inf, strict);
64723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
64733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
64743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
64753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
64763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6477afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompEqualityExpr:
64783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
64793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [23]   EqualityExpr ::=   RelationalExpr
64813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                 | EqualityExpr '=' RelationalExpr
64823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                 | EqualityExpr '!=' RelationalExpr
64833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  A != B != C is allowed ? Answer from James, yes with
64853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (RelationalExpr = RelationalExpr) = RelationalExpr
64863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  (RelationalExpr != RelationalExpr) != RelationalExpr
64873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  which is basically what got implemented.
64883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6489afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an Equality expression.
64903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
64913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
6492afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6493afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompEqualityExpr(xmlXPathParserContextPtr ctxt) {
6494afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompRelationalExpr(ctxt);
64953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
64963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
64973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == '=') || ((CUR == '!') && (NXT(1) == '='))) {
64989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int eq;
64999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
65003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        if (CUR == '=') eq = 1;
65023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else eq = 0;
65033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
65043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (!eq) NEXT;
65053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
6506afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompRelationalExpr(ctxt);
65073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
65089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_EQUAL, op1, ctxt->comp->last, eq, 0);
65093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
65103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
65113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
65123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6514afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompAndExpr:
65153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
65163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [22]   AndExpr ::=   EqualityExpr
65183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                 | AndExpr 'and' EqualityExpr
65193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6520afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an AND expression.
65213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
6523afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6524afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompAndExpr(xmlXPathParserContextPtr ctxt) {
6525afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompEqualityExpr(ctxt);
65263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
65273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
65283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == 'a') && (NXT(1) == 'n') && (NXT(2) == 'd')) {
65299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
65303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        SKIP(3);
65313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
6532afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompEqualityExpr(ctxt);
65333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
65349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_AND, op1, ctxt->comp->last, 0, 0);
65353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
65363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
65373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
65383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6540afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompExpr:
65413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
65423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [14]   Expr ::=   OrExpr
65443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [21]   OrExpr ::=   AndExpr
65453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                 | OrExpr 'or' AndExpr
65463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6547afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and compile an expression
65483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
6549afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6550afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompileExpr(xmlXPathParserContextPtr ctxt) {
6551afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompAndExpr(ctxt);
65523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_ERROR;
65533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
65543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while ((CUR == 'o') && (NXT(1) == 'r')) {
65559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	int op1 = ctxt->comp->last;
65563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        SKIP(2);
65573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
6558afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompAndExpr(ctxt);
65593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
65609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_OR, op1, ctxt->comp->last, 0, 0);
65619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	op1 = ctxt->comp->nbStep;
65623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
65633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
65649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ctxt->comp->steps[ctxt->comp->last].op != XPATH_OP_VALUE) {
65659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	/* more ops could be optimized too */
65669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_UNARY_EXPR(XPATH_OP_SORT, ctxt->comp->last , 0, 0);
65679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
65683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
65693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
65703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6571afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompPredicate:
65723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
6573d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @filter:  act as a filter
65743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
65753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [8]   Predicate ::=   '[' PredicateExpr ']'
65763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [9]   PredicateExpr ::=   Expr
65773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6578afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a predicate expression
65799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
6580afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6581d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompPredicate(xmlXPathParserContextPtr ctxt, int filter) {
65829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int op1 = ctxt->comp->last;
65839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
65849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
65859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (CUR != '[') {
65869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
65879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
65889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NEXT;
65899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
65909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
65919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ctxt->comp->last = -1;
6592afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompileExpr(ctxt);
65939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    CHECK_ERROR;
65949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
65959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (CUR != ']') {
65969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
65979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
65989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
6599d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (filter)
6600d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_FILTER, op1, ctxt->comp->last, 0, 0);
6601d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    else
6602d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	PUSH_BINARY_EXPR(XPATH_OP_PREDICATE, op1, ctxt->comp->last, 0, 0);
66039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
66049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    NEXT;
66059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    SKIP_BLANKS;
66069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
66079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
66089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
6609afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompNodeTest:
66103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
66113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @test:  pointer to a xmlXPathTestVal
66123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @type:  pointer to a xmlXPathTypeVal
66133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @prefix:  placeholder for a possible name prefix
66143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [7] NodeTest ::=   NameTest
66163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | NodeType '(' ')'
66173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | 'processing-instruction' '(' Literal ')'
66183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [37] NameTest ::=  '*'
66203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | NCName ':' '*'
66213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		    | QName
66223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [38] NodeType ::= 'comment'
66233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'text'
66243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'processing-instruction'
66253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *		   | 'node'
66263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
66273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the name found and update @test, @type and @prefix appropriately
66283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
662956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlChar *
6630afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompNodeTest(xmlXPathParserContextPtr ctxt, xmlXPathTestVal *test,
6631afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	             xmlXPathTypeVal *type, const xmlChar **prefix,
6632afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		     xmlChar *name) {
66333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int blanks;
66343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((test == NULL) || (type == NULL) || (prefix == NULL)) {
66363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	STRANGE;
66373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
66383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
66393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *type = 0;
66403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *test = 0;
66413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *prefix = NULL;
66423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
66433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((name == NULL) && (CUR == '*')) {
66453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
66463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * All elements
66473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
66483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
66493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*test = NODE_TEST_ALL;
66503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(NULL);
66513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
66523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL)
66543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathParseNCName(ctxt);
66553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (name == NULL) {
66563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	XP_ERROR0(XPATH_EXPR_ERROR);
66573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
66583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    blanks = IS_BLANK(CUR);
66603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
66613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR == '(') {
66623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
66633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
66643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * NodeType or PI search
66653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
66663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (xmlStrEqual(name, BAD_CAST "comment"))
66673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_COMMENT;
66683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "node"))
66693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_NODE;
66703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "processing-instruction"))
66713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_PI;
66723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else if (xmlStrEqual(name, BAD_CAST "text"))
66733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *type = NODE_TYPE_TEXT;
66743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	else {
66753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
66763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
66773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR0(XPATH_EXPR_ERROR);
66783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
66793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*test = NODE_TEST_TYPE;
66813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
66823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
66833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (*type == NODE_TYPE_PI) {
66843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    /*
66853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * Specific case: search a PI by name.
66863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     */
66873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
66883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
668982e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    name = NULL;
669082e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    if (CUR != ')') {
669182e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard		name = xmlXPathParseLiteral(ctxt);
669282e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard		CHECK_ERROR 0;
669382e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard		SKIP_BLANKS;
669482e4971dc2f470c9b6f19cf8b15ff32781067167Daniel Veillard	    }
66953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
66963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR != ')') {
66973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (name != NULL)
66983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
66993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR0(XPATH_UNCLOSED_ERROR);
67003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
67013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
67023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	return(name);
67033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
67043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    *test = NODE_TEST_NAME;
67053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((!blanks) && (CUR == ':')) {
67063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
67073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
6709fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * Since currently the parser context don't have a
6710fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * namespace list associated:
6711fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * The namespace name for this prefix can be computed
6712fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * only at evaluation time. The compilation is done
6713fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	 * outside of any context.
67143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
6715fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#if 0
67163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	*prefix = xmlXPathNsLookup(ctxt->context, name);
67173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (name != NULL)
67183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlFree(name);
67193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (*prefix == NULL) {
67203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR0(XPATH_UNDEF_PREFIX_ERROR);
67213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
6722fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#else
6723fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	*prefix = name;
6724fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard#endif
67253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (CUR == '*') {
67273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    /*
67283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     * All elements
67293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	     */
67303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
67313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    *test = NODE_TEST_ALL;
67323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return(NULL);
67333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
67343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	name = xmlXPathParseNCName(ctxt);
67363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (name == NULL) {
67373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    XP_ERROR0(XPATH_EXPR_ERROR);
67383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
67393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
67403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(name);
67413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
67423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
67433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
67443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathIsAxisName:
67453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @name:  a preparsed name token
67463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [6] AxisName ::=   'ancestor'
67483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'ancestor-or-self'
67493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'attribute'
67503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'child'
67513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'descendant'
67523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'descendant-or-self'
67533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'following'
67543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'following-sibling'
67553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'namespace'
67563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'parent'
67573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'preceding'
67583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'preceding-sibling'
67593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | 'self'
67603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
67613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the axis or 0
67623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
676356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillardstatic xmlXPathAxisVal
67643473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathIsAxisName(const xmlChar *name) {
67653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathAxisVal ret = 0;
67663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    switch (name[0]) {
67673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'a':
67683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "ancestor"))
67693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ANCESTOR;
67703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "ancestor-or-self"))
67713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ANCESTOR_OR_SELF;
67723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "attribute"))
67733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_ATTRIBUTE;
67743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
67753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'c':
67763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "child"))
67773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_CHILD;
67783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
67793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'd':
67803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "descendant"))
67813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_DESCENDANT;
67823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "descendant-or-self"))
67833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_DESCENDANT_OR_SELF;
67843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
67853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'f':
67863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "following"))
67873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_FOLLOWING;
67883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "following-sibling"))
67893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_FOLLOWING_SIBLING;
67903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
67913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'n':
67923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "namespace"))
67933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_NAMESPACE;
67943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
67953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 'p':
67963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "parent"))
67973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PARENT;
67983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "preceding"))
67993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PRECEDING;
68003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "preceding-sibling"))
68013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_PRECEDING_SIBLING;
68023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
68033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	case 's':
68043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (xmlStrEqual(name, BAD_CAST "self"))
68053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		ret = AXIS_SELF;
68063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    break;
68073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
68083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(ret);
68093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
68103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6812afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompStep:
68133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
68143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [4] Step ::=   AxisSpecifier NodeTest Predicate*
68163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | AbbreviatedStep
68173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [12] AbbreviatedStep ::=   '.' | '..'
68193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [5] AxisSpecifier ::= AxisName '::'
68213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                  | AbbreviatedAxisSpecifier
68223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * [13] AbbreviatedAxisSpecifier ::= '@'?
68243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Modified for XPtr range support as:
68263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
68273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [4xptr] Step ::= AxisSpecifier NodeTest Predicate*
68283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | AbbreviatedStep
68293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | 'range-to' '(' Expr ')' Predicate*
68303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6831afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile one step in a Location Path
68323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * A location step of . is short for self::node(). This is
68333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * particularly useful in conjunction with //. For example, the
68343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * location path .//para is short for
68353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * self::node()/descendant-or-self::node()/child::para
68363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select all para descendant elements of the context
68373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node.
68383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Similarly, a location step of .. is short for parent::node().
68393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * For example, ../title is short for parent::node()/child::title
68403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * and so will select the title children of the parent of the context
68413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * node.
68423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
6843afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
6844afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompStep(xmlXPathParserContextPtr ctxt) {
6845fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
6846fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    int rangeto = 0;
6847fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    int op2 = -1;
6848fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
6849fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard
68503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
68513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR == '.') && (NXT(1) == '.')) {
68523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP(2);
68533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
68549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_PARENT,
68559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
68563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '.') {
68573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	NEXT;
68583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
68593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
68603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlChar *name = NULL;
68613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	const xmlChar *prefix = NULL;
68623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathTestVal test;
6863d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlXPathAxisVal axis = 0;
68643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathTypeVal type;
6865d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	int op1;
68663473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	/*
68683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 * The modification needed for XPointer change to the production
68693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	 */
68703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef LIBXML_XPTR_ENABLED
6871fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	if (ctxt->xptr) {
68723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    name = xmlXPathParseNCName(ctxt);
68733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((name != NULL) && (xmlStrEqual(name, BAD_CAST "range-to"))) {
6874fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard                op2 = ctxt->comp->last;
68753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		xmlFree(name);
68763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
68773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (CUR != '(') {
68783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    XP_ERROR(XPATH_EXPR_ERROR);
68793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
68803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
68813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
68823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6883afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		xmlXPathCompileExpr(ctxt);
6884fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		/* PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, ctxt->comp->last, 0, 0); */
68853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		CHECK_ERROR;
68863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
68873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
68883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (CUR != ')') {
68893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    XP_ERROR(XPATH_EXPR_ERROR);
68903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
68913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
6892fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		rangeto = 1;
68933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		goto eval_predicates;
68943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
68953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
68963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
68972156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	if (CUR == '*') {
68982156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    axis = AXIS_CHILD;
68992156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	} else {
69002156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (name == NULL)
69012156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		name = xmlXPathParseNCName(ctxt);
69022156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    if (name != NULL) {
69032156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = xmlXPathIsAxisName(name);
69042156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		if (axis != 0) {
69052156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    SKIP_BLANKS;
69062156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    if ((CUR == ':') && (NXT(1) == ':')) {
69072156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			SKIP(2);
69082156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			xmlFree(name);
69092156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			name = NULL;
69102156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    } else {
69112156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			/* an element name can conflict with an axis one :-\ */
69122156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard			axis = AXIS_CHILD;
69132156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		    }
69143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		} else {
69153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		    axis = AXIS_CHILD;
69163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		}
69172156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard	    } else if (CUR == '@') {
69182156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		NEXT;
69192156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = AXIS_ATTRIBUTE;
69203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else {
69212156a56bcbf5d83fb3d694123be01beebf84d273Daniel Veillard		axis = AXIS_CHILD;
69223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
69233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
69243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
69253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	CHECK_ERROR;
69263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
6927afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	name = xmlXPathCompNodeTest(ctxt, &test, &type, &prefix, name);
69283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (test == 0)
69293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    return;
69303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
69313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
69323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
69333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"Basis : computing new set\n");
69343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
69359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
69363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
69373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext, "Basis : ");
6938fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	if (ctxt->value == NULL)
6939fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "no value\n");
6940fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	else if (ctxt->value->nodesetval == NULL)
6941fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericError(xmlGenericErrorContext, "Empty\n");
6942fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	else
6943fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    xmlGenericErrorContextNodeSet(stdout, ctxt->value->nodesetval);
69443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
69453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
69463473f88a7abdf4e585e267288fb77e898c580d2bOwen Tayloreval_predicates:
6947d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	op1 = ctxt->comp->last;
6948d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	ctxt->comp->last = -1;
6949d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
69503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
69513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while (CUR == '[') {
6952d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompPredicate(ctxt, 0);
69533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
6954d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
6955fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#ifdef LIBXML_XPTR_ENABLED
6956fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	if (rangeto) {
6957fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    PUSH_BINARY_EXPR(XPATH_OP_RANGETO, op2, op1, 0, 0);
6958fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	} else
6959fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard#endif
6960fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	    PUSH_FULL_EXPR(XPATH_OP_COLLECT, op1, ctxt->comp->last, axis,
6961fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard			   test, type, (void *)prefix, (void *)name);
6962d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
69633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
69643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef DEBUG_STEP
69653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlGenericError(xmlGenericErrorContext, "Step : ");
6966fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    if (ctxt->value == NULL)
6967fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "no value\n");
6968fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    else if (ctxt->value->nodesetval == NULL)
6969fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericError(xmlGenericErrorContext, "Empty\n");
6970fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard    else
6971fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard	xmlGenericErrorContextNodeSet(xmlGenericErrorContext,
6972fd0c3ebb0931af19ab3b4da3493f027fca849cf7Daniel Veillard		ctxt->value->nodesetval);
69733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
69743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
69753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
69763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
6977afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompRelativeLocationPath:
69783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
69793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
69803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [3]   RelativeLocationPath ::=   Step
69813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | RelativeLocationPath '/' Step
69823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | AbbreviatedRelativeLocationPath
69833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [11]  AbbreviatedRelativeLocationPath ::=   RelativeLocationPath '//' Step
69843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
6985afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a relative location path.
69863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
6987afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
69883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#ifdef VMS
6989afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelLocationPath
69903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#else
6991afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompRelativeLocationPath
69923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif
69933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor(xmlXPathParserContextPtr ctxt) {
69943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
69953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((CUR == '/') && (NXT(1) == '/')) {
69963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP(2);
69973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
69989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
69999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		         NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
70003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (CUR == '/') {
70013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
70023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
70033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
7004afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompStep(ctxt);
70053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
70063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    while (CUR == '/') {
70073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if ((CUR == '/') && (NXT(1) == '/')) {
70083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP(2);
70093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
70109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
70113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor			     NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
7012afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompStep(ctxt);
70133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	} else if (CUR == '/') {
70143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    NEXT;
70153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    SKIP_BLANKS;
7016afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    xmlXPathCompStep(ctxt);
70173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
70183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	SKIP_BLANKS;
70193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
70203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
70213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
70223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
7023afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompLocationPath:
70243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath Parser context
70253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
70263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [1]   LocationPath ::=   RelativeLocationPath
70273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | AbsoluteLocationPath
70283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [2]   AbsoluteLocationPath ::=   '/' RelativeLocationPath?
70293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                     | AbbreviatedAbsoluteLocationPath
70303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *  [10]   AbbreviatedAbsoluteLocationPath ::=
70313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *                           '//' RelativeLocationPath
70323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
7033afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile a location path
7034afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
70353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * // is short for /descendant-or-self::node()/. For example,
70363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * //para is short for /descendant-or-self::node()/child::para and
70373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * so will select any para element in the document (even a para element
70383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * that is a document element will be selected by //para since the
70393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * document element node is a child of the root node); div//para is
70403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * short for div/descendant-or-self::node()/child::para and so will
70413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * select all para descendants of div children.
70423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
7043afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardstatic void
7044afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompLocationPath(xmlXPathParserContextPtr ctxt) {
70453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    SKIP_BLANKS;
70463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (CUR != '/') {
7047afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        xmlXPathCompRelativeLocationPath(ctxt);
70483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
70493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	while (CUR == '/') {
70503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if ((CUR == '/') && (NXT(1) == '/')) {
70513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP(2);
70523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
70539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		PUSH_LONG_EXPR(XPATH_OP_COLLECT, AXIS_DESCENDANT_OR_SELF,
70549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			     NODE_TEST_TYPE, NODE_TYPE_NODE, NULL, NULL);
7055afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		xmlXPathCompRelativeLocationPath(ctxt);
70563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    } else if (CUR == '/') {
70573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		NEXT;
70583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		SKIP_BLANKS;
70593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		if (CUR != 0)
7060afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard		    xmlXPathCompRelativeLocationPath(ctxt);
70613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    }
70623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
70633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
70643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
70653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
70669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/************************************************************************
70679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *									*
70689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * 		XPath precompiled expression evaluation			*
70699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *									*
70709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard ************************************************************************/
70719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
7072d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void
7073d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op);
7074d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
70759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
7076d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathNodeCollectAndTest:
7077d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath Parser context
7078d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op:  the XPath precompiled step operation
70799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
7080d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * This is the function implementing a step: based on the current list
7081d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * of nodes, it builds up a new list, looking at all nodes under that
7082d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * axis and selecting them it also do the predicate filtering
7083d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
7084d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Pushes the new NodeSet resulting from the search.
70859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
7086fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic void
7087d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathNodeCollectAndTest(xmlXPathParserContextPtr ctxt,
7088d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	                   xmlXPathStepOpPtr op) {
7089d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathAxisVal axis = op->value;
7090d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathTestVal test = op->value2;
7091d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathTypeVal type = op->value3;
7092d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    const xmlChar *prefix = op->value4;
7093d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    const xmlChar *name = op->value5;
7094e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    const xmlChar *URI = NULL;
70959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
7096d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7097d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    int n = 0, t = 0;
7098d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7099d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    int i;
7100d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlNodeSetPtr ret, list;
7101d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathTraversalFunction next = NULL;
7102d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    void (*addNode)(xmlNodeSetPtr, xmlNodePtr);
7103d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlNodePtr cur = NULL;
7104d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathObjectPtr obj;
7105d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlNodeSetPtr nodelist;
7106d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlNodePtr tmp;
7107d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7108d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    CHECK_TYPE(XPATH_NODESET);
7109d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    obj = valuePop(ctxt);
7110d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    addNode = xmlXPathNodeSetAdd;
7111e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    if (prefix != NULL) {
7112e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	URI = xmlXPathNsLookup(ctxt->context, prefix);
7113e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	if (URI == NULL)
7114e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard	    XP_ERROR(XPATH_UNDEF_PREFIX_ERROR);
7115e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard    }
7116d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7117d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7118d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
7119d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    "new step : ");
7120d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7121d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    switch (axis) {
7122d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ANCESTOR:
7123d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7124d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7125d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'ancestors' ");
7126d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7127d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextAncestor; break;
7128d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ANCESTOR_OR_SELF:
7129d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7130d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7131d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'ancestors-or-self' ");
7132d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7133d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextAncestorOrSelf; break;
7134d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_ATTRIBUTE:
7135d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7136d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7137d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'attributes' ");
7138d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7139d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextAttribute; break;
7140d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    break;
7141d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_CHILD:
7142d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7143d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7144d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'child' ");
7145d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7146d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextChild; break;
7147d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_DESCENDANT:
7148d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7149d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7150d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'descendant' ");
7151d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7152d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextDescendant; break;
7153d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_DESCENDANT_OR_SELF:
7154d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7155d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7156d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'descendant-or-self' ");
7157d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7158d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextDescendantOrSelf; break;
7159d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_FOLLOWING:
7160d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7161d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7162d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'following' ");
7163d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7164d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextFollowing; break;
7165d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_FOLLOWING_SIBLING:
7166d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7167d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7168d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'following-siblings' ");
7169d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7170d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextFollowingSibling; break;
7171d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_NAMESPACE:
7172d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7173d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7174d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'namespace' ");
7175d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7176d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = (xmlXPathTraversalFunction) xmlXPathNextNamespace; break;
7177d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    break;
7178d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PARENT:
7179d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7180d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7181d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'parent' ");
7182d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7183d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextParent; break;
7184d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PRECEDING:
7185d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7186d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7187d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'preceding' ");
7188d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7189d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextPreceding; break;
7190d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_PRECEDING_SIBLING:
7191d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7192d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7193d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'preceding-sibling' ");
7194d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7195d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextPrecedingSibling; break;
7196d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        case AXIS_SELF:
7197d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7198d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7199d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "axis 'self' ");
7200d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7201d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    next = xmlXPathNextSelf; break;
7202d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
7203d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (next == NULL)
7204d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	return;
7205d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7206d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    nodelist = obj->nodesetval;
7207d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    if (nodelist == NULL) {
7208d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	xmlXPathFreeObject(obj);
7209d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	valuePush(ctxt, xmlXPathWrapNodeSet(NULL));
7210d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	return;
7211d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
7212d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    addNode = xmlXPathNodeSetAddUnique;
7213d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    ret = NULL;
7214d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7215d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
7216d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    " context contains %d nodes\n",
7217d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard            nodelist->nodeNr);
7218d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    switch (test) {
7219d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case NODE_TEST_NONE:
7220d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7221d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "           searching for none !!!\n");
7222d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    break;
7223d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case NODE_TEST_TYPE:
7224d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7225d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "           searching for type %d\n", type);
7226d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    break;
7227d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case NODE_TEST_PI:
7228d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7229d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "           searching for PI !!!\n");
7230d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    break;
7231d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case NODE_TEST_ALL:
7232d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7233d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "           searching for *\n");
7234d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    break;
7235d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case NODE_TEST_NS:
7236d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7237d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "           searching for namespace %s\n",
7238d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	            prefix);
7239d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    break;
7240d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case NODE_TEST_NAME:
7241d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlGenericError(xmlGenericErrorContext,
7242d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    "           searching for name %s\n", name);
7243d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    if (prefix != NULL)
7244d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		xmlGenericError(xmlGenericErrorContext,
7245d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			"           with namespace %s\n",
7246d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		        prefix);
7247d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    break;
7248d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
7249d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlGenericError(xmlGenericErrorContext, "Testing : ");
7250d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7251d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    /*
7252d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     * 2.3 Node Tests
7253d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     *  - For the attribute axis, the principal node type is attribute.
7254d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     *  - For the namespace axis, the principal node type is namespace.
7255d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     *  - For other axes, the principal node type is element.
7256d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     *
7257d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     * A node test * is true for any node of the
7258d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     * principal node type. For example, child::* willi
7259d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     * select all element children of the context node
7260d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard     */
7261d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    tmp = ctxt->context->node;
7262d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    for (i = 0;i < nodelist->nodeNr; i++) {
7263d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        ctxt->context->node = nodelist->nodeTab[i];
7264d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7265d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	cur = NULL;
7266d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	list = xmlXPathNodeSetCreate(NULL);
7267d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	do {
7268d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    cur = next(ctxt, cur);
7269d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    if (cur == NULL) break;
7270d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7271d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard            t++;
7272d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard            xmlGenericError(xmlGenericErrorContext, " %s", cur->name);
7273d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7274d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    switch (test) {
7275d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard                case NODE_TEST_NONE:
7276d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    ctxt->context->node = tmp;
7277d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    STRANGE
7278d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    return;
7279d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard                case NODE_TEST_TYPE:
7280d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    if ((cur->type == type) ||
7281d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		        ((type == NODE_TYPE_NODE) &&
7282d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			 ((cur->type == XML_DOCUMENT_NODE) ||
7283d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			  (cur->type == XML_HTML_DOCUMENT_NODE) ||
7284d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			  (cur->type == XML_ELEMENT_NODE) ||
7285d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			  (cur->type == XML_PI_NODE) ||
7286d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			  (cur->type == XML_COMMENT_NODE) ||
7287d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			  (cur->type == XML_CDATA_SECTION_NODE) ||
7288d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			  (cur->type == XML_TEXT_NODE)))) {
7289d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7290d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard                        n++;
7291d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7292d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		        addNode(list, cur);
7293d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    }
7294d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    break;
7295d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard                case NODE_TEST_PI:
7296d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    if (cur->type == XML_PI_NODE) {
7297d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		        if ((name != NULL) &&
7298d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    (!xmlStrEqual(name, cur->name)))
7299d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    break;
7300d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7301d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			n++;
7302d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7303d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			addNode(list, cur);
7304d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    }
7305d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    break;
7306d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard                case NODE_TEST_ALL:
7307d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    if (axis == AXIS_ATTRIBUTE) {
7308d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			if (cur->type == XML_ATTRIBUTE_NODE) {
7309d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7310d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    n++;
7311d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7312d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    addNode(list, cur);
7313d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			}
7314d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    } else if (axis == AXIS_NAMESPACE) {
7315d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			if (cur->type == XML_NAMESPACE_DECL) {
7316d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7317d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    n++;
7318d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7319d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    addNode(list, cur);
7320d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			}
7321d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    } else {
7322d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			if ((cur->type == XML_ELEMENT_NODE) ||
7323d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    (cur->type == XML_DOCUMENT_NODE) ||
7324d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    (cur->type == XML_HTML_DOCUMENT_NODE)) {
7325d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    if (prefix == NULL) {
7326d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7327d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				n++;
7328d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7329d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				addNode(list, cur);
7330d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    } else if ((cur->ns != NULL) &&
7331e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard				(xmlStrEqual(URI,
7332d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					     cur->ns->href))) {
7333d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7334d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				n++;
7335d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7336d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				addNode(list, cur);
7337d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    }
7338d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			}
7339d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    }
7340d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    break;
7341d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard                case NODE_TEST_NS: {
7342d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    TODO;
7343d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    break;
7344d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		}
7345d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard                case NODE_TEST_NAME:
7346d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    switch (cur->type) {
7347d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		        case XML_ELEMENT_NODE:
7348d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    if (xmlStrEqual(name, cur->name)) {
7349d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				if (prefix == NULL) {
7350af86c7f4631c95b93f9132825113ce6bd2144f44Daniel Veillard				    if (cur->ns == NULL) {
7351d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7352d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					n++;
7353d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7354d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					addNode(list, cur);
7355d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				    }
7356d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				} else {
7357d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				    if ((cur->ns != NULL) &&
7358e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard				        (xmlStrEqual(URI,
7359d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard						     cur->ns->href))) {
7360d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7361d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					n++;
7362d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7363d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					addNode(list, cur);
7364d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				    }
7365d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				}
7366d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    }
7367d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    break;
7368d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		        case XML_ATTRIBUTE_NODE: {
7369d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    xmlAttrPtr attr = (xmlAttrPtr) cur;
7370d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    if (xmlStrEqual(name, attr->name)) {
7371d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				if (prefix == NULL) {
7372d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				    if ((attr->ns == NULL) ||
7373d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					(attr->ns->prefix == NULL)) {
7374d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7375d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					n++;
7376d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7377d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					addNode(list, (xmlNodePtr) attr);
7378d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				    }
7379d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				} else {
7380d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				    if ((attr->ns != NULL) &&
7381e043ee17c26c41c6d50c38d07d69dd1900d8ad01Daniel Veillard				        (xmlStrEqual(URI,
7382d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard						     attr->ns->href))) {
7383d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7384d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					n++;
7385d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7386d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard					addNode(list, (xmlNodePtr) attr);
7387d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				    }
7388d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard				}
7389d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    }
7390d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    break;
7391d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			}
7392d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			case XML_NAMESPACE_DECL: {
7393d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    TODO;
7394d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    break;
7395d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			}
7396d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			default:
7397d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard			    break;
7398d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		    }
7399d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	            break;
7400d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    }
7401d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	} while (cur != NULL);
7402d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7403d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	/*
7404d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	 * If there is some predicate filtering do it now
7405d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	 */
7406d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	if (op->ch2 != -1) {
7407d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathObjectPtr obj2;
7408d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7409d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    valuePush(ctxt, xmlXPathWrapNodeSet(list));
7410d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &ctxt->comp->steps[op->ch2]);
7411d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    CHECK_TYPE(XPATH_NODESET);
7412d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    obj2 = valuePop(ctxt);
7413d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    list = obj2->nodesetval;
7414d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    obj2->nodesetval = NULL;
7415d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathFreeObject(obj2);
7416d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	}
7417d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	if (ret == NULL) {
7418d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    ret = list;
7419d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	} else {
7420d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    ret = xmlXPathNodeSetMerge(ret, list);
7421d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathFreeNodeSet(list);
7422d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	}
7423d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    }
7424d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    ctxt->context->node = tmp;
7425d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#ifdef DEBUG_STEP
7426d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlGenericError(xmlGenericErrorContext,
7427d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard            "\nExamined %d nodes, found %d nodes at that step\n", t, n);
7428d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard#endif
7429d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathFreeObject(obj);
7430d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    valuePush(ctxt, xmlXPathWrapNodeSet(ret));
7431d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard}
7432d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7433d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard/**
7434d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * xmlXPathCompOpEval:
7435d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @ctxt:  the XPath parser context with the compiled expression
7436d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * @op:  an XPath compiled operation
7437d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard *
7438d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard * Evaluate the Precompiled XPath operation
7439d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard */
7440d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillardstatic void
7441d8df6c0e8c883e1d618388d266015dda36731440Daniel VeillardxmlXPathCompOpEval(xmlXPathParserContextPtr ctxt, xmlXPathStepOpPtr op) {
7442d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    int equal, ret;
7443d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathCompExprPtr comp;
7444d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    xmlXPathObjectPtr arg1, arg2;
7445d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7446d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    comp = ctxt->comp;
7447d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard    switch (op->op) {
7448d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_END:
7449d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    return;
7450d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_AND:
7451d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
7452d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathBooleanFunction(ctxt, 1);
745376d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	    if ((ctxt->value == NULL) || (ctxt->value->boolval == 0))
7454d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		return;
7455d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    arg2 = valuePop(ctxt);
7456d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
7457d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathBooleanFunction(ctxt, 1);
7458d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    arg1 = valuePop(ctxt);
7459d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    arg1->boolval &= arg2->boolval;
7460d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    valuePush(ctxt, arg1);
7461d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathFreeObject(arg2);
7462d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    return;
7463d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_OR:
7464d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
7465d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathBooleanFunction(ctxt, 1);
746676d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	    if ((ctxt->value == NULL) || (ctxt->value->boolval == 1))
7467d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		return;
7468d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    arg2 = valuePop(ctxt);
7469d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
7470d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathBooleanFunction(ctxt, 1);
7471d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    arg1 = valuePop(ctxt);
7472d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    arg1->boolval |= arg2->boolval;
7473d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    valuePush(ctxt, arg1);
7474d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathFreeObject(arg2);
7475d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    return;
7476d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_EQUAL:
7477d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
7478d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
7479d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    equal = xmlXPathEqualValues(ctxt);
7480d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    if (op->value) valuePush(ctxt, xmlXPathNewBoolean(equal));
7481d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    else valuePush(ctxt, xmlXPathNewBoolean(!equal));
7482d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    return;
7483d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_CMP:
7484d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
7485d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
7486d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    ret = xmlXPathCompareValues(ctxt, op->value, op->value2);
7487d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    valuePush(ctxt, xmlXPathNewBoolean(ret));
7488d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    return;
7489d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_PLUS:
74909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
74919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch2 != -1)
74929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
74939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->value == 0) xmlXPathSubValues(ctxt);
74949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else if (op->value == 1) xmlXPathAddValues(ctxt);
74959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else if (op->value == 2) xmlXPathValueFlipSign(ctxt);
74969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else if (op->value == 3) {
7497ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		CAST_TO_NUMBER;
7498ba0b8c94acad3f8e880002b3069f074be582e893Daniel Veillard		CHECK_TYPE(XPATH_NUMBER);
74999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
75009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
75019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_MULT:
75029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
75039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
75049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->value == 0) xmlXPathMultValues(ctxt);
75059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else if (op->value == 1) xmlXPathDivValues(ctxt);
75069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else if (op->value == 2) xmlXPathModValues(ctxt);
75079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
75089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_UNION:
75099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
75109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
75119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    CHECK_TYPE(XPATH_NODESET);
75129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    arg2 = valuePop(ctxt);
75139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
75149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    CHECK_TYPE(XPATH_NODESET);
75159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    arg1 = valuePop(ctxt);
75169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
75179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    arg1->nodesetval = xmlXPathNodeSetMerge(arg1->nodesetval,
75189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard						    arg2->nodesetval);
75199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    valuePush(ctxt, arg1);
75209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathFreeObject(arg2);
75219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
75229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_ROOT:
75239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathRoot(ctxt);
75249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
75259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_NODE:
75269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch1 != -1)
75279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
75289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch2 != -1)
75299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
75309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    valuePush(ctxt, xmlXPathNewNodeSet(ctxt->context->node));
75319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
75329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_RESET:
75339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch1 != -1)
75349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
75359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch2 != -1)
75369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
75379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    ctxt->context->node = NULL;
75389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
7539d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_COLLECT: {
7540d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    if (op->ch1 == -1)
7541d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		return;
7542d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard
7543d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
7544d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    xmlXPathNodeCollectAndTest(ctxt, op);
75459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
7546d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard        }
75479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_VALUE:
75489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    valuePush(ctxt,
75499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPathObjectCopy((xmlXPathObjectPtr) op->value4));
75509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
75519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_VARIABLE: {
75529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch1 != -1)
75539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
75549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->value5 == NULL)
75559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		valuePush(ctxt,
75569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPathVariableLookup(ctxt->context, op->value4));
75579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else {
75589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		const xmlChar *URI;
75599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		URI = xmlXPathNsLookup(ctxt->context, op->value5);
75609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		if (URI == NULL) {
75619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlGenericError(xmlGenericErrorContext,
75629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	   "xmlXPathRunEval: variable %s bound to undefined prefix %s\n",
75639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard				    op->value4, op->value5);
75649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    return;
75659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		}
75669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		valuePush(ctxt,
75679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPathVariableLookupNS(ctxt->context,
75689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard					     op->value4, URI));
75699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
75709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
75719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
75729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_FUNCTION: {
75739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathFunction func;
757442596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard	    const xmlChar *oldFunc, *oldFuncURI;
75759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
75769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch1 != -1)
75779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
7578e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard	    if (op->cache != NULL)
7579e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		func = (xmlXPathFunction) op->cache;
75809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    else {
758142596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard		const xmlChar *URI = NULL;
758242596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard
7583e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		if (op->value5 == NULL)
7584e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		    func = xmlXPathFunctionLookup(ctxt->context, op->value4);
7585e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		else {
7586e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		    URI = xmlXPathNsLookup(ctxt->context, op->value5);
7587e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		    if (URI == NULL) {
7588e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard			xmlGenericError(xmlGenericErrorContext,
7589e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard	       "xmlXPathRunEval: function %s bound to undefined prefix %s\n",
7590e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard					op->value4, op->value5);
7591e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard			return;
7592e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		    }
7593e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		    func = xmlXPathFunctionLookupNS(ctxt->context,
7594e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard						    op->value4, URI);
7595e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		}
7596e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		if (func == NULL) {
75979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlGenericError(xmlGenericErrorContext,
7598e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard			   "xmlXPathRunEval: function %s not found\n",
7599e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard				    op->value4);
7600e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		    XP_ERROR(XPATH_UNKNOWN_FUNC_ERROR);
76019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    return;
76029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		}
7603e39a93d0d3df9907cf3538cd3f1fbbe4106e893dDaniel Veillard		op->cache = (void *) func;
760442596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard		op->cacheURI = (void *) URI;
76059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
760642596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard            oldFunc = ctxt->context->function;
760742596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard            oldFuncURI = ctxt->context->functionURI;
760842596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard	    ctxt->context->function = op->value4;
760942596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard	    ctxt->context->functionURI = op->cacheURI;
76109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    func(ctxt, op->value);
761142596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard            ctxt->context->function = oldFunc;
761242596ad20cdf1925dd79ea801cbe598b6e7b7aecDaniel Veillard            ctxt->context->functionURI = oldFuncURI;
76139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
76149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
76159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_ARG:
76169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch1 != -1)
76179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
76189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch2 != -1)
76199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
76209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
7621d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_PREDICATE:
7622d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	case XPATH_OP_FILTER: {
76239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathObjectPtr res;
76249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathObjectPtr obj, tmp;
76259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlNodeSetPtr newset = NULL;
76269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlNodeSetPtr oldset;
76279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlNodePtr oldnode;
76289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    int i;
76299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
76309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch1 != -1)
76319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
76329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch2 == -1)
76339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		return;
763476d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard	    if (ctxt->value == NULL)
763576d66f416d2d0d5db4a09d212b4e43087e9cdae7Daniel Veillard		return;
76369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
76379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    oldnode = ctxt->context->node;
76389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
76399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED
76409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    /*
76419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     * Hum are we filtering the result of an XPointer expression
76429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     */
76439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (ctxt->value->type == XPATH_LOCATIONSET) {
764456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		xmlLocationSetPtr newlocset = NULL;
764556a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		xmlLocationSetPtr oldlocset;
76469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
76479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		/*
764856a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		 * Extract the old locset, and then evaluate the result of the
764956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		 * expression for all the element in the locset. use it to grow
765056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		 * up a new locset.
76519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 */
76529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		CHECK_TYPE(XPATH_LOCATIONSET);
76539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		obj = valuePop(ctxt);
765456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		oldlocset = obj->user;
76559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->node = NULL;
76569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
765756a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		if ((oldlocset == NULL) || (oldlocset->locNr == 0)) {
76589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    ctxt->context->contextSize = 0;
76599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    ctxt->context->proximityPosition = 0;
76609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (op->ch2 != -1)
76619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
76629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    res = valuePop(ctxt);
76639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (res != NULL)
76649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathFreeObject(res);
76659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    valuePush(ctxt, obj);
76669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    CHECK_ERROR;
76679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    return;
76689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		}
766956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		newlocset = xmlXPtrLocationSetCreate(NULL);
76709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
767156a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		for (i = 0; i < oldlocset->locNr; i++) {
76729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    /*
76739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * Run the evaluation with a node list made of a
767456a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		     * single item in the nodelocset.
76759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     */
767656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		    ctxt->context->node = oldlocset->locTab[i]->user;
76779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    tmp = xmlXPathNewNodeSet(ctxt->context->node);
76789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    valuePush(ctxt, tmp);
767956a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		    ctxt->context->contextSize = oldlocset->locNr;
76809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    ctxt->context->proximityPosition = i + 1;
76819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
76829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (op->ch2 != -1)
76839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
76849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    CHECK_ERROR;
76859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
76869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    /*
76879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * The result of the evaluation need to be tested to
76889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * decided whether the filter succeeded or not
76899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     */
76909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    res = valuePop(ctxt);
76919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
769256a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard			xmlXPtrLocationSetAdd(newlocset,
769356a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard				xmlXPathObjectCopy(oldlocset->locTab[i]));
76949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    }
76959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
76969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    /*
76979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * Cleanup
76989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     */
76999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (res != NULL)
77009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathFreeObject(res);
77019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (ctxt->value == tmp) {
77029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			res = valuePop(ctxt);
77039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathFreeObject(res);
77049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    }
77059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    ctxt->context->node = NULL;
77079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		}
77089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		/*
771056a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		 * The result is used as the new evaluation locset.
77119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 */
77129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathFreeObject(obj);
77139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->node = NULL;
77149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->contextSize = -1;
77159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->proximityPosition = -1;
771656a4cb8c4d3eab4ab3295a61c87e8e92483922c6Daniel Veillard		valuePush(ctxt, xmlXPtrWrapLocationSet(newlocset));
77179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->node = oldnode;
77189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		return;
77199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
77209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */
77219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    /*
77239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     * Extract the old set, and then evaluate the result of the
77249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     * expression for all the element in the set. use it to grow
77259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     * up a new set.
77269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     */
77279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    CHECK_TYPE(XPATH_NODESET);
77289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    obj = valuePop(ctxt);
77299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    oldset = obj->nodesetval;
7730911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard
77319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    oldnode = ctxt->context->node;
77329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    ctxt->context->node = NULL;
77339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if ((oldset == NULL) || (oldset->nodeNr == 0)) {
77359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->contextSize = 0;
77369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->proximityPosition = 0;
77379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		if (op->ch2 != -1)
77389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
77399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		res = valuePop(ctxt);
77409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		if (res != NULL)
77419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPathFreeObject(res);
77429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		valuePush(ctxt, obj);
7743911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		ctxt->context->node = oldnode;
77449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		CHECK_ERROR;
77459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    } else {
77469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		/*
77479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 * Initialize the new set.
77489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 */
77499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		newset = xmlXPathNodeSetCreate(NULL);
77509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		for (i = 0; i < oldset->nodeNr; i++) {
77529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    /*
77539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * Run the evaluation with a node list made of
77549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * a single item in the nodeset.
77559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     */
77569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    ctxt->context->node = oldset->nodeTab[i];
77579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    tmp = xmlXPathNewNodeSet(ctxt->context->node);
77589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    valuePush(ctxt, tmp);
77599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    ctxt->context->contextSize = oldset->nodeNr;
77609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    ctxt->context->proximityPosition = i + 1;
77619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (op->ch2 != -1)
77639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
77649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    CHECK_ERROR;
77659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    /*
77679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * The result of the evaluation need to be tested to
77689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * decided whether the filter succeeded or not
77699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     */
77709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    res = valuePop(ctxt);
77719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
77729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathNodeSetAdd(newset, oldset->nodeTab[i]);
77739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    }
77749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    /*
77769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     * Cleanup
77779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		     */
77789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (res != NULL)
77799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathFreeObject(res);
77809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    if (ctxt->value == tmp) {
77819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			res = valuePop(ctxt);
77829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			xmlXPathFreeObject(res);
77839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    }
77849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    ctxt->context->node = NULL;
77869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		}
77879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
77889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		/*
77899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 * The result is used as the new evaluation set.
77909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 */
77919e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathFreeObject(obj);
77929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->node = NULL;
77939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->contextSize = -1;
77949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->proximityPosition = -1;
77959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		valuePush(ctxt, xmlXPathWrapNodeSet(newset));
77969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
77979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    ctxt->context->node = oldnode;
77989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
77999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
78009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_SORT:
78019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch1 != -1)
78029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
78039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if ((ctxt->value != NULL) &&
78049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		(ctxt->value->type == XPATH_NODESET) &&
78059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		(ctxt->value->nodesetval != NULL))
78069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathNodeSetSort(ctxt->value->nodesetval);
78079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
78089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#ifdef LIBXML_XPTR_ENABLED
78099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	case XPATH_OP_RANGETO: {
78109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathObjectPtr range;
78119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathObjectPtr res, obj;
78129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathObjectPtr tmp;
78139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlLocationSetPtr newset = NULL;
78149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlNodeSetPtr oldset;
78159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    int i;
78169e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78179e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch1 != -1)
78189e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		xmlXPathCompOpEval(ctxt, &comp->steps[op->ch1]);
78199e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (op->ch2 == -1)
78209e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		return;
78219e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78229e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    CHECK_TYPE(XPATH_NODESET);
78239e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    obj = valuePop(ctxt);
78249e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    oldset = obj->nodesetval;
78259e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    ctxt->context->node = NULL;
78269e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78279e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    newset = xmlXPtrLocationSetCreate(NULL);
78289e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
7829911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    if (oldset != NULL) {
78309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    for (i = 0; i < oldset->nodeNr; i++) {
78319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		/*
78329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 * Run the evaluation with a node list made of a single item
78339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 * in the nodeset.
78349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 */
78359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->node = oldset->nodeTab[i];
78369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		tmp = xmlXPathNewNodeSet(ctxt->context->node);
78379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		valuePush(ctxt, tmp);
78389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		if (op->ch2 != -1)
78409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPathCompOpEval(ctxt, &comp->steps[op->ch2]);
78419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		CHECK_ERROR;
78429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		/*
78449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 * The result of the evaluation need to be tested to
78459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 * decided whether the filter succeeded or not
78469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 */
78479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		res = valuePop(ctxt);
78489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
78499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		if (range != NULL) {
78509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPtrLocationSetAdd(newset, range);
78519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		}
78529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		/*
78549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 * Cleanup
78559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		 */
78569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		if (res != NULL)
78579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPathFreeObject(res);
78589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		if (ctxt->value == tmp) {
78599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    res = valuePop(ctxt);
78609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    xmlXPathFreeObject(res);
78619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		}
78629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		ctxt->context->node = NULL;
78649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    }
7865911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard	    }
78669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    /*
78689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     * The result is used as the new evaluation set.
78699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	     */
78709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathFreeObject(obj);
78719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    ctxt->context->node = NULL;
78729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    ctxt->context->contextSize = -1;
78739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    ctxt->context->proximityPosition = -1;
78749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
78759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
78769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
78779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard#endif /* LIBXML_XPTR_ENABLED */
78789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
78799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlGenericError(xmlGenericErrorContext,
78809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard       "XPath: unknown precompiled operation %d\n",
78819e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    op->op);
78829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return;
78839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
78849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
78869e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathRunEval:
78879e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctxt:  the XPath parser context with the compiled expression
78889e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
78899e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context.
78909e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
7891fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardstatic void
78929e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathRunEval(xmlXPathParserContextPtr ctxt) {
78939e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompExprPtr comp;
78949e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78959e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if ((ctxt == NULL) || (ctxt->comp == NULL))
78969e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return;
78979e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
78989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ctxt->valueTab == NULL) {
78999e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	/* Allocate the value stack */
79009e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->valueTab = (xmlXPathObjectPtr *)
79019e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard			 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
79029e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (ctxt->valueTab == NULL) {
79039e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlFree(ctxt);
79049e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlGenericError(xmlGenericErrorContext,
79059e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		    "xmlXPathRunEval: out of memory\n");
79069e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    return;
79079e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	}
79089e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->valueNr = 0;
79099e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->valueMax = 10;
79109e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	ctxt->value = NULL;
79119e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
79129e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    comp = ctxt->comp;
79139e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathCompOpEval(ctxt, &comp->steps[comp->last]);
79149e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
79159e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
7916afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/************************************************************************
7917afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *									*
7918afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * 			Public interfaces				*
7919afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *									*
7920afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard ************************************************************************/
7921afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
7922afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
7923fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * xmlXPathEvalPredicate:
7924fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @ctxt:  the XPath context
7925fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * @res:  the Predicate Expression evaluation result
7926fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
7927fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Evaluate a predicate result for the current node.
7928fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting
7929fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * the result to a boolean. If the result is a number, the result will
7930fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * be converted to true if the number is equal to the position of the
7931fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * context node in the context node list (as returned by the position
7932fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * function) and will be converted to false otherwise; if the result
7933fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * is not a number, then the result will be converted as if by a call
7934fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * to the boolean function.
7935fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard *
7936fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard * Return 1 if predicate is true, 0 otherwise
7937fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard */
7938fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillardint
7939fbf8a2d0c8145b713099df63d174154a8442e60dDaniel VeillardxmlXPathEvalPredicate(xmlXPathContextPtr ctxt, xmlXPathObjectPtr res) {
7940fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    if (res == NULL) return(0);
7941fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    switch (res->type) {
7942fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_BOOLEAN:
7943fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->boolval);
7944fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_NUMBER:
7945fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->floatval == ctxt->proximityPosition);
7946fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_NODESET:
7947fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_XSLT_TREE:
7948d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard	    if (res->nodesetval == NULL)
7949d8df6c0e8c883e1d618388d266015dda36731440Daniel Veillard		return(0);
7950fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return(res->nodesetval->nodeNr != 0);
7951fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        case XPATH_STRING:
7952fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    return((res->stringval != NULL) &&
7953fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	           (xmlStrlen(res->stringval) != 0));
7954fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard        default:
7955fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard	    STRANGE
7956fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    }
7957fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard    return(0);
7958fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard}
7959fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard
7960fbf8a2d0c8145b713099df63d174154a8442e60dDaniel Veillard/**
7961afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvaluatePredicateResult:
7962afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt:  the XPath Parser context
7963afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @res:  the Predicate Expression evaluation result
7964afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
7965afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Evaluate a predicate result for the current node.
7966afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * A PredicateExpr is evaluated by evaluating the Expr and converting
7967afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * the result to a boolean. If the result is a number, the result will
7968afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * be converted to true if the number is equal to the position of the
7969afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * context node in the context node list (as returned by the position
7970afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * function) and will be converted to false otherwise; if the result
7971afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * is not a number, then the result will be converted as if by a call
7972afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * to the boolean function.
7973afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
7974afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Return 1 if predicate is true, 0 otherwise
7975afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
7976afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardint
7977afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvaluatePredicateResult(xmlXPathParserContextPtr ctxt,
7978afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard                                xmlXPathObjectPtr res) {
7979afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    if (res == NULL) return(0);
7980afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    switch (res->type) {
7981afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_BOOLEAN:
7982afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->boolval);
7983afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_NUMBER:
7984afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->floatval == ctxt->context->proximityPosition);
7985afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_NODESET:
7986afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_XSLT_TREE:
798773639a73c5a51c3739595f54c338bb531c1319c2Daniel Veillard	    if (res->nodesetval == NULL)
7988911f49a0a02d13f5432ddd75ff497290619be924Daniel Veillard		return(0);
7989afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return(res->nodesetval->nodeNr != 0);
7990afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        case XPATH_STRING:
7991afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    return((res->stringval != NULL) &&
7992afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	           (xmlStrlen(res->stringval) != 0));
7993afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard        default:
7994afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard	    STRANGE
7995afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    }
7996afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    return(0);
7997afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
7998afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
7999afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
8000afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathCompile:
8001afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @str:  the XPath expression
8002afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
8003afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Compile an XPath expression
8004afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
8005afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
8006afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *         the caller has to free the object.
8007afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
8008afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompExprPtr
8009afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathCompile(const xmlChar *str) {
8010afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathParserContextPtr ctxt;
8011afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompExprPtr comp;
8012afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
8013afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathInit();
8014afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
8015afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    ctxt = xmlXPathNewParserContext(str, NULL);
8016afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompileExpr(ctxt);
8017afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
801840af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard    if (*ctxt->cur != 0) {
801940af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard	xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
802040af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard	comp = NULL;
802140af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard    } else {
802240af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard	comp = ctxt->comp;
802340af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard	ctxt->comp = NULL;
802440af649f9b5b32f97879f10432c56bb5ef60c958Daniel Veillard    }
8025afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathFreeParserContext(ctxt);
8026afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    return(comp);
8027afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
8028afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard
80299e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard/**
80309e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * xmlXPathCompiledEval:
80319e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @comp:  the compiled XPath expression
80329e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * @ctx:  the XPath context
80339e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
80349e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Evaluate the Precompiled XPath expression in the given context.
80359e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *
80369e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
80379e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard *         the caller has to free the object.
80389e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard */
80399e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathObjectPtr
80409e7160d45a18bfa26d708e22ba991f7670d0128bDaniel VeillardxmlXPathCompiledEval(xmlXPathCompExprPtr comp, xmlXPathContextPtr ctx) {
80419e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathParserContextPtr ctxt;
80429e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathObjectPtr res, tmp, init = NULL;
80439e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    int stack = 0;
80449e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80459e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if ((comp == NULL) || (ctx == NULL))
80469e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	return(NULL);
80479e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathInit();
80489e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80499e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    CHECK_CONTEXT(ctx)
80509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80519e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    ctxt = xmlXPathCompParserContext(comp, ctx);
80529e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathRunEval(ctxt);
80539e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80549e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ctxt->value == NULL) {
80559e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlGenericError(xmlGenericErrorContext,
80569e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		"xmlXPathEval: evaluation failed\n");
80579e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	res = NULL;
80589e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    } else {
80599e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	res = valuePop(ctxt);
80609e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
80619e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80629e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    do {
80639e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        tmp = valuePop(ctxt);
80649e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	if (tmp != NULL) {
80659e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    if (tmp != init)
80669e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		stack++;
80679e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	    xmlXPathFreeObject(tmp);
80689e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard        }
80699e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    } while (tmp != NULL);
80709e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if ((stack != 0) && (res != NULL)) {
80719e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlGenericError(xmlGenericErrorContext,
80729e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard		"xmlXPathEval: %d object left on the stack\n",
80739e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	        stack);
80749e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
80759e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    if (ctxt->error != XPATH_EXPRESSION_OK) {
80769e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	xmlXPathFreeObject(res);
80779e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard	res = NULL;
80789e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    }
80799e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80809e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8081afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    ctxt->comp = NULL;
80829e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    xmlXPathFreeParserContext(ctxt);
80839e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard    return(res);
80849e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard}
80859e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
8086afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard/**
8087afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * xmlXPathEvalExpr:
8088afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * @ctxt:  the XPath Parser context
8089afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard *
8090afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * Parse and evaluate an XPath expression in the given context,
8091afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard * then push the result on the context stack
8092afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard */
8093afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillardvoid
8094afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel VeillardxmlXPathEvalExpr(xmlXPathParserContextPtr ctxt) {
8095afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathCompileExpr(ctxt);
8096afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard    xmlXPathRunEval(ctxt);
8097afcbe1cb12ae42a3be93249730e631d795d63a4fDaniel Veillard}
80989e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
80993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
81003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEval:
81013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
81023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctx:  the XPath context
81033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath Location Path in the given context.
81053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathObjectPtr resulting from the eveluation or NULL.
81073473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *         the caller has to free the object.
81083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
81093473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
81103473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEval(const xmlChar *str, xmlXPathContextPtr ctx) {
81113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr ctxt;
81123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr res, tmp, init = NULL;
81133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int stack = 0;
81143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathInit();
81163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_CONTEXT(ctx)
81183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    ctxt = xmlXPathNewParserContext(str, ctx);
81203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathEvalExpr(ctxt);
81213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->value == NULL) {
81233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
81243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEval: evaluation failed\n");
81253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
81263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else if (*ctxt->cur != 0) {
81273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPatherror(ctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
81283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
81293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
81303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = valuePop(ctxt);
81313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
81323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
81343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        tmp = valuePop(ctxt);
81353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (tmp != NULL) {
81363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    if (tmp != init)
81373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		stack++;
81383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathFreeObject(tmp);
81393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        }
81403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (tmp != NULL);
81413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((stack != 0) && (res != NULL)) {
81423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
81433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEval: %d object left on the stack\n",
81443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        stack);
81453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
81463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (ctxt->error != XPATH_EXPRESSION_OK) {
81473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPathFreeObject(res);
81483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
81493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
81509e7160d45a18bfa26d708e22ba991f7670d0128bDaniel Veillard
81513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeParserContext(ctxt);
81523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(res);
81533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
81543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
81563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathEvalExpression:
81573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @str:  the XPath expression
81583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
81593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Evaluate the XPath expression in the given context.
81613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
81623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
81633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *         the caller has to free the object.
81643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
81653473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathObjectPtr
81663473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathEvalExpression(const xmlChar *str, xmlXPathContextPtr ctxt) {
81673473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathParserContextPtr pctxt;
81683473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathObjectPtr res, tmp;
81693473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    int stack = 0;
81703473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81713473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathInit();
81723473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81733473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    CHECK_CONTEXT(ctxt)
81743473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81753473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    pctxt = xmlXPathNewParserContext(str, ctxt);
81763473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathEvalExpr(pctxt);
81773473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
81783473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if (*pctxt->cur != 0) {
81793473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlXPatherror(pctxt, __FILE__, __LINE__, XPATH_EXPR_ERROR);
81803473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = NULL;
81813473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } else {
81823473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	res = valuePop(pctxt);
81833473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
81843473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    do {
81853473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor        tmp = valuePop(pctxt);
81863473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	if (tmp != NULL) {
81873473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    xmlXPathFreeObject(tmp);
81883473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	    stack++;
81893473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	}
81903473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    } while (tmp != NULL);
81913473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    if ((stack != 0) && (res != NULL)) {
81923473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	xmlGenericError(xmlGenericErrorContext,
81933473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor		"xmlXPathEvalExpression: %d object left on the stack\n",
81943473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor	        stack);
81953473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    }
81963473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathFreeParserContext(pctxt);
81973473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    return(res);
81983473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
81993473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
82003473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor/**
82013473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * xmlXPathRegisterAllFunctions:
82023473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * @ctxt:  the XPath context
82033473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor *
82043473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor * Registers all default XPath functions in this context
82053473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor */
82063473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylorvoid
82073473f88a7abdf4e585e267288fb77e898c580d2bOwen TaylorxmlXPathRegisterAllFunctions(xmlXPathContextPtr ctxt)
82083473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor{
82093473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"boolean",
82103473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathBooleanFunction);
82113473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"ceiling",
82123473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathCeilingFunction);
82133473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"count",
82143473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathCountFunction);
82153473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"concat",
82163473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathConcatFunction);
82173473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"contains",
82183473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathContainsFunction);
82193473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"id",
82203473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathIdFunction);
82213473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"false",
82223473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathFalseFunction);
82233473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"floor",
82243473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathFloorFunction);
82253473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"last",
82263473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLastFunction);
82273473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"lang",
82283473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLangFunction);
82293473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"local-name",
82303473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathLocalNameFunction);
82313473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"not",
82323473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNotFunction);
82333473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"name",
82343473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNameFunction);
82353473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"namespace-uri",
82363473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNamespaceURIFunction);
82373473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"normalize-space",
82383473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNormalizeFunction);
82393473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"number",
82403473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathNumberFunction);
82413473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"position",
82423473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathPositionFunction);
82433473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"round",
82443473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathRoundFunction);
82453473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string",
82463473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStringFunction);
82473473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"string-length",
82483473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStringLengthFunction);
82493473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"starts-with",
82503473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathStartsWithFunction);
82513473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring",
82523473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringFunction);
82533473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-before",
82543473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringBeforeFunction);
82553473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"substring-after",
82563473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSubstringAfterFunction);
82573473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"sum",
82583473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathSumFunction);
82593473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"true",
82603473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathTrueFunction);
82613473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor    xmlXPathRegisterFunc(ctxt, (const xmlChar *)"translate",
82623473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor                         xmlXPathTranslateFunction);
82633473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor}
82643473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor
82653473f88a7abdf4e585e267288fb77e898c580d2bOwen Taylor#endif /* LIBXML_XPATH_ENABLED */
8266