pattern.c revision 9740d1d42595ec01cafcfe49c7217229fd8b5bb8
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 .
22f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard * - xmlPatterncompile support of namespaces arguments, I'm not sure
23f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard *   it's implemented and definitely not tested
24f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard * - handling of disjunction "pattern1 | pattern2" mean needed to build
25f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard *   and check a list internally
26f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard */
27f9d169142dd652f5e077e1c2391facaa6bf40f4dDaniel Veillard
28b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define IN_LIBXML
29b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include "libxml.h"
30b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
31b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <string.h>
32b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/xmlmemory.h>
33b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/tree.h>
34b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/hash.h>
35b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/dict.h>
36b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/xmlerror.h>
37b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/parserInternals.h>
38b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/pattern.h>
39b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
40b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_PATTERN_ENABLED
41b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
429740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard#define DEBUG_STREAMING
432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
44b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define ERROR(a, b, c, d)
45b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define ERROR5(a, b, c, d, e)
46b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_DESC	1
482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_FINAL	2
492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_ROOT	4
502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef struct _xmlStreamStep xmlStreamStep;
522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef xmlStreamStep *xmlStreamStepPtr;
532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamStep {
542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int flags;			/* properties of that step */
552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    const xmlChar *name;	/* first string value if NULL accept all */
562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    const xmlChar *ns;		/* second string value */
572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef struct _xmlStreamComp xmlStreamComp;
602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef xmlStreamComp *xmlStreamCompPtr;
612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamComp {
622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlDict *dict;		/* the dictionnary if any */
632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int nbStep;			/* number of steps in the automata */
642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int maxStep;		/* allocated number of steps */
652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamStepPtr steps;	/* the array of steps */
662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamCtxt {
692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr comp;	/* the compiled stream */
702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int nbState;		/* number of state in the automata */
712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int maxState;		/* allocated number of state */
722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int level;			/* how deep are we ? */
732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int *states;		/* the array of step indexes */
742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard};
752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void xmlFreeStreamComp(xmlStreamCompPtr comp);
772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
78b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/*
79b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Types are private:
80b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
81b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
82b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef enum {
83b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_END=0,
84b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ROOT,
85b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ELEM,
86b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_CHILD,
87b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ATTR,
88b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_PARENT,
89b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ANCESTOR,
90b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_NS,
91b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ALL
92b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} xmlPatOp;
93b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
94b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
95b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlStepOp xmlStepOp;
96b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlStepOp *xmlStepOpPtr;
97b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlStepOp {
98b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatOp op;
99b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *value;
100b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *value2;
101b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
102b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
103b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPattern {
104b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    void *data;    		/* the associated template */
1052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlDictPtr dict;		/* the optional dictionnary */
1062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    struct _xmlPattern *next;	/* siblings */
107b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *pattern;	/* the pattern */
108b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
109b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int nbStep;
110b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int maxStep;
111c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    xmlStepOpPtr steps;        /* ops for computation */
1122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr stream;	/* the streaming data if any */
113b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
114b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
115b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlPatParserContext xmlPatParserContext;
116b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlPatParserContext *xmlPatParserContextPtr;
117b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPatParserContext {
118b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *cur;			/* the current char being parsed */
119b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *base;		/* the full expression */
120b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int	           error;		/* error code */
121b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlDictPtr     dict;		/* the dictionnary if any */
122b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr  comp;		/* the result */
123b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlNodePtr     elem;		/* the current node if any */
124ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    const xmlChar **namespaces;		/* the namespaces definitions */
125ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    int   nb_namespaces;		/* the number of namespaces */
126b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
127b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
128b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
129b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
130b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 			Type functions 					*
131b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
132b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
133b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
134b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
135b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPattern:
136b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
137b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XSLT Pattern
138b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
139b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatternPtr or NULL in case of error
140b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
141b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatternPtr
142b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlNewPattern(void) {
143b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr cur;
144b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
145b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));
146b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (cur == NULL) {
147b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ERROR(NULL, NULL, NULL,
148b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		"xmlNewPattern : malloc failed\n");
149b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
150b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
151b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(cur, 0, sizeof(xmlPattern));
152b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->maxStep = 10;
153c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    cur->steps = (xmlStepOpPtr) xmlMalloc(cur->maxStep * sizeof(xmlStepOp));
154c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (cur->steps == NULL) {
155c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlFree(cur);
156c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	ERROR(NULL, NULL, NULL,
157c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard		"xmlNewPattern : malloc failed\n");
158c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	return(NULL);
159c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    }
160b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(cur);
161b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
162b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
163b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
164b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePattern:
165b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  an XSLT comp
166b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
167b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @comp
168b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
169b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid
170b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePattern(xmlPatternPtr comp) {
171b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOpPtr op;
172b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
173b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
174b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp == NULL)
175b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
1762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->stream != NULL)
1772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFreeStreamComp(comp->stream);
178b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp->pattern != NULL)
179b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree((xmlChar *)comp->pattern);
180c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->steps != NULL) {
1812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->dict == NULL) {
1822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    for (i = 0;i < comp->nbStep;i++) {
1832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		op = &comp->steps[i];
1842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (op->value != NULL)
1852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    xmlFree((xmlChar *) op->value);
1862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (op->value2 != NULL)
1872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    xmlFree((xmlChar *) op->value2);
1882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
189c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
190c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	xmlFree(comp->steps);
191b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
1922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->dict != NULL)
1932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlDictFree(comp->dict);
1942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
195b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(comp, -1, sizeof(xmlPattern));
196b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFree(comp);
197b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
198b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
199b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
200b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatternList:
201b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  an XSLT comp list
202b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
203b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by all the elements of @comp
204b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
205b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid
206b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatternList(xmlPatternPtr comp) {
207b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr cur;
208b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
209b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (comp != NULL) {
210b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = comp;
211b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp = comp->next;
212b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFreePattern(cur);
213b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
214b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
215b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
216b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
217b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPatParserContext:
218b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern:  the pattern context
219ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * @dict:  the inherited dictionnary or NULL
2202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] terminated
2212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *              with [NULL, NULL] or NULL if no namespace is used
222b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
223b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XML pattern parser context
224b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
225b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error
226b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
227b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatParserContextPtr
228ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel VeillardxmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict,
229ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard                       const xmlChar **namespaces) {
230b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatParserContextPtr cur;
231b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
232b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (pattern == NULL)
233b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return(NULL);
234b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
235b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));
236b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (cur == NULL) {
237b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ERROR(NULL, NULL, NULL,
238b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		"xmlNewPatParserContext : malloc failed\n");
239b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
240b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
241b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(cur, 0, sizeof(xmlPatParserContext));
242b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->dict = dict;
243b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->cur = pattern;
244b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->base = pattern;
245ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    if (namespaces != NULL) {
246ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        int i;
247ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard	for (i = 0;namespaces[2 * i] != NULL;i++);
248ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        cur->nb_namespaces = i;
249ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    } else {
250ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard        cur->nb_namespaces = 0;
251ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    }
252ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    cur->namespaces = namespaces;
253b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(cur);
254b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
255b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
256b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
257b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatParserContext:
258b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  an XSLT parser context
259b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
260b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @ctxt
261b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
262b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
263b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
264b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt == NULL)
265b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
266b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(ctxt, -1, sizeof(xmlPatParserContext));
267b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFree(ctxt);
268b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
269b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
270b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
271b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternAdd:
272b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
273b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @op:  an op
274b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value:  the first value
275b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value2:  the second value
276b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
277b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Add an step to an XSLT Compiled Match
278b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
279b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns -1 in case of failure, 0 otherwise.
280b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
281b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int
282b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
283b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                xmlPatternPtr comp,
284b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                xmlPatOp op, xmlChar * value, xmlChar * value2)
285b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{
286c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->nbStep >= comp->maxStep) {
287c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlStepOpPtr temp;
288c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
289c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	                                 sizeof(xmlStepOp));
290c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        if (temp == NULL) {
291c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    ERROR(ctxt, NULL, NULL,
292c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard			     "xmlPatternAdd: realloc failed\n");
293c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    return (-1);
294c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
295c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->steps = temp;
296c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->maxStep *= 2;
297b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
298b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].op = op;
299b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].value = value;
300b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].value2 = value2;
301b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->nbStep++;
302b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return (0);
303b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
304b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
305b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
306b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
307b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xsltSwapTopPattern:
308b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
309b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
310b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse the two top steps.
311b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
312b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
313b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxsltSwapTopPattern(xmlPatternPtr comp) {
314b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
315b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int j = comp->nbStep - 1;
316b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
317b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (j > 0) {
318b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register const xmlChar *tmp;
319b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register xmlPatOp op;
320b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	i = j - 1;
321b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value;
322b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value = comp->steps[j].value;
323b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value = tmp;
324b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value2;
325b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value2 = comp->steps[j].value2;
326b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value2 = tmp;
327b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = comp->steps[i].op;
328b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].op = comp->steps[j].op;
329b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].op = op;
330b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
331b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
332b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
333b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
334b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
335b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlReversePattern:
336b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
337b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
338b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse all the stack of expressions
339c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard *
340c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard * returns 0 in case of success and -1 in case of error.
341b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
342c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillardstatic int
343b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlReversePattern(xmlPatternPtr comp) {
344b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i = 0;
345b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int j = comp->nbStep - 1;
346b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
347c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (comp->nbStep >= comp->maxStep) {
348c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        xmlStepOpPtr temp;
349c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
350c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	                                 sizeof(xmlStepOp));
351c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        if (temp == NULL) {
352c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    ERROR(ctxt, NULL, NULL,
353c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard			     "xmlReversePattern: realloc failed\n");
354c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	    return (-1);
355c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	}
356c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->steps = temp;
357c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard	comp->maxStep *= 2;
358c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    }
359b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (j > i) {
360b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register const xmlChar *tmp;
361b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register xmlPatOp op;
362b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value;
363b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value = comp->steps[j].value;
364b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value = tmp;
365b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value2;
366b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value2 = comp->steps[j].value2;
367b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value2 = tmp;
368b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = comp->steps[i].op;
369b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].op = comp->steps[j].op;
370b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].op = op;
371b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	j--;
372b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	i++;
373b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
374c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    comp->steps[comp->nbStep].value = NULL;
375c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    comp->steps[comp->nbStep].value2 = NULL;
376b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep++].op = XML_OP_END;
377c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    return(0);
378b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
379b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
380b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
381b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
382b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 		The interpreter for the precompiled patterns		*
383b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
384b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
385b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
386b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
387b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatMatch:
388b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern
389b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node
390b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
391b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Test wether the node matches the pattern
392b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
393b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
394b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
395b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int
396b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
397b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
398b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOpPtr step;
399b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
400b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((comp == NULL) || (node == NULL)) return(-1);
401b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    for (i = 0;i < comp->nbStep;i++) {
402b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	step = &comp->steps[i];
403b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	switch (step->op) {
404b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_END:
405b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		return(1);
406b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ROOT:
4072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (node->type == XML_NAMESPACE_DECL)
4082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    return(0);
4092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		node = node->parent;
410b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
411b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
412b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
413b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
414b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE))
415b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
416b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		return(0);
417b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ELEM:
418b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
419b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
420b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL)
421b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
422b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value[0] != node->name[0])
423b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
424b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (!xmlStrEqual(step->value, node->name))
425b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
426b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
427b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
428b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
429b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
430b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
431b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
432b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 == NULL)
433b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
434b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
435b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
436b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
437b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
438b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_CHILD: {
439b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlNodePtr lst;
440b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
441b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type != XML_ELEMENT_NODE) &&
442b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_DOCUMENT_NODE) &&
443b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
444b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_DOCB_DOCUMENT_NODE) &&
445b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
446b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_HTML_DOCUMENT_NODE))
447b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
448b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
449b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		lst = node->children;
450b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
451b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value != NULL) {
452b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    while (lst != NULL) {
453b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			if ((lst->type == XML_ELEMENT_NODE) &&
454b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    (step->value[0] == lst->name[0]) &&
455b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    (xmlStrEqual(step->value, lst->name)))
456b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    break;
457b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			lst = lst->next;
458b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
459b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (lst != NULL)
460b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			continue;
461b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
462b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		return(0);
463b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
464b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ATTR:
465b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ATTRIBUTE_NODE)
466b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
467b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value != NULL) {
468b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value[0] != node->name[0])
469b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
470b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value, node->name))
471b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
472b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
473b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
474b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
475b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
476b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
477b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (step->value2 != NULL) {
478b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
479b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
480b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
481b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
482b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_PARENT:
483b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
484b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE) ||
485b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
486b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
487b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
488b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_NAMESPACE_DECL))
489b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
490b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		node = node->parent;
491b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
492b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
493b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL)
494b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
495b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value[0] != node->name[0])
496b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
497b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (!xmlStrEqual(step->value, node->name))
498b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
499b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
500b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
501b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
502b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
503b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
504b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 == NULL)
505b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
506b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
507b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
508b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
509b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
510b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ANCESTOR:
511b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* TODO: implement coalescing of ANCESTOR/NODE ops */
512b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL) {
513b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    i++;
514b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    step = &comp->steps[i];
515b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->op == XML_OP_ROOT)
516b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(1);
517b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->op != XML_OP_ELEM)
518b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
519b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value == NULL)
520b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(-1);
521b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
522b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
523b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
524b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
525b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE) ||
526b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
527b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
528b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
529b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_NAMESPACE_DECL))
530b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
531b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		node = node->parent;
532b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		while (node != NULL) {
533b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (node == NULL)
534b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
535b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if ((node->type == XML_ELEMENT_NODE) &&
536b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			(step->value[0] == node->name[0]) &&
537b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			(xmlStrEqual(step->value, node->name))) {
538b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			/* Namespace test */
539b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			if (node->ns == NULL) {
540b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    if (step->value2 == NULL)
541b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				break;
542b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			} else if (node->ns->href != NULL) {
543b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    if ((step->value2 != NULL) &&
544b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			        (xmlStrEqual(step->value2, node->ns->href)))
545b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				break;
546b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			}
547b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
548b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    node = node->parent;
549b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
550b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
551b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
552b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
553b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_NS:
554b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
555b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
556b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
557b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value != NULL)
558b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
559b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
560b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value == NULL)
561b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
562b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value, node->ns->href))
563b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
564b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
565b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		break;
566b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ALL:
567b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
568b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
569b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		break;
570b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
571b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
572b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(1);
573b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
574b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
575b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
576b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
577b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *			Dedicated parser for templates			*
578b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
579b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
580b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
581b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define TODO 								\
582b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
583b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
584b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            __FILE__, __LINE__);
585b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR (*ctxt->cur)
586b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP(val) ctxt->cur += (val)
587b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NXT(val) ctxt->cur[(val)]
588b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR_PTR ctxt->cur
589b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
590b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP_BLANKS 							\
591427174fbf2544b44071c1039720e6634fb154f84Daniel Veillard    while (IS_BLANK_CH(CUR)) NEXT
592b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
593b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CURRENT (*ctxt->cur)
594b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
595b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
596b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
597b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define PUSH(op, val, val2) 						\
598b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
599b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
600b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR(X)							\
601b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    { xsltError(ctxt, __FILE__, __LINE__, X);			\
602b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard      ctxt->error = (X); return; }
603b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
604b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR0(X)							\
605b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    { xsltError(ctxt, __FILE__, __LINE__, X);			\
606b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard      ctxt->error = (X); return(0); }
607b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
608b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
609b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
610b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanLiteral:
611b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
612b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
613b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse an XPath Litteral:
614b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
615b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [29] Literal ::= '"' [^"]* '"'
616b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *                | "'" [^']* "'"
617b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
618b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Literal parsed or NULL
619b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
620b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
621b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
622b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
623b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
624b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
625b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
626b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
627b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
628b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '"') {
629b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        NEXT;
630b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = q = CUR_PTR;
631b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
632b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while ((IS_CHAR(val)) && (val != '"')) {
633b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    cur += len;
634b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    val = xmlStringCurrentChar(NULL, cur, &len);
635b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
636b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (!IS_CHAR(val)) {
637b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
638b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return(NULL);
639b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
640b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ret = xmlStrndup(q, cur - q);
641b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        }
642b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
643b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	CUR_PTR = cur;
644b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if (CUR == '\'') {
645b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        NEXT;
646b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = q = CUR_PTR;
647b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
648b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while ((IS_CHAR(val)) && (val != '\'')) {
649b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    cur += len;
650b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    val = xmlStringCurrentChar(NULL, cur, &len);
651b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
652b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (!IS_CHAR(val)) {
653b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
654b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return(NULL);
655b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
656b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ret = xmlStrndup(q, cur - q);
657b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        }
658b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
659b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	CUR_PTR = cur;
660b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
661b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/* XP_ERROR(XPATH_START_LITERAL_ERROR); */
662b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ctxt->error = 1;
663b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
664b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
665b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
666b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
667b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
668b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
669b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
670b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanName:
671b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
672b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
673b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |
674b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *                  CombiningChar | Extender
675b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
676b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5] Name ::= (Letter | '_' | ':') (NameChar)*
677b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
678b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [6] Names ::= Name (S Name)*
679b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
680b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
681b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
682b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
683b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
684b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanName(xmlPatParserContextPtr ctxt) {
685b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
686b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
687b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
688b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
689b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
690b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
691b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = q = CUR_PTR;
692b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    val = xmlStringCurrentChar(NULL, cur, &len);
693b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (!IS_LETTER(val) && (val != '_') && (val != ':'))
694b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
695b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
696b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
697b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard           (val == '.') || (val == '-') ||
698b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (val == '_') ||
699b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_COMBINING(val)) ||
700b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_EXTENDER(val))) {
701b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
702b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
703b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
704b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlStrndup(q, cur - q);
705b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    CUR_PTR = cur;
706b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
707b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
708b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
709b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
710b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanNCName:
711b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
712b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
713b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parses a non qualified name
714b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
715b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
716b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
717b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
718b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
719b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanNCName(xmlPatParserContextPtr ctxt) {
720b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
721b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
722b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
723b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
724b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
725b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
726b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = q = CUR_PTR;
727b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    val = xmlStringCurrentChar(NULL, cur, &len);
728b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (!IS_LETTER(val) && (val != '_'))
729b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
730b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
731b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
732b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard           (val == '.') || (val == '-') ||
733b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (val == '_') ||
734b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_COMBINING(val)) ||
735b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_EXTENDER(val))) {
736b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
737b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
738b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
739b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlStrndup(q, cur - q);
740b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    CUR_PTR = cur;
741b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
742b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
743b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
744b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
745b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
746b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanQName:
747b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
748b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @prefix:  the place to store the prefix
749b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
750b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse a qualified name
751b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
752b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
753b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
754b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
755b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
756b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) {
757b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
758b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
759b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    *prefix = NULL;
760b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlPatScanNCName(ctxt);
761b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == ':') {
762b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        *prefix = ret;
763b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
764b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ret = xmlPatScanNCName(ctxt);
765b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
766b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
767b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
768b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
769b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
770b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
771b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompileStepPattern:
772b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the compilation context
773b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
774b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Step Pattern and generates a precompiled
775b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching.
776b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
777b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [3]    Step    ::=    '.' | NameTest
778b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [4]    NameTest    ::=    QName | '*' | NCName ':' '*'
779b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
780b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
781b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
782b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
783b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *token = NULL;
784b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *name = NULL;
785b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *URI = NULL;
786b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *URL = NULL;
787b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
788b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
789b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '.') {
790b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
791b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ELEM, NULL, NULL);
792b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
793b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
794b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    name = xmlPatScanNCName(ctxt);
795b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (name == NULL) {
796b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (CUR == '*') {
797b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    NEXT;
798b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    PUSH(XML_OP_ALL, NULL, NULL);
799b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return;
800b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
801b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ERROR(NULL, NULL, NULL,
802b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    "xmlCompileStepPattern : Name expected\n");
803b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
804b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return;
805b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
806b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
807b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
808b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == ':') {
809b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
810b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (CUR != ':') {
811b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlChar *prefix = name;
812b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlNsPtr ns;
813b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
814b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    /*
815b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	     * This is a namespace match
816b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	     */
817b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    token = xmlPatScanName(ctxt);
818b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ns = xmlSearchNs(NULL, ctxt->elem, prefix);
819b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (ns == NULL) {
820b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ERROR5(NULL, NULL, NULL,
821b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    "xmlCompileStepPattern : no namespace bound to prefix %s\n",
822b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				 prefix);
823b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ctxt->error = 1;
824b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		goto error;
825b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
826b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		URL = xmlStrdup(ns->href);
827b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
828b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree(prefix);
829b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (token == NULL) {
830b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (CUR == '*') {
831b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    NEXT;
832b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    PUSH(XML_OP_NS, URL, NULL);
833b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
834b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ERROR(NULL, NULL, NULL,
835b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : Name expected\n");
836b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
837b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
838b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
839b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
840b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_ELEM, token, URL);
841b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
842b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
843b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    NEXT;
844b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (xmlStrEqual(token, (const xmlChar *) "child")) {
845b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlFree(token);
846b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		token = xmlPatScanName(ctxt);
847b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
848b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	            if (CUR == '*') {
849b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            	        NEXT;
850b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	                PUSH(XML_OP_ALL, token, NULL);
851b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	                return;
852b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	            } else {
853b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        ERROR(NULL, NULL, NULL,
854b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : QName expected\n");
855b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        ctxt->error = 1;
856b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        goto error;
857b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
858b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
859b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		TODO
860b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* URI = xsltGetQNameURI(ctxt->elem, &token); */
861b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
862b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
863b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
864b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
865b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    name = xmlStrdup(token);
866b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (URI != NULL)
867b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			URL = xmlStrdup(URI);
868b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
869b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_CHILD, name, URL);
870b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else if (xmlStrEqual(token, (const xmlChar *) "attribute")) {
871b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlFree(token);
872b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		token = xmlPatScanName(ctxt);
873b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
874b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ERROR(NULL, NULL, NULL,
875b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : QName expected\n");
876b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
877b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
878b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
879b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		TODO
880b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* URI = xsltGetQNameURI(ctxt->elem, &token); */
881b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
882b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
883b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
884b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
885b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    name = xmlStrdup(token);
886b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (URI != NULL)
887b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			URL = xmlStrdup(URI);
888b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
889b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_ATTR, name, URL);
890b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
891b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ERROR(NULL, NULL, NULL,
892b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    "xmlCompileStepPattern : 'child' or 'attribute' expected\n");
893b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ctxt->error = 1;
894b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		goto error;
895b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
896b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree(token);
897b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
898b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if (CUR == '*') {
899b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
900b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ALL, token, NULL);
901b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
902b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (name == NULL) {
903b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
904b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    goto error;
905b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
906b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ELEM, name, NULL);
907b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
908b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return;
909b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
910b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (token != NULL)
911b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree(token);
912b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (name != NULL)
913b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree(name);
914b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
915b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
916b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
917b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompilePathPattern:
918b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the compilation context
919b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
920b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Path Pattern and generates a precompiled
921b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching.
922b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
923b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )
924b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
925b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
926b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
927b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
928b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((CUR == '/') && (NXT(1) == '/')) {
929b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/*
930b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * since we reverse the query
931b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * a leading // can be safely ignored
932b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 */
933b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
934b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
935b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {
936b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/*
937b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * a leading .// can be safely ignored
938b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 */
939b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
940b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
941b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
942b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
943b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '@') {
944b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	TODO
945b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
9462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (CUR == '/') {
9472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    PUSH(XML_OP_ROOT, NULL, NULL);
9482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    NEXT;
9492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
950b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlCompileStepPattern(ctxt);
951b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	SKIP_BLANKS;
952b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while (CUR == '/') {
953b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if ((CUR == '/') && (NXT(1) == '/')) {
954b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	        PUSH(XML_OP_ANCESTOR, NULL, NULL);
955b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
956b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
957b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		SKIP_BLANKS;
958b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlCompileStepPattern(ctxt);
959b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
960b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	        PUSH(XML_OP_PARENT, NULL, NULL);
961b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
962b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		SKIP_BLANKS;
963b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((CUR != 0) || (CUR == '|')) {
964b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    xmlCompileStepPattern(ctxt);
965b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
966b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
967b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
968b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
969b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
970b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return;
971b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
9722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
9732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/************************************************************************
9742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *									*
9752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *			The streaming code				*
9762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *									*
9772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ************************************************************************/
9782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
9792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING
9802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
9812fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamComp(xmlStreamCompPtr stream) {
9822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
9832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
9842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL) {
9852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("Stream: NULL\n");
9862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return;
9872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
9882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    printf("Stream: %d steps\n", stream->nbStep);
9892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < stream->nbStep;i++) {
9902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].ns != NULL) {
9912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("{%s}", stream->steps[i].ns);
9922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
9932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (stream->steps[i].name == NULL) {
9942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("* ");
9952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	} else {
9962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("%s ", stream->steps[i].name);
9972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
9982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_ROOT)
9992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("root ");
10002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_DESC)
10012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("// ");
10022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->steps[i].flags & XML_STREAM_STEP_FINAL)
10032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf("final ");
10042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	printf("\n");
10052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
10072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
10082fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) {
10092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
10102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (ctxt == NULL) {
10122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("Stream: NULL\n");
10132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return;
10142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState);
10162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (match)
10172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("matches\n");
10182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    else
10192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        printf("\n");
10202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < ctxt->nbState;i++) {
10212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (ctxt->states[2 * i] < 0)
10222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf(" %d: free\n", i);
10232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	else {
10242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    printf(" %d: step %d, level %d", i, ctxt->states[2 * i],
10252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	           ctxt->states[(2 * i) + 1]);
10262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard            if (ctxt->comp->steps[ctxt->states[2 * i]].flags &
10272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        XML_STREAM_STEP_DESC)
10282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        printf(" //\n");
10292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    else
10302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        printf("\n");
10312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
10322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
10342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif
10352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
10362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamComp:
10372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected steps
10382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
10392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new compiled pattern for streaming
10402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
10412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error.
10422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
10432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCompPtr
10442fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamComp(int size) {
10452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr cur;
10462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (size < 4)
10482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        size  = 4;
10492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp));
10512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur == NULL) {
10522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
10532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		"xmlNewStreamComp: malloc failed\n");
10542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
10552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    memset(cur, 0, sizeof(xmlStreamComp));
10572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep));
10582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur->steps == NULL) {
10592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlFree(cur);
10602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
10612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	      "xmlNewStreamComp: malloc failed\n");
10622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
10632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->nbStep = 0;
10652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->maxStep = size;
10662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(cur);
10672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
10682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
10702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamComp:
10712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming
10722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
10732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the compiled pattern for streaming
10742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
10752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void
10762fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamComp(xmlStreamCompPtr comp) {
10772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp != NULL) {
10782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->steps != NULL)
10792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlFree(comp->steps);
10802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (comp->dict != NULL)
10812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlDictFree(comp->dict);
10822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFree(comp);
10832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
10842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
10852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
10862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
10872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompAddStep:
10882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming
10892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the first string, the name, or NULL for *
10902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the second step, the namespace name
10912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @flags: the flags for that step
10922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
10932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new step to the compiled pattern
10942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
10952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the step index if successful
10962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
10972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
10982fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name,
10992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard                     const xmlChar *ns, int flags) {
11002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamStepPtr cur;
11012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->nbStep >= comp->maxStep) {
11032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	cur = (xmlStreamStepPtr) xmlRealloc(comp->steps,
11042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard				 comp->maxStep * 2 * sizeof(xmlStreamStep));
11052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (cur == NULL) {
11062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    ERROR(NULL, NULL, NULL,
11072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		  "xmlNewStreamComp: malloc failed\n");
11082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(-1);
11092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
11102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	comp->steps = cur;
11112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        comp->maxStep *= 2;
11122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
11132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = &comp->steps[comp->nbStep++];
11142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->flags = flags;
11152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->name = name;
11162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->ns = ns;
11172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(comp->nbStep - 1);
11182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
11192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
11212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompile:
11222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern
11232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Tries to stream compile a pattern
11252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of failure and 0 in case of success.
11272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
11282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
11292fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompile(xmlPatternPtr comp) {
11302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr stream;
11312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i, s = 0, root = 0, desc = 0;
11322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((comp == NULL) || (comp->steps == NULL))
11342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
11352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    stream = xmlNewStreamComp((comp->nbStep / 2) + 1);
11362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL)
11372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
11382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->dict != NULL) {
11392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        stream->dict = comp->dict;
11402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlDictReference(stream->dict);
11412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
11422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < comp->nbStep;i++) {
11432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        switch (comp->steps[i].op) {
11442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_END:
11452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        break;
11462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ROOT:
11472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        if (i != 0)
11482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
11492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		root = 1;
11502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
11512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_CHILD:
11522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ATTR:
11532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_NS:
11542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        goto error;
11552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ELEM:
11562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        s = xmlStreamCompAddStep(stream, comp->steps[i].value,
11572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		                         comp->steps[i].value2, desc);
11582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		desc = 0;
11592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (s < 0)
11602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
11612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
11622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ALL:
11632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        s = xmlStreamCompAddStep(stream, NULL, NULL, desc);
11642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		desc = 0;
11652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		if (s < 0)
11662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    goto error;
11672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
11682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_PARENT:
11692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        break;
11702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    case XML_OP_ANCESTOR:
11712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        desc = XML_STREAM_STEP_DESC;
11722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		break;
11732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
11742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
11752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    stream->steps[s].flags |= XML_STREAM_STEP_FINAL;
11762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (root)
11772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	stream->steps[0].flags |= XML_STREAM_STEP_ROOT;
11782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING
11792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlDebugStreamComp(stream);
11802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif
11812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->stream = stream;
11822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
11832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillarderror:
11842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlFreeStreamComp(stream);
11852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
11862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
11872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
11882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
11892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamCtxt:
11902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected states
11912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new stream context
11932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
11942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error.
11952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
11962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCtxtPtr
11972fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamCtxt(xmlStreamCompPtr stream) {
11982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCtxtPtr cur;
11992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt));
12012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur == NULL) {
12022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
12032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		"xmlNewStreamCtxt: malloc failed\n");
12042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
12052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    memset(cur, 0, sizeof(xmlStreamCtxt));
12072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int));
12082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (cur->states == NULL) {
12092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	xmlFree(cur);
12102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	ERROR(NULL, NULL, NULL,
12112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	      "xmlNewStreamCtxt: malloc failed\n");
12122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(NULL);
12132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->nbState = 0;
12152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->maxState = 4;
12162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->level = 0;
12172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    cur->comp = stream;
12182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(cur);
12192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
12202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
12222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamCtxt:
12232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
12242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the stream context
12262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
12272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardvoid
12282fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamCtxt(xmlStreamCtxtPtr stream) {
12292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream != NULL) {
12302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (stream->states != NULL)
12312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    xmlFree(stream->states);
12322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        xmlFree(stream);
12332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
12352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
12372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCtxtAddState:
12382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the stream context
12392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @idx: the step index for that streaming state
12402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new state to the stream context
12422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the state index if successful
12442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
12452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int
12462fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) {
12472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    int i;
12482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < comp->nbState;i++) {
12492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->states[2 * i] < 0) {
12502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    comp->states[2 * i] = idx;
12512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    comp->states[2 * i + 1] = level;
12522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(i);
12532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
12542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (comp->nbState >= comp->maxState) {
12562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        int *cur;
12572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	cur = (int *) xmlRealloc(comp->states,
12592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard				 comp->maxState * 4 * sizeof(int));
12602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (cur == NULL) {
12612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    ERROR(NULL, NULL, NULL,
12622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		  "xmlNewStreamCtxt: malloc failed\n");
12632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    return(-1);
12642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
12652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	comp->states = cur;
12662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        comp->maxState *= 2;
12672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
12682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->states[2 * comp->nbState] = idx;
12692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp->states[2 * comp->nbState++ + 1] = level;
12702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(comp->nbState - 1);
12712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
12722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
12742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamPush:
12752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
12762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the current name
12772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the namespace name
12782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * push new data onto the stream. NOTE: if the call xmlPatterncompile()
12802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * indicated a dictionnary, then strings for name and ns will be expected
12812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * to come from the dictionary.
12822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Both @name and @ns being NULL means the / i.e. the root of the document.
12832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * This can also act as a reset.
12842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
12852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 1 if the current state in the stream is a
12862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *    match and 0 otherwise.
12872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
12882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardint
12892fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamPush(xmlStreamCtxtPtr stream,
12902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard              const xmlChar *name, const xmlChar *ns) {
129116ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard    int ret = 0, tmp, i, m, match, step, desc, final;
12922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompPtr comp;
12932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
12942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((stream == NULL) || (stream->nbState < 0))
12952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
12962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    comp = stream->comp;
12972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((name == NULL) && (ns == NULL)) {
12982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        stream->nbState = 0;
12992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	stream->level = 0;
13002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) {
13012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    tmp = xmlStreamCtxtAddState(stream, 0, 0);
13022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    if (tmp < 0)
13032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        return(-1);
13042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    if (comp->steps[tmp].flags & XML_STREAM_STEP_FINAL)
13052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		return(1);
13062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
13072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	return(0);
13082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
13092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    /*
13102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard     * Check evolution of existing states
13112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard     */
13122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    m = stream->nbState;
13132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    for (i = 0;i < m;i++) {
13142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        match = 0;
13152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	step = stream->states[2 * i];
13162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	/* dead states */
13172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (step < 0) continue;
13182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	/* skip new states just added */
13192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (stream->states[(2 * i) + 1] > stream->level) continue;
132016ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard	/* skip continuations */
132116ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard	desc = comp->steps[step].flags & XML_STREAM_STEP_DESC;
132216ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard	if ((stream->states[(2 * i) + 1] < stream->level) && (!desc))continue;
13232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	/* discard old states */
13252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	/* something needed about old level discarded */
13262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->dict) {
13282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    if (comp->steps[step].name == NULL) {
13292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        if (comp->steps[step].ns == NULL)
13302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    match = 1;
13312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		else
13322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    match = (comp->steps[step].ns == ns);
13332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    } else {
13342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		match = ((comp->steps[step].name == name) &&
13352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard			 (comp->steps[step].ns == ns));
13362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
13372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	} else {
13382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    if (comp->steps[step].name == NULL) {
13392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        if (comp->steps[step].ns == NULL)
13402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    match = 1;
13412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		else
13422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    match = xmlStrEqual(comp->steps[step].ns, ns);
13432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    } else {
13442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		match = ((xmlStrEqual(comp->steps[step].name, name)) &&
13452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard			 (xmlStrEqual(comp->steps[step].ns, ns)));
13462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
13472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
13482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (match) {
134916ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard	    final = comp->steps[step].flags & XML_STREAM_STEP_FINAL;
135016ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard	    if (desc) {
135116ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard		if (final) {
13522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    ret = 1;
13532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		} else {
13542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    /* descending match create a new state */
13552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    xmlStreamCtxtAddState(stream, step + 1, stream->level + 1);
13562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		}
13572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    } else {
135816ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard		if (final) {
13592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    ret = 1;
136016ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard#if 0
13612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    stream->states[2 * i] = -1;
136216ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard#endif
13632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		} else {
136416ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard#if 0
13652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    stream->states[2 * i] = step + 1;
13662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    stream->states[2 * i + 1] = stream->level + 1;
136716ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard#endif
136816ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard		    xmlStreamCtxtAddState(stream, step + 1, stream->level + 1);
13692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		}
13702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
13719740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard#if 0
137216ef800bd682f0f59284e2f983c3a72e6b3e2245Daniel Veillard	} else if (!desc) {
13732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    /* didn't match, discard */
13742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    stream->states[2 * i] = -1;
13759740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard#endif
13762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
13772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
13782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
13792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    /*
13802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard     * Check creating a new state.
13812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard     */
13822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    stream->level++;
13832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (!(comp->steps[0].flags & XML_STREAM_STEP_ROOT)) {
13842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        match = 0;
13852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        if (comp->dict) {
13862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    if (comp->steps[0].name == NULL) {
13872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        if (comp->steps[0].ns == NULL)
13882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    match = 1;
13892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		else
13902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    match = (comp->steps[0].ns == ns);
13912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    } else {
13922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		match = ((comp->steps[0].name == name) &&
13932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard			 (comp->steps[0].ns == ns));
13942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
13952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	} else {
13962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    if (comp->steps[0].name == NULL) {
13972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        if (comp->steps[0].ns == NULL)
13982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    match = 1;
13992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		else
14002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		    match = xmlStrEqual(comp->steps[0].ns, ns);
14012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    } else {
14022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard		match = ((xmlStrEqual(comp->steps[0].name, name)) &&
14032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard			 (xmlStrEqual(comp->steps[0].ns, ns)));
14042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    }
14052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
14062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	if (match) {
14072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	    if (comp->steps[0].flags & XML_STREAM_STEP_FINAL)
14082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        ret = 1;
14092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard            else
14102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	        xmlStreamCtxtAddState(stream, 1, stream->level);
14112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard	}
14122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    }
14132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
14142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING
14152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlDebugStreamCtxt(stream, ret);
14162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif
14172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(ret);
14182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
14192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
14202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
14212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamPop:
14222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context
14232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
14242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * push one level from the stream.
14252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
14262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 0 otherwise.
14272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
14282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardint
14292fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamPop(xmlStreamCtxtPtr stream) {
14309740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard    int i, m;
14319740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard
14322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream == NULL)
14332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
14342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    stream->level--;
14352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if (stream->level < 0)
14362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(-1);
14372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
14389740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard    /*
14399740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard     * Check evolution of existing states
14409740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard     */
14419740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard    m = stream->nbState;
14429740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard    for (i = 0;i < m;i++) {
14439740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard	if (stream->states[(2 * i)] < 0) break;
14449740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard	/* discard obsoleted states */
14459740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard	if (stream->states[(2 * i) + 1] > stream->level)
14469740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard	    stream->states[(2 * i)] = -1;
14479740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard    }
14482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(0);
14492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
14502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
1451b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
1452b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
1453b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *			The public interfaces				*
1454b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
1455b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
1456b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1457b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
1458b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatterncompile:
1459b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern: the pattern to compile
1460b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @dict: an optional dictionnary for interned strings
1461b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @flags: compilation flags, undefined yet
1462ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] or NULL
1463b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1464ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * Compile a pattern.
1465b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1466b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the compiled for of the pattern or NULL in case of error
1467b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
1468b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternPtr
1469427174fbf2544b44071c1039720e6634fb154f84Daniel VeillardxmlPatterncompile(const xmlChar *pattern, xmlDict *dict,
1470427174fbf2544b44071c1039720e6634fb154f84Daniel Veillard                  int flags ATTRIBUTE_UNUSED,
1471ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard                  const xmlChar **namespaces) {
1472b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr ret = NULL;
1473b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatParserContextPtr ctxt = NULL;
1474b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1475ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard    ctxt = xmlNewPatParserContext(pattern, dict, namespaces);
1476b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt == NULL) goto error;
1477b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlNewPattern();
1478b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ret == NULL) goto error;
1479b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ctxt->comp = ret;
1480b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1481b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlCompilePathPattern(ctxt);
1482b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFreePatParserContext(ctxt);
1483b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
14842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    xmlStreamCompile(ret);
1485c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard    if (xmlReversePattern(ret) < 0)
1486c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard        goto error;
1487b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
1488b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
1489b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt != NULL) xmlFreePatParserContext(ctxt);
1490b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ret != NULL) xmlFreePattern(ret);
1491b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(NULL);
1492b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
1493b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
1494b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
1495b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternMatch:
1496b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern
1497b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node
1498b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1499b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Test wether the node matches the pattern
1500b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
1501b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
1502b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
1503b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardint
1504b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
1505b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{
1506b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((comp == NULL) || (node == NULL))
1507b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return(-1);
1508b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(xmlPatMatch(comp, node));
1509b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
1510b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
15112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/**
15122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlPatternGetStreamCtxt:
15132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern
15142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Get a streaming context for that pattern
15162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Use xmlFreeStreamCtxt to free the context.
15172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard *
15182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns a pointer to the context or NULL in case of failure
15192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */
15202fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtPtr
15212fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlPatternGetStreamCtxt(xmlPatternPtr comp)
15222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard{
15232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    if ((comp == NULL) || (comp->stream == NULL))
15242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard        return(NULL);
15252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard    return(xmlNewStreamCtxt(comp->stream));
15262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}
15272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard
1528b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif /* LIBXML_PATTERN_ENABLED */
1529