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