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