pattern.c revision b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26
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
14b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define IN_LIBXML
15b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include "libxml.h"
16b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
17b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <string.h>
18b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/xmlmemory.h>
19b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/tree.h>
20b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/hash.h>
21b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/dict.h>
22b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/xmlerror.h>
23b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/parserInternals.h>
24b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#include <libxml/pattern.h>
25b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
26b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_PATTERN_ENABLED
27b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
28b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define ERROR(a, b, c, d)
29b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define ERROR5(a, b, c, d, e)
30b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
31b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/*
32b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Types are private:
33b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
34b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
35b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef enum {
36b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_END=0,
37b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ROOT,
38b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ELEM,
39b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_CHILD,
40b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ATTR,
41b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_PARENT,
42b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ANCESTOR,
43b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_NS,
44b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    XML_OP_ALL
45b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} xmlPatOp;
46b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
47b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
48b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlStepOp xmlStepOp;
49b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlStepOp *xmlStepOpPtr;
50b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlStepOp {
51b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatOp op;
52b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *value;
53b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *value2;
54b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
55b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
56b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPattern {
57b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    void *data;    		/* the associated template */
58b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    struct _xmlPattern *next; /* siblings */
59b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *pattern;	/* the pattern */
60b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
61b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    /* TODO fix the statically allocated size steps[] */
62b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int nbStep;
63b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int maxStep;
64b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOp steps[10];        /* ops for computation */
65b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
66b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
67b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlPatParserContext xmlPatParserContext;
68b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlPatParserContext *xmlPatParserContextPtr;
69b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPatParserContext {
70b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *cur;			/* the current char being parsed */
71b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *base;		/* the full expression */
72b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int	           error;		/* error code */
73b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlDictPtr     dict;		/* the dictionnary if any */
74b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr  comp;		/* the result */
75b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlNodePtr     elem;		/* the current node if any */
76b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard};
77b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
78b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
79b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
80b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 			Type functions 					*
81b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
82b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
83b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
84b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
85b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPattern:
86b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
87b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XSLT Pattern
88b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
89b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatternPtr or NULL in case of error
90b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
91b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatternPtr
92b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlNewPattern(void) {
93b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr cur;
94b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
95b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern));
96b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (cur == NULL) {
97b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ERROR(NULL, NULL, NULL,
98b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		"xmlNewPattern : malloc failed\n");
99b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
100b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
101b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(cur, 0, sizeof(xmlPattern));
102b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->maxStep = 10;
103b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(cur);
104b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
105b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
106b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
107b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePattern:
108b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  an XSLT comp
109b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
110b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @comp
111b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
112b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid
113b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePattern(xmlPatternPtr comp) {
114b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOpPtr op;
115b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
116b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
117b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp == NULL)
118b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
119b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp->pattern != NULL)
120b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree((xmlChar *)comp->pattern);
121b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    for (i = 0;i < comp->nbStep;i++) {
122b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = &comp->steps[i];
123b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (op->value != NULL)
124b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree((xmlChar *) op->value);
125b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (op->value2 != NULL)
126b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree((xmlChar *) op->value2);
127b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
128b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(comp, -1, sizeof(xmlPattern));
129b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFree(comp);
130b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
131b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
132b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
133b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatternList:
134b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  an XSLT comp list
135b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
136b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by all the elements of @comp
137b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
138b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid
139b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatternList(xmlPatternPtr comp) {
140b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr cur;
141b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
142b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (comp != NULL) {
143b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = comp;
144b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp = comp->next;
145b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFreePattern(cur);
146b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
147b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
148b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
149b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
150b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPatParserContext:
151b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern:  the pattern context
152b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the transformation context, if done at run-time
153b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
154b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XML pattern parser context
155b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
156b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error
157b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
158b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatParserContextPtr
159b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict) {
160b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatParserContextPtr cur;
161b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
162b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (pattern == NULL)
163b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return(NULL);
164b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
165b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext));
166b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (cur == NULL) {
167b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ERROR(NULL, NULL, NULL,
168b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		"xmlNewPatParserContext : malloc failed\n");
169b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
170b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
171b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(cur, 0, sizeof(xmlPatParserContext));
172b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->dict = dict;
173b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->cur = pattern;
174b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur->base = pattern;
175b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(cur);
176b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
177b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
178b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
179b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatParserContext:
180b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  an XSLT parser context
181b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
182b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @ctxt
183b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
184b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
185b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatParserContext(xmlPatParserContextPtr ctxt) {
186b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt == NULL)
187b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
188b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    memset(ctxt, -1, sizeof(xmlPatParserContext));
189b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFree(ctxt);
190b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
191b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
192b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
193b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternAdd:
194b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
195b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @op:  an op
196b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value:  the first value
197b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value2:  the second value
198b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
199b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Add an step to an XSLT Compiled Match
200b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
201b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns -1 in case of failure, 0 otherwise.
202b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
203b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int
204b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED,
205b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                xmlPatternPtr comp,
206b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                xmlPatOp op, xmlChar * value, xmlChar * value2)
207b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{
208b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (comp->nbStep >= 10) {
209b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        ERROR(ctxt, NULL, NULL,
210b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard                         "xmlPatternAdd: overflow\n");
211b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return (-1);
212b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
213b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].op = op;
214b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].value = value;
215b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep].value2 = value2;
216b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->nbStep++;
217b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return (0);
218b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
219b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
220b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
221b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
222b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xsltSwapTopPattern:
223b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
224b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
225b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse the two top steps.
226b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
227b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
228b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxsltSwapTopPattern(xmlPatternPtr comp) {
229b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
230b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int j = comp->nbStep - 1;
231b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
232b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (j > 0) {
233b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register const xmlChar *tmp;
234b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register xmlPatOp op;
235b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	i = j - 1;
236b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value;
237b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value = comp->steps[j].value;
238b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value = tmp;
239b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value2;
240b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value2 = comp->steps[j].value2;
241b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value2 = tmp;
242b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = comp->steps[i].op;
243b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].op = comp->steps[j].op;
244b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].op = op;
245b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
246b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
247b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
248b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
249b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
250b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlReversePattern:
251b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp:  the compiled match expression
252b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
253b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse all the stack of expressions
254b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
255b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
256b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlReversePattern(xmlPatternPtr comp) {
257b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i = 0;
258b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int j = comp->nbStep - 1;
259b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
260b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (j > i) {
261b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register const xmlChar *tmp;
262b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	register xmlPatOp op;
263b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value;
264b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value = comp->steps[j].value;
265b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value = tmp;
266b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	tmp = comp->steps[i].value2;
267b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].value2 = comp->steps[j].value2;
268b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].value2 = tmp;
269b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	op = comp->steps[i].op;
270b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[i].op = comp->steps[j].op;
271b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	comp->steps[j].op = op;
272b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	j--;
273b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	i++;
274b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
275b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    comp->steps[comp->nbStep++].op = XML_OP_END;
276b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
277b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
278b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
279b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
280b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 		The interpreter for the precompiled patterns		*
281b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 									*
282b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
283b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
284b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
285b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatMatch:
286b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern
287b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node
288b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
289b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Test wether the node matches the pattern
290b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
291b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
292b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
293b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int
294b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) {
295b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int i;
296b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlStepOpPtr step;
297b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
298b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((comp == NULL) || (node == NULL)) return(-1);
299b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    for (i = 0;i < comp->nbStep;i++) {
300b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	step = &comp->steps[i];
301b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	switch (step->op) {
302b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_END:
303b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		return(1);
304b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ROOT:
305b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
306b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
307b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
308b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
309b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE))
310b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
311b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		return(0);
312b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ELEM:
313b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
314b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
315b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL)
316b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
317b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value[0] != node->name[0])
318b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
319b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (!xmlStrEqual(step->value, node->name))
320b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
321b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
322b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
323b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
324b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
325b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
326b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
327b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 == NULL)
328b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
329b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
330b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
331b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
332b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
333b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_CHILD: {
334b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlNodePtr lst;
335b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
336b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type != XML_ELEMENT_NODE) &&
337b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_DOCUMENT_NODE) &&
338b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
339b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_DOCB_DOCUMENT_NODE) &&
340b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
341b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type != XML_HTML_DOCUMENT_NODE))
342b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
343b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
344b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		lst = node->children;
345b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
346b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value != NULL) {
347b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    while (lst != NULL) {
348b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			if ((lst->type == XML_ELEMENT_NODE) &&
349b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    (step->value[0] == lst->name[0]) &&
350b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    (xmlStrEqual(step->value, lst->name)))
351b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    break;
352b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			lst = lst->next;
353b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
354b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (lst != NULL)
355b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			continue;
356b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
357b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		return(0);
358b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
359b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ATTR:
360b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ATTRIBUTE_NODE)
361b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
362b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value != NULL) {
363b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value[0] != node->name[0])
364b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
365b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value, node->name))
366b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
367b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
368b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
369b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
370b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
371b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
372b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (step->value2 != NULL) {
373b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
374b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
375b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
376b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
377b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_PARENT:
378b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
379b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE) ||
380b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
381b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
382b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
383b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_NAMESPACE_DECL))
384b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
385b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		node = node->parent;
386b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
387b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
388b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL)
389b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    continue;
390b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value[0] != node->name[0])
391b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
392b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (!xmlStrEqual(step->value, node->name))
393b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
394b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* Namespace test */
395b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
396b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 != NULL)
397b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
398b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
399b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value2 == NULL)
400b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
401b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value2, node->ns->href))
402b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
403b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
404b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
405b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ANCESTOR:
406b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* TODO: implement coalescing of ANCESTOR/NODE ops */
407b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (step->value == NULL) {
408b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    i++;
409b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    step = &comp->steps[i];
410b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->op == XML_OP_ROOT)
411b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(1);
412b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->op != XML_OP_ELEM)
413b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
414b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value == NULL)
415b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(-1);
416b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
417b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
418b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
419b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((node->type == XML_DOCUMENT_NODE) ||
420b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_HTML_DOCUMENT_NODE) ||
421b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED
422b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_DOCB_DOCUMENT_NODE) ||
423b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
424b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    (node->type == XML_NAMESPACE_DECL))
425b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
426b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		node = node->parent;
427b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		while (node != NULL) {
428b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (node == NULL)
429b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
430b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if ((node->type == XML_ELEMENT_NODE) &&
431b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			(step->value[0] == node->name[0]) &&
432b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			(xmlStrEqual(step->value, node->name))) {
433b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			/* Namespace test */
434b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			if (node->ns == NULL) {
435b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    if (step->value2 == NULL)
436b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				break;
437b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			} else if (node->ns->href != NULL) {
438b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    if ((step->value2 != NULL) &&
439b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			        (xmlStrEqual(step->value2, node->ns->href)))
440b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				break;
441b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			}
442b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
443b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    node = node->parent;
444b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
445b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node == NULL)
446b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
447b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		continue;
448b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_NS:
449b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
450b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
451b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->ns == NULL) {
452b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value != NULL)
453b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
454b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else if (node->ns->href != NULL) {
455b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (step->value == NULL)
456b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
457b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (!xmlStrEqual(step->value, node->ns->href))
458b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			return(0);
459b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
460b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		break;
461b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            case XML_OP_ALL:
462b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (node->type != XML_ELEMENT_NODE)
463b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    return(0);
464b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		break;
465b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
466b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
467b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(1);
468b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
469b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
470b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
471b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
472b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *			Dedicated parser for templates			*
473b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
474b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
475b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
476b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define TODO 								\
477b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlGenericError(xmlGenericErrorContext,				\
478b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    "Unimplemented block at %s:%d\n",				\
479b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            __FILE__, __LINE__);
480b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR (*ctxt->cur)
481b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP(val) ctxt->cur += (val)
482b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NXT(val) ctxt->cur[(val)]
483b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR_PTR ctxt->cur
484b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
485b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP_BLANKS 							\
486b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while (IS_BLANK(CUR)) NEXT
487b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
488b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CURRENT (*ctxt->cur)
489b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NEXT ((*ctxt->cur) ?  ctxt->cur++: ctxt->cur)
490b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
491b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
492b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define PUSH(op, val, val2) 						\
493b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error;
494b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
495b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR(X)							\
496b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    { xsltError(ctxt, __FILE__, __LINE__, X);			\
497b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard      ctxt->error = (X); return; }
498b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
499b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR0(X)							\
500b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    { xsltError(ctxt, __FILE__, __LINE__, X);			\
501b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard      ctxt->error = (X); return(0); }
502b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
503b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
504b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
505b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanLiteral:
506b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
507b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
508b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse an XPath Litteral:
509b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
510b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [29] Literal ::= '"' [^"]* '"'
511b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *                | "'" [^']* "'"
512b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
513b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Literal parsed or NULL
514b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
515b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
516b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
517b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanLiteral(xmlPatParserContextPtr ctxt) {
518b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
519b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
520b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
521b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
522b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
523b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '"') {
524b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        NEXT;
525b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = q = CUR_PTR;
526b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
527b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while ((IS_CHAR(val)) && (val != '"')) {
528b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    cur += len;
529b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    val = xmlStringCurrentChar(NULL, cur, &len);
530b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
531b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (!IS_CHAR(val)) {
532b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
533b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return(NULL);
534b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
535b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ret = xmlStrndup(q, cur - q);
536b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        }
537b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
538b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	CUR_PTR = cur;
539b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if (CUR == '\'') {
540b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        NEXT;
541b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur = q = CUR_PTR;
542b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
543b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while ((IS_CHAR(val)) && (val != '\'')) {
544b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    cur += len;
545b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    val = xmlStringCurrentChar(NULL, cur, &len);
546b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
547b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (!IS_CHAR(val)) {
548b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
549b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return(NULL);
550b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
551b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ret = xmlStrndup(q, cur - q);
552b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        }
553b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
554b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	CUR_PTR = cur;
555b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
556b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/* XP_ERROR(XPATH_START_LITERAL_ERROR); */
557b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ctxt->error = 1;
558b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
559b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
560b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
561b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
562b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
563b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
564b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
565b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanName:
566b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
567b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
568b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' |
569b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *                  CombiningChar | Extender
570b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
571b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5] Name ::= (Letter | '_' | ':') (NameChar)*
572b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
573b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [6] Names ::= Name (S Name)*
574b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
575b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
576b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
577b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
578b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
579b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanName(xmlPatParserContextPtr ctxt) {
580b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
581b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
582b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
583b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
584b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
585b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
586b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = q = CUR_PTR;
587b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    val = xmlStringCurrentChar(NULL, cur, &len);
588b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (!IS_LETTER(val) && (val != '_') && (val != ':'))
589b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
590b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
591b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
592b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard           (val == '.') || (val == '-') ||
593b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (val == '_') ||
594b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_COMBINING(val)) ||
595b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_EXTENDER(val))) {
596b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
597b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
598b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
599b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlStrndup(q, cur - q);
600b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    CUR_PTR = cur;
601b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
602b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
603b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
604b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
605b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanNCName:
606b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
607b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
608b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parses a non qualified name
609b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
610b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
611b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
612b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
613b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
614b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanNCName(xmlPatParserContextPtr ctxt) {
615b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *q, *cur;
616b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
617b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    int val, len;
618b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
619b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
620b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
621b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    cur = q = CUR_PTR;
622b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    val = xmlStringCurrentChar(NULL, cur, &len);
623b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (!IS_LETTER(val) && (val != '_'))
624b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return(NULL);
625b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
626b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    while ((IS_LETTER(val)) || (IS_DIGIT(val)) ||
627b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard           (val == '.') || (val == '-') ||
628b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (val == '_') ||
629b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_COMBINING(val)) ||
630b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	   (IS_EXTENDER(val))) {
631b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	cur += len;
632b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	val = xmlStringCurrentChar(NULL, cur, &len);
633b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
634b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlStrndup(q, cur - q);
635b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    CUR_PTR = cur;
636b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
637b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
638b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
639b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0
640b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
641b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanQName:
642b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the XPath Parser context
643b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @prefix:  the place to store the prefix
644b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
645b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse a qualified name
646b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
647b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL
648b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
649b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
650b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar *
651b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) {
652b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *ret = NULL;
653b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
654b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    *prefix = NULL;
655b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlPatScanNCName(ctxt);
656b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == ':') {
657b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        *prefix = ret;
658b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
659b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	ret = xmlPatScanNCName(ctxt);
660b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
661b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
662b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
663b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif
664b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
665b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
666b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompileStepPattern:
667b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the compilation context
668b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
669b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Step Pattern and generates a precompiled
670b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching.
671b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
672b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [3]    Step    ::=    '.' | NameTest
673b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [4]    NameTest    ::=    QName | '*' | NCName ':' '*'
674b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
675b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
676b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
677b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompileStepPattern(xmlPatParserContextPtr ctxt) {
678b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *token = NULL;
679b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *name = NULL;
680b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    const xmlChar *URI = NULL;
681b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlChar *URL = NULL;
682b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
683b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
684b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '.') {
685b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
686b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ELEM, NULL, NULL);
687b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	return;
688b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
689b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    name = xmlPatScanNCName(ctxt);
690b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (name == NULL) {
691b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (CUR == '*') {
692b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    NEXT;
693b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    PUSH(XML_OP_ALL, NULL, NULL);
694b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return;
695b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
696b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ERROR(NULL, NULL, NULL,
697b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    "xmlCompileStepPattern : Name expected\n");
698b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
699b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    return;
700b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
701b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
702b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
703b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == ':') {
704b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
705b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (CUR != ':') {
706b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlChar *prefix = name;
707b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlNsPtr ns;
708b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
709b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    /*
710b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	     * This is a namespace match
711b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	     */
712b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    token = xmlPatScanName(ctxt);
713b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ns = xmlSearchNs(NULL, ctxt->elem, prefix);
714b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (ns == NULL) {
715b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ERROR5(NULL, NULL, NULL,
716b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    "xmlCompileStepPattern : no namespace bound to prefix %s\n",
717b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard				 prefix);
718b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ctxt->error = 1;
719b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		goto error;
720b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
721b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		URL = xmlStrdup(ns->href);
722b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
723b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree(prefix);
724b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (token == NULL) {
725b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (CUR == '*') {
726b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    NEXT;
727b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    PUSH(XML_OP_NS, URL, NULL);
728b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
729b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ERROR(NULL, NULL, NULL,
730b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : Name expected\n");
731b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
732b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
733b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
734b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
735b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_ELEM, token, URL);
736b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
737b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	} else {
738b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    NEXT;
739b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if (xmlStrEqual(token, (const xmlChar *) "child")) {
740b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlFree(token);
741b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		token = xmlPatScanName(ctxt);
742b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
743b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	            if (CUR == '*') {
744b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard            	        NEXT;
745b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	                PUSH(XML_OP_ALL, token, NULL);
746b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	                return;
747b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	            } else {
748b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        ERROR(NULL, NULL, NULL,
749b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : QName expected\n");
750b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        ctxt->error = 1;
751b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		        goto error;
752b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    }
753b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
754b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		TODO
755b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* URI = xsltGetQNameURI(ctxt->elem, &token); */
756b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
757b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
758b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
759b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
760b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    name = xmlStrdup(token);
761b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (URI != NULL)
762b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			URL = xmlStrdup(URI);
763b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
764b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_CHILD, name, URL);
765b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else if (xmlStrEqual(token, (const xmlChar *) "attribute")) {
766b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlFree(token);
767b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		token = xmlPatScanName(ctxt);
768b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
769b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ERROR(NULL, NULL, NULL,
770b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			    "xmlCompileStepPattern : QName expected\n");
771b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
772b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
773b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
774b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		TODO
775b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		/* URI = xsltGetQNameURI(ctxt->elem, &token); */
776b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if (token == NULL) {
777b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    ctxt->error = 1;
778b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    goto error;
779b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		} else {
780b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    name = xmlStrdup(token);
781b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    if (URI != NULL)
782b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard			URL = xmlStrdup(URI);
783b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
784b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		PUSH(XML_OP_ATTR, name, URL);
785b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
786b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ERROR(NULL, NULL, NULL,
787b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    "xmlCompileStepPattern : 'child' or 'attribute' expected\n");
788b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		ctxt->error = 1;
789b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		goto error;
790b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
791b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    xmlFree(token);
792b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
793b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if (CUR == '*') {
794b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
795b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ALL, token, NULL);
796b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
797b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	if (name == NULL) {
798b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    ctxt->error = 1;
799b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    goto error;
800b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
801b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	PUSH(XML_OP_ELEM, name, NULL);
802b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
803b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return;
804b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
805b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (token != NULL)
806b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree(token);
807b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (name != NULL)
808b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlFree(name);
809b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
810b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
811b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
812b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompilePathPattern:
813b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt:  the compilation context
814b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
815b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Path Pattern and generates a precompiled
816b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching.
817b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
818b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5]    Path    ::=    ('.//')? ( Step '/' )* ( Step | '@' NameTest )
819b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
820b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void
821b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompilePathPattern(xmlPatParserContextPtr ctxt) {
822b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    SKIP_BLANKS;
823b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((CUR == '/') && (NXT(1) == '/')) {
824b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/*
825b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * since we reverse the query
826b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * a leading // can be safely ignored
827b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 */
828b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
829b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
830b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) {
831b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	/*
832b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 * a leading .// can be safely ignored
833b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	 */
834b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
835b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
836b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	NEXT;
837b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
838b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (CUR == '@') {
839b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	TODO
840b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    } else {
841b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	xmlCompileStepPattern(ctxt);
842b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	SKIP_BLANKS;
843b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	while (CUR == '/') {
844b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    if ((CUR == '/') && (NXT(1) == '/')) {
845b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	        PUSH(XML_OP_ANCESTOR, NULL, NULL);
846b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
847b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
848b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		SKIP_BLANKS;
849b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		xmlCompileStepPattern(ctxt);
850b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    } else {
851b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	        PUSH(XML_OP_PARENT, NULL, NULL);
852b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		NEXT;
853b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		SKIP_BLANKS;
854b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		if ((CUR != 0) || (CUR == '|')) {
855b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		    xmlCompileStepPattern(ctxt);
856b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard		}
857b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	    }
858b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard	}
859b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    }
860b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
861b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return;
862b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
863b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************
864b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
865b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *			The public interfaces				*
866b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *									*
867b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/
868b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
869b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
870b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatterncompile:
871b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern: the pattern to compile
872b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @dict: an optional dictionnary for interned strings
873b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @flags: compilation flags, undefined yet
874b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
875b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile a pattern
876b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
877b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the compiled for of the pattern or NULL in case of error
878b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
879b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternPtr
880b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatterncompile(const xmlChar *pattern, xmlDict *dictionnary, int flags) {
881b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatternPtr ret = NULL;
882b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlPatParserContextPtr ctxt = NULL;
883b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
884b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ctxt = xmlNewPatParserContext(pattern, dictionnary);
885b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt == NULL) goto error;
886b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ret = xmlNewPattern();
887b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ret == NULL) goto error;
888b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    ctxt->comp = ret;
889b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
890b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlCompilePathPattern(ctxt);
891b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlFreePatParserContext(ctxt);
892b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
893b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    xmlReversePattern(ret);
894b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(ret);
895b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror:
896b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ctxt != NULL) xmlFreePatParserContext(ctxt);
897b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if (ret != NULL) xmlFreePattern(ret);
898b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(NULL);
899b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
900b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
901b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/**
902b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternMatch:
903b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern
904b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node
905b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
906b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Test wether the node matches the pattern
907b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *
908b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure
909b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */
910b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardint
911b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node)
912b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{
913b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    if ((comp == NULL) || (node == NULL))
914b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard        return(-1);
915b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard    return(xmlPatMatch(comp, node));
916b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}
917b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard
918b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif /* LIBXML_PATTERN_ENABLED */
919