pattern.c revision 627e9a934b692768f1d2715a9429315e0b04b94e
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
482a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik#define XML_STREAM_STEP_ATTR	8
492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
509ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik/*
519ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik* TODO: This is used on _xmlStreamCtxt, so don't use any values
529ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik* from xmlPatternFlags.
539ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik*/
549ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik#define XML_STREAM_DESC 1<<16
559ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
56ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack#define XML_PATTERN_NOTPATTERN  (XML_PATTERN_XPATH | \
57ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack				 XML_PATTERN_XSSEL | \
58ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack				 XML_PATTERN_XSFIELD)
599ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
609ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik#define XML_STREAM_XS_IDC(item) (item->flags & \
619ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik    (XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD))
62285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik
632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef struct _xmlStreamStep xmlStreamStep;
642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef xmlStreamStep *xmlStreamStepPtr;
652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamStep {
662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int flags;			/* properties of that step */
672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    const xmlChar *name;	/* first string value if NULL accept all */
682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    const xmlChar *ns;		/* second string value */
692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef struct _xmlStreamComp xmlStreamComp;
722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef xmlStreamComp *xmlStreamCompPtr;
732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamComp {
74fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack    xmlDict *dict;		/* the dictionary if any */
752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int nbStep;			/* number of steps in the automata */
762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int maxStep;		/* allocated number of steps */
772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamStepPtr steps;	/* the array of steps */
789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik    int flags;
792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamCtxt {
82f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    struct _xmlStreamCtxt *next;/* link to next sub pattern if | */
832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr comp;	/* the compiled stream */
84fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack    int nbState;		/* number of states in the automata */
85fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack    int maxState;		/* allocated number of states */
862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int level;			/* how deep are we ? */
872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int *states;		/* the array of step indexes */
88285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik    int flags;			/* validation options */
899ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik    int blockLevel;
902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void xmlFreeStreamComp(xmlStreamCompPtr comp);
932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
94b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/*
95b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Types are private:
96b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
97b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
98b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef enum {
99b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_END=0,
100b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ROOT,
101b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ELEM,
102b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_CHILD,
103b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ATTR,
104b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_PARENT,
105b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ANCESTOR,
106b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_NS,
107b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ALL
108b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} xmlPatOp;
109b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
110b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
111d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef struct _xmlStepState xmlStepState;
112d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef xmlStepState *xmlStepStatePtr;
113d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstruct _xmlStepState {
114d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    int step;
115d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    xmlNodePtr node;
116d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard};
117d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard
118d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef struct _xmlStepStates xmlStepStates;
119d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef xmlStepStates *xmlStepStatesPtr;
120d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstruct _xmlStepStates {
121d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    int nbstates;
122d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    int maxstates;
123d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    xmlStepStatePtr states;
124d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard};
125d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard
126b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlStepOp xmlStepOp;
127b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlStepOp *xmlStepOpPtr;
128b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlStepOp {
129b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatOp op;
130b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *value;
131b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *value2;
132b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
133b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
134ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack#define PAT_FROM_ROOT	(1<<8)
135ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack#define PAT_FROM_CUR	(1<<9)
13656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
137b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPattern {
138b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    void *data;    		/* the associated template */
139fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack    xmlDictPtr dict;		/* the optional dictionary */
140f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    struct _xmlPattern *next;	/* next pattern if | is used */
141b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *pattern;	/* the pattern */
142ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack    xmlPatternFlags flags;	/* flags */
143b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int nbStep;
144b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int maxStep;
145c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    xmlStepOpPtr steps;        /* ops for computation */
1462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr stream;	/* the streaming data if any */
147b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
148b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
149b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlPatParserContext xmlPatParserContext;
150b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlPatParserContext *xmlPatParserContextPtr;
151b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPatParserContext {
152b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *cur;			/* the current char being parsed */
153b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *base;		/* the full expression */
154b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int	           error;		/* error code */
155fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack    xmlDictPtr     dict;		/* the dictionary if any */
156b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr  comp;		/* the result */
157b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlNodePtr     elem;		/* the current node if any */
158ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    const xmlChar **namespaces;		/* the namespaces definitions */
159ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    int   nb_namespaces;		/* the number of namespaces */
160b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
161b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
162b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
163b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
164b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 			Type functions 					*
165b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
166b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
167b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
168b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
169b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPattern:
170b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
171b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XSLT Pattern
172b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
173b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatternPtr or NULL in case of error
174b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
175b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatternPtr
176b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlNewPattern(void) {
177b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr cur;
178b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
179b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));
180b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (cur == NULL) {
181b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ERROR(NULL, NULL, NULL,
182b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		"xmlNewPattern : malloc failed\n");
183b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
184b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
185b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(cur, 0, sizeof(xmlPattern));
186b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->maxStep = 10;
187c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    cur->steps = (xmlStepOpPtr) xmlMalloc(cur->maxStep * sizeof(xmlStepOp));
188c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (cur->steps == NULL) {
189c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlFree(cur);
190c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	ERROR(NULL, NULL, NULL,
191c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard		"xmlNewPattern : malloc failed\n");
192c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	return(NULL);
193c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    }
194b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(cur);
195b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
196b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
197b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
198b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePattern:
199b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  an XSLT comp
200b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
201b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @comp
202b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
203b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid
204b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePattern(xmlPatternPtr comp) {
205b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOpPtr op;
206b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
207b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
208b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp == NULL)
209b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
210f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    if (comp->next != NULL)
211f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        xmlFreePattern(comp->next);
2122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->stream != NULL)
2132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFreeStreamComp(comp->stream);
214b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp->pattern != NULL)
215b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree((xmlChar *)comp->pattern);
216c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->steps != NULL) {
2172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->dict == NULL) {
2182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    for (i = 0;i < comp->nbStep;i++) {
2192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		op = &comp->steps[i];
2202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (op->value != NULL)
2212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    xmlFree((xmlChar *) op->value);
2222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (op->value2 != NULL)
2232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    xmlFree((xmlChar *) op->value2);
2242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
225c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
226c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	xmlFree(comp->steps);
227b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
2282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->dict != NULL)
2292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlDictFree(comp->dict);
2302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
231b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(comp, -1, sizeof(xmlPattern));
232b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFree(comp);
233b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
234b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
235b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
236b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatternList:
237b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  an XSLT comp list
238b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
239b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by all the elements of @comp
240b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
241b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid
242b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatternList(xmlPatternPtr comp) {
243b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr cur;
244b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
245b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (comp != NULL) {
246b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = comp;
247b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp = comp->next;
248fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	cur->next = NULL;
249b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFreePattern(cur);
250b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
251b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
252b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
253b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
254b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPatParserContext:
255b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern:  the pattern context
256fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * @dict:  the inherited dictionary or NULL
2572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] terminated
2582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *              with [NULL, NULL] or NULL if no namespace is used
259b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
260b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XML pattern parser context
261b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
262b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error
263b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
264b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatParserContextPtr
265ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel VeillardxmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict,
266ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard                       const xmlChar **namespaces) {
267b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatParserContextPtr cur;
268b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
269b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (pattern == NULL)
270b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return(NULL);
271b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
272b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));
273b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (cur == NULL) {
274b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ERROR(NULL, NULL, NULL,
275b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		"xmlNewPatParserContext : malloc failed\n");
276b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
277b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
278b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(cur, 0, sizeof(xmlPatParserContext));
279b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->dict = dict;
280b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->cur = pattern;
281b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->base = pattern;
282ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    if (namespaces != NULL) {
283ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        int i;
284ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard	for (i = 0;namespaces[2 * i] != NULL;i++);
285ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        cur->nb_namespaces = i;
286ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    } else {
287ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        cur->nb_namespaces = 0;
288ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    }
289ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    cur->namespaces = namespaces;
290b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(cur);
291b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
292b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
293b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
294b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatParserContext:
295b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  an XSLT parser context
296b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
297b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @ctxt
298b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
299b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
300b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
301b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt == NULL)
302b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
303b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(ctxt, -1, sizeof(xmlPatParserContext));
304b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFree(ctxt);
305b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
306b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
307b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
308b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternAdd:
309b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
310b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @op:  an op
311b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value:  the first value
312b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value2:  the second value
313b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
314fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Add a step to an XSLT Compiled Match
315b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
316b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns -1 in case of failure, 0 otherwise.
317b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
318b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int
319b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
320b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                xmlPatternPtr comp,
321b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                xmlPatOp op, xmlChar * value, xmlChar * value2)
322b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{
323c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->nbStep >= comp->maxStep) {
324c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlStepOpPtr temp;
325c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
326c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	                                 sizeof(xmlStepOp));
327c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        if (temp == NULL) {
328c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    ERROR(ctxt, NULL, NULL,
329c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard			     "xmlPatternAdd: realloc failed\n");
330c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    return (-1);
331c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
332c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->steps = temp;
333c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->maxStep *= 2;
334b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
335b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].op = op;
336b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].value = value;
337b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].value2 = value2;
338b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->nbStep++;
339b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return (0);
340b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
341b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
342b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
343b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
344b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xsltSwapTopPattern:
345b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
346b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
347b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse the two top steps.
348b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
349b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
350b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxsltSwapTopPattern(xmlPatternPtr comp) {
351b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
352b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int j = comp->nbStep - 1;
353b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
354b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (j > 0) {
355b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register const xmlChar *tmp;
356b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register xmlPatOp op;
357b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	i = j - 1;
358b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value;
359b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value = comp->steps[j].value;
360b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value = tmp;
361b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value2;
362b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value2 = comp->steps[j].value2;
363b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value2 = tmp;
364b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = comp->steps[i].op;
365b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].op = comp->steps[j].op;
366b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].op = op;
367b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
368b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
369b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
370b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
371b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
372b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlReversePattern:
373b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
374b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
375b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse all the stack of expressions
376c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard *
377c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard * returns 0 in case of success and -1 in case of error.
378b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
379c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillardstatic int
380b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlReversePattern(xmlPatternPtr comp) {
38156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    int i, j;
38256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
38356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    /*
38456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     * remove the leading // for //a or .//a
38556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     */
38656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if ((comp->nbStep > 0) && (comp->steps[0].op == XML_OP_ANCESTOR)) {
38756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        for (i = 0, j = 1;j < comp->nbStep;i++,j++) {
38856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp->steps[i].value = comp->steps[j].value;
38956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp->steps[i].value2 = comp->steps[j].value2;
39056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    comp->steps[i].op = comp->steps[j].op;
39156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	}
39256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	comp->nbStep--;
39356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
394c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->nbStep >= comp->maxStep) {
395c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlStepOpPtr temp;
396c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
397c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	                                 sizeof(xmlStepOp));
398c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        if (temp == NULL) {
399c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    ERROR(ctxt, NULL, NULL,
400c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard			     "xmlReversePattern: realloc failed\n");
401c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    return (-1);
402c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
403c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->steps = temp;
404c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->maxStep *= 2;
405c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    }
40656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    i = 0;
40756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    j = comp->nbStep - 1;
408b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (j > i) {
409b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register const xmlChar *tmp;
410b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register xmlPatOp op;
411b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value;
412b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value = comp->steps[j].value;
413b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value = tmp;
414b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value2;
415b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value2 = comp->steps[j].value2;
416b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value2 = tmp;
417b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = comp->steps[i].op;
418b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].op = comp->steps[j].op;
419b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].op = op;
420b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	j--;
421b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	i++;
422b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
423c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    comp->steps[comp->nbStep].value = NULL;
424c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    comp->steps[comp->nbStep].value2 = NULL;
425b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep++].op = XML_OP_END;
426c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    return(0);
427b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
428b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
429b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
430b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
431b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 		The interpreter for the precompiled patterns		*
432b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
433b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
434b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
435d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstatic int
436d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel VeillardxmlPatPushState(xmlStepStates *states, int step, xmlNodePtr node) {
437d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    if ((states->states == NULL) || (states->maxstates <= 0)) {
438d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard        states->maxstates = 4;
439d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	states->nbstates = 0;
440d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	states->states = xmlMalloc(4 * sizeof(xmlStepState));
441d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    }
442d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    else if (states->maxstates <= states->nbstates) {
443d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard        xmlStepState *tmp;
444d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard
445d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	tmp = (xmlStepStatePtr) xmlRealloc(states->states,
446d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			       2 * states->maxstates * sizeof(xmlStepState));
447d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	if (tmp == NULL)
448d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	    return(-1);
449d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	states->states = tmp;
450d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	states->maxstates *= 2;
451d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    }
452d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    states->states[states->nbstates].step = step;
453d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    states->states[states->nbstates++].node = node;
454d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#if 0
455d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    fprintf(stderr, "Push: %d, %s\n", step, node->name);
456d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#endif
457d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    return(0);
458d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard}
459d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard
460b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
461b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatMatch:
462b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern
463b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node
464b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
465fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Test whether the node matches the pattern
466b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
467b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
468b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
469b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int
470b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
471b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
472b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOpPtr step;
473d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    xmlStepStates states = {0, 0, NULL}; /* // may require backtrack */
474b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
475b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((comp == NULL) || (node == NULL)) return(-1);
476d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    i = 0;
477d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardrestart:
478d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    for (;i < comp->nbStep;i++) {
479b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	step = &comp->steps[i];
480b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	switch (step->op) {
481b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_END:
482d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		goto found;
483b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ROOT:
4842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (node->type == XML_NAMESPACE_DECL)
485d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
4862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		node = node->parent;
487b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
488b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
489b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
490b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
491b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE))
492b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
493d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		goto rollback;
494b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ELEM:
495b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
496d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
497b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL)
498b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
499b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value[0] != node->name[0])
500d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
501b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (!xmlStrEqual(step->value, node->name))
502d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
503b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
504b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
505b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
506b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
507d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
508b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
509b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 == NULL)
510d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
511b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
512d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
513b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
514b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
515b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_CHILD: {
516b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlNodePtr lst;
517b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
518b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type != XML_ELEMENT_NODE) &&
519b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_DOCUMENT_NODE) &&
520b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
521b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_DOCB_DOCUMENT_NODE) &&
522b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
523b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_HTML_DOCUMENT_NODE))
524d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
525b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
526b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		lst = node->children;
527b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
528b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value != NULL) {
529b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    while (lst != NULL) {
530b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			if ((lst->type == XML_ELEMENT_NODE) &&
531b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    (step->value[0] == lst->name[0]) &&
532b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    (xmlStrEqual(step->value, lst->name)))
533b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    break;
534b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			lst = lst->next;
535b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
536b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (lst != NULL)
537b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			continue;
538b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
539d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		goto rollback;
540b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
541b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ATTR:
542b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ATTRIBUTE_NODE)
543d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
544b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value != NULL) {
545b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value[0] != node->name[0])
546d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
547b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value, node->name))
548d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
549b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
550b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
551b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
552b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
553d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
554b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (step->value2 != NULL) {
555b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
556d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
557b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
558b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
559b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_PARENT:
560b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
561b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE) ||
562b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
563b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
564b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
565b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_NAMESPACE_DECL))
566d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
567b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		node = node->parent;
568b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
569d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
570b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL)
571b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
572b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value[0] != node->name[0])
573d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
574b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (!xmlStrEqual(step->value, node->name))
575d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
576b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
577b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
578b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
579d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
580b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
581b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 == NULL)
582d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
583b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
584d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
585b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
586b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
587b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ANCESTOR:
588b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* TODO: implement coalescing of ANCESTOR/NODE ops */
589b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL) {
590b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    i++;
591b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    step = &comp->steps[i];
592b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->op == XML_OP_ROOT)
593d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto found;
594b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->op != XML_OP_ELEM)
595d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
596b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value == NULL)
597b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(-1);
598b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
599b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
600d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
601b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
602b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE) ||
603b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
604b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
605b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
606b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_NAMESPACE_DECL))
607d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
608b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		node = node->parent;
609b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		while (node != NULL) {
610b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (node == NULL)
611d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
612b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if ((node->type == XML_ELEMENT_NODE) &&
613b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			(step->value[0] == node->name[0]) &&
614b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			(xmlStrEqual(step->value, node->name))) {
615b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			/* Namespace test */
616b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			if (node->ns == NULL) {
617b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    if (step->value2 == NULL)
618b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				break;
619b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			} else if (node->ns->href != NULL) {
620b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    if ((step->value2 != NULL) &&
621b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			        (xmlStrEqual(step->value2, node->ns->href)))
622b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				break;
623b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			}
624b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
625b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    node = node->parent;
626b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
627b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
628d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
629d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		/*
630d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		 * prepare a potential rollback from here
631d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		 * for ancestors of that node.
632d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		 */
633d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		if (step->op == XML_OP_ANCESTOR)
634d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    xmlPatPushState(&states, i, node);
635d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		else
636d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    xmlPatPushState(&states, i - 1, node);
637b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
638b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_NS:
639b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
640d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
641b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
642b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value != NULL)
643d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
644b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
645b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value == NULL)
646d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
647b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value, node->ns->href))
648d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard			goto rollback;
649b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
650b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		break;
651b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ALL:
652b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
653d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		    goto rollback;
654b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		break;
655b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
656b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
657d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardfound:
658d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    if (states.states != NULL) {
659d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard        /* Free the rollback states */
660d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	xmlFree(states.states);
661d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    }
662b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(1);
663d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardrollback:
664d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    /* got an error try to rollback */
665d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    if (states.states == NULL)
666d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	return(0);
667d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    if (states.nbstates <= 0) {
668d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	xmlFree(states.states);
669d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	return(0);
670d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    }
671d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    states.nbstates--;
672d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    i = states.states[states.nbstates].step;
673d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    node = states.states[states.nbstates].node;
674d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#if 0
675d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    fprintf(stderr, "Pop: %d, %s\n", i, node->name);
676d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#endif
677d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard    goto restart;
678b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
679b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
680b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
681b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
682b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *			Dedicated parser for templates			*
683b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
684b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
685b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
686b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define TODO 								\
687b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
688b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
689b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            __FILE__, __LINE__);
690b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR (*ctxt->cur)
691b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP(val) ctxt->cur += (val)
692b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NXT(val) ctxt->cur[(val)]
693b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR_PTR ctxt->cur
694b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
695b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP_BLANKS 							\
696427174fbf2544b44071c1039720e6634fb154f84Daniel Veillard    while (IS_BLANK_CH(CUR)) NEXT
697b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
698b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CURRENT (*ctxt->cur)
699b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
700b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
701b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
702b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define PUSH(op, val, val2) 						\
703b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
704b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
705b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR(X)							\
706ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack    { xsltError(ctxt, __FILE__, __LINE__, X);				\
707b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard      ctxt->error = (X); return; }
708b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
709b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR0(X)							\
710ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack    { xsltError(ctxt, __FILE__, __LINE__, X);				\
711b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard      ctxt->error = (X); return(0); }
712b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
713b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
714b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
715b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanLiteral:
716b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
717b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
718b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse an XPath Litteral:
719b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
720b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [29] Literal ::= '"' [^"]* '"'
721b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *                | "'" [^']* "'"
722b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
723b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Literal parsed or NULL
724b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
725b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
726b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
727b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
728b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
729b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
730b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
731b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
732b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
733b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '"') {
734b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        NEXT;
735b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = q = CUR_PTR;
736b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
737b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while ((IS_CHAR(val)) && (val != '"')) {
738b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    cur += len;
739b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    val = xmlStringCurrentChar(NULL, cur, &len);
740b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
741b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (!IS_CHAR(val)) {
742b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
743b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return(NULL);
744b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
745b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ret = xmlStrndup(q, cur - q);
746b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        }
747b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
748b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	CUR_PTR = cur;
749b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if (CUR == '\'') {
750b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        NEXT;
751b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = q = CUR_PTR;
752b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
753b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while ((IS_CHAR(val)) && (val != '\'')) {
754b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    cur += len;
755b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    val = xmlStringCurrentChar(NULL, cur, &len);
756b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
757b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (!IS_CHAR(val)) {
758b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
759b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return(NULL);
760b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
761b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ret = xmlStrndup(q, cur - q);
762b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        }
763b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
764b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	CUR_PTR = cur;
765b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
766b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/* XP_ERROR(XPATH_START_LITERAL_ERROR); */
767b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ctxt->error = 1;
768b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
769b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
770b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
771b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
772b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
773b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
774b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
775b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanName:
776b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
777b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
778b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |
779b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *                  CombiningChar | Extender
780b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
781b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5] Name ::= (Letter | '_' | ':') (NameChar)*
782b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
783b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [6] Names ::= Name (S Name)*
784b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
785b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
786b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
787b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
788b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
789b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanName(xmlPatParserContextPtr ctxt) {
790b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
791b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
792b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
793b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
794b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
795b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
796b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = q = CUR_PTR;
797b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    val = xmlStringCurrentChar(NULL, cur, &len);
798b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (!IS_LETTER(val) && (val != '_') && (val != ':'))
799b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
800b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
801b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
802b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard           (val == '.') || (val == '-') ||
803b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (val == '_') ||
804b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_COMBINING(val)) ||
805b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_EXTENDER(val))) {
806b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
807b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
808b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
809b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlStrndup(q, cur - q);
810b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    CUR_PTR = cur;
811b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
812b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
813b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
814b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
815b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanNCName:
816b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
817b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
818b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parses a non qualified name
819b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
820b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
821b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
822b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
823b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
824b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanNCName(xmlPatParserContextPtr ctxt) {
825b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
826b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
827b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
828b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
829b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
830b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
831b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = q = CUR_PTR;
832b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    val = xmlStringCurrentChar(NULL, cur, &len);
833b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (!IS_LETTER(val) && (val != '_'))
834b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
835b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
836b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
837b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard           (val == '.') || (val == '-') ||
838b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (val == '_') ||
839b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_COMBINING(val)) ||
840b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_EXTENDER(val))) {
841b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
842b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
843b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
844b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlStrndup(q, cur - q);
845b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    CUR_PTR = cur;
846b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
847b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
848b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
849b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
850b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
851b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanQName:
852b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
853b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @prefix:  the place to store the prefix
854b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
855b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse a qualified name
856b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
857b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
858b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
859b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
860b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
861b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) {
862b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
863b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
864b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    *prefix = NULL;
865b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlPatScanNCName(ctxt);
866b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == ':') {
867b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        *prefix = ret;
868b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
869b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ret = xmlPatScanNCName(ctxt);
870b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
871b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
872b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
873b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
874b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
875b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
8762a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * xmlCompileAttributeTest:
8772a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @ctxt:  the compilation context
8782a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik *
8792a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Compile an attribute test.
8802a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */
8812a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikstatic void
8822a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlCompileAttributeTest(xmlPatParserContextPtr ctxt) {
8832a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    xmlChar *token = NULL;
8842a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    xmlChar *name = NULL;
8852a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    xmlChar *URL = NULL;
8862a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
8872a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    name = xmlPatScanNCName(ctxt);
8882a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    if (name == NULL) {
8892a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	if (CUR == '*') {
8902a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    PUSH(XML_OP_ATTR, NULL, NULL);
8919ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    NEXT;
8922a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	} else {
8932a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    ERROR(NULL, NULL, NULL,
8942a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		"xmlCompileAttributeTest : Name expected\n");
8952a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    ctxt->error = 1;
8962a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	}
8972a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	return;
8982a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    }
8992a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    if (CUR == ':') {
9002a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	int i;
9012a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	xmlChar *prefix = name;
9022a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
9032a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	NEXT;
9042a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	/*
9052a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	* This is a namespace match
9062a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	*/
9072a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	token = xmlPatScanName(ctxt);
908627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	if ((prefix[0] == 'x') &&
909627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    (prefix[1] == 'm') &&
910627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    (prefix[2] == 'l') &&
911627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    (prefix[3] == 0)) {
912627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    URL = xmlStrdup(XML_XML_NAMESPACE);
913627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	} else {
914627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    for (i = 0;i < ctxt->nb_namespaces;i++) {
915627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
916627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    URL = xmlStrdup(ctxt->namespaces[2 * i]);
917627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    break;
918627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		}
919627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    }
920627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    if (i >= ctxt->nb_namespaces) {
921627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		ERROR5(NULL, NULL, NULL,
922627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    "xmlCompileAttributeTest : no namespace bound to prefix %s\n",
923627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    prefix);
924627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		ctxt->error = 1;
925627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		goto error;
9262a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    }
9272a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	}
9282a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	xmlFree(prefix);
9292a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	if (token == NULL) {
9302a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    if (CUR == '*') {
9312a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		NEXT;
9322a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		PUSH(XML_OP_ATTR, NULL, URL);
9332a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    } else {
9342a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		ERROR(NULL, NULL, NULL,
9352a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    "xmlCompileAttributeTest : Name expected\n");
9362a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		ctxt->error = 1;
9372a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		goto error;
9382a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    }
9392a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	} else {
9402a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    PUSH(XML_OP_ATTR, token, URL);
9412a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	}
9422a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    } else {
9432a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	PUSH(XML_OP_ATTR, name, NULL);
9442a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    }
9452a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    return;
9462a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikerror:
9472a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    if (URL != NULL)
9482a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	xmlFree(URL);
9492a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    if (token != NULL)
9502a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	xmlFree(token);
9512a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik}
9522a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
9532a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
9542a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/**
955b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompileStepPattern:
956b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the compilation context
957b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
958b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Step Pattern and generates a precompiled
959b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching.
960b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
961b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [3]    Step    ::=    '.' | NameTest
962b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [4]    NameTest    ::=    QName | '*' | NCName ':' '*'
963b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
964b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
965b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
966b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
967b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *token = NULL;
968b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *name = NULL;
969b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *URL = NULL;
970b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
971b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
972b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '.') {
973b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
974b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ELEM, NULL, NULL);
975b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
976b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
977b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    name = xmlPatScanNCName(ctxt);
978b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (name == NULL) {
979b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (CUR == '*') {
980b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    NEXT;
981b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    PUSH(XML_OP_ALL, NULL, NULL);
982b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return;
9832a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	} else if (CUR == '@') {
9842a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    NEXT;
9852a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    xmlCompileAttributeTest(ctxt);
9862a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    if (ctxt->error != 0)
9872a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		goto error;
9882a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    return;
989b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
990b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ERROR(NULL, NULL, NULL,
991b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    "xmlCompileStepPattern : Name expected\n");
992b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
993b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return;
994b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
995b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
996b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
997b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == ':') {
998b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
999b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (CUR != ':') {
1000b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlChar *prefix = name;
1001d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard	    int i;
1002b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1003b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    /*
1004b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	     * This is a namespace match
1005b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	     */
1006b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    token = xmlPatScanName(ctxt);
1007627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    if ((prefix[0] == 'x') &&
1008627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		(prefix[1] == 'm') &&
1009627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		(prefix[2] == 'l') &&
1010627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		(prefix[3] == 0)) {
1011627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		URL = xmlStrdup(XML_XML_NAMESPACE);
1012627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik	    } else {
1013627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		for (i = 0;i < ctxt->nb_namespaces;i++) {
1014627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
1015627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			URL = xmlStrdup(ctxt->namespaces[2 * i]);
1016627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			break;
1017627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    }
1018627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		}
1019627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		if (i >= ctxt->nb_namespaces) {
1020627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    ERROR5(NULL, NULL, NULL,
1021627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			"xmlCompileStepPattern : no namespace bound to prefix %s\n",
1022627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			prefix);
1023627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    ctxt->error = 1;
1024627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    goto error;
1025d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard		}
1026b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
1027b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree(prefix);
1028b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (token == NULL) {
1029b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (CUR == '*') {
1030b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    NEXT;
1031b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    PUSH(XML_OP_NS, URL, NULL);
1032b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
1033b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ERROR(NULL, NULL, NULL,
1034b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : Name expected\n");
1035b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
1036b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
1037b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
1038b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
1039b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_ELEM, token, URL);
1040b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
1041b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
1042b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    NEXT;
10432a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    if (xmlStrEqual(name, (const xmlChar *) "child")) {
10442a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		xmlFree(name);
10452a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		name = xmlPatScanName(ctxt);
10462a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		if (name == NULL) {
10472a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    if (CUR == '*') {
10482a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			NEXT;
10492a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			PUSH(XML_OP_ALL, NULL, NULL);
10502a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			return;
10512a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    } else {
10522a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			ERROR(NULL, NULL, NULL,
1053b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : QName expected\n");
10542a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			ctxt->error = 1;
10552a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			goto error;
1056b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
1057b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
10582a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		if (CUR == ':') {
10592a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    xmlChar *prefix = name;
10602a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    int i;
10612a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
10622a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    NEXT;
10632a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    /*
10642a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    * This is a namespace match
10652a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    */
10662a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    token = xmlPatScanName(ctxt);
1067627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    if ((prefix[0] == 'x') &&
1068627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			(prefix[1] == 'm') &&
1069627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			(prefix[2] == 'l') &&
1070627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			(prefix[3] == 0)) {
1071627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			URL = xmlStrdup(XML_XML_NAMESPACE);
1072627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik		    } else {
1073627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			for (i = 0;i < ctxt->nb_namespaces;i++) {
1074627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			    if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) {
1075627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik				URL = xmlStrdup(ctxt->namespaces[2 * i]);
1076627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik				break;
1077627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			    }
1078627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			}
1079627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			if (i >= ctxt->nb_namespaces) {
1080627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			    ERROR5(NULL, NULL, NULL,
1081627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik				"xmlCompileStepPattern : no namespace bound "
1082627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik				"to prefix %s\n", prefix);
1083627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			    ctxt->error = 1;
1084627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik			    goto error;
10852a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			}
10862a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    }
10872a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    xmlFree(prefix);
10882a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    if (token == NULL) {
10892a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			if (CUR == '*') {
10902a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			    NEXT;
10912a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			    PUSH(XML_OP_NS, URL, NULL);
10922a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			} else {
10932a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			    ERROR(NULL, NULL, NULL,
10942a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik				"xmlCompileStepPattern : Name expected\n");
10952a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			    ctxt->error = 1;
10962a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			    goto error;
10972a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			}
10982a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    } else {
10992a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik			PUSH(XML_OP_CHILD, token, URL);
11002a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    }
11012a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		} else
11022a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    PUSH(XML_OP_CHILD, name, NULL);
11032a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		return;
11042a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    } else if (xmlStrEqual(name, (const xmlChar *) "attribute")) {
11052a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		xmlFree(name);
11062a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		name = NULL;
11072a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		xmlCompileAttributeTest(ctxt);
11082a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		if (ctxt->error != 0)
1109b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
11102a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		return;
1111b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
1112b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ERROR(NULL, NULL, NULL,
1113b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    "xmlCompileStepPattern : 'child' or 'attribute' expected\n");
1114b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ctxt->error = 1;
1115b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		goto error;
1116b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
11170e460da346bfb2cc9d5d6cb4be8f851c18bfb81eDaniel Veillard	    /* NOT REACHED xmlFree(name); */
1118b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
1119b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if (CUR == '*') {
1120fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard        if (name != NULL) {
1121fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    ctxt->error = 1;
1122fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    goto error;
1123fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	}
1124b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1125b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ALL, token, NULL);
1126b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
1127b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (name == NULL) {
1128b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
1129b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    goto error;
1130b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
1131b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ELEM, name, NULL);
1132b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
1133b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return;
1134b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
11352a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    if (URL != NULL)
11362a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	xmlFree(URL);
1137b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (token != NULL)
1138b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree(token);
1139b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (name != NULL)
1140b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree(name);
1141b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
1142b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1143b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
1144b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompilePathPattern:
1145b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the compilation context
1146b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1147b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Path Pattern and generates a precompiled
1148b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching.
1149b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1150b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )
1151b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
1152b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
1153b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
1154b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
1155537f1173c39eb21f9c5e8ad3cbc9bed2a08f25e4William M. Brack    if (CUR == '/') {
115656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        ctxt->comp->flags |= PAT_FROM_ROOT;
1157ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack    } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) {
115856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        ctxt->comp->flags |= PAT_FROM_CUR;
115956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1160ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack
1161b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((CUR == '/') && (NXT(1) == '/')) {
116256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	PUSH(XML_OP_ANCESTOR, NULL, NULL);
1163b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1164b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1165b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {
116656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	PUSH(XML_OP_ANCESTOR, NULL, NULL);
1167b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1168b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1169b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
1170b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
1171b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '@') {
11722a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	NEXT;
11732a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	xmlCompileAttributeTest(ctxt);
11742a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	SKIP_BLANKS;
1175fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack	if (CUR != 0) {
11762a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    xmlCompileStepPattern(ctxt);
11772a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	}
1178b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
11792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (CUR == '/') {
11802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    PUSH(XML_OP_ROOT, NULL, NULL);
11812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    NEXT;
11822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
1183b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlCompileStepPattern(ctxt);
1184b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	SKIP_BLANKS;
1185b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while (CUR == '/') {
1186fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack	    if (NXT(1) == '/') {
1187b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	        PUSH(XML_OP_ANCESTOR, NULL, NULL);
1188b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
1189b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
1190b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		SKIP_BLANKS;
1191b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlCompileStepPattern(ctxt);
1192b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
1193b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	        PUSH(XML_OP_PARENT, NULL, NULL);
1194b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
1195b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		SKIP_BLANKS;
1196fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack		if (CUR != 0) {
1197b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    xmlCompileStepPattern(ctxt);
1198b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
1199b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
1200b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
1201b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
120256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (CUR != 0) {
120356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	ERROR5(NULL, NULL, NULL,
120456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	       "Failed to compile pattern %s\n", ctxt->base);
120556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	ctxt->error = 1;
120656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
1207b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
1208b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return;
1209b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
12102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/************************************************************************
12122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *									*
12132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *			The streaming code				*
12142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *									*
12152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ************************************************************************/
12162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING
12182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
12192fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamComp(xmlStreamCompPtr stream) {
12202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
12212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL) {
12232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("Stream: NULL\n");
12242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return;
12252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    printf("Stream: %d steps\n", stream->nbStep);
12272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < stream->nbStep;i++) {
12282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].ns != NULL) {
12292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("{%s}", stream->steps[i].ns);
12302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
12312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (stream->steps[i].name == NULL) {
12322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("* ");
12332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	} else {
12342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("%s ", stream->steps[i].name);
12352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
12362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_ROOT)
12372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("root ");
12382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_DESC)
12392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("// ");
12402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_FINAL)
12412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("final ");
12422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	printf("\n");
12432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
12452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
12462fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) {
12472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
12482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (ctxt == NULL) {
12502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("Stream: NULL\n");
12512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return;
12522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState);
12542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (match)
12552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("matches\n");
12562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    else
12572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("\n");
12582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < ctxt->nbState;i++) {
12592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (ctxt->states[2 * i] < 0)
12602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf(" %d: free\n", i);
12612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	else {
12622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf(" %d: step %d, level %d", i, ctxt->states[2 * i],
12632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	           ctxt->states[(2 * i) + 1]);
12642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard            if (ctxt->comp->steps[ctxt->states[2 * i]].flags &
12652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        XML_STREAM_STEP_DESC)
12662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        printf(" //\n");
12672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    else
12682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        printf("\n");
12692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
12702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
12722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif
12732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
12742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamComp:
12752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected steps
12762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new compiled pattern for streaming
12782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error.
12802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
12812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCompPtr
12822fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamComp(int size) {
12832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr cur;
12842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (size < 4)
12862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        size  = 4;
12872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp));
12892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur == NULL) {
12902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
12912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		"xmlNewStreamComp: malloc failed\n");
12922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
12932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    memset(cur, 0, sizeof(xmlStreamComp));
12952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep));
12962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur->steps == NULL) {
12972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlFree(cur);
12982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
12992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	      "xmlNewStreamComp: malloc failed\n");
13002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
13012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
13022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->nbStep = 0;
13032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->maxStep = size;
13042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(cur);
13052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
13062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
13082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamComp:
13092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming
13102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the compiled pattern for streaming
13122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
13132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
13142fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamComp(xmlStreamCompPtr comp) {
13152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp != NULL) {
13162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->steps != NULL)
13172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlFree(comp->steps);
13182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (comp->dict != NULL)
13192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlDictFree(comp->dict);
13202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFree(comp);
13212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
13222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
13232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
13252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompAddStep:
13262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming
13272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the first string, the name, or NULL for *
13282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the second step, the namespace name
13292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @flags: the flags for that step
13302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new step to the compiled pattern
13322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the step index if successful
13342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
13352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
13362fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name,
13372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard                     const xmlChar *ns, int flags) {
13382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamStepPtr cur;
13392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->nbStep >= comp->maxStep) {
13412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	cur = (xmlStreamStepPtr) xmlRealloc(comp->steps,
13422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard				 comp->maxStep * 2 * sizeof(xmlStreamStep));
13432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (cur == NULL) {
13442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    ERROR(NULL, NULL, NULL,
13452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		  "xmlNewStreamComp: malloc failed\n");
13462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(-1);
13472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
13482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	comp->steps = cur;
13492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        comp->maxStep *= 2;
13502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
13512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = &comp->steps[comp->nbStep++];
13522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->flags = flags;
13532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->name = name;
13542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->ns = ns;
13552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(comp->nbStep - 1);
13562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
13572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
13592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompile:
13602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern
13612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Tries to stream compile a pattern
13632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
13642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of failure and 0 in case of success.
13652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
13662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
13672fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompile(xmlPatternPtr comp) {
13682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr stream;
13692a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    int i, s = 0, root = 0, flags = 0;
13702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((comp == NULL) || (comp->steps == NULL))
13722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
137356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    /*
137456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     * special case for .
137556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard     */
137656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if ((comp->nbStep == 1) &&
137756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        (comp->steps[0].op == XML_OP_ELEM) &&
137856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	(comp->steps[0].value == NULL) &&
137956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	(comp->steps[0].value2 == NULL)) {
138056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	stream = xmlNewStreamComp(0);
138156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (stream == NULL)
138256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    return(-1);
138356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	comp->stream = stream;
138456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	return(0);
138556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
138656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
13872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    stream = xmlNewStreamComp((comp->nbStep / 2) + 1);
13882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL)
13892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
13902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->dict != NULL) {
13912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        stream->dict = comp->dict;
13922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlDictReference(stream->dict);
13932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
1394fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard
1395fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    /*
1396fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard     * Skip leading ./ on relative paths
1397fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard     */
1398fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    i = 0;
1399fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    while ((comp->flags & PAT_FROM_CUR) && (comp->nbStep > i + 2) &&
1400fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard        (comp->steps[i].op == XML_OP_ELEM) &&
1401fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	(comp->steps[i].value == NULL) &&
1402fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	(comp->steps[i].value2 == NULL) &&
1403fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	(comp->steps[i + 1].op == XML_OP_PARENT)) {
1404fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	i += 2;
1405fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    }
1406fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    for (;i < comp->nbStep;i++) {
14072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        switch (comp->steps[i].op) {
14082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_END:
14092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        break;
14102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ROOT:
14112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        if (i != 0)
14122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
14132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		root = 1;
14142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
14152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_NS:
14162a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		s = xmlStreamCompAddStep(stream, NULL,
14172a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    comp->steps[i].value, flags);
14182a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		flags = 0;
14192a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		if (s < 0)
14202a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    goto error;
14212a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		break;
14222a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    case XML_OP_ATTR:
14232a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		flags |= XML_STREAM_STEP_ATTR;
14242a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		s = xmlStreamCompAddStep(stream, comp->steps[i].value,
14252a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    comp->steps[i].value2, flags);
14262a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		flags = 0;
14272a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		if (s < 0)
14282a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		    goto error;
14292a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		break;
14302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ELEM:
1431fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	        if ((comp->steps[i].value == NULL) &&
1432fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    (comp->steps[i].value2 == NULL) &&
1433fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    (comp->nbStep > i + 2) &&
1434fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    (comp->steps[i + 1].op == XML_OP_PARENT)) {
1435fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    i++;
1436fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    continue;
1437fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		 }
1438fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    case XML_OP_CHILD:
14392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        s = xmlStreamCompAddStep(stream, comp->steps[i].value,
14402a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		                         comp->steps[i].value2, flags);
14412a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		flags = 0;
14422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (s < 0)
14432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
14442a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		break;
14452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ALL:
14462a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	        s = xmlStreamCompAddStep(stream, NULL, NULL, flags);
14472a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		flags = 0;
14482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (s < 0)
14492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
14502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
14512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_PARENT:
1452fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	        if ((comp->nbStep > i + 1) &&
1453fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    (comp->steps[i + 1].op == XML_OP_ELEM) &&
1454fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    (comp->steps[i + 1].value == NULL) &&
1455fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    (comp->steps[i + 1].value2 == NULL)) {
1456fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    i++;
1457fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    continue;
1458fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		 }
14592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        break;
14602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ANCESTOR:
14612a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	        flags |= XML_STREAM_STEP_DESC;
14629ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/*
14639ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* Mark the expression as having "//".
14649ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		*/
14659ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		if ((stream->flags & XML_STREAM_DESC) == 0)
14669ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    stream->flags |= XML_STREAM_DESC;
14672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
14682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
14699ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik    }
14709ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik    if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) {
14719ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	/*
14729ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	* If this should behave like a real pattern, we will mark
14739ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	* the first step as having "//", to be reentrant on every
14749ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	* tree level.
14759ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	*/
14769ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if ((stream->flags & XML_STREAM_DESC) == 0)
14779ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    stream->flags |= XML_STREAM_DESC;
14789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
14799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if (stream->nbStep > 0) {
14809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0)
14819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		stream->steps[0].flags |= XML_STREAM_STEP_DESC;
14829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	}
14832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
14842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
14852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (root)
14862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	stream->steps[0].flags |= XML_STREAM_STEP_ROOT;
14872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING
14882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlDebugStreamComp(stream);
14892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif
14902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->stream = stream;
14912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
14922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillarderror:
14932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlFreeStreamComp(stream);
14942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
14952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
14962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
14972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
14982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamCtxt:
14992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected states
15002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new stream context
15022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error.
15042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
15052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCtxtPtr
15062fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamCtxt(xmlStreamCompPtr stream) {
15072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCtxtPtr cur;
15082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
15092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt));
15102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur == NULL) {
15112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
15122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		"xmlNewStreamCtxt: malloc failed\n");
15132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
15142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
15152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    memset(cur, 0, sizeof(xmlStreamCtxt));
15162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int));
15172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur->states == NULL) {
15182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlFree(cur);
15192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
15202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	      "xmlNewStreamCtxt: malloc failed\n");
15212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
15222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
15232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->nbState = 0;
15242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->maxState = 4;
15252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->level = 0;
15262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->comp = stream;
15279ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik    cur->blockLevel = -1;
15282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(cur);
15292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
15302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
15312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
15322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamCtxt:
15332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
15342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the stream context
15362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
15372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardvoid
15382fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamCtxt(xmlStreamCtxtPtr stream) {
15392b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    xmlStreamCtxtPtr next;
15402b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard
15412b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    while (stream != NULL) {
15422b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard        next = stream->next;
15432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (stream->states != NULL)
15442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlFree(stream->states);
15452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFree(stream);
15462b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard	stream = next;
15472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
15482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
15492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
15502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
15512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCtxtAddState:
15522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the stream context
15532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @idx: the step index for that streaming state
15542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new state to the stream context
15562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the state index if successful
15582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
15592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
15602fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) {
15612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
15622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < comp->nbState;i++) {
15632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->states[2 * i] < 0) {
15642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    comp->states[2 * i] = idx;
15652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    comp->states[2 * i + 1] = level;
15662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(i);
15672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
15682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
15692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->nbState >= comp->maxState) {
15702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        int *cur;
15712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
15722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	cur = (int *) xmlRealloc(comp->states,
15732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard				 comp->maxState * 4 * sizeof(int));
15742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (cur == NULL) {
15752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    ERROR(NULL, NULL, NULL,
15762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		  "xmlNewStreamCtxt: malloc failed\n");
15772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(-1);
15782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
15792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	comp->states = cur;
15802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        comp->maxState *= 2;
15812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
15822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->states[2 * comp->nbState] = idx;
15832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->states[2 * comp->nbState++ + 1] = level;
15842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(comp->nbState - 1);
15852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
15862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
15872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
15882a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * xmlStreamPushInternal:
15892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
15902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the current name
15912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the namespace name
15922a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @nodeType: the type of the node
15932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
1594fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
1595fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * indicated a dictionary, then strings for name and ns will be expected
15962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * to come from the dictionary.
15972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Both @name and @ns being NULL means the / i.e. the root of the document.
15982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * This can also act as a reset.
15992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
16002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 1 if the current state in the stream is a
16012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *    match and 0 otherwise.
16022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
16032a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikstatic int
16042a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPushInternal(xmlStreamCtxtPtr stream,
16052a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		      const xmlChar *name, const xmlChar *ns,
16062a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		      xmlElementType nodeType) {
1607537f1173c39eb21f9c5e8ad3cbc9bed2a08f25e4William M. Brack    int ret = 0, err = 0, final = 0, tmp, i, m, match, step, desc;
16082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr comp;
16092b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#ifdef DEBUG_STREAMING
16102b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    xmlStreamCtxtPtr orig = stream;
16112b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#endif
16122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
16132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((stream == NULL) || (stream->nbState < 0))
16142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
1615f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1616f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (stream != NULL) {
1617f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	comp = stream->comp;
1618f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if ((name == NULL) && (ns == NULL)) {
1619f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    stream->nbState = 0;
1620f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    stream->level = 0;
16219ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    stream->blockLevel = -1;
1622f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
1623f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		tmp = xmlStreamCtxtAddState(stream, 0, 0);
1624f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (tmp < 0)
1625f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    err++;
162656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard		if (comp->nbStep == 0)
1627f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    ret = 1;
16282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
16292b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard	    stream = stream->next;
1630f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    continue; /* while */
16312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
16322a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
16332a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	/*
16342a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	* Fast check for ".".
16352a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	*/
16362a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	if (comp->nbStep == 0) {
163722678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik	    /*
1638ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	    * For non-pattern like evaluation like XML Schema IDCs
1639ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	    * or traditional XPath expressions, this will match if
1640ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	    * we are at the first level only, otherwise on every level.
164122678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik	    */
164222678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik	    if ((nodeType == XML_ELEMENT_NODE) &&
164322678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik		(((stream->flags & XML_PATTERN_NOTPATTERN) == 0) ||
164422678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik		(stream->level == 0))) {
164522678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik		    ret = 1;
164622678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik	    }
164722678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik	    stream->level++;
16482a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    goto stream_next;
16492a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	}
16509ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if (stream->blockLevel != -1) {
16519ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    /*
16529ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * Skip blocked expressions.
16539ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    */
16549ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik    	    stream->level++;
16559ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    goto stream_next;
1656ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	}
1657f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	/*
1658f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 * Check evolution of existing states
1659f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 */
16609ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	i = 0;
1661f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	m = stream->nbState;
16629ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	while (i < m) {
16639ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if ((comp->flags & XML_STREAM_DESC) == 0) {
16649ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/*
16659ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* If there is no "//", then only the last
16669ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* added state is of interest.
16679ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		*/
16689ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		step = stream->states[2 * (stream->nbState -1)];
16699ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/*
16709ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* TODO: Security check, should not happen, remove it.
16719ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		*/
16729ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		if (stream->states[(2 * (stream->nbState -1)) + 1] <
16739ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    stream->level) {
16749ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    return (-1);
16759ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		}
16769ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		desc = 0;
16779ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/* loop-stopper */
16789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		i = m;
16799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    } else {
16809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/*
16819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* If there are "//", then we need to process every "//"
16829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* occuring in the states, plus any other state for this
16839ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* level.
16849ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		*/
16859ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		step = stream->states[2 * i];
16869ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
16879ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/* TODO: should not happen anymore: dead states */
16889ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		if (step < 0)
16899ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    goto next_state;
16909ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
16919ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		tmp = stream->states[(2 * i) + 1];
16929ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
16939ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/* skip new states just added */
16949ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		if (tmp > stream->level)
16959ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    goto next_state;
16969ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
16979ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/* skip states at ancestor levels, except if "//" */
16989ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		desc = comp->steps[step].flags & XML_STREAM_STEP_DESC;
16999ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		if ((tmp < stream->level) && (!desc))
17009ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    goto next_state;
17019ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    }
17022a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    /*
17032a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    * Check for correct node-type.
17042a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    */
17059ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if ((nodeType == XML_ATTRIBUTE_NODE) &&
17068798b735a603d0b7120182d15f04f7ec740b6c79Kasimier T. Buchcik		((comp->steps[step].flags & XML_STREAM_STEP_ATTR) == 0))
17079ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		goto next_state;
17089ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    /*
17099ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * Compare local/namespace-name.
17109ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    */
17119ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    match = 0;
1712f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (comp->dict) {
1713f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (comp->steps[step].name == NULL) {
1714f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (comp->steps[step].ns == NULL)
1715f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = 1;
1716f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    else
1717f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = (comp->steps[step].ns == ns);
17182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		} else {
1719f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    match = ((comp->steps[step].name == name) &&
1720f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			     (comp->steps[step].ns == ns));
17212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		}
17222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    } else {
1723f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (comp->steps[step].name == NULL) {
1724f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (comp->steps[step].ns == NULL)
1725f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = 1;
1726f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    else
1727f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			match = xmlStrEqual(comp->steps[step].ns, ns);
17282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		} else {
1729f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    match = ((xmlStrEqual(comp->steps[step].name, name)) &&
1730f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			     (xmlStrEqual(comp->steps[step].ns, ns)));
1731f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		}
1732f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    }
17332a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	    if (match) {
1734f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		final = comp->steps[step].flags & XML_STREAM_STEP_FINAL;
1735f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		if (desc) {
1736f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (final) {
1737f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			ret = 1;
1738f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    } else {
1739f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			/* descending match create a new state */
1740f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			xmlStreamCtxtAddState(stream, step + 1,
1741f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			                      stream->level + 1);
1742f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    }
1743f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		} else {
1744f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    if (final) {
1745f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			ret = 1;
1746f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    } else {
1747f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			xmlStreamCtxtAddState(stream, step + 1,
1748f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard			                      stream->level + 1);
1749f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		    }
17502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		}
17512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
17529ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if (((comp->flags & XML_STREAM_DESC) == 0) &&
17539ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		((! match) || final))  {
17549ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		/*
17559ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* Mark this expression as blocked for any evaluation at
17569ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* deeper levels. Note that this includes "/foo"
17579ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		* expressions if the *pattern* behaviour is used.
17589ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		*/
17599ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		stream->blockLevel = stream->level +1;
17609ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    }
17619ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchciknext_state:
17629ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    i++;
17632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
17642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
1765f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	stream->level++;
17669ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
17672a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	/*
17689ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	* Re/enter the expression.
17692a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	*/
17709ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if (comp->steps[0].flags & XML_STREAM_STEP_ROOT)
17719ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    goto stream_next;
17729ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
17732a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik	desc = comp->steps[0].flags & XML_STREAM_STEP_DESC;
17749ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if (stream->flags & XML_PATTERN_NOTPATTERN) {
17759ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    /*
17769ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * Re/enter the expression if it is a "descendant" one,
17779ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * or if we are at the 1st level of evaluation.
17789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    */
17799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
17809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if (stream->level == 1) {
17819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		if (XML_STREAM_XS_IDC(stream)) {
17829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    /*
17839ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    * XS-IDC: The missing "self::node()" will always
17849ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    * match the first given node.
17859ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    */
17869ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    goto stream_next;
17879ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		} else
17889ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    goto compare;
17899ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    }
17909ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    /*
17919ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * A "//" is always reentrant.
17929ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    */
17939ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if (desc)
17949ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		goto compare;
1795285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik
17969ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    /*
17979ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * XS-IDC: Process the 2nd level, since the missing
17989ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * "self::node()" is responsible for the 2nd level being
17999ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * the real start level.
18009ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    */
18019ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if ((stream->level == 2) && XML_STREAM_XS_IDC(stream))
18029ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		goto compare;
1803285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik
18049ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    goto stream_next;
18059ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	}
1806285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik
18079ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcikcompare:
18089ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	/*
18099ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	* Check expected node-type.
1810285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik	*/
18119ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if ((nodeType == XML_ATTRIBUTE_NODE) &&
18129ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    ((comp->steps[0].flags & XML_STREAM_STEP_ATTR) == 0))
18139ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    goto stream_next;
18149ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	/*
18159ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	* Compare local/namespace-name.
18169ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	*/
18179ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	match = 0;
18189ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if (comp->steps[0].name == NULL) {
18199ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if (comp->steps[0].ns == NULL)
18209ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		match = 1;
18219ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    else {
18229ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		if (comp->dict)
18239ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    match = (comp->steps[0].ns == ns);
18242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		else
18259ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    match = xmlStrEqual(comp->steps[0].ns, ns);
18262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
18279ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	} else {
18289ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if (comp->dict)
18299ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		match = ((comp->steps[0].name == name) &&
18309ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    (comp->steps[0].ns == ns));
18319ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    else
18329ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		match = ((xmlStrEqual(comp->steps[0].name, name)) &&
18339ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		    (xmlStrEqual(comp->steps[0].ns, ns)));
18342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
18359ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if (match) {
18369ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    final = comp->steps[0].flags & XML_STREAM_STEP_FINAL;
18379ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if (final)
18389ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		ret = 1;
18399ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    else
18409ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		xmlStreamCtxtAddState(stream, 1, stream->level);
18419ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	}
18429ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if (((comp->flags & XML_STREAM_DESC) == 0) &&
18439ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    ((! match) || final))  {
18449ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    /*
18459ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * Mark this expression as blocked for any evaluation at
18469ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    * deeper levels.
18479ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    */
18489ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    stream->blockLevel = stream->level;
18499ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	}
18509ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
18512a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikstream_next:
1852f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        stream = stream->next;
1853f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    } /* while stream != NULL */
18542a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
1855f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    if (err > 0)
1856f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        ret = -1;
18572b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#ifdef DEBUG_STREAMING
18582b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    xmlDebugStreamCtxt(orig, ret);
18592b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#endif
18602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(ret);
18612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
18622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
18632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
18642a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * xmlStreamPush:
18652a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @stream: the stream context
18662a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @name: the current name
18672a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @ns: the namespace name
18682a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik *
1869fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Push new data onto the stream. NOTE: if the call xmlPatterncompile()
1870fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * indicated a dictionary, then strings for name and ns will be expected
18712a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * to come from the dictionary.
18722a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Both @name and @ns being NULL means the / i.e. the root of the document.
18732a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * This can also act as a reset.
18742a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik *
18752a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Returns: -1 in case of error, 1 if the current state in the stream is a
18762a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik *    match and 0 otherwise.
18772a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */
18782a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikint
18792a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPush(xmlStreamCtxtPtr stream,
18802a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik              const xmlChar *name, const xmlChar *ns) {
18812a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    return (xmlStreamPushInternal(stream, name, ns, XML_ELEMENT_NODE));
18822a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik}
18832a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
18842a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/**
18852a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* xmlStreamPushAttr:
18862a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @stream: the stream context
18872a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @name: the current name
18882a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @ns: the namespace name
18892a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik*
1890fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack* Push new attribute data onto the stream. NOTE: if the call xmlPatterncompile()
1891fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack* indicated a dictionary, then strings for name and ns will be expected
18922a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* to come from the dictionary.
18932a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* Both @name and @ns being NULL means the / i.e. the root of the document.
18942a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* This can also act as a reset.
18952a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik*
18962a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* Returns: -1 in case of error, 1 if the current state in the stream is a
18972a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik*    match and 0 otherwise.
18982a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik*/
18992a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikint
19002a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPushAttr(xmlStreamCtxtPtr stream,
19012a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik		  const xmlChar *name, const xmlChar *ns) {
19022a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik    return (xmlStreamPushInternal(stream, name, ns, XML_ATTRIBUTE_NODE));
19032a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik}
19042a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
19052a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/**
19062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamPop:
19072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
19082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
19092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * push one level from the stream.
19102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
19112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 0 otherwise.
19122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
19132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardint
19142fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamPop(xmlStreamCtxtPtr stream) {
19159ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik    int i, lev;
1916f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    int ret;
19179740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard
19182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL)
19192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
1920f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    ret = 0;
1921f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (stream != NULL) {
19229ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	/*
19239ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	* Reset block-level.
19249ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	*/
19259ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	if (stream->blockLevel == stream->level)
19269ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    stream->blockLevel = -1;
19279ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik
1928f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	stream->level--;
1929f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (stream->level < 0)
19309ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    ret = -1;
1931f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	/*
1932f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	 * Check evolution of existing states
19339ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	 */
19349ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	for (i = stream->nbState -1; i >= 0; i--) {
1935f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    /* discard obsoleted states */
19369ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    lev = stream->states[(2 * i) + 1];
19379ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if (lev > stream->level)
19389ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		stream->nbState--;
19399ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik	    if (lev <= stream->level)
19409ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik		break;
1941f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
1942f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	stream = stream->next;
19439740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard    }
19442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
19452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
19462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
1947b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
1948b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
1949b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *			The public interfaces				*
1950b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
1951b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
1952b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1953b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
1954b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatterncompile:
1955b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern: the pattern to compile
1956fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * @dict: an optional dictionary for interned strings
1957b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @flags: compilation flags, undefined yet
1958ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
1959b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1960ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * Compile a pattern.
1961b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1962fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Returns the compiled form of the pattern or NULL in case of error
1963b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
1964b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternPtr
1965427174fbf2544b44071c1039720e6634fb154f84Daniel VeillardxmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
1966ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack                  xmlPatternFlags flags,
1967ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard                  const xmlChar **namespaces) {
1968f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    xmlPatternPtr ret = NULL, cur;
1969b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatParserContextPtr ctxt = NULL;
1970f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    const xmlChar *or, *start;
1971f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    xmlChar *tmp = NULL;
1972fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    int type = 0;
1973fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    int streamable = 1;
1974f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1975f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    if (pattern == NULL)
1976f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        return(NULL);
1977f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
1978f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    start = pattern;
19792b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard    or = start;
1980f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (*or != 0) {
1981f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	tmp = NULL;
1982f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	while ((*or != 0) && (*or != '|')) or++;
1983f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        if (*or == 0)
1984f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ctxt = xmlNewPatParserContext(start, dict, namespaces);
1985f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	else {
1986f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    tmp = xmlStrndup(start, or - start);
1987f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    if (tmp != NULL) {
1988f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard		ctxt = xmlNewPatParserContext(tmp, dict, namespaces);
1989f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    }
1990f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    or++;
1991f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
1992f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (ctxt == NULL) goto error;
1993f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	cur = xmlNewPattern();
1994f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (cur == NULL) goto error;
1995f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (ret == NULL)
1996f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret = cur;
1997f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	else {
1998f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    cur->next = ret->next;
1999f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret->next = cur;
2000f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
2001285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik	cur->flags = flags;
2002f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	ctxt->comp = cur;
2003b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
2004f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	xmlCompilePathPattern(ctxt);
200556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (ctxt->error != 0)
200656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    goto error;
2007f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	xmlFreePatParserContext(ctxt);
2008fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack	ctxt = NULL;
2009b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
2010b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
2011fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard        if (streamable) {
2012fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    if (type == 0) {
2013fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	        type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR);
2014fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    } else if (type == PAT_FROM_ROOT) {
2015fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	        if (cur->flags & PAT_FROM_CUR)
2016fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    streamable = 0;
2017fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    } else if (type == PAT_FROM_CUR) {
2018fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	        if (cur->flags & PAT_FROM_ROOT)
2019fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		    streamable = 0;
2020fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    }
2021fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	}
2022fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	if (streamable)
2023fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    xmlStreamCompile(cur);
2024f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (xmlReversePattern(cur) < 0)
2025f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    goto error;
2026ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	if (tmp != NULL) {
2027f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    xmlFree(tmp);
2028ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	    tmp = NULL;
2029ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack	}
20302b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard	start = or;
2031f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    }
2032fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    if (streamable == 0) {
2033fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard        cur = ret;
2034fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	while (cur != NULL) {
2035fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    if (cur->stream != NULL) {
2036fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		xmlFreeStreamComp(cur->stream);
2037fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard		cur->stream = NULL;
2038fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    }
2039fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	    cur = cur->next;
2040fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard	}
2041fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard    }
2042285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik
2043b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
2044b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
2045b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt != NULL) xmlFreePatParserContext(ctxt);
2046b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ret != NULL) xmlFreePattern(ret);
2047f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    if (tmp != NULL) xmlFree(tmp);
2048b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(NULL);
2049b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
2050b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
2051b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
2052b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternMatch:
2053b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern
2054b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node
2055b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
2056fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Test whether the node matches the pattern
2057b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
2058b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
2059b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
2060b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardint
2061b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
2062b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{
2063f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    int ret = 0;
2064f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
2065b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((comp == NULL) || (node == NULL))
2066b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return(-1);
2067f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
2068f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (comp != NULL) {
2069f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        ret = xmlPatMatch(comp, node);
2070f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (ret != 0)
2071f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    return(ret);
2072f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	comp = comp->next;
2073f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    }
2074f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    return(ret);
2075b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
2076b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
20772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
20782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlPatternGetStreamCtxt:
20792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern
20802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
20812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Get a streaming context for that pattern
20822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Use xmlFreeStreamCtxt to free the context.
20832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
20842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns a pointer to the context or NULL in case of failure
20852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
20862fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtPtr
20872fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlPatternGetStreamCtxt(xmlPatternPtr comp)
20882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard{
2089f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    xmlStreamCtxtPtr ret = NULL, cur;
2090f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
20912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((comp == NULL) || (comp->stream == NULL))
20922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(NULL);
2093f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard
2094f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    while (comp != NULL) {
2095f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard        if (comp->stream == NULL)
2096f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    goto failed;
2097f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	cur = xmlNewStreamCtxt(comp->stream);
2098f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (cur == NULL)
2099f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    goto failed;
2100f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	if (ret == NULL)
2101f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret = cur;
2102f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	else {
2103f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    cur->next = ret->next;
2104f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	    ret->next = cur;
2105f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	}
2106285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik	cur->flags = comp->flags;
2107f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard	comp = comp->next;
2108f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    }
2109f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    return(ret);
2110f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillardfailed:
2111f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    xmlFreeStreamCtxt(ret);
2112f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard    return(NULL);
21132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
21142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
211556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/**
211656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternStreamable:
211756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern
211856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
211956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check if the pattern is streamable i.e. xmlPatternGetStreamCtxt()
212056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * should work.
212156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
212256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns 1 if streamable, 0 if not and -1 in case of error.
212356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */
212456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint
212556de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternStreamable(xmlPatternPtr comp) {
212656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp == NULL)
212756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        return(-1);
212856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    while (comp != NULL) {
212956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        if (comp->stream == NULL)
213056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    return(0);
213156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	comp = comp->next;
213256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
213356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    return(1);
213456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard}
213556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
213656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/**
213756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternMaxDepth:
213856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern
213956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
214056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check the maximum depth reachable by a pattern
214156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
214256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns -2 if no limit (using //), otherwise the depth,
214356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *         and -1 in case of error
214456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */
214556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint
214656de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternMaxDepth(xmlPatternPtr comp) {
214756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    int ret = 0, i;
214856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp == NULL)
214956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        return(-1);
215056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    while (comp != NULL) {
215156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        if (comp->stream == NULL)
215256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    return(-1);
215356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	for (i = 0;i < comp->stream->nbStep;i++)
215456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    if (comp->stream->steps[i].flags & XML_STREAM_STEP_DESC)
215556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	        return(-2);
215656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (comp->stream->nbStep > ret)
215756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    ret = comp->stream->nbStep;
215856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	comp = comp->next;
215956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
216056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    return(ret);
216156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
216256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard}
216356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
216456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/**
216556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternFromRoot:
216656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern
216756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
216856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check if the pattern must be looked at from the root.
216956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard *
217056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns 1 if true, 0 if false and -1 in case of error
217156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */
217256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint
217356de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternFromRoot(xmlPatternPtr comp) {
217456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    if (comp == NULL)
217556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        return(-1);
217656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    while (comp != NULL) {
217756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard        if (comp->stream == NULL)
217856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    return(-1);
217956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	if (comp->flags & PAT_FROM_ROOT)
218056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	    return(1);
218156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard	comp = comp->next;
218256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    }
218356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard    return(0);
218456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard
218556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard}
21862a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik
21875d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_pattern
21885d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h"
2189b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif /* LIBXML_PATTERN_ENABLED */
2190