15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xpointer.c : Code to handle XML Pointer
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Base implementation was made accordingly to
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * W3C Candidate Recommendation 7 June 2000
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.w3.org/TR/2000/CR-xptr-20000607
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Added support for the element() scheme described in:
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * W3C Proposed Recommendation 13 November 2002
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.w3.org/TR/2002/PR-xptr-element-20021113/
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software.
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * daniel@veillard.com
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXML
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxml.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: better handling of error cases, the full expression should
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *       be parsed beforehand instead of a progressive evaluation
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: Access into entities references are not supported now ...
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *       need a start to be able to pop out of entities refs since
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *       parent is the endity declaration, not the ref.
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpointer.h>
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h>
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parserInternals.h>
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/uri.h>
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpath.h>
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xpathInternals.h>
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlerror.h>
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/globals.h>
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_XPTR_ENABLED
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* Add support of the xmlns() xpointer scheme to initialize the namespaces */
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XPTR_XMLNS_SCHEME
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* #define DEBUG_RANGES */
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RANGES
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DEBUG_ENABLED
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/debugXML.h>
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TODO 								\
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlGenericError(xmlGenericErrorContext,				\
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "Unimplemented block at %s:%d\n",				\
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            __FILE__, __LINE__);
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define STRANGE 							\
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlGenericError(xmlGenericErrorContext,				\
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "Internal error at %s:%d\n",				\
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            __FILE__, __LINE__);
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 		Some factorized error routines				*
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrErrMemory:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra:  extra informations
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle a redefinition of attribute error
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrErrMemory(const char *extra)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    __xmlRaiseError(NULL, NULL, NULL, NULL, NULL, XML_FROM_XPOINTER,
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    XML_ERR_NO_MEMORY, XML_ERR_ERROR, NULL, 0, extra,
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    NULL, NULL, 0, 0,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "Memory allocation failed : %s\n", extra);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrErr:
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  an XPTR evaluation context
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @extra:  extra informations
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Handle a redefinition of attribute error
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrErr(xmlXPathParserContextPtr ctxt, int error,
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           const char * msg, const xmlChar *extra)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt != NULL)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ctxt->error = error;
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (ctxt->context == NULL)) {
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	__xmlRaiseError(NULL, NULL, NULL,
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			NULL, NULL, XML_FROM_XPOINTER, error,
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			XML_ERR_ERROR, NULL, 0,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(const char *) extra, NULL, NULL, 0, 0,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			msg, extra);
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->lastError.domain = XML_FROM_XPOINTER;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->lastError.code = error;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->lastError.level = XML_ERR_ERROR;
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->lastError.str1 = (char *) xmlStrdup(ctxt->base);
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->lastError.int1 = ctxt->cur - ctxt->base;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->lastError.node = ctxt->context->debugNode;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->context->error != NULL) {
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->error(ctxt->context->userData,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                     &ctxt->context->lastError);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	__xmlRaiseError(NULL, NULL, NULL,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			NULL, ctxt->context->debugNode, XML_FROM_XPOINTER,
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			error, XML_ERR_ERROR, NULL, 0,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(const char *) extra, (const char *) ctxt->base, NULL,
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ctxt->cur - ctxt->base, 0,
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			msg, extra);
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *		A few helper functions for child sequences		*
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* xmlXPtrAdvanceNode is a private function, but used by xinclude.c */
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNodePtr xmlXPtrAdvanceNode(xmlNodePtr cur, int *level);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrGetArity:
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur:  the node
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of child for an element, -1 in case of error
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrGetArity(xmlNodePtr cur) {
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = cur->children;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;cur != NULL;cur = cur->next) {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((cur->type == XML_ELEMENT_NODE) ||
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (cur->type == XML_DOCUMENT_NODE) ||
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    i++;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(i);
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrGetIndex:
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur:  the node
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the index of the node in its parent children list, -1
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         in case of error
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrGetIndex(xmlNodePtr cur) {
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 1;cur != NULL;cur = cur->prev) {
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((cur->type == XML_ELEMENT_NODE) ||
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (cur->type == XML_DOCUMENT_NODE) ||
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    i++;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(i);
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrGetNthChild:
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur:  the node
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @no:  the child number
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the @no'th element child of @cur or NULL
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlNodePtr
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrGetNthChild(xmlNodePtr cur, int no) {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(cur);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = cur->children;
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i <= no;cur = cur->next) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == NULL)
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(cur);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((cur->type == XML_ELEMENT_NODE) ||
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (cur->type == XML_DOCUMENT_NODE) ||
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (cur->type == XML_HTML_DOCUMENT_NODE)) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    i++;
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (i == no)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(cur);
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *		Handling of XPointer specific types			*
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrCmpPoints:
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node1:  the first node
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @index1:  the first index
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node2:  the second node
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @index2:  the second index
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compare two points w.r.t document order
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -2 in case of error 1 if first point < second point, 0 if
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         that's the same point, -1 otherwise
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrCmpPoints(xmlNodePtr node1, int index1, xmlNodePtr node2, int index2) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((node1 == NULL) || (node2 == NULL))
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-2);
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * a couple of optimizations which will avoid computations in most cases
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (node1 == node2) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (index1 < index2)
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(1);
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (index1 > index2)
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(xmlXPathCmpNodes(node1, node2));
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewPoint:
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  the xmlNodePtr
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @indx:  the indx within the node
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type point
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlXPathObjectPtr
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewPoint(xmlNodePtr node, int indx) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (node == NULL)
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (indx < 0)
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating point");
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_POINT;
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = (void *) node;
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index = indx;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrRangeCheckOrder:
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @range:  an object range
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Make sure the points in the range are in the right order
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrRangeCheckOrder(xmlXPathObjectPtr range) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int tmp;
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr tmp2;
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range == NULL)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range->type != XPATH_RANGE)
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range->user2 == NULL)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tmp = xmlXPtrCmpPoints(range->user, range->index,
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                     range->user2, range->index2);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (tmp == -1) {
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp2 = range->user;
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	range->user = range->user2;
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	range->user2 = tmp2;
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = range->index;
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	range->index = range->index2;
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	range->index2 = tmp;
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrRangesEqual:
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @range1:  the first range
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @range2:  the second range
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compare two ranges
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if equal, 0 otherwise
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrRangesEqual(xmlXPathObjectPtr range1, xmlXPathObjectPtr range2) {
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range1 == range2)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(1);
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((range1 == NULL) || (range2 == NULL))
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range1->type != range2->type)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range1->type != XPATH_RANGE)
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range1->user != range2->user)
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range1->index != range2->index)
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range1->user2 != range2->user2)
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range1->index2 != range2->index2)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(1);
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewRange:
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the starting node
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @startindex:  the start index
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the ending point
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @endindex:  the ending index
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type range
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewRange(xmlNodePtr start, int startindex,
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlNodePtr end, int endindex) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == NULL)
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (startindex < 0)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (endindex < 0)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating range");
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_RANGE;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = start;
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index = startindex;
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user2 = end;
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index2 = endindex;
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPtrRangeCheckOrder(ret);
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewRangePoints:
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the starting point
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the ending point
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type range using 2 Points
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewRangePoints(xmlXPathObjectPtr start, xmlXPathObjectPtr end) {
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == NULL)
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start->type != XPATH_POINT)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end->type != XPATH_POINT)
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating range");
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_RANGE;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = start->user;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index = start->index;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user2 = end->user;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index2 = end->index;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPtrRangeCheckOrder(ret);
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewRangePointNode:
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the starting point
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the ending node
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type range from a point to a node
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewRangePointNode(xmlXPathObjectPtr start, xmlNodePtr end) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == NULL)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start->type != XPATH_POINT)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating range");
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_RANGE;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = start->user;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index = start->index;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user2 = end;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index2 = -1;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPtrRangeCheckOrder(ret);
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewRangeNodePoint:
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the starting node
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the ending point
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type range from a node to a point
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewRangeNodePoint(xmlNodePtr start, xmlXPathObjectPtr end) {
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == NULL)
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start->type != XPATH_POINT)
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end->type != XPATH_POINT)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating range");
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_RANGE;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = start;
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index = -1;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user2 = end->user;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index2 = end->index;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPtrRangeCheckOrder(ret);
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewRangeNodes:
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the starting node
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the ending node
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type range using 2 nodes
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewRangeNodes(xmlNodePtr start, xmlNodePtr end) {
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == NULL)
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating range");
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_RANGE;
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = start;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index = -1;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user2 = end;
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index2 = -1;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPtrRangeCheckOrder(ret);
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewCollapsedRange:
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the starting and ending node
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type range using a single nodes
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewCollapsedRange(xmlNodePtr start) {
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating range");
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_RANGE;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = start;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index = -1;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user2 = NULL;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index2 = -1;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewRangeNodeObject:
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the starting node
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the ending object
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type range from a not to an object
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewRangeNodeObject(xmlNodePtr start, xmlXPathObjectPtr end) {
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == NULL)
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (end->type) {
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_POINT:
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_RANGE:
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_NODESET:
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Empty set ...
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (end->nodesetval->nodeNr <= 0)
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* TODO */
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating range");
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_RANGE;
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = start;
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->index = -1;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (end->type) {
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_POINT:
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret->user2 = end->user;
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret->index2 = end->index;
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_RANGE:
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret->user2 = end->user2;
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret->index2 = end->index2;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_NODESET: {
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret->user2 = end->nodesetval->nodeTab[end->nodesetval->nodeNr - 1];
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret->index2 = -1;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    STRANGE
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPtrRangeCheckOrder(ret);
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XML_RANGESET_DEFAULT	10
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrLocationSetCreate:
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @val:  an initial xmlXPathObjectPtr, or NULL
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlLocationSetPtr of type double and of value @val
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlLocationSetPtr
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrLocationSetCreate(xmlXPathObjectPtr val) {
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr ret;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlLocationSetPtr) xmlMalloc(sizeof(xmlLocationSet));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating locationset");
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlLocationSet));
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (val != NULL) {
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					     sizeof(xmlXPathObjectPtr));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret->locTab == NULL) {
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrErrMemory("allocating locationset");
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(ret);
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memset(ret->locTab, 0 ,
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        ret->locMax = XML_RANGESET_DEFAULT;
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->locTab[ret->locNr++] = val;
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrLocationSetAdd:
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur:  the initial range set
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @val:  a new xmlXPathObjectPtr
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * add a new xmlXPathObjectPtr to an existing LocationSet
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the location already exist in the set @val is freed.
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrLocationSetAdd(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((cur == NULL) || (val == NULL)) return;
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * check against doublons
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < cur->locNr;i++) {
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (xmlXPtrRangesEqual(cur->locTab[i], val)) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathFreeObject(val);
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * grow the locTab if needed
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur->locMax == 0) {
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur->locTab = (xmlXPathObjectPtr *) xmlMalloc(XML_RANGESET_DEFAULT *
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					     sizeof(xmlXPathObjectPtr));
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur->locTab == NULL) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrErrMemory("adding location to set");
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	memset(cur->locTab, 0 ,
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       XML_RANGESET_DEFAULT * (size_t) sizeof(xmlXPathObjectPtr));
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur->locMax = XML_RANGESET_DEFAULT;
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (cur->locNr == cur->locMax) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPathObjectPtr *temp;
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur->locMax *= 2;
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	temp = (xmlXPathObjectPtr *) xmlRealloc(cur->locTab, cur->locMax *
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      sizeof(xmlXPathObjectPtr));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (temp == NULL) {
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrErrMemory("adding location to set");
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur->locTab = temp;
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->locTab[cur->locNr++] = val;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrLocationSetMerge:
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @val1:  the first LocationSet
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @val2:  the second LocationSet
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Merges two rangesets, all ranges from @val2 are added to @val1
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns val1 once extended or NULL in case of error.
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlLocationSetPtr
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrLocationSetMerge(xmlLocationSetPtr val1, xmlLocationSetPtr val2) {
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (val1 == NULL) return(NULL);
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (val2 == NULL) return(val1);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * !!!!! this can be optimized a lot, knowing that both
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *       val1 and val2 already have unicity of their values.
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < val2->locNr;i++)
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrLocationSetAdd(val1, val2->locTab[i]);
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(val1);
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrLocationSetDel:
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur:  the initial range set
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @val:  an xmlXPathObjectPtr
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Removes an xmlXPathObjectPtr from an existing LocationSet
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrLocationSetDel(xmlLocationSetPtr cur, xmlXPathObjectPtr val) {
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL) return;
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (val == NULL) return;
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * check against doublons
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < cur->locNr;i++)
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (cur->locTab[i] == val) break;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (i >= cur->locNr) {
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlGenericError(xmlGenericErrorContext,
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        "xmlXPtrLocationSetDel: Range wasn't found in RangeList\n");
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return;
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->locNr--;
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (;i < cur->locNr;i++)
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur->locTab[i] = cur->locTab[i + 1];
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->locTab[cur->locNr] = NULL;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrLocationSetRemove:
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur:  the initial range set
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @val:  the index to remove
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Removes an entry from an existing LocationSet list.
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrLocationSetRemove(xmlLocationSetPtr cur, int val) {
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL) return;
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (val >= cur->locNr) return;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->locNr--;
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (;val < cur->locNr;val++)
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur->locTab[val] = cur->locTab[val + 1];
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->locTab[cur->locNr] = NULL;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrFreeLocationSet:
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @obj:  the xmlLocationSetPtr to free
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free the LocationSet compound (not the actual ranges !).
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrFreeLocationSet(xmlLocationSetPtr obj) {
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj == NULL) return;
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj->locTab != NULL) {
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < obj->locNr; i++) {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            xmlXPathFreeObject(obj->locTab[i]);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(obj->locTab);
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(obj);
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewLocationSetNodes:
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the start NodePtr value
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the end NodePtr value or NULL
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type LocationSet and initialize
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it with the single range made of the two nodes @start and @end
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewLocationSetNodes(xmlNodePtr start, xmlNodePtr end) {
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating locationset");
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_LOCATIONSET;
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == NULL)
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewCollapsedRange(start));
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->user = xmlXPtrLocationSetCreate(xmlXPtrNewRangeNodes(start,end));
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewLocationSetNodeSet:
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @set:  a node set
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new xmlXPathObjectPtr of type LocationSet and initialize
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it with all the nodes from @set
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewLocationSetNodeSet(xmlNodeSetPtr set) {
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating locationset");
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_LOCATIONSET;
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (set != NULL) {
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlLocationSetPtr newset;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	newset = xmlXPtrLocationSetCreate(NULL);
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (newset == NULL)
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(ret);
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0;i < set->nodeNr;i++)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrLocationSetAdd(newset,
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		        xmlXPtrNewCollapsedRange(set->nodeTab[i]));
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret->user = (void *) newset;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrWrapLocationSet:
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @val:  the LocationSet value
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Wrap the LocationSet @val in a new xmlXPathObjectPtr
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly created object.
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrWrapLocationSet(xmlLocationSetPtr val) {
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr ret;
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = (xmlXPathObjectPtr) xmlMalloc(sizeof(xmlXPathObject));
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL) {
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating locationset");
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ret, 0 , (size_t) sizeof(xmlXPathObject));
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->type = XPATH_LOCATIONSET;
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->user = (void *) val;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *			The parser					*
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name);
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Macros for accessing the content. Those should be used only by the parser,
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and not exported.
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Dirty macros, i.e. one need to make assumption on the context to use them
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   CUR_PTR return the current pointer to the xmlChar to be parsed.
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   CUR     returns the current xmlChar value, i.e. a 8 bit value
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           in ISO-Latin or UTF-8.
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           This should be used internally by the parser
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           only to compare to ASCII values otherwise it would break when
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           running with UTF-8 encoding.
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   NXT(n)  returns the n'th next xmlChar. Same as CUR is should be used only
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           to compare on ASCII based substring.
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   SKIP(n) Skip n xmlChar, and must also be used only to skip ASCII defined
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           strings within the parser.
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   CURRENT Returns the current char value, with the full decoding of
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           UTF-8 if we are using this mode. It returns an int.
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   NEXT    Skip to the next character, this does the proper decoding
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           in UTF-8 mode. It also pop-up unfinished entities on the fly.
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           It returns the pointer to the current xmlChar.
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR (*ctxt->cur)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SKIP(val) ctxt->cur += (val)
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NXT(val) ctxt->cur[(val)]
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR_PTR ctxt->cur
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SKIP_BLANKS 							\
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (IS_BLANK_CH(*(ctxt->cur))) NEXT
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CURRENT (*ctxt->cur)
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrGetChildNo:
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @index:  the child number
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Move the current node of the nodeset on the stack to the
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * given child if found
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrGetChildNo(xmlXPathParserContextPtr ctxt, int indx) {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr cur = NULL;
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr obj;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodeSetPtr oldset;
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_TYPE(XPATH_NODESET);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    obj = valuePop(ctxt);
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset = obj->nodesetval;
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((indx <= 0) || (oldset == NULL) || (oldset->nodeNr != 1)) {
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(obj);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	valuePush(ctxt, xmlXPathNewNodeSet(NULL));
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = xmlXPtrGetNthChild(oldset->nodeTab[0], indx);
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL) {
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(obj);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	valuePush(ctxt, xmlXPathNewNodeSet(NULL));
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset->nodeTab[0] = cur;
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, obj);
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrEvalXPtrPart:
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name:  the preparsed Scheme for the XPtrPart
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XPtrPart ::= 'xpointer' '(' XPtrExpr ')'
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *            | Scheme '(' SchemeSpecificExpr ')'
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Scheme   ::=  NCName - 'xpointer' [VC: Non-XPointer schemes]
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * SchemeSpecificExpr ::= StringWithBalancedParens
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * StringWithBalancedParens ::=
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *              [^()]* ('(' StringWithBalancedParens ')' [^()]*)*
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *              [VC: Parenthesis escaping]
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XPtrExpr ::= Expr [VC: Parenthesis escaping]
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * VC: Parenthesis escaping:
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   The end of an XPointer part is signaled by the right parenthesis ")"
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   character that is balanced with the left parenthesis "(" character
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   that began the part. Any unbalanced parenthesis character inside the
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   expression, even within literals, must be escaped with a circumflex (^)
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   character preceding it. If the expression contains any literal
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   occurrences of the circumflex, each must be escaped with an additional
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   circumflex (that is, ^^). If the unescaped parentheses in the expression
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   are not balanced, a syntax error results.
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parse and evaluate an XPtrPart. Basically it generates the unescaped
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string and if the scheme is 'xpointer' it will call the XPath interpreter.
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: there is no new scheme registration mechanism
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrEvalXPtrPart(xmlXPathParserContextPtr ctxt, xmlChar *name) {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *buffer, *cur;
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len;
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int level;
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name == NULL)
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = xmlXPathParseName(ctxt);
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name == NULL)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPATH_EXPR_ERROR);
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR != '(')
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPATH_EXPR_ERROR);
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEXT;
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    level = 1;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    len = xmlStrlen(ctxt->cur);
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    len++;
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    buffer = (xmlChar *) xmlMallocAtomic(len * sizeof (xmlChar));
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (buffer == NULL) {
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErrMemory("allocating buffer");
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = buffer;
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (CUR != 0) {
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == ')') {
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    level--;
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (level == 0) {
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NEXT;
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (CUR == '(') {
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    level++;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (CUR == '^') {
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((NXT(1) == ')') || (NXT(1) == '(') || (NXT(1) == '^')) {
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        NEXT;
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*cur++ = CUR;
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *cur = 0;
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((level != 0) && (CUR == 0)) {
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(buffer);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPTR_SYNTAX_ERROR);
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xmlStrEqual(name, (xmlChar *) "xpointer")) {
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const xmlChar *left = CUR_PTR;
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CUR_PTR = buffer;
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * To evaluate an xpointer scheme element (4.3) we need:
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   context initialized to the root
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   context position initalized to 1
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 *   context size initialized to 1
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->node = (xmlNodePtr)ctxt->context->doc;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->proximityPosition = 1;
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->contextSize = 1;
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathEvalExpr(ctxt);
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CUR_PTR=left;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (xmlStrEqual(name, (xmlChar *) "element")) {
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const xmlChar *left = CUR_PTR;
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *name2;
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CUR_PTR = buffer;
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (buffer[0] == '/') {
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathRoot(ctxt);
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrEvalChildSeq(ctxt, NULL);
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    name2 = xmlXPathParseName(ctxt);
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (name2 == NULL) {
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		CUR_PTR = left;
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree(buffer);
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		XP_ERROR(XPATH_EXPR_ERROR);
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrEvalChildSeq(ctxt, name2);
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CUR_PTR = left;
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XPTR_XMLNS_SCHEME
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (xmlStrEqual(name, (xmlChar *) "xmlns")) {
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const xmlChar *left = CUR_PTR;
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *prefix;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *URI;
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlURIPtr value;
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CUR_PTR = buffer;
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        prefix = xmlXPathParseNCName(ctxt);
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (prefix == NULL) {
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(buffer);
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(name);
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XP_ERROR(XPTR_SYNTAX_ERROR);
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != '=') {
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(prefix);
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(buffer);
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(name);
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XP_ERROR(XPTR_SYNTAX_ERROR);
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* @@ check escaping in the XPointer WD */
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	value = xmlParseURI((const char *)ctxt->cur);
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (value == NULL) {
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(prefix);
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(buffer);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(name);
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XP_ERROR(XPTR_SYNTAX_ERROR);
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	URI = xmlSaveUri(value);
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFreeURI(value);
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (URI == NULL) {
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(prefix);
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(buffer);
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(name);
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XP_ERROR(XPATH_MEMORY_ERROR);
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathRegisterNs(ctxt->context, prefix, URI);
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CUR_PTR = left;
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(URI);
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(prefix);
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif /* XPTR_XMLNS_SCHEME */
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErr(ctxt, XML_XPTR_UNKNOWN_SCHEME,
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   "unsupported scheme '%s'\n", name);
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(buffer);
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(name);
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrEvalFullXPtr:
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name:  the preparsed Scheme for the first XPtrPart
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * FullXPtr ::= XPtrPart (S? XPtrPart)*
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * As the specs says:
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -----------
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * When multiple XPtrParts are provided, they must be evaluated in
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * left-to-right order. If evaluation of one part fails, the nexti
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is evaluated. The following conditions cause XPointer part failure:
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - An unknown scheme
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - A scheme that does not locate any sub-resource present in the resource
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - A scheme that is not applicable to the media type of the resource
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The XPointer application must consume a failed XPointer part and
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * attempt to evaluate the next one, if any. The result of the first
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XPointer part whose evaluation succeeds is taken to be the fragment
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * located by the XPointer as a whole. If all the parts fail, the result
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for the XPointer as a whole is a sub-resource error.
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * -----------
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parse and evaluate a Full XPtr i.e. possibly a cascade of XPath based
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * expressions or other schemes.
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrEvalFullXPtr(xmlXPathParserContextPtr ctxt, xmlChar *name) {
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name == NULL)
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    name = xmlXPathParseName(ctxt);
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name == NULL)
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPATH_EXPR_ERROR);
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (name != NULL) {
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = XPATH_EXPRESSION_OK;
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPtrEvalXPtrPart(ctxt, name);
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* in case of syntax error, break here */
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((ctxt->error != XPATH_EXPRESSION_OK) &&
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (ctxt->error != XML_XPTR_UNKNOWN_SCHEME))
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * If the returned value is a non-empty nodeset
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * or location set, return here.
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->value != NULL) {
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathObjectPtr obj = ctxt->value;
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    switch (obj->type) {
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XPATH_LOCATIONSET: {
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlLocationSetPtr loc = ctxt->value->user;
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((loc != NULL) && (loc->locNr > 0))
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return;
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XPATH_NODESET: {
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlNodeSetPtr loc = ctxt->value->nodesetval;
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((loc != NULL) && (loc->nodeNr > 0))
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return;
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Evaluating to improper values is equivalent to
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * a sub-resource error, clean-up the stack
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    do {
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		obj = valuePop(ctxt);
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (obj != NULL) {
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPathFreeObject(obj);
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } while (obj != NULL);
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Is there another XPointer part.
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	name = xmlXPathParseName(ctxt);
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrEvalChildSeq:
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name:  a possible ID name of the child sequence
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  ChildSeq ::= '/1' ('/' [0-9]*)*
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *             | Name ('/' [0-9]*)+
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parse and evaluate a Child Sequence. This routine also handle the
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * case of a Bare Name used to get a document ID.
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrEvalChildSeq(xmlXPathParserContextPtr ctxt, xmlChar *name) {
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * XPointer don't allow by syntax to address in mutirooted trees
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * this might prove useful in some cases, warn about it.
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((name == NULL) && (CUR == '/') && (NXT(1) != '1')) {
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErr(ctxt, XML_XPTR_CHILDSEQ_START,
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   "warning: ChildSeq not starting by /1\n", NULL);
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name != NULL) {
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	valuePush(ctxt, xmlXPathNewString(name));
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(name);
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathIdFunction(ctxt, 1);
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CHECK_ERROR;
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (CUR == '/') {
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int child = 0;
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((CUR >= '0') && (CUR <= '9')) {
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    child = child * 10 + (CUR - '0');
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPtrGetChildNo(ctxt, child);
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrEvalXPointer:
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  XPointer ::= Name
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *             | ChildSeq
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *             | FullXPtr
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parse and evaluate an XPointer
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrEvalXPointer(xmlXPathParserContextPtr ctxt) {
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->valueTab == NULL) {
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* Allocate the value stack */
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->valueTab = (xmlXPathObjectPtr *)
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 xmlMalloc(10 * sizeof(xmlXPathObjectPtr));
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->valueTab == NULL) {
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrErrMemory("allocating evaluation context");
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->valueNr = 0;
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->valueMax = 10;
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->value = NULL;
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR == '/') {
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathRoot(ctxt);
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrEvalChildSeq(ctxt, NULL);
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *name;
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	name = xmlXPathParseName(ctxt);
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (name == NULL)
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XP_ERROR(XPATH_EXPR_ERROR);
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == '(') {
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrEvalFullXPtr(ctxt, name);
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Short evaluation */
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* this handle both Bare Names and Child Sequences */
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrEvalChildSeq(ctxt, name);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR != 0)
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPATH_EXPR_ERROR);
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *			General routines				*
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs);
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs);
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs);
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs);
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs);
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNewContext:
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @doc:  the XML document
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @here:  the node that directly contains the XPointer being evaluated or NULL
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @origin:  the element from which a user or program initiated traversal of
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *           the link, or NULL.
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new XPointer context
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the xmlXPathContext just allocated.
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathContextPtr
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNewContext(xmlDocPtr doc, xmlNodePtr here, xmlNodePtr origin) {
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathContextPtr ret;
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlXPathNewContext(doc);
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ret == NULL)
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(ret);
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->xptr = 1;
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->here = here;
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret->origin = origin;
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathRegisterFunc(ret, (xmlChar *)"range-to",
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlXPtrRangeToFunction);
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathRegisterFunc(ret, (xmlChar *)"range",
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlXPtrRangeFunction);
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathRegisterFunc(ret, (xmlChar *)"range-inside",
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlXPtrRangeInsideFunction);
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathRegisterFunc(ret, (xmlChar *)"string-range",
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlXPtrStringRangeFunction);
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathRegisterFunc(ret, (xmlChar *)"start-point",
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlXPtrStartPointFunction);
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathRegisterFunc(ret, (xmlChar *)"end-point",
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlXPtrEndPointFunction);
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathRegisterFunc(ret, (xmlChar *)"here",
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlXPtrHereFunction);
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathRegisterFunc(ret, (xmlChar *)" origin",
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                 xmlXPtrOriginFunction);
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrEval:
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @str:  the XPointer expression
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctx:  the XPointer context
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Evaluate the XPath Location Path in the given context.
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the xmlXPathObjectPtr resulting from the evaluation or NULL.
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         the caller has to free the object.
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPathObjectPtr
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrEval(const xmlChar *str, xmlXPathContextPtr ctx) {
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathParserContextPtr ctxt;
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr res = NULL, tmp;
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr init = NULL;
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int stack = 0;
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathInit();
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctx == NULL) || (str == NULL))
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt = xmlXPathNewParserContext(str, ctx);
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->xptr = 1;
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPtrEvalXPointer(ctxt);
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt->value != NULL) &&
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ctxt->value->type != XPATH_NODESET) &&
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ctxt->value->type != XPATH_LOCATIONSET)) {
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErr(ctxt, XML_XPTR_EVAL_FAILED,
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"xmlXPtrEval: evaluation failed to return a node set\n",
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   NULL);
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	res = valuePop(ctxt);
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = valuePop(ctxt);
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp != NULL) {
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp != init) {
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (tmp->type == XPATH_NODESET) {
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * Evaluation may push a root nodeset which is unused
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlNodeSetPtr set;
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    set = tmp->nodesetval;
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((set->nodeNr != 1) ||
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(set->nodeTab[0] != (xmlNodePtr) ctx->doc))
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			stack++;
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    stack++;
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathFreeObject(tmp);
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (tmp != NULL);
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (stack != 0) {
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xmlXPtrErr(ctxt, XML_XPTR_EXTRA_OBJECTS,
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   "xmlXPtrEval: object(s) left on the eval stack\n",
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   NULL);
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->error != XPATH_EXPRESSION_OK) {
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(res);
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	res = NULL;
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeParserContext(ctxt);
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(res);
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrBuildRangeNodeList:
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @range:  a range object
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build a node list tree copy of the range
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns an xmlNodePtr list or NULL.
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         the caller has to free the node tree.
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlNodePtr
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrBuildRangeNodeList(xmlXPathObjectPtr range) {
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* pointers to generated nodes */
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr list = NULL, last = NULL, parent = NULL, tmp;
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* pointers to traversal nodes */
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr start, cur, end;
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int index1, index2;
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range == NULL)
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (range->type != XPATH_RANGE)
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    start = (xmlNodePtr) range->user;
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    end = range->user2;
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == NULL)
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(xmlCopyNode(start, 1));
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = start;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    index1 = range->index;
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    index2 = range->index2;
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (cur != NULL) {
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == end) {
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (cur->type == XML_TEXT_NODE) {
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		const xmlChar *content = cur->content;
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int len;
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (content == NULL) {
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp = xmlNewTextLen(NULL, 0);
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    len = index2;
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((cur == start) && (index1 > 1)) {
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			content += (index1 - 1);
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			len -= (index1 - 1);
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			index1 = 0;
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			len = index2;
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp = xmlNewTextLen(content, len);
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* single sub text node selection */
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (list == NULL)
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(tmp);
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* prune and return full set */
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (last != NULL)
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlAddNextSibling(last, tmp);
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlAddChild(parent, tmp);
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(list);
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp = xmlCopyNode(cur, 0);
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (list == NULL)
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    list = tmp;
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else {
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (last != NULL)
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlAddNextSibling(last, tmp);
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    else
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlAddChild(parent, tmp);
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		last = NULL;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parent = tmp;
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (index2 > 1) {
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    end = xmlXPtrGetNthChild(cur, index2 - 1);
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    index2 = 0;
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((cur == start) && (index1 > 1)) {
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    cur = xmlXPtrGetNthChild(cur, index1 - 1);
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    index1 = 0;
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    cur = cur->children;
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * Now gather the remaining nodes from cur to end
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue; /* while */
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((cur == start) &&
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (list == NULL) /* looks superfluous but ... */ ) {
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((cur->type == XML_TEXT_NODE) ||
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(cur->type == XML_CDATA_SECTION_NODE)) {
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		const xmlChar *content = cur->content;
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (content == NULL) {
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp = xmlNewTextLen(NULL, 0);
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (index1 > 1) {
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			content += (index1 - 1);
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp = xmlNewText(content);
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		last = list = tmp;
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((cur == start) && (index1 > 1)) {
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp = xmlCopyNode(cur, 0);
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    list = tmp;
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    parent = tmp;
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    last = NULL;
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    cur = xmlXPtrGetNthChild(cur, index1 - 1);
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    index1 = 0;
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * Now gather the remaining nodes from cur to end
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue; /* while */
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		tmp = xmlCopyNode(cur, 1);
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = tmp;
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		parent = NULL;
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		last = tmp;
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = NULL;
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    switch (cur->type) {
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_DTD_NODE:
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ELEMENT_DECL:
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ATTRIBUTE_DECL:
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ENTITY_NODE:
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* Do not copy DTD informations */
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ENTITY_DECL:
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    TODO /* handle crossing entities -> stack needed */
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_XINCLUDE_START:
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_XINCLUDE_END:
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* don't consider it part of the tree content */
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ATTRIBUTE_NODE:
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* Humm, should not happen ! */
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    STRANGE
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    tmp = xmlCopyNode(cur, 1);
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp != NULL) {
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((list == NULL) || ((last == NULL) && (parent == NULL)))  {
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    STRANGE
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(NULL);
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (last != NULL)
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlAddNextSibling(last, tmp);
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else {
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlAddChild(parent, tmp);
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    last = tmp;
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Skip to next node in document order
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((list == NULL) || ((last == NULL) && (parent == NULL)))  {
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    STRANGE
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = xmlXPtrAdvanceNode(cur, NULL);
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(list);
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrBuildNodeList:
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @obj:  the XPointer result from the evaluation.
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Build a node list tree copy of the XPointer result.
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This will drop Attributes and Namespace declarations.
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns an xmlNodePtr list or NULL.
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *         the caller has to free the node tree.
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNodePtr
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrBuildNodeList(xmlXPathObjectPtr obj) {
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr list = NULL, last = NULL;
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj == NULL)
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (obj->type) {
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_NODESET: {
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlNodeSetPtr set = obj->nodesetval;
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (set == NULL)
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < set->nodeNr;i++) {
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (set->nodeTab[i] == NULL)
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch (set->nodeTab[i]->type) {
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_TEXT_NODE:
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_CDATA_SECTION_NODE:
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ELEMENT_NODE:
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ENTITY_REF_NODE:
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ENTITY_NODE:
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_PI_NODE:
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_COMMENT_NODE:
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_DOCUMENT_NODE:
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_HTML_DOCUMENT_NODE:
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DOCB_ENABLED
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_DOCB_DOCUMENT_NODE:
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_XINCLUDE_START:
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_XINCLUDE_END:
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ATTRIBUTE_NODE:
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_NAMESPACE_DECL:
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_DOCUMENT_TYPE_NODE:
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_DOCUMENT_FRAG_NODE:
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_NOTATION_NODE:
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_DTD_NODE:
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ELEMENT_DECL:
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ATTRIBUTE_DECL:
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ENTITY_DECL:
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			continue; /* for */
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (last == NULL)
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    list = last = xmlCopyNode(set->nodeTab[i], 1);
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else {
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlAddNextSibling(last, xmlCopyNode(set->nodeTab[i], 1));
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (last->next != NULL)
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			last = last->next;
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_LOCATIONSET: {
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlLocationSetPtr set = (xmlLocationSetPtr) obj->user;
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (set == NULL)
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    for (i = 0;i < set->locNr;i++) {
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (last == NULL)
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    list = last = xmlXPtrBuildNodeList(set->locTab[i]);
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlAddNextSibling(last,
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlXPtrBuildNodeList(set->locTab[i]));
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (last != NULL) {
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    while (last->next != NULL)
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			last = last->next;
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_RANGE:
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(xmlXPtrBuildRangeNodeList(obj));
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XPATH_POINT:
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(xmlCopyNode(obj->user, 0));
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(list);
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *			XPointer functions				*
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrNbLocChildren:
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  an xmlNodePtr
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Count the number of location children of @node or the length of the
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string value in case of text/PI/Comments nodes
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the number of location children
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrNbLocChildren(xmlNodePtr node) {
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret = 0;
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (node == NULL)
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (node->type) {
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_HTML_DOCUMENT_NODE:
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_DOCUMENT_NODE:
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_ELEMENT_NODE:
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    node = node->children;
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    while (node != NULL) {
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->type == XML_ELEMENT_NODE)
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret++;
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		node = node->next;
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_ATTRIBUTE_NODE:
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_PI_NODE:
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_COMMENT_NODE:
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_TEXT_NODE:
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_CDATA_SECTION_NODE:
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XML_ENTITY_REF_NODE:
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrlen(node->content);
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrHereFunction:
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of args
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Function implementing here() operation
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * as described in 5.4.3
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrHereFunction(xmlXPathParserContextPtr ctxt, int nargs) {
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_ARITY(0);
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->context->here == NULL)
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPTR_SYNTAX_ERROR);
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->here, NULL));
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrOriginFunction:
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of args
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Function implementing origin() operation
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * as described in 5.4.3
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrOriginFunction(xmlXPathParserContextPtr ctxt, int nargs) {
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_ARITY(0);
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->context->origin == NULL)
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPTR_SYNTAX_ERROR);
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPtrNewLocationSetNodes(ctxt->context->origin, NULL));
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrStartPointFunction:
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of args
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Function implementing start-point() operation
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * as described in 5.4.3
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ----------------
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * location-set start-point(location-set)
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For each location x in the argument location-set, start-point adds a
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * location of type point to the result location-set. That point represents
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the start point of location x and is determined by the following rules:
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type point, the start point is x.
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type range, the start point is the start point of x.
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type root, element, text, comment, or processing instruction,
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - the container node of the start point is x and the index is 0.
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type attribute or namespace, the function must signal a
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   syntax error.
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ----------------
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrStartPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr tmp, obj, point;
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr newset = NULL;
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr oldset = NULL;
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_ARITY(1);
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt->value == NULL) ||
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	((ctxt->value->type != XPATH_LOCATIONSET) &&
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 (ctxt->value->type != XPATH_NODESET)))
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XP_ERROR(XPATH_INVALID_TYPE)
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    obj = valuePop(ctxt);
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj->type == XPATH_NODESET) {
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * First convert to a location set
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(obj);
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	obj = tmp;
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newset = xmlXPtrLocationSetCreate(NULL);
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (newset == NULL) {
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(obj);
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XP_ERROR(XPATH_MEMORY_ERROR);
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset = (xmlLocationSetPtr) obj->user;
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (oldset != NULL) {
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < oldset->locNr; i++) {
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = oldset->locTab[i];
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp == NULL)
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    point = NULL;
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    switch (tmp->type) {
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XPATH_POINT:
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    point = xmlXPtrNewPoint(tmp->user, tmp->index);
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XPATH_RANGE: {
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlNodePtr node = tmp->user;
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (node != NULL) {
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (node->type == XML_ATTRIBUTE_NODE) {
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /* TODO: Namespace Nodes ??? */
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlXPathFreeObject(obj);
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlXPtrFreeLocationSet(newset);
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    XP_ERROR(XPTR_SYNTAX_ERROR);
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			point = xmlXPtrNewPoint(node, tmp->index);
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        }
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*** Should we raise an error ?
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPathFreeObject(obj);
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPathFreeObject(newset);
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    XP_ERROR(XPATH_INVALID_TYPE)
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ***/
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (point != NULL)
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlXPtrLocationSetAdd(newset, point);
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeObject(obj);
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrEndPointFunction:
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of args
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Function implementing end-point() operation
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * as described in 5.4.3
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ----------------------------
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * location-set end-point(location-set)
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * For each location x in the argument location-set, end-point adds a
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * location of type point to the result location-set. That point represents
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the end point of location x and is determined by the following rules:
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type point, the resulting point is x.
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type range, the resulting point is the end point of x.
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type root or element, the container node of the resulting
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   point is x and the index is the number of location children of x.
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type text, comment, or processing instruction, the container
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   node of the resulting point is x and the index is the length of the
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   string-value of x.
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * - If x is of type attribute or namespace, the function must signal a
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   syntax error.
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ----------------------------
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrEndPointFunction(xmlXPathParserContextPtr ctxt, int nargs) {
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr tmp, obj, point;
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr newset = NULL;
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr oldset = NULL;
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_ARITY(1);
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt->value == NULL) ||
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	((ctxt->value->type != XPATH_LOCATIONSET) &&
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 (ctxt->value->type != XPATH_NODESET)))
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XP_ERROR(XPATH_INVALID_TYPE)
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    obj = valuePop(ctxt);
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (obj->type == XPATH_NODESET) {
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * First convert to a location set
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = xmlXPtrNewLocationSetNodeSet(obj->nodesetval);
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(obj);
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	obj = tmp;
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newset = xmlXPtrLocationSetCreate(NULL);
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset = (xmlLocationSetPtr) obj->user;
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (oldset != NULL) {
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int i;
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (i = 0; i < oldset->locNr; i++) {
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = oldset->locTab[i];
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (tmp == NULL)
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    point = NULL;
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    switch (tmp->type) {
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XPATH_POINT:
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    point = xmlXPtrNewPoint(tmp->user, tmp->index);
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XPATH_RANGE: {
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlNodePtr node = tmp->user2;
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (node != NULL) {
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (node->type == XML_ATTRIBUTE_NODE) {
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /* TODO: Namespace Nodes ??? */
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlXPathFreeObject(obj);
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlXPtrFreeLocationSet(newset);
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    XP_ERROR(XPTR_SYNTAX_ERROR);
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			point = xmlXPtrNewPoint(node, tmp->index2);
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else if (tmp->user == NULL) {
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			point = xmlXPtrNewPoint(node,
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				       xmlXPtrNbLocChildren(node));
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        }
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*** Should we raise an error ?
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPathFreeObject(obj);
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPathFreeObject(newset);
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    XP_ERROR(XPATH_INVALID_TYPE)
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ***/
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            if (point != NULL)
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlXPtrLocationSetAdd(newset, point);
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeObject(obj);
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrCoveringRange:
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @loc:  the location for which the covering range must be computed
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A covering range is a range that wholly encompasses a location
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Section 5.3.3. Covering Ranges for All Location Types
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *        http://www.w3.org/TR/xptr#N2267
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a new location or NULL in case of error
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlXPathObjectPtr
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrCoveringRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (loc == NULL)
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (ctxt->context == NULL) ||
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ctxt->context->doc == NULL))
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (loc->type) {
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_POINT:
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(xmlXPtrNewRange(loc->user, loc->index,
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			           loc->user, loc->index));
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_RANGE:
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (loc->user2 != NULL) {
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(xmlXPtrNewRange(loc->user, loc->index,
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			              loc->user2, loc->index2));
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlNodePtr node = (xmlNodePtr) loc->user;
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node == (xmlNodePtr) ctxt->context->doc) {
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(xmlXPtrNewRange(node, 0, node,
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   xmlXPtrGetArity(node)));
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    switch (node->type) {
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_ATTRIBUTE_NODE:
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* !!! our model is slightly different than XPath */
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    return(xmlXPtrNewRange(node, 0, node,
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					           xmlXPtrGetArity(node)));
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_ELEMENT_NODE:
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_TEXT_NODE:
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_CDATA_SECTION_NODE:
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_ENTITY_REF_NODE:
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_PI_NODE:
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_COMMENT_NODE:
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_DOCUMENT_NODE:
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_NOTATION_NODE:
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			case XML_HTML_DOCUMENT_NODE: {
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    int indx = xmlXPtrGetIndex(node);
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    node = node->parent;
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    return(xmlXPtrNewRange(node, indx - 1,
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					           node, indx + 1));
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			default:
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    return(NULL);
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TODO /* missed one case ??? */
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(NULL);
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrRangeFunction:
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of args
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Function implementing the range() function 5.4.3
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  location-set range(location-set )
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  The range function returns ranges covering the locations in
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  the argument location-set. For each location x in the argument
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  location-set, a range location representing the covering range of
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  x is added to the result location-set.
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr set;
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr oldset;
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr newset;
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_ARITY(1);
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt->value == NULL) ||
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	((ctxt->value->type != XPATH_LOCATIONSET) &&
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 (ctxt->value->type != XPATH_NODESET)))
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XP_ERROR(XPATH_INVALID_TYPE)
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set = valuePop(ctxt);
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (set->type == XPATH_NODESET) {
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathObjectPtr tmp;
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * First convert to a location set
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(set);
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	set = tmp;
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset = (xmlLocationSetPtr) set->user;
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The loop is to compute the covering range for each item and add it
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newset = xmlXPtrLocationSetCreate(NULL);
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < oldset->locNr;i++) {
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPtrLocationSetAdd(newset,
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlXPtrCoveringRange(ctxt, oldset->locTab[i]));
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Save the new value and cleanup
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeObject(set);
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrInsideRange:
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @loc:  the location for which the inside range must be computed
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * A inside range is a range described in the range-inside() description
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns a new location or NULL in case of error
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlXPathObjectPtr
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrInsideRange(xmlXPathParserContextPtr ctxt, xmlXPathObjectPtr loc) {
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (loc == NULL)
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (ctxt->context == NULL) ||
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(ctxt->context->doc == NULL))
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (loc->type) {
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_POINT: {
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlNodePtr node = (xmlNodePtr) loc->user;
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    switch (node->type) {
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_PI_NODE:
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_COMMENT_NODE:
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_TEXT_NODE:
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_CDATA_SECTION_NODE: {
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (node->content == NULL) {
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(xmlXPtrNewRange(node, 0, node, 0));
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(xmlXPtrNewRange(node, 0, node,
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					       xmlStrlen(node->content)));
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ATTRIBUTE_NODE:
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ELEMENT_NODE:
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ENTITY_REF_NODE:
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_DOCUMENT_NODE:
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_NOTATION_NODE:
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_HTML_DOCUMENT_NODE: {
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(xmlXPtrNewRange(node, 0, node,
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   xmlXPtrGetArity(node)));
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_RANGE: {
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlNodePtr node = (xmlNodePtr) loc->user;
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (loc->user2 != NULL) {
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(xmlXPtrNewRange(node, loc->index,
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			               loc->user2, loc->index2));
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch (node->type) {
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_PI_NODE:
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_COMMENT_NODE:
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_TEXT_NODE:
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_CDATA_SECTION_NODE: {
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (node->content == NULL) {
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    return(xmlXPtrNewRange(node, 0, node, 0));
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else {
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    return(xmlXPtrNewRange(node, 0, node,
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						   xmlStrlen(node->content)));
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ATTRIBUTE_NODE:
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ELEMENT_NODE:
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ENTITY_REF_NODE:
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_DOCUMENT_NODE:
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_NOTATION_NODE:
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_HTML_DOCUMENT_NODE: {
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			return(xmlXPtrNewRange(node, 0, node,
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					       xmlXPtrGetArity(node)));
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    default:
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(NULL);
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    TODO /* missed one case ??? */
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(NULL);
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrRangeInsideFunction:
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of args
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Function implementing the range-inside() function 5.4.3
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  location-set range-inside(location-set )
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  The range-inside function returns ranges covering the contents of
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  the locations in the argument location-set. For each location x in
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  the argument location-set, a range location is added to the result
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  location-set. If x is a range location, then x is added to the
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  result location-set. If x is not a range location, then x is used
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  as the container location of the start and end points of the range
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  location to be added; the index of the start point of the range is
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  zero; if the end point is a character point then its index is the
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  length of the string-value of x, and otherwise is the number of
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  location children of x.
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrRangeInsideFunction(xmlXPathParserContextPtr ctxt, int nargs) {
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr set;
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr oldset;
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr newset;
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_ARITY(1);
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt->value == NULL) ||
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	((ctxt->value->type != XPATH_LOCATIONSET) &&
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 (ctxt->value->type != XPATH_NODESET)))
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XP_ERROR(XPATH_INVALID_TYPE)
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set = valuePop(ctxt);
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (set->type == XPATH_NODESET) {
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathObjectPtr tmp;
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * First convert to a location set
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(set);
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	set = tmp;
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset = (xmlLocationSetPtr) set->user;
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The loop is to compute the covering range for each item and add it
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newset = xmlXPtrLocationSetCreate(NULL);
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < oldset->locNr;i++) {
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPtrLocationSetAdd(newset,
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlXPtrInsideRange(ctxt, oldset->locTab[i]));
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Save the new value and cleanup
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeObject(set);
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrRangeToFunction:
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of args
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Implement the range-to() XPointer function
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrRangeToFunction(xmlXPathParserContextPtr ctxt, int nargs) {
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr range;
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *cur;
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr res, obj;
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr tmp;
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr newset = NULL;
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodeSetPtr oldset;
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL) return;
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_ARITY(1);
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Save the expression pointer since we will have to evaluate
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * it multiple times. Initialize the new set.
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_TYPE(XPATH_NODESET);
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    obj = valuePop(ctxt);
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset = obj->nodesetval;
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->node = NULL;
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = ctxt->cur;
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newset = xmlXPtrLocationSetCreate(NULL);
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0; i < oldset->nodeNr; i++) {
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->cur = cur;
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Run the evaluation with a node list made of a single item
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * in the nodeset.
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->node = oldset->nodeTab[i];
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = xmlXPathNewNodeSet(ctxt->context->node);
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	valuePush(ctxt, tmp);
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathEvalExpr(ctxt);
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CHECK_ERROR;
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * The result of the evaluation need to be tested to
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * decided whether the filter succeeded or not
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	res = valuePop(ctxt);
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	range = xmlXPtrNewRangeNodeObject(oldset->nodeTab[i], res);
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (range != NULL) {
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPtrLocationSetAdd(newset, range);
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Cleanup
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (res != NULL)
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathFreeObject(res);
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->value == tmp) {
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    res = valuePop(ctxt);
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathFreeObject(res);
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->node = NULL;
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The result is used as the new evaluation set.
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeObject(obj);
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->node = NULL;
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->contextSize = -1;
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->proximityPosition = -1;
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrAdvanceNode:
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur:  the node
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @level: incremented/decremented to show level in tree
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Advance to the next element or text node in document order
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: add a stack for entering/exiting entities
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 otherwise
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlNodePtr
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrAdvanceNode(xmlNodePtr cur, int *level) {
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)next:
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur->children != NULL) {
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur = cur->children ;
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (level != NULL)
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (*level)++;
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto found;
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)skip:		/* This label should only be needed if something is wrong! */
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur->next != NULL) {
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = cur->next;
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto found;
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    do {
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur = cur->parent;
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (level != NULL)
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (*level)--;
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (cur == NULL) return(NULL);
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (cur->next != NULL) {
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cur = cur->next;
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto found;
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } while (cur != NULL);
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)found:
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((cur->type != XML_ELEMENT_NODE) &&
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur->type != XML_TEXT_NODE) &&
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur->type != XML_DOCUMENT_NODE) &&
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur->type != XML_HTML_DOCUMENT_NODE) &&
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur->type != XML_CDATA_SECTION_NODE)) {
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (cur->type == XML_ENTITY_REF_NODE) {	/* Shouldn't happen */
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		TODO
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto skip;
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto next;
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(cur);
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrAdvanceChar:
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  the node
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @indx:  the indx
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @bytes:  the number of bytes
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Advance a point of the associated number of bytes (not UTF8 chars)
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 otherwise
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrAdvanceChar(xmlNodePtr *node, int *indx, int bytes) {
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr cur;
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pos;
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len;
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((node == NULL) || (indx == NULL))
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = *node;
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pos = *indx;
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (bytes >= 0) {
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * First position to the beginning of the first text node
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * corresponding to this point
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((cur != NULL) &&
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       ((cur->type == XML_ELEMENT_NODE) ||
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (cur->type == XML_DOCUMENT_NODE) ||
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        (cur->type == XML_HTML_DOCUMENT_NODE))) {
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (pos > 0) {
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		cur = xmlXPtrGetNthChild(cur, pos);
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pos = 0;
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		cur = xmlXPtrAdvanceNode(cur, NULL);
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pos = 0;
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == NULL) {
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *node = NULL;
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *indx = 0;
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * if there is no move needed return the current value.
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (pos == 0) pos = 1;
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (bytes == 0) {
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *node = cur;
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *indx = pos;
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * We should have a text (or cdata) node ...
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	len = 0;
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((cur->type != XML_ELEMENT_NODE) &&
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            (cur->content != NULL)) {
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    len = xmlStrlen(cur->content);
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (pos > len) {
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Strange, the indx in the text node is greater than it's len */
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    STRANGE
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    pos = len;
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (pos + bytes >= len) {
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    bytes -= (len - pos);
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cur = xmlXPtrAdvanceNode(cur, NULL);
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    pos = 0;
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (pos + bytes < len) {
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    pos += bytes;
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *node = cur;
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *indx = pos;
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(-1);
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrMatchString:
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @string:  the string to search
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the start textnode
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @startindex:  the start index
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the end textnode IN/OUT
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @endindex:  the end index IN/OUT
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Check whether the document contains @string at the position
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (@start, @startindex) and limited by the (@end, @endindex) point
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 if not found, 1 if found in which case
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *            (@start, @startindex) will indicate the position of the beginning
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *            of the range and (@end, @endindex) will indicate the end
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *            of the range
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrMatchString(const xmlChar *string, xmlNodePtr start, int startindex,
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	            xmlNodePtr *end, int *endindex) {
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr cur;
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pos; /* 0 based */
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len; /* in bytes */
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int stringlen; /* in bytes */
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int match;
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (string == NULL)
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (start == NULL)
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((end == NULL) || (endindex == NULL))
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = start;
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pos = startindex - 1;
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    stringlen = xmlStrlen(string);
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (stringlen > 0) {
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((cur == *end) && (pos + stringlen > *endindex))
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    len = xmlStrlen(cur->content);
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (len >= pos + stringlen) {
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		match = (!xmlStrncmp(&cur->content[pos], string, stringlen));
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (match) {
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RANGES
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlGenericError(xmlGenericErrorContext,
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    "found range %d bytes at index %d of ->",
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    stringlen, pos + 1);
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlDebugDumpString(stdout, cur->content);
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlGenericError(xmlGenericErrorContext, "\n");
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *end = cur;
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *endindex = pos + stringlen;
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(1);
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(0);
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                int sub = len - pos;
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		match = (!xmlStrncmp(&cur->content[pos], string, sub));
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (match) {
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RANGES
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlGenericError(xmlGenericErrorContext,
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    "found subrange %d bytes at index %d of ->",
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    sub, pos + 1);
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlDebugDumpString(stdout, cur->content);
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlGenericError(xmlGenericErrorContext, "\n");
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    string = &string[sub];
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    stringlen -= sub;
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(0);
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = xmlXPtrAdvanceNode(cur, NULL);
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == NULL)
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos = 0;
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(1);
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
25145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrSearchString:
25155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @string:  the string to search
25165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @start:  the start textnode IN/OUT
25175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @startindex:  the start index IN/OUT
25185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @end:  the end textnode
25195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @endindex:  the end index
25205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
25215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Search the next occurrence of @string within the document content
25225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * until the (@end, @endindex) point is reached
25235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
25245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 if not found, 1 if found in which case
25255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *            (@start, @startindex) will indicate the position of the beginning
25265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *            of the range and (@end, @endindex) will indicate the end
25275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *            of the range
25285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
25295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
25305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrSearchString(const xmlChar *string, xmlNodePtr *start, int *startindex,
25315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	            xmlNodePtr *end, int *endindex) {
25325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr cur;
25335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *str;
25345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pos; /* 0 based */
25355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int len; /* in bytes */
25365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar first;
25375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (string == NULL)
25395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
25405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((start == NULL) || (startindex == NULL))
25415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
25425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((end == NULL) || (endindex == NULL))
25435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
25445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = *start;
25455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
25465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
25475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pos = *startindex - 1;
25485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    first = string[0];
25495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
25505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (cur != NULL) {
25515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((cur->type != XML_ELEMENT_NODE) && (cur->content != NULL)) {
25525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    len = xmlStrlen(cur->content);
25535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    while (pos <= len) {
25545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (first != 0) {
25555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    str = xmlStrchr(&cur->content[pos], first);
25565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (str != NULL) {
25575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pos = (str - (xmlChar *)(cur->content));
25585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RANGES
25595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlGenericError(xmlGenericErrorContext,
25605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				"found '%c' at index %d of ->",
25615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				first, pos + 1);
25625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlDebugDumpString(stdout, cur->content);
25635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlGenericError(xmlGenericErrorContext, "\n");
25645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
25655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (xmlXPtrMatchString(string, cur, pos + 1,
25665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					       end, endindex)) {
25675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    *start = cur;
25685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    *startindex = pos + 1;
25695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    return(1);
25705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
25715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pos++;
25725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
25735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pos = len + 1;
25745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
25755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
25765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
25775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * An empty string is considered to match before each
25785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * character of the string-value and after the final
25795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * character.
25805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
25815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RANGES
25825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlGenericError(xmlGenericErrorContext,
25835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    "found '' at index %d of ->",
25845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    pos + 1);
25855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlDebugDumpString(stdout, cur->content);
25865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlGenericError(xmlGenericErrorContext, "\n");
25875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
25885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *start = cur;
25895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *startindex = pos + 1;
25905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *end = cur;
25915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    *endindex = pos + 1;
25925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(1);
25935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
25945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
25955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
25965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((cur == *end) && (pos >= *endindex))
25975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
25985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = xmlXPtrAdvanceNode(cur, NULL);
25995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur == NULL)
26005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
26015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pos = 1;
26025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
26045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
26075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrGetLastChar:
26085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  the node
26095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @index:  the index
26105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
26115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Computes the point coordinates of the last char of this point
26125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
26135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 otherwise
26145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
26155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
26165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrGetLastChar(xmlNodePtr *node, int *indx) {
26175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr cur;
26185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int pos, len = 0;
26195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((node == NULL) || (indx == NULL))
26215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
26225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = *node;
26235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pos = *indx;
26245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
26265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
26275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((cur->type == XML_ELEMENT_NODE) ||
26295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur->type == XML_DOCUMENT_NODE) ||
26305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(cur->type == XML_HTML_DOCUMENT_NODE)) {
26315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (pos > 0) {
26325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cur = xmlXPtrGetNthChild(cur, pos);
26335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (cur != NULL) {
26365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (cur->last != NULL)
26375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cur = cur->last;
26385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if ((cur->type != XML_ELEMENT_NODE) &&
26395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	         (cur->content != NULL)) {
26405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    len = xmlStrlen(cur->content);
26415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
26425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
26435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
26445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
26455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL)
26475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
26485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *node = cur;
26495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *indx = len;
26505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
26515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
26545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrGetStartPoint:
26555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @obj:  an range
26565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  the resulting node
26575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @indx:  the resulting index
26585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
26595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * read the object and return the start point coordinates.
26605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
26615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 otherwise
26625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
26635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
26645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrGetStartPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *indx) {
26655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((obj == NULL) || (node == NULL) || (indx == NULL))
26665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
26675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (obj->type) {
26695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_POINT:
26705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *node = obj->user;
26715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (obj->index <= 0)
26725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*indx = 0;
26735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
26745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*indx = obj->index;
26755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
26765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_RANGE:
26775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *node = obj->user;
26785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (obj->index <= 0)
26795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*indx = 0;
26805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
26815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*indx = obj->index;
26825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
26835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
26845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
26855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
26865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(-1);
26875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
26885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
26905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrGetEndPoint:
26915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @obj:  an range
26925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  the resulting node
26935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @indx:  the resulting indx
26945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
26955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * read the object and return the end point coordinates.
26965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
26975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 otherwise
26985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
26995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
27005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrGetEndPoint(xmlXPathObjectPtr obj, xmlNodePtr *node, int *indx) {
27015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((obj == NULL) || (node == NULL) || (indx == NULL))
27025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
27035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (obj->type) {
27055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_POINT:
27065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *node = obj->user;
27075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (obj->index <= 0)
27085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*indx = 0;
27095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
27105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*indx = obj->index;
27115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
27125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XPATH_RANGE:
27135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *node = obj->user;
27145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (obj->index <= 0)
27155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*indx = 0;
27165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
27175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*indx = obj->index;
27185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
27195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	default:
27205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
27215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
27225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(-1);
27235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
27245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
27265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrStringRangeFunction:
27275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
27285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nargs:  the number of args
27295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
27305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Function implementing the string-range() function
27315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * range as described in 5.4.2
27325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
27335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ------------------------------
27345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [Definition: For each location in the location-set argument,
27355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string-range returns a set of string ranges, a set of substrings in a
27365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string. Specifically, the string-value of the location is searched for
27375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * substrings that match the string argument, and the resulting location-set
27385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * will contain a range location for each non-overlapping match.]
27395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * An empty string is considered to match before each character of the
27405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * string-value and after the final character. Whitespace in a string
27415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * is matched literally, with no normalization except that provided by
27425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * XML for line ends. The third argument gives the position of the first
27435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * character to be in the resulting range, relative to the start of the
27445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * match. The default value is 1, which makes the range start immediately
27455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * before the first character of the matched string. The fourth argument
27465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * gives the number of characters in the range; the default is that the
27475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * range extends to the end of the matched string.
27485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
27495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Element boundaries, as well as entire embedded nodes such as processing
27505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * instructions and comments, are ignored as defined in [XPath].
27515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
27525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the string in the second argument is not found in the string-value
27535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * of the location, or if a value in the third or fourth argument indicates
27545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a string that is beyond the beginning or end of the document, the
27555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * expression fails.
27565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
27575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The points of the range-locations in the returned location-set will
27585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * all be character points.
27595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * ------------------------------
27605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
27615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
27625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrStringRangeFunction(xmlXPathParserContextPtr ctxt, int nargs) {
27635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i, startindex, endindex = 0, fendindex;
27645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr start, end = 0, fend;
27655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr set;
27665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr oldset;
27675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr newset;
27685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr string;
27695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr position = NULL;
27705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr number = NULL;
27715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int found, pos = 0, num = 0;
27725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
27745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Grab the arguments
27755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
27765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((nargs < 2) || (nargs > 4))
27775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPATH_INVALID_ARITY);
27785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs >= 4) {
27805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CHECK_TYPE(XPATH_NUMBER);
27815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	number = valuePop(ctxt);
27825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (number != NULL)
27835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    num = (int) number->floatval;
27845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
27855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nargs >= 3) {
27865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CHECK_TYPE(XPATH_NUMBER);
27875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	position = valuePop(ctxt);
27885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (position != NULL)
27895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    pos = (int) position->floatval;
27905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
27915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_TYPE(XPATH_STRING);
27925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string = valuePop(ctxt);
27935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt->value == NULL) ||
27945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	((ctxt->value->type != XPATH_LOCATIONSET) &&
27955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 (ctxt->value->type != XPATH_NODESET)))
27965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        XP_ERROR(XPATH_INVALID_TYPE)
27975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
27985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    set = valuePop(ctxt);
27995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    newset = xmlXPtrLocationSetCreate(NULL);
28005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (set->nodesetval == NULL) {
28015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        goto error;
28025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
28035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (set->type == XPATH_NODESET) {
28045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathObjectPtr tmp;
28055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
28075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * First convert to a location set
28085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
28095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = xmlXPtrNewLocationSetNodeSet(set->nodesetval);
28105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(set);
28115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	set = tmp;
28125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
28135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset = (xmlLocationSetPtr) set->user;
28145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
28165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * The loop is to search for each element in the location set
28175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * the list of location set corresponding to that search
28185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
28195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < oldset->locNr;i++) {
28205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RANGES
28215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathDebugDumpObject(stdout, oldset->locTab[i], 0);
28225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
28235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPtrGetStartPoint(oldset->locTab[i], &start, &startindex);
28255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPtrGetEndPoint(oldset->locTab[i], &end, &endindex);
28265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPtrAdvanceChar(&start, &startindex, 0);
28275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPtrGetLastChar(&end, &endindex);
28285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef DEBUG_RANGES
28305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlGenericError(xmlGenericErrorContext,
28315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"from index %d of ->", startindex);
28325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlDebugDumpString(stdout, start->content);
28335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlGenericError(xmlGenericErrorContext, "\n");
28345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlGenericError(xmlGenericErrorContext,
28355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"to index %d of ->", endindex);
28365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlDebugDumpString(stdout, end->content);
28375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlGenericError(xmlGenericErrorContext, "\n");
28385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
28395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	do {
28405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fend = end;
28415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            fendindex = endindex;
28425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    found = xmlXPtrSearchString(string->stringval, &start, &startindex,
28435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		                        &fend, &fendindex);
28445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (found == 1) {
28455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (position == NULL) {
28465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPtrLocationSetAdd(newset,
28475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 xmlXPtrNewRange(start, startindex, fend, fendindex));
28485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (xmlXPtrAdvanceChar(&start, &startindex,
28495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			                      pos - 1) == 0) {
28505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((number != NULL) && (num > 0)) {
28515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			int rindx;
28525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlNodePtr rend;
28535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			rend = start;
28545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			rindx = startindex - 1;
28555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (xmlXPtrAdvanceChar(&rend, &rindx,
28565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				               num) == 0) {
28575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    xmlXPtrLocationSetAdd(newset,
28585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					xmlXPtrNewRange(start, startindex,
28595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)							rend, rindx));
28605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
28615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else if ((number != NULL) && (num <= 0)) {
28625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlXPtrLocationSetAdd(newset,
28635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    xmlXPtrNewRange(start, startindex,
28645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						    start, startindex));
28655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
28665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlXPtrLocationSetAdd(newset,
28675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    xmlXPtrNewRange(start, startindex,
28685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						    fend, fendindex));
28695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
28705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
28715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		start = fend;
28725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		startindex = fendindex;
28735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (string->stringval[0] == 0)
28745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    startindex++;
28755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
28765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} while (found == 1);
28775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
28785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
28805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Save the new value and cleanup
28815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
28825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
28835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
28845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeObject(set);
28855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathFreeObject(string);
28865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (position) xmlXPathFreeObject(position);
28875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (number) xmlXPathFreeObject(number);
28885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
28895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
28905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
28915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xmlXPtrEvalRangePredicate:
28925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPointer Parser context
28935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
28945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  [8]   Predicate ::=   '[' PredicateExpr ']'
28955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *  [9]   PredicateExpr ::=   Expr
28965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
28975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Evaluate a predicate as in xmlXPathEvalPredicate() but for
28985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a Location Set instead of a node set
28995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
29005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
29015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xmlXPtrEvalRangePredicate(xmlXPathParserContextPtr ctxt) {
29025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *cur;
29035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr res;
29045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr obj, tmp;
29055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr newset = NULL;
29065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlLocationSetPtr oldset;
29075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
29085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL) return;
29105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
29125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR != '[') {
29135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
29145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
29155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEXT;
29165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
29175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
29195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Extract the old set, and then evaluate the result of the
29205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * expression for all the element in the set. use it to grow
29215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * up a new set.
29225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
29235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CHECK_TYPE(XPATH_LOCATIONSET);
29245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    obj = valuePop(ctxt);
29255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    oldset = obj->user;
29265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->context->node = NULL;
29275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((oldset == NULL) || (oldset->locNr == 0)) {
29295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->contextSize = 0;
29305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->proximityPosition = 0;
29315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathEvalExpr(ctxt);
29325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	res = valuePop(ctxt);
29335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (res != NULL)
29345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathFreeObject(res);
29355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	valuePush(ctxt, obj);
29365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CHECK_ERROR;
29375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
29385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
29395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Save the expression pointer since we will have to evaluate
29405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * it multiple times. Initialize the new set.
29415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
29425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        cur = ctxt->cur;
29435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	newset = xmlXPtrLocationSetCreate(NULL);
29445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        for (i = 0; i < oldset->locNr; i++) {
29465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->cur = cur;
29475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
29495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Run the evaluation with a node list made of a single item
29505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * in the nodeset.
29515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
29525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->context->node = oldset->locTab[i]->user;
29535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    tmp = xmlXPathNewNodeSet(ctxt->context->node);
29545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    valuePush(ctxt, tmp);
29555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->context->contextSize = oldset->locNr;
29565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->context->proximityPosition = i + 1;
29575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathEvalExpr(ctxt);
29595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    CHECK_ERROR;
29605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
29625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * The result of the evaluation need to be tested to
29635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * decided whether the filter succeeded or not
29645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
29655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    res = valuePop(ctxt);
29665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (xmlXPathEvaluatePredicateResult(ctxt, res)) {
29675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlXPtrLocationSetAdd(newset,
29685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlXPathObjectCopy(oldset->locTab[i]));
29695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
29705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
29725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Cleanup
29735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
29745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (res != NULL)
29755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlXPathFreeObject(res);
29765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ctxt->value == tmp) {
29775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		res = valuePop(ctxt);
29785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlXPathFreeObject(res);
29795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
29805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->context->node = NULL;
29825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
29835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
29855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * The result is used as the new evaluation set.
29865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
29875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(obj);
29885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->node = NULL;
29895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->contextSize = -1;
29905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->context->proximityPosition = -1;
29915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	valuePush(ctxt, xmlXPtrWrapLocationSet(newset));
29925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
29935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR != ']') {
29945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XP_ERROR(XPATH_INVALID_PREDICATE_ERROR);
29955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
29965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    NEXT;
29985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
29995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
30005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
30015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define bottom_xpointer
30025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "elfgcchack.h"
30035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
30045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005