15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pattern.c: Implemetation of the template match compilation and lookup
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Reference:
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *   http://www.w3.org/TR/1999/REC-xslt-19991116
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software.
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * daniel@veillard.com
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: handle pathological cases like *[*[@a="b"]]
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: detect [number] at compilation, optimize accordingly
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXSLT
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxslt.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h>
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h>
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h>
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/valid.h>
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/hash.h>
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlerror.h>
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parserInternals.h>
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xslt.h"
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltInternals.h"
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltutils.h"
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "imports.h"
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "templates.h"
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "keys.h"
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pattern.h"
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "documents.h"
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WITH_XSLT_DEBUG_PATTERN
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Types are private:
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_END=0,
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_ROOT,
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_ELEM,
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_ATTR,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_PARENT,
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_ANCESTOR,
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_ID,
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_KEY,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_NS,
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_ALL,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_PI,
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_COMMENT,
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_TEXT,
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_NODE,
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    XSLT_OP_PREDICATE
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xsltOp;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum {
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AXIS_CHILD=1,
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AXIS_ATTRIBUTE
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xsltAxis;
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xsltStepState xsltStepState;
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xsltStepState *xsltStepStatePtr;
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltStepState {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int step;
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr node;
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xsltStepStates xsltStepStates;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xsltStepStates *xsltStepStatesPtr;
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltStepStates {
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbstates;
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxstates;
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStepStatePtr states;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xsltStepOp xsltStepOp;
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xsltStepOp *xsltStepOpPtr;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltStepOp {
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltOp op;
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *value;
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *value2;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *value3;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathCompExprPtr comp;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * Optimisations for count
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        previousExtra;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        indexExtra;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int        lenExtra;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltCompMatch {
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    struct _xsltCompMatch *next; /* siblings in the name hash */
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float priority;              /* the priority */
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *pattern;       /* the pattern */
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *mode;         /* the mode */
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *modeURI;      /* the mode URI */
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltTemplatePtr template;    /* the associated template */
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int direct;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TODO fix the statically allocated size steps[] */
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nbStep;
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int maxStep;
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNsPtr *nsList;		/* the namespaces in scope */
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nsNr;			/* the number of namespaces in scope */
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStepOpPtr steps;        /* ops for computation */
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xsltParserContext xsltParserContext;
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xsltParserContext *xsltParserContextPtr;
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltParserContext {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStylesheetPtr style;		/* the stylesheet */
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltTransformContextPtr ctxt;	/* the transformation or NULL */
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *cur;			/* the current char being parsed */
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *base;		/* the full expression */
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlDocPtr      doc;			/* the source document */
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlNodePtr    elem;			/* the source element */
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int error;				/* error code */
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompMatchPtr comp;		/* the result */
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 			Type functions 					*
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltNewCompMatch:
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new XSLT CompMatch
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly allocated xsltCompMatchPtr or NULL in case of error
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xsltCompMatchPtr
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltNewCompMatch(void) {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompMatchPtr cur;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = (xsltCompMatchPtr) xmlMalloc(sizeof(xsltCompMatch));
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL) {
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(NULL, NULL, NULL,
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"xsltNewCompMatch : out of memory error\n");
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(cur, 0, sizeof(xsltCompMatch));
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->maxStep = 10;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->nbStep = 0;
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur-> steps = (xsltStepOpPtr) xmlMalloc(sizeof(xsltStepOp) *
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                            cur->maxStep);
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur->steps == NULL) {
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(NULL, NULL, NULL,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"xsltNewCompMatch : out of memory error\n");
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(cur);
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->nsNr = 0;
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->nsList = NULL;
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->direct = 0;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(cur);
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeCompMatch:
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  an XSLT comp
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory allocated by @comp
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeCompMatch(xsltCompMatchPtr comp) {
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStepOpPtr op;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp == NULL)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp->pattern != NULL)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree((xmlChar *)comp->pattern);
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp->nsList != NULL)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(comp->nsList);
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < comp->nbStep;i++) {
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	op = &comp->steps[i];
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (op->value != NULL)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(op->value);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (op->value2 != NULL)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(op->value2);
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (op->value3 != NULL)
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(op->value3);
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (op->comp != NULL)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathFreeCompExpr(op->comp);
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(comp->steps);
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(comp, -1, sizeof(xsltCompMatch));
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(comp);
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeCompMatchList:
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  an XSLT comp list
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory allocated by all the elements of @comp
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeCompMatchList(xsltCompMatchPtr comp) {
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompMatchPtr cur;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (comp != NULL) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = comp;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp = comp->next;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltFreeCompMatch(cur);
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltNormalizeCompSteps:
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @payload: pointer to template hash table entry
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: pointer to the stylesheet
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: template match name
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a hashtable scanner function to normalize the compiled
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * steps of an imported stylesheet.
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xsltNormalizeCompSteps(void *payload,
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        void *data, const xmlChar *name ATTRIBUTE_UNUSED) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompMatchPtr comp = payload;
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStylesheetPtr style = data;
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ix;
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (ix = 0; ix < comp->nbStep; ix++) {
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        comp->steps[ix].previousExtra += style->extrasNr;
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        comp->steps[ix].indexExtra += style->extrasNr;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        comp->steps[ix].lenExtra += style->extrasNr;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltNewParserContext:
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style:  the stylesheet
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the transformation context, if done at run-time
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new XSLT ParserContext
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly allocated xsltParserContextPtr or NULL in case of error
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xsltParserContextPtr
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltNewParserContext(xsltStylesheetPtr style, xsltTransformContextPtr ctxt) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltParserContextPtr cur;
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = (xsltParserContextPtr) xmlMalloc(sizeof(xsltParserContext));
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (cur == NULL) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(NULL, NULL, NULL,
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"xsltNewParserContext : malloc failed\n");
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(cur, 0, sizeof(xsltParserContext));
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->style = style;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur->ctxt = ctxt;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(cur);
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeParserContext:
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  an XSLT parser context
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory allocated by @ctxt
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeParserContext(xsltParserContextPtr ctxt) {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memset(ctxt, -1, sizeof(xsltParserContext));
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlFree(ctxt);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompMatchAdd:
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  the compiled match expression
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @op:  an op
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value:  the first value
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value2:  the second value
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar:  flag to set XML_XPATH_NOVAR
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add an step to an XSLT Compiled Match
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 otherwise.
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp,
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 xsltOp op, xmlChar * value, xmlChar * value2, int novar)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (comp->nbStep >= comp->maxStep) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltStepOpPtr tmp;
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xsltStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                                 sizeof(xsltStepOp));
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltGenericError(xsltGenericErrorContext,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     "xsltCompMatchAdd: memory re-allocation failure.\n");
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ctxt->style != NULL)
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->style->errors++;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return (-1);
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        comp->maxStep *= 2;
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps = tmp;
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    comp->steps[comp->nbStep].op = op;
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    comp->steps[comp->nbStep].value = value;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    comp->steps[comp->nbStep].value2 = value2;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    comp->steps[comp->nbStep].value3 = NULL;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    comp->steps[comp->nbStep].comp = NULL;
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->ctxt != NULL) {
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[comp->nbStep].previousExtra =
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltAllocateExtraCtxt(ctxt->ctxt);
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[comp->nbStep].indexExtra =
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltAllocateExtraCtxt(ctxt->ctxt);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[comp->nbStep].lenExtra =
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltAllocateExtraCtxt(ctxt->ctxt);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[comp->nbStep].previousExtra =
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltAllocateExtra(ctxt->style);
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[comp->nbStep].indexExtra =
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltAllocateExtra(ctxt->style);
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[comp->nbStep].lenExtra =
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltAllocateExtra(ctxt->style);
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (op == XSLT_OP_PREDICATE) {
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathContextPtr xctxt;
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->style != NULL)
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xctxt = xmlXPathNewContext(ctxt->style->doc);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xctxt = xmlXPathNewContext(NULL);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XML_XPATH_NOVAR
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (novar != 0)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xctxt->flags = XML_XPATH_NOVAR;
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->style != NULL)
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xctxt->dict = ctxt->style->dict;
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[comp->nbStep].comp = xmlXPathCtxtCompile(xctxt, value);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeContext(xctxt);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (comp->steps[comp->nbStep].comp == NULL) {
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, ctxt->style, ctxt->elem,
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "Failed to compile predicate\n");
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ctxt->style != NULL)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->style->errors++;
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    comp->nbStep++;
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (0);
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltSwapTopCompMatch:
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  the compiled match expression
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reverse the two top steps.
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltSwapTopCompMatch(xsltCompMatchPtr comp) {
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int j = comp->nbStep - 1;
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (j > 0) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	register xmlChar *tmp;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	register xsltOp op;
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	register xmlXPathCompExprPtr expr;
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	register int t;
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	i = j - 1;
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = comp->steps[i].value;
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].value = comp->steps[j].value;
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].value = tmp;
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = comp->steps[i].value2;
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].value2 = comp->steps[j].value2;
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].value2 = tmp;
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = comp->steps[i].value3;
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].value3 = comp->steps[j].value3;
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].value3 = tmp;
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	op = comp->steps[i].op;
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].op = comp->steps[j].op;
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].op = op;
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	expr = comp->steps[i].comp;
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].comp = comp->steps[j].comp;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].comp = expr;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	t = comp->steps[i].previousExtra;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].previousExtra = comp->steps[j].previousExtra;
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].previousExtra = t;
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	t = comp->steps[i].indexExtra;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].indexExtra = comp->steps[j].indexExtra;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].indexExtra = t;
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	t = comp->steps[i].lenExtra;
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].lenExtra = comp->steps[j].lenExtra;
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].lenExtra = t;
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltReverseCompMatch:
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the parser context
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  the compiled match expression
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reverse all the stack of expressions
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) {
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i = 0;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int j = comp->nbStep - 1;
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (j > i) {
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	register xmlChar *tmp;
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	register xsltOp op;
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	register xmlXPathCompExprPtr expr;
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	register int t;
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = comp->steps[i].value;
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].value = comp->steps[j].value;
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].value = tmp;
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = comp->steps[i].value2;
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].value2 = comp->steps[j].value2;
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].value2 = tmp;
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = comp->steps[i].value3;
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].value3 = comp->steps[j].value3;
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].value3 = tmp;
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	op = comp->steps[i].op;
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].op = comp->steps[j].op;
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].op = op;
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	expr = comp->steps[i].comp;
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].comp = comp->steps[j].comp;
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].comp = expr;
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	t = comp->steps[i].previousExtra;
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].previousExtra = comp->steps[j].previousExtra;
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].previousExtra = t;
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	t = comp->steps[i].indexExtra;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].indexExtra = comp->steps[j].indexExtra;
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].indexExtra = t;
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	t = comp->steps[i].lenExtra;
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[i].lenExtra = comp->steps[j].lenExtra;
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp->steps[j].lenExtra = t;
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	j--;
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	i++;
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompMatchAdd(ctxt, comp, XSLT_OP_END, NULL, NULL, 0);
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * detect consecutive XSLT_OP_PREDICATE indicating a direct
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * matching should be done.
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (i = 0;i < comp->nbStep - 1;i++) {
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if ((comp->steps[i].op == XSLT_OP_PREDICATE) &&
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (comp->steps[i + 1].op == XSLT_OP_PREDICATE)) {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    comp->direct = 1;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (comp->pattern[0] != '/') {
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlChar *query;
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		query = xmlStrdup((const xmlChar *)"//");
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		query = xmlStrcat(query, comp->pattern);
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree((xmlChar *) comp->pattern);
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		comp->pattern = query;
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 		The interpreter for the precompiled patterns		*
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 									*
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states,
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                 int step, xmlNodePtr node) {
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((states->states == NULL) || (states->maxstates <= 0)) {
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        states->maxstates = 4;
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	states->nbstates = 0;
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	states->states = xmlMalloc(4 * sizeof(xsltStepState));
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (states->maxstates <= states->nbstates) {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltStepState *tmp;
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	tmp = (xsltStepStatePtr) xmlRealloc(states->states,
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			       2 * states->maxstates * sizeof(xsltStepState));
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (tmp == NULL) {
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltGenericError(xsltGenericErrorContext,
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     "xsltPatPushState: memory re-allocation failure.\n");
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->state = XSLT_STATE_STOPPED;
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	states->states = tmp;
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	states->maxstates *= 2;
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    states->states[states->nbstates].step = step;
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    states->states[states->nbstates++].node = node;
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "Push: %d, %s\n", step, node->name);
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltTestCompMatchDirect:
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a XSLT process context
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the precompiled pattern
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: a node
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nsList: the namespaces in scope
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nsNr: the number of namespaces in scope
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Test whether the node matches the pattern, do a direct evalutation
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and not a step by step evaluation.
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	                xmlNodePtr node, xmlNsPtr *nsList, int nsNr) {
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStepOpPtr sel = NULL;
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlDocPtr prevdoc;
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlDocPtr doc;
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlXPathObjectPtr list;
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ix, j;
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int nocache = 0;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int isRVT;
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    doc = node->doc;
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (XSLT_IS_RES_TREE_FRAG(doc))
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	isRVT = 1;
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	isRVT = 0;
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    sel = &comp->steps[0]; /* store extra in first step arbitrarily */
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    prevdoc = (xmlDocPtr)
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr);
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    list = (xmlXPathObjectPtr)
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra);
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((list == NULL) || (prevdoc != doc)) {
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathObjectPtr newlist;
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlNodePtr parent = node->parent;
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlDocPtr olddoc;
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlNodePtr oldnode;
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	int oldNsNr;
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlNsPtr *oldNamespaces;
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	oldnode = ctxt->xpathCtxt->node;
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	olddoc = ctxt->xpathCtxt->doc;
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	oldNsNr = ctxt->xpathCtxt->nsNr;
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	oldNamespaces = ctxt->xpathCtxt->namespaces;
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->xpathCtxt->node = node;
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->xpathCtxt->doc = doc;
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->xpathCtxt->namespaces = nsList;
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->xpathCtxt->nsNr = nsNr;
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	newlist = xmlXPathEval(comp->pattern, ctxt->xpathCtxt);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->xpathCtxt->node = oldnode;
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->xpathCtxt->doc = olddoc;
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->xpathCtxt->namespaces = oldNamespaces;
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->xpathCtxt->nsNr = oldNsNr;
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (newlist == NULL)
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (newlist->type != XPATH_NODESET) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathFreeObject(newlist);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ix = 0;
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((parent == NULL) || (node->doc == NULL) || isRVT)
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    nocache = 1;
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (nocache == 0) {
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (list != NULL)
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlXPathFreeObject(list);
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = newlist;
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra) =
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(void *) list;
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) =
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(void *) doc;
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) =
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		0;
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    XSLT_RUNTIME_EXTRA_FREE(ctxt, sel->lenExtra) =
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(xmlFreeFunc) xmlXPathFreeObject;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = newlist;
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((list->nodesetval == NULL) ||
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	(list->nodesetval->nodeNr <= 0)) {
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (nocache == 1)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlXPathFreeObject(list);
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* TODO: store the index and use it for the scan */
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ix == 0) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	for (j = 0;j < list->nodesetval->nodeNr;j++) {
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (list->nodesetval->nodeTab[j] == node) {
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (nocache == 1)
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlXPathFreeObject(list);
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return(1);
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (nocache == 1)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlXPathFreeObject(list);
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltTestCompMatch:
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a XSLT process context
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the precompiled pattern
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: a node
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @mode:  the mode name or NULL
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @modeURI:  the mode URI or NULL
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Test whether the node matches the pattern
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp,
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	          xmlNodePtr node, const xmlChar *mode,
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		  const xmlChar *modeURI) {
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int i;
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStepOpPtr step, sel = NULL;
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStepStates states = {0, 0, NULL}; /* // may require backtrack */
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((comp == NULL) || (node == NULL) || (ctxt == NULL)) {
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(ctxt, NULL, node,
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"xsltTestCompMatch: null arg\n");
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return(-1);
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (mode != NULL) {
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (comp->mode == NULL)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * both mode strings must be interned on the stylesheet dictionary
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (comp->mode != mode)
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (comp->mode != NULL)
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (modeURI != NULL) {
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (comp->modeURI == NULL)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * both modeURI strings must be interned on the stylesheet dictionary
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (comp->modeURI != modeURI)
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (comp->modeURI != NULL)
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(0);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i = 0;
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)restart:
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (;i < comp->nbStep;i++) {
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	step = &comp->steps[i];
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (step->op != XSLT_OP_PREDICATE)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    sel = step;
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (step->op) {
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_END:
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto found;
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_ROOT:
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((node->type == XML_DOCUMENT_NODE) ||
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DOCB_ENABLED
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_HTML_DOCUMENT_NODE))
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((node->type == XML_ELEMENT_NODE) && (node->name[0] == ' '))
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto rollback;
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_ELEM:
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->type != XML_ELEMENT_NODE)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value == NULL)
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value[0] != node->name[0])
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!xmlStrEqual(step->value, node->name))
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Namespace test */
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->ns == NULL) {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->value2 != NULL)
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (node->ns->href != NULL) {
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->value2 == NULL)
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!xmlStrEqual(step->value2, node->ns->href))
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_ATTR:
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->type != XML_ATTRIBUTE_NODE)
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value != NULL) {
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->value[0] != node->name[0])
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!xmlStrEqual(step->value, node->name))
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Namespace test */
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->ns == NULL) {
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->value2 != NULL)
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (step->value2 != NULL) {
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!xmlStrEqual(step->value2, node->ns->href))
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_PARENT:
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((node->type == XML_DOCUMENT_NODE) ||
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_HTML_DOCUMENT_NODE) ||
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DOCB_ENABLED
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_NAMESPACE_DECL))
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		node = node->parent;
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node == NULL)
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value == NULL)
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value[0] != node->name[0])
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!xmlStrEqual(step->value, node->name))
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* Namespace test */
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->ns == NULL) {
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->value2 != NULL)
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (node->ns->href != NULL) {
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->value2 == NULL)
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!xmlStrEqual(step->value2, node->ns->href))
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_ANCESTOR:
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* TODO: implement coalescing of ANCESTOR/NODE ops */
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value == NULL) {
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    step = &comp->steps[i+1];
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->op == XSLT_OP_ROOT)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto found;
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /* added NS, ID and KEY as a result of bug 168208 */
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((step->op != XSLT_OP_ELEM) &&
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(step->op != XSLT_OP_ALL) &&
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(step->op != XSLT_OP_NS) &&
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(step->op != XSLT_OP_ID) &&
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(step->op != XSLT_OP_KEY))
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node == NULL)
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((node->type == XML_DOCUMENT_NODE) ||
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_HTML_DOCUMENT_NODE) ||
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DOCB_ENABLED
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_NAMESPACE_DECL))
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		node = node->parent;
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((step->op != XSLT_OP_ELEM) && step->op != XSLT_OP_ALL) {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xsltPatPushState(ctxt, &states, i, node);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		i++;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value == NULL) {
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xsltPatPushState(ctxt, &states, i - 1, node);
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    continue;
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while (node != NULL) {
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((node->type == XML_ELEMENT_NODE) &&
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(step->value[0] == node->name[0]) &&
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(xmlStrEqual(step->value, node->name))) {
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* Namespace test */
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (node->ns == NULL) {
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (step->value2 == NULL)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				break;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else if (node->ns->href != NULL) {
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if ((step->value2 != NULL) &&
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			        (xmlStrEqual(step->value2, node->ns->href)))
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				break;
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    node = node->parent;
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node == NULL)
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xsltPatPushState(ctxt, &states, i - 1, node);
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		continue;
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_ID: {
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/* TODO Handle IDs decently, must be done differently */
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlAttrPtr id;
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->type != XML_ELEMENT_NODE)
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		id = xmlGetID(node->doc, step->value);
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((id == NULL) || (id->parent != node))
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_KEY: {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlNodeSetPtr list;
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int indx;
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = xsltGetKey(ctxt, step->value,
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			          step->value3, step->value2);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (list == NULL)
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		for (indx = 0;indx < list->nodeNr;indx++)
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (list->nodeTab[indx] == node)
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (indx >= list->nodeNr)
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_NS:
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->type != XML_ELEMENT_NODE)
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->ns == NULL) {
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->value != NULL)
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if (node->ns->href != NULL) {
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (step->value == NULL)
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!xmlStrEqual(step->value, node->ns->href))
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_ALL:
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->type != XML_ELEMENT_NODE)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XSLT_OP_PREDICATE: {
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlNodePtr oldNode;
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlDocPtr doc;
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int oldCS, oldCP;
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int pos = 0, len = 0;
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int isRVT;
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * when there is cascading XSLT_OP_PREDICATE, then use a
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * direct computation approach. It's not done directly
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * at the beginning of the routine to filter out as much
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * as possible this costly computation.
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (comp->direct) {
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (states.states != NULL) {
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/* Free the rollback states */
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlFree(states.states);
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(xsltTestCompMatchDirect(ctxt, comp, node,
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    				   comp->nsList, comp->nsNr));
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		doc = node->doc;
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (XSLT_IS_RES_TREE_FRAG(doc))
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    isRVT = 1;
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    isRVT = 0;
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		/*
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * Depending on the last selection, one may need to
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 * recompute contextSize and proximityPosition.
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 */
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		oldCS = ctxt->xpathCtxt->contextSize;
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		oldCP = ctxt->xpathCtxt->proximityPosition;
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((sel != NULL) &&
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (sel->op == XSLT_OP_ELEM) &&
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (sel->value != NULL) &&
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type == XML_ELEMENT_NODE) &&
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->parent != NULL)) {
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlNodePtr previous;
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int ix, nocache = 0;
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    previous = (xmlNodePtr)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr);
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival);
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((previous != NULL) &&
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(previous->parent == node->parent)) {
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * just walk back to adjust the index
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			int indx = 0;
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlNodePtr sibling = node;
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			while (sibling != NULL) {
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (sibling == previous)
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				break;
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if ((previous->type == XML_ELEMENT_NODE) &&
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				(previous->name != NULL) &&
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				(sibling->name != NULL) &&
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				(previous->name[0] == sibling->name[0]) &&
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				(xmlStrEqual(previous->name, sibling->name)))
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    {
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if ((sel->value2 == NULL) ||
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    ((sibling->ns != NULL) &&
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     (xmlStrEqual(sel->value2,
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						  sibling->ns->href))))
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    indx++;
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    sibling = sibling->prev;
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (sibling == NULL) {
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /* hum going backward in document order ... */
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    indx = 0;
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    sibling = node;
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    while (sibling != NULL) {
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (sibling == previous)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    break;
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if ((previous->type == XML_ELEMENT_NODE) &&
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    (previous->name != NULL) &&
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    (sibling->name != NULL) &&
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    (previous->name[0] == sibling->name[0]) &&
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    (xmlStrEqual(previous->name, sibling->name)))
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				{
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    if ((sel->value2 == NULL) ||
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					((sibling->ns != NULL) &&
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					(xmlStrEqual(sel->value2,
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					sibling->ns->href))))
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    {
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					indx--;
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    }
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				sibling = sibling->next;
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (sibling != NULL) {
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    pos = ix + indx;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /*
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     * If the node is in a Value Tree we need to
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     * save len, but cannot cache the node!
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     * (bugs 153137 and 158840)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     */
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (node->doc != NULL) {
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				len = XSLT_RUNTIME_EXTRA(ctxt,
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				        sel->lenExtra, ival);
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (!isRVT) {
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    XSLT_RUNTIME_EXTRA(ctxt,
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					sel->previousExtra, ptr) = node;
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    XSLT_RUNTIME_EXTRA(ctxt,
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				        sel->indexExtra, ival) = pos;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    ix = pos;
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    pos = 0;
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * recompute the index
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlNodePtr parent = node->parent;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlNodePtr siblings = NULL;
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if (parent) siblings = parent->children;
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			while (siblings != NULL) {
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (siblings->type == XML_ELEMENT_NODE) {
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (siblings == node) {
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    len++;
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    pos = len;
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				} else if ((node->name != NULL) &&
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					   (siblings->name != NULL) &&
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    (node->name[0] == siblings->name[0]) &&
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    (xmlStrEqual(node->name, siblings->name))) {
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    if ((sel->value2 == NULL) ||
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					((siblings->ns != NULL) &&
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					 (xmlStrEqual(sel->value2,
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)						      siblings->ns->href))))
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					len++;
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    siblings = siblings->next;
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ((parent == NULL) || (node->doc == NULL))
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    nocache = 1;
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			else {
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    while (parent->parent != NULL)
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				parent = parent->parent;
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (((parent->type != XML_DOCUMENT_NODE) &&
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (parent->type != XML_HTML_DOCUMENT_NODE)) ||
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (parent != (xmlNodePtr) node->doc))
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				nocache = 1;
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (pos != 0) {
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ctxt->xpathCtxt->contextSize = len;
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ctxt->xpathCtxt->proximityPosition = pos;
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * If the node is in a Value Tree we cannot
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * cache it !
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ((!isRVT) && (node->doc != NULL) &&
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    (nocache == 0)) {
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) =
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				node;
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) =
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				pos;
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) =
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				len;
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else if ((sel != NULL) && (sel->op == XSLT_OP_ALL) &&
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			   (node->type == XML_ELEMENT_NODE)) {
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlNodePtr previous;
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    int ix, nocache = 0;
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    previous = (xmlNodePtr)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr);
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if ((previous != NULL) &&
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			(previous->parent == node->parent)) {
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * just walk back to adjust the index
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			int indx = 0;
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlNodePtr sibling = node;
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			while (sibling != NULL) {
10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (sibling == previous)
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				break;
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (sibling->type == XML_ELEMENT_NODE)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				indx++;
10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    sibling = sibling->prev;
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (sibling == NULL) {
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /* hum going backward in document order ... */
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    indx = 0;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    sibling = node;
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    while (sibling != NULL) {
10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (sibling == previous)
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    break;
10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (sibling->type == XML_ELEMENT_NODE)
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    indx--;
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				sibling = sibling->next;
10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if (sibling != NULL) {
10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    pos = ix + indx;
10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    /*
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     * If the node is in a Value Tree we cannot
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     * cache it !
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     */
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if ((node->doc != NULL) && !isRVT) {
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				len = XSLT_RUNTIME_EXTRA(ctxt,
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				        sel->lenExtra, ival);
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				XSLT_RUNTIME_EXTRA(ctxt,
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					sel->previousExtra, ptr) = node;
10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				XSLT_RUNTIME_EXTRA(ctxt,
10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					sel->indexExtra, ival) = pos;
10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			} else
10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    pos = 0;
10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * recompute the index
10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlNodePtr parent = node->parent;
10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlNodePtr siblings = NULL;
10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        if (parent) siblings = parent->children;
10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			while (siblings != NULL) {
10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (siblings->type == XML_ELEMENT_NODE) {
10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				len++;
10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				if (siblings == node) {
10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				    pos = len;
10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				}
10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    }
10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    siblings = siblings->next;
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ((parent == NULL) || (node->doc == NULL))
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    nocache = 1;
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			else {
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    while (parent->parent != NULL)
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				parent = parent->parent;
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (((parent->type != XML_DOCUMENT_NODE) &&
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (parent->type != XML_HTML_DOCUMENT_NODE)) ||
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 (parent != (xmlNodePtr) node->doc))
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				nocache = 1;
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (pos != 0) {
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ctxt->xpathCtxt->contextSize = len;
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			ctxt->xpathCtxt->proximityPosition = pos;
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			/*
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * If the node is in a Value Tree we cannot
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 * cache it !
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 */
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			if ((node->doc != NULL) && (nocache == 0) && !isRVT) {
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) =
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				node;
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) =
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				pos;
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) =
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				len;
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		oldNode = ctxt->node;
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->node = node;
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value == NULL)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto wrong_index;
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->comp == NULL)
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto wrong_index;
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (!xsltEvalXPathPredicate(ctxt, step->comp, comp->nsList,
11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			                    comp->nsNr))
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto wrong_index;
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (pos != 0) {
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->xpathCtxt->contextSize = oldCS;
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->xpathCtxt->proximityPosition = oldCP;
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->node = oldNode;
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)wrong_index:
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (pos != 0) {
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->xpathCtxt->contextSize = oldCS;
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->xpathCtxt->proximityPosition = oldCP;
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->node = oldNode;
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto rollback;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_PI:
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->type != XML_PI_NODE)
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (step->value != NULL) {
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (!xmlStrEqual(step->value, node->name))
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_COMMENT:
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->type != XML_COMMENT_NODE)
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_TEXT:
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if ((node->type != XML_TEXT_NODE) &&
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (node->type != XML_CDATA_SECTION_NODE))
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto rollback;
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            case XSLT_OP_NODE:
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		switch (node->type) {
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_ELEMENT_NODE:
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_CDATA_SECTION_NODE:
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_PI_NODE:
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_COMMENT_NODE:
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    case XML_TEXT_NODE:
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    default:
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			goto rollback;
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)found:
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (states.states != NULL) {
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        /* Free the rollback states */
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(states.states);
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(1);
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rollback:
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /* got an error try to rollback */
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (states.states == NULL)
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (states.nbstates <= 0) {
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(states.states);
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(0);
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    states.nbstates--;
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    i = states.states[states.nbstates].step;
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    node = states.states[states.nbstates].node;
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fprintf(stderr, "Pop: %d, %s\n", i, node->name);
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    goto restart;
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltTestCompMatchList:
11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a XSLT process context
11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: a node
11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the precompiled pattern list
11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Test whether the node matches one of the patterns in the list
12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node,
12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	              xsltCompMatchPtr comp) {
12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int ret;
12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (node == NULL))
12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (comp != NULL) {
12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xsltTestCompMatch(ctxt, comp, node, NULL, NULL);
12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret == 1)
12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(1);
12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	comp = comp->next;
12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *			Dedicated parser for templates			*
12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR (*ctxt->cur)
12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SKIP(val) ctxt->cur += (val)
12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NXT(val) ctxt->cur[(val)]
12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR_PTR ctxt->cur
12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SKIP_BLANKS 							\
12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (IS_BLANK_CH(CUR)) NEXT
12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CURRENT (*ctxt->cur)
12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PUSH(op, val, val2, novar) 						\
12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (xsltCompMatchAdd(ctxt, ctxt->comp, (op), (val), (val2), (novar))) goto error;
12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SWAP() 						\
12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltSwapTopCompMatch(ctxt->comp);
12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XSLT_ERROR(X)							\
12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { xsltError(ctxt, __FILE__, __LINE__, X);			\
12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctxt->error = (X); return; }
12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XSLT_ERROR0(X)							\
12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { xsltError(ctxt, __FILE__, __LINE__, X);			\
12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ctxt->error = (X); return(0); }
12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltScanLiteral:
12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPath Parser context
12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parse an XPath Litteral:
12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [29] Literal ::= '"' [^"]* '"'
12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                | "'" [^']* "'"
12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the Literal parsed or NULL
12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlChar *
12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltScanLiteral(xsltParserContextPtr ctxt) {
12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *q, *cur;
12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *ret = NULL;
12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int val, len;
12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR == '"') {
12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT;
12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = q = CUR_PTR;
12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	val = xmlStringCurrentChar(NULL, cur, &len);
12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((IS_CHAR(val)) && (val != '"')) {
12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cur += len;
12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    val = xmlStringCurrentChar(NULL, cur, &len);
12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!IS_CHAR(val)) {
12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrndup(q, cur - q);
12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur += len;
12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CUR_PTR = cur;
12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '\'') {
12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        NEXT;
12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur = q = CUR_PTR;
12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	val = xmlStringCurrentChar(NULL, cur, &len);
12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((IS_CHAR(val)) && (val != '\'')) {
12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    cur += len;
12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    val = xmlStringCurrentChar(NULL, cur, &len);
12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (!IS_CHAR(val)) {
12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(NULL);
12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ret = xmlStrndup(q, cur - q);
12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur += len;
13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	CUR_PTR = cur;
13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* XP_ERROR(XPATH_START_LITERAL_ERROR); */
13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = 1;
13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltScanNCName:
13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the XPath Parser context
13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parses a non qualified name
13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the Name parsed or NULL
13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlChar *
13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltScanNCName(xsltParserContextPtr ctxt) {
13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *q, *cur;
13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *ret = NULL;
13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int val, len;
13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cur = q = CUR_PTR;
13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    val = xmlStringCurrentChar(NULL, cur, &len);
13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!IS_LETTER(val) && (val != '_'))
13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)           (val == '.') || (val == '-') ||
13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   (val == '_') ||
13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   (IS_COMBINING(val)) ||
13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	   (IS_EXTENDER(val))) {
13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	cur += len;
13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	val = xmlStringCurrentChar(NULL, cur, &len);
13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ret = xmlStrndup(q, cur - q);
13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CUR_PTR = cur;
13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(ret);
13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/*
13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompileIdKeyPattern:
13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the compilation context
13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name:  a preparsed name
13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @aid:  whether id/key are allowed there
13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar:  flag to prohibit xslt var
13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT LocationIdKeyPattern
13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [3] IdKeyPattern ::= 'id' '(' Literal ')'
13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                    | 'key' '(' Literal ',' Literal ')'
13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * also handle NodeType and PI from:
13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [7]  NodeTest ::= NameTest
13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                 | NodeType '(' ')'
13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                 | 'processing-instruction' '(' Literal ')'
13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name,
13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		int aid, int novar, xsltAxis axis) {
13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *lit = NULL;
13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *lit2 = NULL;
13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR != '(') {
13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(NULL, NULL, NULL,
13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		"xsltCompileIdKeyPattern : ( expected\n");
13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = 1;
13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((aid) && (xmlStrEqual(name, (const xmlChar *)"id"))) {
13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (axis != 0) {
13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileIdKeyPattern : NodeTest expected\n");
13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lit = xsltScanLiteral(ctxt);
13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->error)
13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != ')') {
13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileIdKeyPattern : ) expected\n");
13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PUSH(XSLT_OP_ID, lit, NULL, novar);
13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if ((aid) && (xmlStrEqual(name, (const xmlChar *)"key"))) {
13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (axis != 0) {
13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileIdKeyPattern : NodeTest expected\n");
13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lit = xsltScanLiteral(ctxt);
14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->error)
14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != ',') {
14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileIdKeyPattern : , expected\n");
14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        lit2 = xsltScanLiteral(ctxt);
14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->error)
14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != ')') {
14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileIdKeyPattern : ) expected\n");
14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* URGENT TODO: support namespace in keys */
14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PUSH(XSLT_OP_KEY, lit, lit2, novar);
14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (xmlStrEqual(name, (const xmlChar *)"processing-instruction")) {
14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != ')') {
14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    lit = xsltScanLiteral(ctxt);
14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ctxt->error)
14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SKIP_BLANKS;
14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (CUR != ')') {
14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xsltTransformError(NULL, NULL, NULL,
14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			"xsltCompileIdKeyPattern : ) expected\n");
14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->error = 1;
14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PUSH(XSLT_OP_PI, lit, NULL, novar);
14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (xmlStrEqual(name, (const xmlChar *)"text")) {
14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != ')') {
14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileIdKeyPattern : ) expected\n");
14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PUSH(XSLT_OP_TEXT, NULL, NULL, novar);
14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (xmlStrEqual(name, (const xmlChar *)"comment")) {
14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != ')') {
14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileIdKeyPattern : ) expected\n");
14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PUSH(XSLT_OP_COMMENT, NULL, NULL, novar);
14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (xmlStrEqual(name, (const xmlChar *)"node")) {
14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != ')') {
14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileIdKeyPattern : ) expected\n");
14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (axis == AXIS_ATTRIBUTE) {
14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PUSH(XSLT_OP_ATTR, NULL, NULL, novar);
14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else {
14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PUSH(XSLT_OP_NODE, NULL, NULL, novar);
14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (aid) {
14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(NULL, NULL, NULL,
14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "xsltCompileIdKeyPattern : expecting 'key' or 'id' or node type\n");
14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = 1;
14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(NULL, NULL, NULL,
14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "xsltCompileIdKeyPattern : node type\n");
14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->error = 1;
14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return;
14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name != NULL)
14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(name);
14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompileStepPattern:
15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the compilation context
15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token:  a posible precompiled name
15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar: flag to prohibit xslt variables from pattern
15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT StepPattern and generates a precompiled
15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * form suitable for fast matching.
15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [5] StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate*
15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [6] ChildOrAttributeAxisSpecifier ::= AbbreviatedAxisSpecifier
15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                                     | ('child' | 'attribute') '::'
15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from XPath
15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [7]  NodeTest ::= NameTest
15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                 | NodeType '(' ')'
15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                 | 'processing-instruction' '(' Literal ')'
15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [8] Predicate ::= '[' PredicateExpr ']'
15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [9] PredicateExpr ::= Expr
15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [13] AbbreviatedAxisSpecifier ::= '@'?
15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [37] NameTest ::= '*' | NCName ':' '*' | QName
15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *name = NULL;
15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *URI = NULL;
15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xmlChar *URL = NULL;
15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int level;
15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltAxis axis = 0;
15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((token == NULL) && (CUR == '@')) {
15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        axis = AXIS_ATTRIBUTE;
15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parse_node_test:
15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (token == NULL)
15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	token = xsltScanNCName(ctxt);
15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (token == NULL) {
15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == '*') {
15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (axis == AXIS_ATTRIBUTE) {
15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                PUSH(XSLT_OP_ATTR, NULL, NULL, novar);
15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            else {
15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                PUSH(XSLT_OP_ALL, NULL, NULL, novar);
15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            }
15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto parse_predicate;
15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileStepPattern : Name expected\n");
15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (CUR == '(') {
15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltCompileIdKeyPattern(ctxt, token, 0, novar, axis);
15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->error)
15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == ':') {
15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR != ':') {
15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlChar *prefix = token;
15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlNsPtr ns;
15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * This is a namespace match
15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    token = xsltScanNCName(ctxt);
15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix);
15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ns == NULL) {
15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xsltTransformError(NULL, NULL, NULL,
15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "xsltCompileStepPattern : no namespace bound to prefix %s\n",
15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				 prefix);
15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlFree(prefix);
15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->error = 1;
15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto error;
15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		URL = xmlStrdup(ns->href);
15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(prefix);
15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (token == NULL) {
15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (CUR == '*') {
15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    NEXT;
15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    if (axis == AXIS_ATTRIBUTE) {
15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        PUSH(XSLT_OP_ATTR, NULL, URL, novar);
15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    else {
15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                        PUSH(XSLT_OP_NS, URL, NULL, novar);
15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    }
15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xsltTransformError(NULL, NULL, NULL,
15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    "xsltCompileStepPattern : Name expected\n");
15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ctxt->error = 1;
15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    goto error;
15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                if (axis == AXIS_ATTRIBUTE) {
16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PUSH(XSLT_OP_ATTR, token, URL, novar);
16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                else {
16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    PUSH(XSLT_OP_ELEM, token, URL, novar);
16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                }
16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (axis != 0) {
16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xsltTransformError(NULL, NULL, NULL,
16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileStepPattern : NodeTest expected\n");
16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->error = 1;
16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto error;
16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (xmlStrEqual(token, (const xmlChar *) "child")) {
16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        axis = AXIS_CHILD;
16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (xmlStrEqual(token, (const xmlChar *) "attribute")) {
16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        axis = AXIS_ATTRIBUTE;
16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xsltTransformError(NULL, NULL, NULL,
16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileStepPattern : 'child' or 'attribute' expected\n");
16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ctxt->error = 1;
16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto error;
16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xmlFree(token);
16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            SKIP_BLANKS;
16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            token = xsltScanNCName(ctxt);
16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto parse_node_test;
16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	URI = xsltGetQNameURI(ctxt->elem, &token);
16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (token == NULL) {
16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (URI != NULL)
16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    URL = xmlStrdup(URI);
16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if (axis == AXIS_ATTRIBUTE) {
16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PUSH(XSLT_OP_ATTR, token, URL, novar);
16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        else {
16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            PUSH(XSLT_OP_ELEM, token, URL, novar);
16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parse_predicate:
16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    level = 0;
16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (CUR == '[') {
16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	const xmlChar *q;
16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *ret = NULL;
16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	level++;
16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	q = CUR_PTR;
16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (CUR != 0) {
16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* Skip over nested predicates */
16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (CUR == '[')
16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		level++;
16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (CUR == ']') {
16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		level--;
16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (level == 0)
16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (CUR == '"') {
16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NEXT;
16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while ((CUR != 0) && (CUR != '"'))
16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    NEXT;
16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (CUR == '\'') {
16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NEXT;
16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while ((CUR != 0) && (CUR != '\''))
16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    NEXT;
16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (CUR == 0) {
16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileStepPattern : ']' expected\n");
16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        }
16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ret = xmlStrndup(q, CUR_PTR - q);
16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PUSH(XSLT_OP_PREDICATE, ret, NULL, novar);
16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* push the predicate lower than local test */
16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SWAP();
16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (token != NULL)
16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(token);
16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (name != NULL)
16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlFree(name);
16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompileRelativePathPattern:
16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp:  the compilation context
16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token:  a posible precompiled name
16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar:  flag to prohibit xslt variables
17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT RelativePathPattern and generates a precompiled
17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * form suitable for fast matching.
17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [4] RelativePathPattern ::= StepPattern
17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                           | RelativePathPattern '/' StepPattern
17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                           | RelativePathPattern '//' StepPattern
17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompileRelativePathPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) {
17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompileStepPattern(ctxt, token, novar);
17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->error)
17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto error;
17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((CUR != 0) && (CUR != '|')) {
17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((CUR == '/') && (NXT(1) == '/')) {
17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar);
17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SKIP_BLANKS;
17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltCompileStepPattern(ctxt, NULL, novar);
17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (CUR == '/') {
17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PUSH(XSLT_OP_PARENT, NULL, NULL, novar);
17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    NEXT;
17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    SKIP_BLANKS;
17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((CUR != 0) && (CUR != '|')) {
17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xsltCompileRelativePathPattern(ctxt, NULL, novar);
17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->error)
17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompileLocationPathPattern:
17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  the compilation context
17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar:  flag to prohibit xslt variables
17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT LocationPathPattern and generates a precompiled
17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * form suitable for fast matching.
17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [2] LocationPathPattern ::= '/' RelativePathPattern?
17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                           | IdKeyPattern (('/' | '//') RelativePathPattern)?
17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *                           | '//'? RelativePathPattern
17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void
17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompileLocationPathPattern(xsltParserContextPtr ctxt, int novar) {
17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SKIP_BLANKS;
17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((CUR == '/') && (NXT(1) == '/')) {
17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * since we reverse the query
17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * a leading // can be safely ignored
17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->comp->priority = 0.5;	/* '//' means not 0 priority */
17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltCompileRelativePathPattern(ctxt, NULL, novar);
17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '/') {
17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * We need to find root as the parent
17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	NEXT;
17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	PUSH(XSLT_OP_ROOT, NULL, NULL, novar);
17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((CUR != 0) && (CUR != '|')) {
17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    PUSH(XSLT_OP_PARENT, NULL, NULL, novar);
17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltCompileRelativePathPattern(ctxt, NULL, novar);
17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '*') {
17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltCompileRelativePathPattern(ctxt, NULL, novar);
17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else if (CUR == '@') {
17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltCompileRelativePathPattern(ctxt, NULL, novar);
17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlChar *name;
17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	name = xsltScanNCName(ctxt);
17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (name == NULL) {
17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, NULL,
17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    "xsltCompileLocationPathPattern : Name expected\n");
17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ctxt->error = 1;
17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	SKIP_BLANKS;
17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((CUR == '(') && !xmlXPathIsNodeType(name)) {
17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltCompileIdKeyPattern(ctxt, name, 1, novar, 0);
17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (ctxt->error)
17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		return;
17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if ((CUR == '/') && (NXT(1) == '/')) {
17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar);
17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NEXT;
17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NEXT;
17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SKIP_BLANKS;
17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xsltCompileRelativePathPattern(ctxt, NULL, novar);
17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (CUR == '/') {
17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		PUSH(XSLT_OP_PARENT, NULL, NULL, novar);
18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		NEXT;
18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		SKIP_BLANKS;
18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xsltCompileRelativePathPattern(ctxt, NULL, novar);
18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return;
18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltCompileRelativePathPattern(ctxt, name, novar);
18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompilePatternInternal:
18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @pattern: an XSLT pattern
18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @doc:  the containing document
18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  the containing element
18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style:  the stylesheet
18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @runtime:  the transformation context, if done at run-time
18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar:  flag to prohibit xslt variables
18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT pattern and generates a list of precompiled form suitable
18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for fast matching.
18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [1] Pattern ::= LocationPathPattern | Pattern '|' LocationPathPattern
18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the generated pattern list or NULL in case of failure
18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xsltCompMatchPtr
18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc,
18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           xmlNodePtr node, xsltStylesheetPtr style,
18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   xsltTransformContextPtr runtime, int novar) {
18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltParserContextPtr ctxt = NULL;
18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompMatchPtr element, first = NULL, previous = NULL;
18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int current, start, end, level, j;
18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pattern == NULL) {
18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(NULL, NULL, node,
18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 "xsltCompilePattern : NULL pattern\n");
18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt = xsltNewParserContext(style, runtime);
18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt == NULL)
18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->doc = doc;
18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->elem = node;
18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    current = end = 0;
18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (pattern[current] != 0) {
18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	start = current;
18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (IS_BLANK_CH(pattern[current]))
18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    current++;
18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	end = current;
18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	level = 0;
18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((pattern[end] != 0) && ((pattern[end] != '|') || (level != 0))) {
18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (pattern[end] == '[')
18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		level++;
18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (pattern[end] == ']')
18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		level--;
18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else if (pattern[end] == '\'') {
18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		end++;
18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while ((pattern[end] != 0) && (pattern[end] != '\''))
18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    end++;
18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (pattern[end] == '"') {
18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		end++;
18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while ((pattern[end] != 0) && (pattern[end] != '"'))
18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    end++;
18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (pattern[end] == 0)
18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          break;
18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    end++;
18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (current == end) {
18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, NULL, node,
18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     "xsltCompilePattern : NULL pattern\n");
18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	element = xsltNewCompMatch();
18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (element == NULL) {
18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (first == NULL)
18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    first = element;
18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if (previous != NULL)
18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    previous->next = element;
18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	previous = element;
18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->comp = element;
18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->base = xmlStrndup(&pattern[start], end - start);
18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->base == NULL)
18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->cur = &(ctxt->base)[current - start];
18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	element->pattern = ctxt->base;
18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	element->nsList = xmlGetNsList(doc, node);
18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	j = 0;
18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (element->nsList != NULL) {
18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    while (element->nsList[j] != NULL)
18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		j++;
18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	element->nsNr = j;
19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG_PATTERN
19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltGenericDebug(xsltGenericDebugContext,
19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 "xsltCompilePattern : parsing '%s'\n",
19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 element->pattern);
19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 Preset default priority to be zero.
19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 This may be changed by xsltCompileLocationPathPattern.
19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	element->priority = 0;
19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltCompileLocationPathPattern(ctxt, novar);
19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->error) {
19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, style, node,
19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     "xsltCompilePattern : failed to compile '%s'\n",
19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     element->pattern);
19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (style != NULL) style->errors++;
19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto error;
19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Reverse for faster interpretation.
19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltReverseCompMatch(ctxt, element);
19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Set-up the priority
19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (element->priority == 0) {	/* if not yet determined */
19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (((element->steps[0].op == XSLT_OP_ELEM) ||
19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (element->steps[0].op == XSLT_OP_ATTR) ||
19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		 (element->steps[0].op == XSLT_OP_PI)) &&
19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(element->steps[0].value != NULL) &&
19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		(element->steps[1].op == XSLT_OP_END)) {
19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		;	/* previously preset */
19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if ((element->steps[0].op == XSLT_OP_ATTR) &&
19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[0].value2 != NULL) &&
19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[1].op == XSLT_OP_END)) {
19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			element->priority = -0.25;
19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if ((element->steps[0].op == XSLT_OP_NS) &&
19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[0].value != NULL) &&
19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[1].op == XSLT_OP_END)) {
19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			element->priority = -0.25;
19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if ((element->steps[0].op == XSLT_OP_ATTR) &&
19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[0].value == NULL) &&
19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[0].value2 == NULL) &&
19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[1].op == XSLT_OP_END)) {
19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			element->priority = -0.5;
19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (((element->steps[0].op == XSLT_OP_PI) ||
19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[0].op == XSLT_OP_TEXT) ||
19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[0].op == XSLT_OP_ALL) ||
19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[0].op == XSLT_OP_NODE) ||
19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[0].op == XSLT_OP_COMMENT)) &&
19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		       (element->steps[1].op == XSLT_OP_END)) {
19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			element->priority = -0.5;
19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		element->priority = 0.5;
19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG_PATTERN
19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltGenericDebug(xsltGenericDebugContext,
19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     "xsltCompilePattern : parsed %s, default priority %f\n",
19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 element->pattern, element->priority);
19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (pattern[end] == '|')
19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    end++;
19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	current = end;
19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (end == 0) {
19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(NULL, style, node,
19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 "xsltCompilePattern : NULL pattern\n");
19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (style != NULL) style->errors++;
19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	goto error;
19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltFreeParserContext(ctxt);
19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(first);
19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt != NULL)
19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltFreeParserContext(ctxt);
19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (first != NULL)
19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltFreeCompMatchList(first);
19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(NULL);
19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompilePattern:
19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @pattern: an XSLT pattern
19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @doc:  the containing document
19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  the containing element
19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style:  the stylesheet
19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @runtime:  the transformation context, if done at run-time
19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT pattern and generates a list of precompiled form suitable
19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for fast matching.
19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [1] Pattern ::= LocationPathPattern | Pattern '|' LocationPathPattern
20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the generated pattern list or NULL in case of failure
20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompMatchPtr
20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompilePattern(const xmlChar *pattern, xmlDocPtr doc,
20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	           xmlNodePtr node, xsltStylesheetPtr style,
20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   xsltTransformContextPtr runtime) {
20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return (xsltCompilePatternInternal(pattern, doc, node, style, runtime, 0));
20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************
20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *			Module interfaces				*
20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *									*
20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/
20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltAddTemplate:
20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: an XSLT stylesheet
20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: an XSLT template
20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @mode:  the mode name or NULL
20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @modeURI:  the mode URI or NULL
20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Register the XSLT pattern associated to @cur
20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of error, 0 otherwise
20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int
20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur,
20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        const xmlChar *mode, const xmlChar *modeURI) {
20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompMatchPtr pat, list, next;
20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    /*
20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     * 'top' will point to style->xxxMatch ptr - declaring as 'void'
20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     *  avoids gcc 'type-punned pointer' warning.
20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     */
20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void **top = NULL;
20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *name = NULL;
20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float priority;              /* the priority */
20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((style == NULL) || (cur == NULL) || (cur->match == NULL))
20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    priority = cur->priority;
20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pat = xsltCompilePatternInternal(cur->match, style->doc, cur->elem,
20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    style, NULL, 1);
20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (pat == NULL)
20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    	return(-1);
20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while (pat) {
20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	next = pat->next;
20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pat->next = NULL;
20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	name = NULL;
20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pat->template = cur;
20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (mode != NULL)
20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    pat->mode = xmlDictLookup(style->dict, mode, -1);
20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (modeURI != NULL)
20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    pat->modeURI = xmlDictLookup(style->dict, modeURI, -1);
20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (priority != XSLT_PAT_NO_PRIORITY)
20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    pat->priority = priority;
20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * insert it in the hash table list corresponding to its lookup name
20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (pat->steps[0].op) {
20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_ATTR:
20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (pat->steps[0].value != NULL)
20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		name = pat->steps[0].value;
20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		top = &(style->attrMatch);
20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_PARENT:
20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_ANCESTOR:
20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    top = &(style->elemMatch);
20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_ROOT:
20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    top = &(style->rootMatch);
20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_KEY:
20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    top = &(style->keyMatch);
20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_ID:
20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /* TODO optimize ID !!! */
20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_NS:
20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_ALL:
20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    top = &(style->elemMatch);
20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_END:
20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XSLT_OP_PREDICATE:
20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, style, NULL,
20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     "xsltAddTemplate: invalid compiled pattern\n");
20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltFreeCompMatch(pat);
20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * TODO: some flags at the top level about type based patterns
20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     *       would be faster than inclusion in the hash table.
20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XSLT_OP_PI:
20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (pat->steps[0].value != NULL)
20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		name = pat->steps[0].value;
21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		top = &(style->piMatch);
21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XSLT_OP_COMMENT:
21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    top = &(style->commentMatch);
21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XSLT_OP_TEXT:
21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    top = &(style->textMatch);
21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        case XSLT_OP_ELEM:
21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	case XSLT_OP_NODE:
21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (pat->steps[0].value != NULL)
21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		name = pat->steps[0].value;
21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    else
21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		top = &(style->elemMatch);
21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    break;
21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (name != NULL) {
21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (style->templatesHash == NULL) {
21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		style->templatesHash = xmlHashCreate(1024);
21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (style->templatesHash == NULL) {
21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xsltFreeCompMatch(pat);
21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(-1);
21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		xmlHashAddEntry3(style->templatesHash, name, mode, modeURI, pat);
21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = (xsltCompMatchPtr) xmlHashLookup3(style->templatesHash,
21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)							 name, mode, modeURI);
21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (list == NULL) {
21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    xmlHashAddEntry3(style->templatesHash, name,
21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				     mode, modeURI, pat);
21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		} else {
21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    /*
21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * Note '<=' since one must choose among the matching
21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * template rules that are left, the one that occurs
21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     * last in the stylesheet
21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		     */
21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (list->priority <= pat->priority) {
21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pat->next = list;
21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			xmlHashUpdateEntry3(style->templatesHash, name,
21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					    mode, modeURI, pat, NULL);
21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    } else {
21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			while (list->next != NULL) {
21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    if (list->next->priority <= pat->priority)
21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				break;
21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			    list = list->next;
21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			}
21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			pat->next = list->next;
21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			list->next = pat;
21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    }
21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if (top != NULL) {
21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = *top;
21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (list == NULL) {
21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*top = pat;
21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pat->next = NULL;
21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else if (list->priority <= pat->priority) {
21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pat->next = list;
21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		*top = pat;
21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    } else {
21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		while (list->next != NULL) {
21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (list->next->priority <= pat->priority)
21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    list = list->next;
21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		pat->next = list->next;
21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list->next = pat;
21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else {
21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltTransformError(NULL, style, NULL,
21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     "xsltAddTemplate: invalid compiled pattern\n");
21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltFreeCompMatch(pat);
21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG_PATTERN
21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (mode)
21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltGenericDebug(xsltGenericDebugContext,
21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 "added pattern : '%s' mode '%s' priority %f\n",
21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     pat->pattern, pat->mode, pat->priority);
21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else
21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    xsltGenericDebug(xsltGenericDebugContext,
21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			 "added pattern : '%s' priority %f\n",
21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			     pat->pattern, pat->priority);
21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	pat = next;
21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(0);
21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int
21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltComputeAllKeys(xsltTransformContextPtr ctxt, xmlNodePtr contextNode)
21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (contextNode == NULL)) {
21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xsltTransformError(ctxt, NULL, ctxt->inst,
21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "Internal error in xsltComputeAllKeys(): "
21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    "Bad arguments.\n");
21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(-1);
21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (ctxt->document == NULL) {
22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	* The document info will only be NULL if we have a RTF.
22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*/
22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (contextNode->doc->_private != NULL)
22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    goto doc_info_mismatch;
22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	* On-demand creation of the document info (needed for keys).
22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	*/
22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	ctxt->document = xsltNewDocument(ctxt, contextNode->doc);
22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ctxt->document == NULL)
22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(-1);
22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return xsltInitAllDocKeys(ctxt);
22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)doc_info_mismatch:
22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltTransformError(ctxt, NULL, ctxt->inst,
22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	"Internal error in xsltComputeAllKeys(): "
22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	"The context's document info doesn't match the "
22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	"document info of the current result tree.\n");
22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ctxt->state = XSLT_STATE_STOPPED;
22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(-1);
22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltGetTemplate:
22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt:  a XSLT process context
22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node:  the node being processed
22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style:  the current style
22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Finds the template applying to this node, if @style is non-NULL
22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it means one needs to look for the next imported template in scope.
22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the xsltTemplatePtr or NULL if not found
22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltTemplatePtr
22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node,
22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xsltStylesheetPtr style)
22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){
22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltStylesheetPtr curstyle;
22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltTemplatePtr ret = NULL;
22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const xmlChar *name = NULL;
22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    xsltCompMatchPtr list = NULL;
22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    float priority;
22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int keyed = 0;
22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((ctxt == NULL) || (node == NULL))
22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	return(NULL);
22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style == NULL) {
22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	curstyle = ctxt->style;
22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	curstyle = xsltNextImport(style);
22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    while ((curstyle != NULL) && (curstyle != style)) {
22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	priority = XSLT_PAT_NO_PRIORITY;
22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/* TODO : handle IDs/keys here ! */
22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (curstyle->templatesHash != NULL) {
22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * Use the top name as selector
22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    switch (node->type) {
22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ELEMENT_NODE:
22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (node->name[0] == ' ')
22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			break;
22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ATTRIBUTE_NODE:
22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_PI_NODE:
22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    name = node->name;
22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_DOCUMENT_NODE:
22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_HTML_DOCUMENT_NODE:
22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_TEXT_NODE:
22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_CDATA_SECTION_NODE:
22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_COMMENT_NODE:
22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ENTITY_REF_NODE:
22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ENTITY_NODE:
22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_DOCUMENT_TYPE_NODE:
22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_DOCUMENT_FRAG_NODE:
22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_NOTATION_NODE:
22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_DTD_NODE:
22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ELEMENT_DECL:
22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ATTRIBUTE_DECL:
22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ENTITY_DECL:
22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_NAMESPACE_DECL:
22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_XINCLUDE_START:
22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_XINCLUDE_END:
22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    return(NULL);
22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (name != NULL) {
22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     * find the list of applicable expressions based on the name
22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     */
22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = (xsltCompMatchPtr) xmlHashLookup3(curstyle->templatesHash,
22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)					     name, ctxt->mode, ctxt->modeURI);
23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else
23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = NULL;
23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while (list != NULL) {
23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (xsltTestCompMatch(ctxt, list, node,
23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			          ctxt->mode, ctxt->modeURI)) {
23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = list->template;
23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		priority = list->priority;
23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = list->next;
23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	list = NULL;
23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * find alternate generic matches
23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	switch (node->type) {
23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_ELEMENT_NODE:
23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->name[0] == ' ')
23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    list = curstyle->rootMatch;
23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		else
23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    list = curstyle->elemMatch;
23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->psvi != NULL) keyed = 1;
23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_ATTRIBUTE_NODE: {
23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlAttrPtr attr;
23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = curstyle->attrMatch;
23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		attr = (xmlAttrPtr) node;
23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (attr->psvi != NULL) keyed = 1;
23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_PI_NODE:
23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = curstyle->piMatch;
23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->psvi != NULL) keyed = 1;
23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_DOCUMENT_NODE:
23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_HTML_DOCUMENT_NODE: {
23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	        xmlDocPtr doc;
23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = curstyle->rootMatch;
23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		doc = (xmlDocPtr) node;
23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (doc->psvi != NULL) keyed = 1;
23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_TEXT_NODE:
23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_CDATA_SECTION_NODE:
23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = curstyle->textMatch;
23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->psvi != NULL) keyed = 1;
23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_COMMENT_NODE:
23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = curstyle->commentMatch;
23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (node->psvi != NULL) keyed = 1;
23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_ENTITY_REF_NODE:
23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_ENTITY_NODE:
23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_DOCUMENT_TYPE_NODE:
23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_DOCUMENT_FRAG_NODE:
23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_NOTATION_NODE:
23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_DTD_NODE:
23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_ELEMENT_DECL:
23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_ATTRIBUTE_DECL:
23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_ENTITY_DECL:
23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_NAMESPACE_DECL:
23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_XINCLUDE_START:
23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    case XML_XINCLUDE_END:
23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    default:
23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	while ((list != NULL) &&
23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	       ((ret == NULL)  || (list->priority > priority))) {
23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (xsltTestCompMatch(ctxt, list, node,
23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)			          ctxt->mode, ctxt->modeURI)) {
23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		ret = list->template;
23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		priority = list->priority;
23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		break;
23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = list->next;
23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Some of the tests for elements can also apply to documents
23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if ((node->type == XML_DOCUMENT_NODE) ||
23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (node->type == XML_HTML_DOCUMENT_NODE) ||
23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    (node->type == XML_TEXT_NODE)) {
23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = curstyle->elemMatch;
23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    while ((list != NULL) &&
23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   ((ret == NULL)  || (list->priority > priority))) {
23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (xsltTestCompMatch(ctxt, list, node,
23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      ctxt->mode, ctxt->modeURI)) {
23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = list->template;
23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    priority = list->priority;
23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = list->next;
23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	} else if ((node->type == XML_PI_NODE) ||
23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   (node->type == XML_COMMENT_NODE)) {
23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = curstyle->elemMatch;
24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    while ((list != NULL) &&
24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   ((ret == NULL)  || (list->priority > priority))) {
24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (xsltTestCompMatch(ctxt, list, node,
24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      ctxt->mode, ctxt->modeURI)) {
24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = list->template;
24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    priority = list->priority;
24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = list->next;
24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)keyed_match:
24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (keyed) {
24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    list = curstyle->keyMatch;
24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    while ((list != NULL) &&
24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		   ((ret == NULL)  || (list->priority > priority))) {
24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		if (xsltTestCompMatch(ctxt, list, node,
24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)				      ctxt->mode, ctxt->modeURI)) {
24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    ret = list->template;
24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    priority = list->priority;
24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		}
24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		list = list->next;
24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	else if (ctxt->hasTemplKeyPatterns &&
24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    ((ctxt->document == NULL) ||
24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	     (ctxt->document->nbKeysComputed < ctxt->nbKeys)))
24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	{
24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    /*
24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    * Compute all remaining keys for this document.
24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    *
24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    * REVISIT TODO: I think this could be further optimized.
24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    */
24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (xsltComputeAllKeys(ctxt, node) == -1)
24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto error;
24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    switch (node->type) {
24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ELEMENT_NODE:
24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (node->psvi != NULL) keyed = 1;
24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_ATTRIBUTE_NODE:
24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (((xmlAttrPtr) node)->psvi != NULL) keyed = 1;
24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_TEXT_NODE:
24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_CDATA_SECTION_NODE:
24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_COMMENT_NODE:
24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_PI_NODE:
24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (node->psvi != NULL) keyed = 1;
24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_DOCUMENT_NODE:
24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		case XML_HTML_DOCUMENT_NODE:
24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    if (((xmlDocPtr) node)->psvi != NULL) keyed = 1;
24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		default:
24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    break;
24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    }
24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    if (keyed)
24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		goto keyed_match;
24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	}
24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	if (ret != NULL)
24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	    return(ret);
24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	/*
24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 * Cycle on next curstylesheet import.
24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	 */
24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	curstyle = xsltNextImport(curstyle);
24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error:
24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return(NULL);
24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCleanupTemplates:
24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: an XSLT stylesheet
24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Cleanup the state of the templates used by the stylesheet and
24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the ones it imports.
24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCleanupTemplates(xsltStylesheetPtr style ATTRIBUTE_UNUSED) {
24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/**
24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeTemplateHashes:
24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: an XSLT stylesheet
24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *
24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory used by xsltAddTemplate/xsltGetTemplate mechanism
24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */
24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void
24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeTemplateHashes(xsltStylesheetPtr style) {
24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->templatesHash != NULL)
24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)	xmlHashFree((xmlHashTablePtr) style->templatesHash,
24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)		    (xmlHashDeallocator) xsltFreeCompMatchList);
24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->rootMatch != NULL)
24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltFreeCompMatchList(style->rootMatch);
24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->keyMatch != NULL)
24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltFreeCompMatchList(style->keyMatch);
25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->elemMatch != NULL)
25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltFreeCompMatchList(style->elemMatch);
25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->attrMatch != NULL)
25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltFreeCompMatchList(style->attrMatch);
25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->parentMatch != NULL)
25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltFreeCompMatchList(style->parentMatch);
25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->textMatch != NULL)
25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltFreeCompMatchList(style->textMatch);
25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->piMatch != NULL)
25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltFreeCompMatchList(style->piMatch);
25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (style->commentMatch != NULL)
25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        xsltFreeCompMatchList(style->commentMatch);
25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2514