pattern.c revision 2b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367
1b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/*
2b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * pattern.c: Implemetation of selectors for nodes
3b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
4b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Reference:
5b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *   http://www.w3.org/TR/2001/REC-xmlschema-1-20010502/
6b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *   to some extent
7b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *   http://www.w3.org/TR/1999/REC-xml-19991116
8b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
9b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * See Copyright for the status of this software.
10b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
11b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * daniel@veillard.com
12b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
13b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
14f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard/*
15f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard * TODO:
16f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard * - compilation flags to check for specific syntaxes
17f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard *   using flags of xmlPatterncompile()
18f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard * - making clear how pattern starting with / or . need to be handled,
19f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard *   currently push(NULL, NULL) means a reset of the streaming context
20f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard *   and indicating we are on / (the document node), probably need
21f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard *   something similar for .
22d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard * - get rid of the "compile" starting with lowercase
23d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard * - get rid of the Strdup/Strndup in case of dictionary
24f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard */
25f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard
26b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define IN_LIBXML
27b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include "libxml.h"
28b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
29b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <string.h>
30b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/xmlmemory.h>
31b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/tree.h>
32b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/hash.h>
33b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/dict.h>
34b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/xmlerror.h>
35b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/parserInternals.h>
36b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/pattern.h>
37b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
38d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#ifdef LIBXML_PATTERN_ENABLED
39b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
40d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard/* #define DEBUG_STREAMING */
412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
42b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define ERROR(a, b, c, d)
43b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define ERROR5(a, b, c, d, e)
44b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_DESC	1
462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_FINAL	2
472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_ROOT	4
482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef struct _xmlStreamStep xmlStreamStep;
502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef xmlStreamStep *xmlStreamStepPtr;
512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamStep {
522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int flags;			/* properties of that step */
532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    const xmlChar *name;	/* first string value if NULL accept all */
542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    const xmlChar *ns;		/* second string value */
552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef struct _xmlStreamComp xmlStreamComp;
582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef xmlStreamComp *xmlStreamCompPtr;
592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamComp {
602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlDict *dict;		/* the dictionnary if any */
612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int nbStep;			/* number of steps in the automata */
622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int maxStep;		/* allocated number of steps */
632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamStepPtr steps;	/* the array of steps */
642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamCtxt {
67f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    struct _xmlStreamCtxt *next;/* link to next sub pattern if | */
682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr comp;	/* the compiled stream */
692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int nbState;		/* number of state in the automata */
702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int maxState;		/* allocated number of state */
712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int level;			/* how deep are we ? */
722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int *states;		/* the array of step indexes */
732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void xmlFreeStreamComp(xmlStreamCompPtr comp);
762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
77b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/*
78b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Types are private:
79b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
80b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
81b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef enum {
82b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_END=0,
83b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ROOT,
84b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ELEM,
85b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_CHILD,
86b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ATTR,
87b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_PARENT,
88b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ANCESTOR,
89b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_NS,
90b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ALL
91b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} xmlPatOp;
92b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
93b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
94d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef struct _xmlStepState xmlStepState;
95d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef xmlStepState *xmlStepStatePtr;
96d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstruct _xmlStepState {
97d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    int step;
98d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    xmlNodePtr node;
99d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard};
100d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard
101d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef struct _xmlStepStates xmlStepStates;
102d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef xmlStepStates *xmlStepStatesPtr;
103d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstruct _xmlStepStates {
104d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    int nbstates;
105d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    int maxstates;
106d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    xmlStepStatePtr states;
107d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard};
108d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard
109b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlStepOp xmlStepOp;
110b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlStepOp *xmlStepOpPtr;
111b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlStepOp {
112b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatOp op;
113b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *value;
114b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *value2;
115b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
116b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
117b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPattern {
118b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    void *data;    		/* the associated template */
1192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlDictPtr dict;		/* the optional dictionnary */
120f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    struct _xmlPattern *next;	/* next pattern if | is used */
121b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *pattern;	/* the pattern */
122b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
123b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int nbStep;
124b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int maxStep;
125c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    xmlStepOpPtr steps;        /* ops for computation */
1262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr stream;	/* the streaming data if any */
127b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
128b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
129b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlPatParserContext xmlPatParserContext;
130b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlPatParserContext *xmlPatParserContextPtr;
131b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPatParserContext {
132b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *cur;			/* the current char being parsed */
133b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *base;		/* the full expression */
134b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int	           error;		/* error code */
135b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlDictPtr     dict;		/* the dictionnary if any */
136b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr  comp;		/* the result */
137b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlNodePtr     elem;		/* the current node if any */
138ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    const xmlChar **namespaces;		/* the namespaces definitions */
139ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    int   nb_namespaces;		/* the number of namespaces */
140b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
141b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
142b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
143b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
144b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 			Type functions 					*
145b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
146b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
147b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
148b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
149b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPattern:
150b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
151b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XSLT Pattern
152b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
153b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatternPtr or NULL in case of error
154b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
155b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatternPtr
156b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlNewPattern(void) {
157b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr cur;
158b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
159b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));
160b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (cur == NULL) {
161b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ERROR(NULL, NULL, NULL,
162b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		"xmlNewPattern : malloc failed\n");
163b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
164b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
165b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(cur, 0, sizeof(xmlPattern));
166b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->maxStep = 10;
167c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    cur->steps = (xmlStepOpPtr) xmlMalloc(cur->maxStep * sizeof(xmlStepOp));
168c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (cur->steps == NULL) {
169c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlFree(cur);
170c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	ERROR(NULL, NULL, NULL,
171c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard		"xmlNewPattern : malloc failed\n");
172c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	return(NULL);
173c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    }
174b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(cur);
175b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
176b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
177b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
178b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePattern:
179b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  an XSLT comp
180b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
181b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @comp
182b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
183b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid
184b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePattern(xmlPatternPtr comp) {
185b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOpPtr op;
186b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
187b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
188b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp == NULL)
189b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
190f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    if (comp->next != NULL)
191f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        xmlFreePattern(comp->next);
1922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->stream != NULL)
1932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFreeStreamComp(comp->stream);
194b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp->pattern != NULL)
195b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree((xmlChar *)comp->pattern);
196c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->steps != NULL) {
1972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->dict == NULL) {
1982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    for (i = 0;i < comp->nbStep;i++) {
1992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		op = &comp->steps[i];
2002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (op->value != NULL)
2012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    xmlFree((xmlChar *) op->value);
2022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (op->value2 != NULL)
2032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    xmlFree((xmlChar *) op->value2);
2042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
205c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
206c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	xmlFree(comp->steps);
207b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
2082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->dict != NULL)
2092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlDictFree(comp->dict);
2102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
211b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(comp, -1, sizeof(xmlPattern));
212b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFree(comp);
213b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
214b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
215b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
216b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatternList:
217b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  an XSLT comp list
218b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
219b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by all the elements of @comp
220b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
221b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid
222b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatternList(xmlPatternPtr comp) {
223b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr cur;
224b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
225b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (comp != NULL) {
226b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = comp;
227b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp = comp->next;
228b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFreePattern(cur);
229b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
230b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
231b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
232b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
233b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPatParserContext:
234b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern:  the pattern context
235ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * @dict:  the inherited dictionnary or NULL
2362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] terminated
2372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *              with [NULL, NULL] or NULL if no namespace is used
238b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
239b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XML pattern parser context
240b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
241b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error
242b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
243b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatParserContextPtr
244ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel VeillardxmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict,
245ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard                       const xmlChar **namespaces) {
246b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatParserContextPtr cur;
247b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
248b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (pattern == NULL)
249b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return(NULL);
250b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
251b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));
252b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (cur == NULL) {
253b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ERROR(NULL, NULL, NULL,
254b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		"xmlNewPatParserContext : malloc failed\n");
255b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
256b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
257b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(cur, 0, sizeof(xmlPatParserContext));
258b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->dict = dict;
259b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->cur = pattern;
260b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->base = pattern;
261ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    if (namespaces != NULL) {
262ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        int i;
263ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard	for (i = 0;namespaces[2 * i] != NULL;i++);
264ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        cur->nb_namespaces = i;
265ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    } else {
266ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        cur->nb_namespaces = 0;
267ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    }
268ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    cur->namespaces = namespaces;
269b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(cur);
270b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
271b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
272b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
273b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatParserContext:
274b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  an XSLT parser context
275b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
276b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @ctxt
277b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
278b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
279b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
280b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt == NULL)
281b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
282b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(ctxt, -1, sizeof(xmlPatParserContext));
283b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFree(ctxt);
284b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
285b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
286b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
287b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternAdd:
288b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
289b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @op:  an op
290b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value:  the first value
291b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value2:  the second value
292b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
293b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Add an step to an XSLT Compiled Match
294b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
295b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns -1 in case of failure, 0 otherwise.
296b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
297b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int
298b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
299b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                xmlPatternPtr comp,
300b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                xmlPatOp op, xmlChar * value, xmlChar * value2)
301b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{
302c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->nbStep >= comp->maxStep) {
303c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlStepOpPtr temp;
304c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
305c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	                                 sizeof(xmlStepOp));
306c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        if (temp == NULL) {
307c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    ERROR(ctxt, NULL, NULL,
308c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard			     "xmlPatternAdd: realloc failed\n");
309c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    return (-1);
310c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
311c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->steps = temp;
312c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->maxStep *= 2;
313b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
314b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].op = op;
315b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].value = value;
316b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].value2 = value2;
317b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->nbStep++;
318b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return (0);
319b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
320b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
321b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
322b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
323b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xsltSwapTopPattern:
324b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
325b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
326b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse the two top steps.
327b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
328b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
329b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxsltSwapTopPattern(xmlPatternPtr comp) {
330b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
331b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int j = comp->nbStep - 1;
332b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
333b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (j > 0) {
334b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register const xmlChar *tmp;
335b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register xmlPatOp op;
336b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	i = j - 1;
337b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value;
338b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value = comp->steps[j].value;
339b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value = tmp;
340b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value2;
341b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value2 = comp->steps[j].value2;
342b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value2 = tmp;
343b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = comp->steps[i].op;
344b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].op = comp->steps[j].op;
345b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].op = op;
346b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
347b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
348b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
349b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
350b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
351b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlReversePattern:
352b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
353b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
354b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse all the stack of expressions
355c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard *
356c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard * returns 0 in case of success and -1 in case of error.
357b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
358c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillardstatic int
359b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlReversePattern(xmlPatternPtr comp) {
360b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i = 0;
361b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int j = comp->nbStep - 1;
362b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
363c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->nbStep >= comp->maxStep) {
364c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlStepOpPtr temp;
365c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
366c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	                                 sizeof(xmlStepOp));
367c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        if (temp == NULL) {
368c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    ERROR(ctxt, NULL, NULL,
369c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard			     "xmlReversePattern: realloc failed\n");
370c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    return (-1);
371c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
372c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->steps = temp;
373c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->maxStep *= 2;
374c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    }
375b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (j > i) {
376b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register const xmlChar *tmp;
377b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register xmlPatOp op;
378b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value;
379b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value = comp->steps[j].value;
380b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value = tmp;
381b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value2;
382b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value2 = comp->steps[j].value2;
383b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value2 = tmp;
384b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = comp->steps[i].op;
385b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].op = comp->steps[j].op;
386b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].op = op;
387b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	j--;
388b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	i++;
389b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
390c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    comp->steps[comp->nbStep].value = NULL;
391c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    comp->steps[comp->nbStep].value2 = NULL;
392b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep++].op = XML_OP_END;
393c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    return(0);
394b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
395b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
396b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
397b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
398b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 		The interpreter for the precompiled patterns		*
399b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
400b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
401b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
402d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstatic int
403d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel VeillardxmlPatPushState(xmlStepStates *states, int step, xmlNodePtr node) {
404d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    if ((states->states == NULL) || (states->maxstates <= 0)) {
405d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard        states->maxstates = 4;
406d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	states->nbstates = 0;
407d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	states->states = xmlMalloc(4 * sizeof(xmlStepState));
408d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    }
409d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    else if (states->maxstates <= states->nbstates) {
410d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard        xmlStepState *tmp;
411d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard
412d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	tmp = (xmlStepStatePtr) xmlRealloc(states->states,
413d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			       2 * states->maxstates * sizeof(xmlStepState));
414d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	if (tmp == NULL)
415d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	    return(-1);
416d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	states->states = tmp;
417d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	states->maxstates *= 2;
418d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    }
419d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    states->states[states->nbstates].step = step;
420d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    states->states[states->nbstates++].node = node;
421d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#if 0
422d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    fprintf(stderr, "Push: %d, %s\n", step, node->name);
423d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#endif
424d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    return(0);
425d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard}
426d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard
427b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
428b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatMatch:
429b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern
430b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node
431b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
432b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Test wether the node matches the pattern
433b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
434b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
435b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
436b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int
437b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
438b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
439b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOpPtr step;
440d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    xmlStepStates states = {0, 0, NULL}; /* // may require backtrack */
441b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
442b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((comp == NULL) || (node == NULL)) return(-1);
443d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    i = 0;
444d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardrestart:
445d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    for (;i < comp->nbStep;i++) {
446b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	step = &comp->steps[i];
447b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	switch (step->op) {
448b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_END:
449d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		goto found;
450b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ROOT:
4512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (node->type == XML_NAMESPACE_DECL)
452d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
4532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		node = node->parent;
454b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
455b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
456b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
457b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
458b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE))
459b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
460d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		goto rollback;
461b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ELEM:
462b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
463d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
464b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL)
465b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
466b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value[0] != node->name[0])
467d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
468b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (!xmlStrEqual(step->value, node->name))
469d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
470b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
471b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
472b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
473b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
474d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
475b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
476b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 == NULL)
477d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
478b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
479d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
480b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
481b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
482b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_CHILD: {
483b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlNodePtr lst;
484b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
485b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type != XML_ELEMENT_NODE) &&
486b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_DOCUMENT_NODE) &&
487b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
488b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_DOCB_DOCUMENT_NODE) &&
489b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
490b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_HTML_DOCUMENT_NODE))
491d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
492b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
493b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		lst = node->children;
494b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
495b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value != NULL) {
496b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    while (lst != NULL) {
497b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			if ((lst->type == XML_ELEMENT_NODE) &&
498b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    (step->value[0] == lst->name[0]) &&
499b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    (xmlStrEqual(step->value, lst->name)))
500b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    break;
501b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			lst = lst->next;
502b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
503b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (lst != NULL)
504b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			continue;
505b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
506d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		goto rollback;
507b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
508b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ATTR:
509b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ATTRIBUTE_NODE)
510d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
511b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value != NULL) {
512b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value[0] != node->name[0])
513d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
514b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value, node->name))
515d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
516b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
517b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
518b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
519b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
520d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
521b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (step->value2 != NULL) {
522b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
523d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
524b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
525b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
526b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_PARENT:
527b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
528b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE) ||
529b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
530b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
531b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
532b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_NAMESPACE_DECL))
533d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
534b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		node = node->parent;
535b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
536d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
537b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL)
538b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
539b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value[0] != node->name[0])
540d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
541b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (!xmlStrEqual(step->value, node->name))
542d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
543b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
544b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
545b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
546d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
547b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
548b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 == NULL)
549d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
550b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
551d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
552b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
553b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
554b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ANCESTOR:
555b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* TODO: implement coalescing of ANCESTOR/NODE ops */
556b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL) {
557b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    i++;
558b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    step = &comp->steps[i];
559b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->op == XML_OP_ROOT)
560d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto found;
561b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->op != XML_OP_ELEM)
562d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
563b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value == NULL)
564b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(-1);
565b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
566b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
567d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
568b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
569b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE) ||
570b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
571b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
572b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
573b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_NAMESPACE_DECL))
574d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
575b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		node = node->parent;
576b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		while (node != NULL) {
577b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (node == NULL)
578d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
579b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if ((node->type == XML_ELEMENT_NODE) &&
580b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			(step->value[0] == node->name[0]) &&
581b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			(xmlStrEqual(step->value, node->name))) {
582b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			/* Namespace test */
583b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			if (node->ns == NULL) {
584b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    if (step->value2 == NULL)
585b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				break;
586b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			} else if (node->ns->href != NULL) {
587b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    if ((step->value2 != NULL) &&
588b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			        (xmlStrEqual(step->value2, node->ns->href)))
589b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				break;
590b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			}
591b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
592b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    node = node->parent;
593b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
594b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
595d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
596d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		/*
597d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		 * prepare a potential rollback from here
598d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		 * for ancestors of that node.
599d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		 */
600d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		if (step->op == XML_OP_ANCESTOR)
601d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    xmlPatPushState(&states, i, node);
602d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		else
603d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    xmlPatPushState(&states, i - 1, node);
604b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
605b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_NS:
606b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
607d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
608b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
609b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value != NULL)
610d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
611b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
612b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value == NULL)
613d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
614b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value, node->ns->href))
615d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
616b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
617b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		break;
618b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ALL:
619b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
620d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
621b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		break;
622b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
623b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
624d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardfound:
625d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    if (states.states != NULL) {
626d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard        /* Free the rollback states */
627d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	xmlFree(states.states);
628d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    }
629b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(1);
630d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardrollback:
631d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    /* got an error try to rollback */
632d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    if (states.states == NULL)
633d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	return(0);
634d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    if (states.nbstates <= 0) {
635d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	xmlFree(states.states);
636d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	return(0);
637d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    }
638d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    states.nbstates--;
639d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    i = states.states[states.nbstates].step;
640d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    node = states.states[states.nbstates].node;
641d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#if 0
642d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    fprintf(stderr, "Pop: %d, %s\n", i, node->name);
643d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#endif
644d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    goto restart;
645b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
646b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
647b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
648b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
649b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *			Dedicated parser for templates			*
650b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
651b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
652b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
653b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define TODO 								\
654b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
655b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
656b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            __FILE__, __LINE__);
657b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR (*ctxt->cur)
658b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP(val) ctxt->cur += (val)
659b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NXT(val) ctxt->cur[(val)]
660b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR_PTR ctxt->cur
661b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
662b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP_BLANKS 							\
663427174fbf2544b44071c1039720e6634fb154f84Daniel Veillard    while (IS_BLANK_CH(CUR)) NEXT
664b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
665b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CURRENT (*ctxt->cur)
666b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
667b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
668b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
669b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define PUSH(op, val, val2) 						\
670b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
671b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
672b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR(X)							\
673b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    { xsltError(ctxt, __FILE__, __LINE__, X);			\
674b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard      ctxt->error = (X); return; }
675b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
676b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR0(X)							\
677b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    { xsltError(ctxt, __FILE__, __LINE__, X);			\
678b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard      ctxt->error = (X); return(0); }
679b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
680b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
681b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
682b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanLiteral:
683b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
684b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
685b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse an XPath Litteral:
686b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
687b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [29] Literal ::= '"' [^"]* '"'
688b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *                | "'" [^']* "'"
689b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
690b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Literal parsed or NULL
691b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
692b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
693b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
694b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
695b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
696b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
697b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
698b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
699b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
700b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '"') {
701b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        NEXT;
702b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = q = CUR_PTR;
703b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
704b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while ((IS_CHAR(val)) && (val != '"')) {
705b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    cur += len;
706b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    val = xmlStringCurrentChar(NULL, cur, &len);
707b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
708b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (!IS_CHAR(val)) {
709b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
710b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return(NULL);
711b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
712b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ret = xmlStrndup(q, cur - q);
713b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        }
714b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
715b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	CUR_PTR = cur;
716b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if (CUR == '\'') {
717b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        NEXT;
718b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = q = CUR_PTR;
719b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
720b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while ((IS_CHAR(val)) && (val != '\'')) {
721b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    cur += len;
722b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    val = xmlStringCurrentChar(NULL, cur, &len);
723b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
724b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (!IS_CHAR(val)) {
725b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
726b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return(NULL);
727b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
728b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ret = xmlStrndup(q, cur - q);
729b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        }
730b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
731b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	CUR_PTR = cur;
732b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
733b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/* XP_ERROR(XPATH_START_LITERAL_ERROR); */
734b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ctxt->error = 1;
735b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
736b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
737b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
738b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
739b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
740b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
741b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
742b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanName:
743b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
744b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
745b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |
746b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *                  CombiningChar | Extender
747b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
748b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5] Name ::= (Letter | '_' | ':') (NameChar)*
749b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
750b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [6] Names ::= Name (S Name)*
751b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
752b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
753b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
754b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
755b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
756b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanName(xmlPatParserContextPtr ctxt) {
757b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
758b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
759b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
760b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
761b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
762b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
763b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = q = CUR_PTR;
764b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    val = xmlStringCurrentChar(NULL, cur, &len);
765b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (!IS_LETTER(val) && (val != '_') && (val != ':'))
766b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
767b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
768b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
769b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard           (val == '.') || (val == '-') ||
770b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (val == '_') ||
771b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_COMBINING(val)) ||
772b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_EXTENDER(val))) {
773b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
774b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
775b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
776b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlStrndup(q, cur - q);
777b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    CUR_PTR = cur;
778b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
779b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
780b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
781b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
782b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanNCName:
783b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
784b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
785b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parses a non qualified name
786b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
787b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
788b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
789b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
790b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
791b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanNCName(xmlPatParserContextPtr ctxt) {
792b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
793b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
794b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
795b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
796b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
797b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
798b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = q = CUR_PTR;
799b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    val = xmlStringCurrentChar(NULL, cur, &len);
800b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (!IS_LETTER(val) && (val != '_'))
801b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
802b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
803b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
804b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard           (val == '.') || (val == '-') ||
805b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (val == '_') ||
806b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_COMBINING(val)) ||
807b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_EXTENDER(val))) {
808b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
809b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
810b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
811b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlStrndup(q, cur - q);
812b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    CUR_PTR = cur;
813b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
814b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
815b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
816b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
817b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
818b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanQName:
819b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
820b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @prefix:  the place to store the prefix
821b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
822b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse a qualified name
823b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
824b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
825b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
826b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
827b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
828b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) {
829b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
830b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
831b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    *prefix = NULL;
832b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlPatScanNCName(ctxt);
833b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == ':') {
834b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        *prefix = ret;
835b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
836b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ret = xmlPatScanNCName(ctxt);
837b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
838b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
839b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
840b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
841b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
842b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
843b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompileStepPattern:
844b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the compilation context
845b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
846b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Step Pattern and generates a precompiled
847b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching.
848b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
849b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [3]    Step    ::=    '.' | NameTest
850b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [4]    NameTest    ::=    QName | '*' | NCName ':' '*'
851b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
852b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
853b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
854b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
855b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *token = NULL;
856b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *name = NULL;
857b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *URI = NULL;
858b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *URL = NULL;
859b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
860b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
861b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '.') {
862b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
863b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ELEM, NULL, NULL);
864b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
865b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
866b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    name = xmlPatScanNCName(ctxt);
867b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (name == NULL) {
868b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (CUR == '*') {
869b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    NEXT;
870b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    PUSH(XML_OP_ALL, NULL, NULL);
871b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return;
872b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
873b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ERROR(NULL, NULL, NULL,
874b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    "xmlCompileStepPattern : Name expected\n");
875b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
876b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return;
877b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
878b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
879b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
880b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == ':') {
881b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
882b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (CUR != ':') {
883b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlChar *prefix = name;
884d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	    int i;
885b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
886b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    /*
887b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	     * This is a namespace match
888b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	     */
889b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    token = xmlPatScanName(ctxt);
890d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	    for (i = 0;i < ctxt->nb_namespaces;i++) {
891d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	        if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
8920996a162c90716627b8b3bfec71fa941357d1acaDaniel Veillard		    URL = xmlStrdup(ctxt->namespaces[2 * i]);
893d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    break;
894d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		}
895d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	    }
896d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	    if (i >= ctxt->nb_namespaces) {
897b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ERROR5(NULL, NULL, NULL,
898b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    "xmlCompileStepPattern : no namespace bound to prefix %s\n",
899b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				 prefix);
900b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ctxt->error = 1;
901b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		goto error;
902b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
903b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree(prefix);
904b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (token == NULL) {
905b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (CUR == '*') {
906b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    NEXT;
907b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    PUSH(XML_OP_NS, URL, NULL);
908b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
909b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ERROR(NULL, NULL, NULL,
910b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : Name expected\n");
911b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
912b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
913b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
914b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
915b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_ELEM, token, URL);
916b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
917b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
918b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    NEXT;
919b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (xmlStrEqual(token, (const xmlChar *) "child")) {
920b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlFree(token);
921b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		token = xmlPatScanName(ctxt);
922b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
923b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	            if (CUR == '*') {
924b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            	        NEXT;
925b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	                PUSH(XML_OP_ALL, token, NULL);
926b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	                return;
927b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	            } else {
928b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        ERROR(NULL, NULL, NULL,
929b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : QName expected\n");
930b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        ctxt->error = 1;
931b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        goto error;
932b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
933b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
934b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		TODO
935b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* URI = xsltGetQNameURI(ctxt->elem, &token); */
936b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
937b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
938b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
939b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
940b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    name = xmlStrdup(token);
941b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (URI != NULL)
942b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			URL = xmlStrdup(URI);
943b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
944b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_CHILD, name, URL);
945b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else if (xmlStrEqual(token, (const xmlChar *) "attribute")) {
946b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlFree(token);
947b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		token = xmlPatScanName(ctxt);
948b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
949b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ERROR(NULL, NULL, NULL,
950b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : QName expected\n");
951b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
952b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
953b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
954b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		TODO
955b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* URI = xsltGetQNameURI(ctxt->elem, &token); */
956b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
957b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
958b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
959b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
960b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    name = xmlStrdup(token);
961b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (URI != NULL)
962b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			URL = xmlStrdup(URI);
963b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
964b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_ATTR, name, URL);
965b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
966b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ERROR(NULL, NULL, NULL,
967b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    "xmlCompileStepPattern : 'child' or 'attribute' expected\n");
968b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ctxt->error = 1;
969b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		goto error;
970b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
971b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree(token);
972b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
973b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if (CUR == '*') {
974b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
975b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ALL, token, NULL);
976b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
977b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (name == NULL) {
978b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
979b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    goto error;
980b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
981b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ELEM, name, NULL);
982b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
983b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return;
984b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
985b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (token != NULL)
986b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree(token);
987b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (name != NULL)
988b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree(name);
989b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
990b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
991b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
992b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompilePathPattern:
993b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the compilation context
994b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
995b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Path Pattern and generates a precompiled
996b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching.
997b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
998b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )
999b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
1000b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
1001b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
1002b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
1003b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((CUR == '/') && (NXT(1) == '/')) {
1004b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/*
1005b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * since we reverse the query
1006b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * a leading // can be safely ignored
1007b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 */
1008b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1009b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1010b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {
1011b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/*
1012b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * a leading .// can be safely ignored
1013b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 */
1014b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1015b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1016b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1017b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
1018b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '@') {
1019b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	TODO
1020b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
10212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (CUR == '/') {
10222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    PUSH(XML_OP_ROOT, NULL, NULL);
10232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    NEXT;
10242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
1025b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlCompileStepPattern(ctxt);
1026b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	SKIP_BLANKS;
1027b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while (CUR == '/') {
1028b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if ((CUR == '/') && (NXT(1) == '/')) {
1029b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	        PUSH(XML_OP_ANCESTOR, NULL, NULL);
1030b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
1031b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
1032b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		SKIP_BLANKS;
1033b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlCompileStepPattern(ctxt);
1034b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
1035b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	        PUSH(XML_OP_PARENT, NULL, NULL);
1036b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
1037b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		SKIP_BLANKS;
1038b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((CUR != 0) || (CUR == '|')) {
1039b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    xmlCompileStepPattern(ctxt);
1040b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
1041b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
1042b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
1043b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
1044b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
1045b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return;
1046b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
10472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/************************************************************************
10492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *									*
10502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *			The streaming code				*
10512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *									*
10522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ************************************************************************/
10532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING
10552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
10562fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamComp(xmlStreamCompPtr stream) {
10572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
10582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL) {
10602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("Stream: NULL\n");
10612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return;
10622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    printf("Stream: %d steps\n", stream->nbStep);
10642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < stream->nbStep;i++) {
10652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].ns != NULL) {
10662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("{%s}", stream->steps[i].ns);
10672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
10682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (stream->steps[i].name == NULL) {
10692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("* ");
10702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	} else {
10712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("%s ", stream->steps[i].name);
10722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
10732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_ROOT)
10742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("root ");
10752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_DESC)
10762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("// ");
10772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_FINAL)
10782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("final ");
10792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	printf("\n");
10802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
10822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
10832fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) {
10842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
10852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (ctxt == NULL) {
10872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("Stream: NULL\n");
10882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return;
10892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState);
10912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (match)
10922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("matches\n");
10932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    else
10942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("\n");
10952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < ctxt->nbState;i++) {
10962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (ctxt->states[2 * i] < 0)
10972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf(" %d: free\n", i);
10982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	else {
10992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf(" %d: step %d, level %d", i, ctxt->states[2 * i],
11002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	           ctxt->states[(2 * i) + 1]);
11012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard            if (ctxt->comp->steps[ctxt->states[2 * i]].flags &
11022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        XML_STREAM_STEP_DESC)
11032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        printf(" //\n");
11042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    else
11052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        printf("\n");
11062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
11072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
11082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
11092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif
11102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
11112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamComp:
11122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected steps
11132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new compiled pattern for streaming
11152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error.
11172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
11182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCompPtr
11192fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamComp(int size) {
11202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr cur;
11212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (size < 4)
11232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        size  = 4;
11242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp));
11262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur == NULL) {
11272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
11282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		"xmlNewStreamComp: malloc failed\n");
11292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
11302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
11312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    memset(cur, 0, sizeof(xmlStreamComp));
11322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep));
11332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur->steps == NULL) {
11342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlFree(cur);
11352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
11362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	      "xmlNewStreamComp: malloc failed\n");
11372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
11382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
11392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->nbStep = 0;
11402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->maxStep = size;
11412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(cur);
11422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
11432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
11452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamComp:
11462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming
11472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the compiled pattern for streaming
11492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
11502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
11512fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamComp(xmlStreamCompPtr comp) {
11522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp != NULL) {
11532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->steps != NULL)
11542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlFree(comp->steps);
11552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (comp->dict != NULL)
11562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlDictFree(comp->dict);
11572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFree(comp);
11582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
11592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
11602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
11622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompAddStep:
11632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming
11642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the first string, the name, or NULL for *
11652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the second step, the namespace name
11662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @flags: the flags for that step
11672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new step to the compiled pattern
11692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the step index if successful
11712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
11722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
11732fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name,
11742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard                     const xmlChar *ns, int flags) {
11752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamStepPtr cur;
11762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->nbStep >= comp->maxStep) {
11782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	cur = (xmlStreamStepPtr) xmlRealloc(comp->steps,
11792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard				 comp->maxStep * 2 * sizeof(xmlStreamStep));
11802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (cur == NULL) {
11812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    ERROR(NULL, NULL, NULL,
11822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		  "xmlNewStreamComp: malloc failed\n");
11832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(-1);
11842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
11852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	comp->steps = cur;
11862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        comp->maxStep *= 2;
11872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
11882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = &comp->steps[comp->nbStep++];
11892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->flags = flags;
11902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->name = name;
11912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->ns = ns;
11922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(comp->nbStep - 1);
11932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
11942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
11962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompile:
11972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern
11982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Tries to stream compile a pattern
12002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of failure and 0 in case of success.
12022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
12032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
12042fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompile(xmlPatternPtr comp) {
12052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr stream;
12062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i, s = 0, root = 0, desc = 0;
12072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((comp == NULL) || (comp->steps == NULL))
12092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
12102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    stream = xmlNewStreamComp((comp->nbStep / 2) + 1);
12112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL)
12122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
12132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->dict != NULL) {
12142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        stream->dict = comp->dict;
12152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlDictReference(stream->dict);
12162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < comp->nbStep;i++) {
12182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        switch (comp->steps[i].op) {
12192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_END:
12202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        break;
12212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ROOT:
12222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        if (i != 0)
12232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
12242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		root = 1;
12252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
12262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_CHILD:
12272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ATTR:
12282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_NS:
12292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        goto error;
12302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ELEM:
12312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        s = xmlStreamCompAddStep(stream, comp->steps[i].value,
12322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		                         comp->steps[i].value2, desc);
12332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		desc = 0;
12342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (s < 0)
12352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
12362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
12372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ALL:
12382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        s = xmlStreamCompAddStep(stream, NULL, NULL, desc);
12392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		desc = 0;
12402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (s < 0)
12412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
12422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
12432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_PARENT:
12442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        break;
12452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ANCESTOR:
12462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        desc = XML_STREAM_STEP_DESC;
12472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
12482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
12492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
12512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (root)
12522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	stream->steps[0].flags |= XML_STREAM_STEP_ROOT;
12532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING
12542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlDebugStreamComp(stream);
12552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif
12562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->stream = stream;
12572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
12582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillarderror:
12592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlFreeStreamComp(stream);
12602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
12612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
12622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
12642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamCtxt:
12652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected states
12662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new stream context
12682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error.
12702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
12712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCtxtPtr
12722fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamCtxt(xmlStreamCompPtr stream) {
12732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCtxtPtr cur;
12742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt));
12762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur == NULL) {
12772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
12782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		"xmlNewStreamCtxt: malloc failed\n");
12792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
12802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    memset(cur, 0, sizeof(xmlStreamCtxt));
12822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int));
12832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur->states == NULL) {
12842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlFree(cur);
12852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
12862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	      "xmlNewStreamCtxt: malloc failed\n");
12872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
12882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->nbState = 0;
12902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->maxState = 4;
12912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->level = 0;
12922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->comp = stream;
12932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(cur);
12942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
12952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
12972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamCtxt:
12982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
12992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the stream context
13012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
13022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardvoid
13032fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamCtxt(xmlStreamCtxtPtr stream) {
13042b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    xmlStreamCtxtPtr next;
13052b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard
13062b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    while (stream != NULL) {
13072b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard        next = stream->next;
13082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (stream->states != NULL)
13092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlFree(stream->states);
13102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFree(stream);
13112b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard	stream = next;
13122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
13132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
13142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
13162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCtxtAddState:
13172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the stream context
13182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @idx: the step index for that streaming state
13192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new state to the stream context
13212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the state index if successful
13232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
13242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
13252fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) {
13262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
13272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < comp->nbState;i++) {
13282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->states[2 * i] < 0) {
13292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    comp->states[2 * i] = idx;
13302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    comp->states[2 * i + 1] = level;
13312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(i);
13322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
13332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
13342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->nbState >= comp->maxState) {
13352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        int *cur;
13362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	cur = (int *) xmlRealloc(comp->states,
13382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard				 comp->maxState * 4 * sizeof(int));
13392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (cur == NULL) {
13402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    ERROR(NULL, NULL, NULL,
13412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		  "xmlNewStreamCtxt: malloc failed\n");
13422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(-1);
13432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
13442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	comp->states = cur;
13452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        comp->maxState *= 2;
13462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
13472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->states[2 * comp->nbState] = idx;
13482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->states[2 * comp->nbState++ + 1] = level;
13492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(comp->nbState - 1);
13502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
13512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
13532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamPush:
13542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
13552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the current name
13562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the namespace name
13572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * push new data onto the stream. NOTE: if the call xmlPatterncompile()
13592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * indicated a dictionnary, then strings for name and ns will be expected
13602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * to come from the dictionary.
13612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Both @name and @ns being NULL means the / i.e. the root of the document.
13622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * This can also act as a reset.
13632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 1 if the current state in the stream is a
13652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *    match and 0 otherwise.
13662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
13672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardint
13682fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamPush(xmlStreamCtxtPtr stream,
13692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard              const xmlChar *name, const xmlChar *ns) {
1370f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    int ret = 0, err = 0, tmp, i, m, match, step, desc, final;
13712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr comp;
13722b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#ifdef DEBUG_STREAMING
13732b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    xmlStreamCtxtPtr orig = stream;
13742b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#endif
13752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((stream == NULL) || (stream->nbState < 0))
13772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
1378f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1379f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (stream != NULL) {
1380f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	comp = stream->comp;
1381f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if ((name == NULL) && (ns == NULL)) {
1382f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    stream->nbState = 0;
1383f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    stream->level = 0;
1384f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
1385f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		tmp = xmlStreamCtxtAddState(stream, 0, 0);
1386f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (tmp < 0)
1387f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    err++;
1388f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (comp->steps[tmp].flags & XML_STREAM_STEP_FINAL)
1389f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    ret = 1;
13902b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard		stream = stream->next;
1391f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		continue; /* while */
13922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
13932b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard	    stream = stream->next;
1394f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    continue; /* while */
13952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
1396f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	/*
1397f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 * Check evolution of existing states
1398f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 */
1399f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	m = stream->nbState;
1400f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	for (i = 0;i < m;i++) {
1401f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    match = 0;
1402f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    step = stream->states[2 * i];
1403f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    /* dead states */
1404f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (step < 0) continue;
1405f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    /* skip new states just added */
1406f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (stream->states[(2 * i) + 1] > stream->level)
1407f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	        continue;
1408f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    /* skip continuations */
1409f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    desc = comp->steps[step].flags & XML_STREAM_STEP_DESC;
1410f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if ((stream->states[(2 * i) + 1] < stream->level) && (!desc))
1411f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	        continue;
1412f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1413f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    /* discard old states */
1414f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    /* something needed about old level discarded */
1415f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1416f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (comp->dict) {
1417f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (comp->steps[step].name == NULL) {
1418f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (comp->steps[step].ns == NULL)
1419f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = 1;
1420f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    else
1421f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = (comp->steps[step].ns == ns);
14222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		} else {
1423f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    match = ((comp->steps[step].name == name) &&
1424f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			     (comp->steps[step].ns == ns));
14252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		}
14262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    } else {
1427f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (comp->steps[step].name == NULL) {
1428f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (comp->steps[step].ns == NULL)
1429f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = 1;
1430f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    else
1431f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = xmlStrEqual(comp->steps[step].ns, ns);
14322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		} else {
1433f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    match = ((xmlStrEqual(comp->steps[step].name, name)) &&
1434f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			     (xmlStrEqual(comp->steps[step].ns, ns)));
1435f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		}
1436f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    }
1437f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (match) {
1438f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		final = comp->steps[step].flags & XML_STREAM_STEP_FINAL;
1439f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (desc) {
1440f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (final) {
1441f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			ret = 1;
1442f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    } else {
1443f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			/* descending match create a new state */
1444f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			xmlStreamCtxtAddState(stream, step + 1,
1445f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			                      stream->level + 1);
1446f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    }
1447f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		} else {
1448f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (final) {
1449f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			ret = 1;
1450f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    } else {
1451f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			xmlStreamCtxtAddState(stream, step + 1,
1452f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			                      stream->level + 1);
1453f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    }
14542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		}
14552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
14562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
14572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
1458f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	/*
1459f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 * Check creating a new state.
1460f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 */
1461f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	stream->level++;
1462f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (!(comp->steps[0].flags & XML_STREAM_STEP_ROOT)) {
1463f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    match = 0;
1464f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (comp->dict) {
1465f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (comp->steps[0].name == NULL) {
1466f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (comp->steps[0].ns == NULL)
1467f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = 1;
1468f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    else
1469f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = (comp->steps[0].ns == ns);
1470f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		} else {
1471f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    match = ((comp->steps[0].name == name) &&
1472f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			     (comp->steps[0].ns == ns));
1473f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		}
14742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    } else {
1475f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (comp->steps[0].name == NULL) {
1476f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (comp->steps[0].ns == NULL)
1477f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = 1;
1478f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    else
1479f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = xmlStrEqual(comp->steps[0].ns, ns);
1480f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		} else {
1481f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    match = ((xmlStrEqual(comp->steps[0].name, name)) &&
1482f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			     (xmlStrEqual(comp->steps[0].ns, ns)));
1483f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		}
14842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
1485f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (match) {
1486f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (comp->steps[0].flags & XML_STREAM_STEP_FINAL)
1487f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    ret = 1;
14882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		else
1489f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    xmlStreamCtxtAddState(stream, 1, stream->level);
14902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
14912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
1492f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1493f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        stream = stream->next;
1494f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    } /* while stream != NULL */
14952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
1496f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    if (err > 0)
1497f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        ret = -1;
14982b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#ifdef DEBUG_STREAMING
14992b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    xmlDebugStreamCtxt(orig, ret);
15002b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#endif
15012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(ret);
15022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
15032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
15042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
15052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamPop:
15062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
15072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * push one level from the stream.
15092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 0 otherwise.
15112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
15122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardint
15132fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamPop(xmlStreamCtxtPtr stream) {
15149740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard    int i, m;
1515f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    int ret;
15169740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard
15172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL)
15182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
1519f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    ret = 0;
1520f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (stream != NULL) {
1521f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	stream->level--;
1522f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (stream->level < 0)
1523f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret = -1;
1524f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1525f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	/*
1526f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 * Check evolution of existing states
1527f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 */
1528f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	m = stream->nbState;
1529f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	for (i = 0;i < m;i++) {
1530f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (stream->states[(2 * i)] < 0) break;
1531f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    /* discard obsoleted states */
1532f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (stream->states[(2 * i) + 1] > stream->level)
1533f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		stream->states[(2 * i)] = -1;
1534f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
1535f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	stream = stream->next;
15369740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard    }
15372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
15382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
15392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
1540b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
1541b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
1542b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *			The public interfaces				*
1543b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
1544b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
1545b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1546b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
1547b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatterncompile:
1548b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern: the pattern to compile
1549b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @dict: an optional dictionnary for interned strings
1550b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @flags: compilation flags, undefined yet
1551ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
1552b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1553ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * Compile a pattern.
1554b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1555b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the compiled for of the pattern or NULL in case of error
1556b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
1557b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternPtr
1558427174fbf2544b44071c1039720e6634fb154f84Daniel VeillardxmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
1559427174fbf2544b44071c1039720e6634fb154f84Daniel Veillard                  int flags ATTRIBUTE_UNUSED,
1560ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard                  const xmlChar **namespaces) {
1561f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    xmlPatternPtr ret = NULL, cur;
1562b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatParserContextPtr ctxt = NULL;
1563f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    const xmlChar *or, *start;
1564f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    xmlChar *tmp = NULL;
1565f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1566f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    if (pattern == NULL)
1567f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        return(NULL);
1568f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1569f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    start = pattern;
15702b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    or = start;
1571f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (*or != 0) {
1572f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	tmp = NULL;
1573f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	while ((*or != 0) && (*or != '|')) or++;
1574f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        if (*or == 0)
1575f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ctxt = xmlNewPatParserContext(start, dict, namespaces);
1576f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	else {
1577f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    tmp = xmlStrndup(start, or - start);
1578f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (tmp != NULL) {
1579f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		ctxt = xmlNewPatParserContext(tmp, dict, namespaces);
1580f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    }
1581f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    or++;
1582f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
1583f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (ctxt == NULL) goto error;
1584f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	cur = xmlNewPattern();
1585f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (cur == NULL) goto error;
1586f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (ret == NULL)
1587f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret = cur;
1588f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	else {
1589f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    cur->next = ret->next;
1590f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret->next = cur;
1591f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
1592f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	ctxt->comp = cur;
1593b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1594f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	xmlCompilePathPattern(ctxt);
1595f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	xmlFreePatParserContext(ctxt);
1596b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1597b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1598f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	xmlStreamCompile(cur);
1599f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (xmlReversePattern(cur) < 0)
1600f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    goto error;
1601f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (tmp != NULL) {
1602f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    xmlFree(tmp);
1603f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    tmp = NULL;
1604f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
16052b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard	start = or;
1606f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    }
1607b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
1608b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
1609b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt != NULL) xmlFreePatParserContext(ctxt);
1610b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ret != NULL) xmlFreePattern(ret);
1611f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    if (tmp != NULL) xmlFree(tmp);
1612b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(NULL);
1613b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
1614b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1615b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
1616b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternMatch:
1617b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern
1618b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node
1619b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1620b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Test wether the node matches the pattern
1621b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1622b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
1623b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
1624b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardint
1625b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
1626b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{
1627f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    int ret = 0;
1628f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1629b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((comp == NULL) || (node == NULL))
1630b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return(-1);
1631f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1632f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (comp != NULL) {
1633f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        ret = xmlPatMatch(comp, node);
1634f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (ret != 0)
1635f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    return(ret);
1636f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	comp = comp->next;
1637f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    }
1638f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    return(ret);
1639b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
1640b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
16412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
16422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlPatternGetStreamCtxt:
16432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern
16442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
16452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Get a streaming context for that pattern
16462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Use xmlFreeStreamCtxt to free the context.
16472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
16482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns a pointer to the context or NULL in case of failure
16492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
16502fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtPtr
16512fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlPatternGetStreamCtxt(xmlPatternPtr comp)
16522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard{
1653f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    xmlStreamCtxtPtr ret = NULL, cur;
1654f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
16552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((comp == NULL) || (comp->stream == NULL))
16562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(NULL);
1657f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1658f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (comp != NULL) {
1659f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        if (comp->stream == NULL)
1660f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    goto failed;
1661f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	cur = xmlNewStreamCtxt(comp->stream);
1662f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (cur == NULL)
1663f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    goto failed;
1664f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (ret == NULL)
1665f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret = cur;
1666f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	else {
1667f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    cur->next = ret->next;
1668f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret->next = cur;
1669f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
1670f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	comp = comp->next;
1671f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    }
1672f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    return(ret);
1673f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillardfailed:
1674f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    xmlFreeStreamCtxt(ret);
1675f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    return(NULL);
16762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
16772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
1678b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif /* LIBXML_PATTERN_ENABLED */
1679