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/ 6f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel 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 236ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * - DONE (2006-05-16): 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 42204f1f144ce1eded7dd25162c1c67e66a93fe450Patrick R. Gansterer#ifdef ERROR 43204f1f144ce1eded7dd25162c1c67e66a93fe450Patrick R. Gansterer#undef ERROR 44204f1f144ce1eded7dd25162c1c67e66a93fe450Patrick R. Gansterer#endif 45b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define ERROR(a, b, c, d) 46b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define ERROR5(a, b, c, d, e) 47b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_DESC 1 492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_FINAL 2 502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#define XML_STREAM_STEP_ROOT 4 512a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik#define XML_STREAM_STEP_ATTR 8 5297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#define XML_STREAM_STEP_NODE 16 53bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik#define XML_STREAM_STEP_IN_SET 32 542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 559ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik/* 5697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* NOTE: Those private flags (XML_STREAM_xxx) are used 5797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* in _xmlStreamCtxt->flag. They extend the public 5897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* xmlPatternFlags, so be carefull not to interfere with the 59f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard* reserved values for xmlPatternFlags. 609ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik*/ 6197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#define XML_STREAM_FINAL_IS_ANY_NODE 1<<14 6297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#define XML_STREAM_FROM_ROOT 1<<15 639ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik#define XML_STREAM_DESC 1<<16 649ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 6597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik/* 6697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* XML_STREAM_ANY_NODE is used for comparison against 6797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* xmlElementType enums, to indicate a node of any type. 6897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik*/ 6997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik#define XML_STREAM_ANY_NODE 100 7097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 71ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack#define XML_PATTERN_NOTPATTERN (XML_PATTERN_XPATH | \ 72ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack XML_PATTERN_XSSEL | \ 73ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack XML_PATTERN_XSFIELD) 749ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 75940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik#define XML_STREAM_XS_IDC(c) ((c)->flags & \ 769ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik (XML_PATTERN_XSSEL | XML_PATTERN_XSFIELD)) 77285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik 78940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik#define XML_STREAM_XS_IDC_SEL(c) ((c)->flags & XML_PATTERN_XSSEL) 79940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 80940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik#define XML_STREAM_XS_IDC_FIELD(c) ((c)->flags & XML_PATTERN_XSFIELD) 81940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 826ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik#define XML_PAT_COPY_NSNAME(c, r, nsname) \ 836ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if ((c)->comp->dict) \ 846ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik r = (xmlChar *) xmlDictLookup((c)->comp->dict, BAD_CAST nsname, -1); \ 856ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik else r = xmlStrdup(BAD_CAST nsname); 866ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik 876ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik#define XML_PAT_FREE_STRING(c, r) if ((c)->comp->dict == NULL) xmlFree(r); 886ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik 892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef struct _xmlStreamStep xmlStreamStep; 902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef xmlStreamStep *xmlStreamStepPtr; 912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamStep { 922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int flags; /* properties of that step */ 932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard const xmlChar *name; /* first string value if NULL accept all */ 942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard const xmlChar *ns; /* second string value */ 9597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik int nodeType; /* type of node */ 962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}; 972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef struct _xmlStreamComp xmlStreamComp; 992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardtypedef xmlStreamComp *xmlStreamCompPtr; 1002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamComp { 101fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack xmlDict *dict; /* the dictionary if any */ 1022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int nbStep; /* number of steps in the automata */ 1032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int maxStep; /* allocated number of steps */ 1042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamStepPtr steps; /* the array of steps */ 1059ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik int flags; 1062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}; 1072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 1082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstruct _xmlStreamCtxt { 109f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard struct _xmlStreamCtxt *next;/* link to next sub pattern if | */ 1102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCompPtr comp; /* the compiled stream */ 111fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack int nbState; /* number of states in the automata */ 112fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack int maxState; /* allocated number of states */ 1132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int level; /* how deep are we ? */ 1142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int *states; /* the array of step indexes */ 115285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik int flags; /* validation options */ 1169ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik int blockLevel; 1172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard}; 1182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 1192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void xmlFreeStreamComp(xmlStreamCompPtr comp); 1202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 121b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/* 122b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Types are private: 123b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 124b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 125b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef enum { 126b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_END=0, 127b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_ROOT, 128b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_ELEM, 129b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_CHILD, 130b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_ATTR, 131b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_PARENT, 132b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_ANCESTOR, 133b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_NS, 134b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard XML_OP_ALL 135b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} xmlPatOp; 136b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 137b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 138d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef struct _xmlStepState xmlStepState; 139d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef xmlStepState *xmlStepStatePtr; 140d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstruct _xmlStepState { 141d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard int step; 142d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard xmlNodePtr node; 143d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard}; 144d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard 145d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef struct _xmlStepStates xmlStepStates; 146d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardtypedef xmlStepStates *xmlStepStatesPtr; 147d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstruct _xmlStepStates { 148d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard int nbstates; 149d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard int maxstates; 150d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard xmlStepStatePtr states; 151d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard}; 152d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard 153b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlStepOp xmlStepOp; 154b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlStepOp *xmlStepOpPtr; 155b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlStepOp { 156b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatOp op; 157b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard const xmlChar *value; 1586ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik const xmlChar *value2; /* The namespace name */ 159b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}; 160b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 161ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack#define PAT_FROM_ROOT (1<<8) 162ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack#define PAT_FROM_CUR (1<<9) 16356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 164b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPattern { 165f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard void *data; /* the associated template */ 166fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack xmlDictPtr dict; /* the optional dictionary */ 167f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard struct _xmlPattern *next; /* next pattern if | is used */ 168b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard const xmlChar *pattern; /* the pattern */ 169f5812c3179f94dc050e9783e77a182f4e8d3c9eaDaniel Veillard int flags; /* flags */ 170b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int nbStep; 171b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int maxStep; 172c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard xmlStepOpPtr steps; /* ops for computation */ 1732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCompPtr stream; /* the streaming data if any */ 174b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}; 175b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 176b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef struct _xmlPatParserContext xmlPatParserContext; 177b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardtypedef xmlPatParserContext *xmlPatParserContextPtr; 178b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstruct _xmlPatParserContext { 179b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard const xmlChar *cur; /* the current char being parsed */ 180b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard const xmlChar *base; /* the full expression */ 181b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int error; /* error code */ 182fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack xmlDictPtr dict; /* the dictionary if any */ 183b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatternPtr comp; /* the result */ 184f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard xmlNodePtr elem; /* the current node if any */ 185ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard const xmlChar **namespaces; /* the namespaces definitions */ 186ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard int nb_namespaces; /* the number of namespaces */ 187b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard}; 188b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 189b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************ 190f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 191f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * Type functions * 192f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 193b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/ 194b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 195b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 196b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPattern: 197b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 198b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XSLT Pattern 199b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 200b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatternPtr or NULL in case of error 201b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 202b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatternPtr 203b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlNewPattern(void) { 204b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatternPtr cur; 205b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 206b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur = (xmlPatternPtr) xmlMalloc(sizeof(xmlPattern)); 207b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (cur == NULL) { 208b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ERROR(NULL, NULL, NULL, 209b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "xmlNewPattern : malloc failed\n"); 210b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 211b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 212b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard memset(cur, 0, sizeof(xmlPattern)); 213b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur->maxStep = 10; 214c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard cur->steps = (xmlStepOpPtr) xmlMalloc(cur->maxStep * sizeof(xmlStepOp)); 215c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard if (cur->steps == NULL) { 216c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard xmlFree(cur); 217c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard ERROR(NULL, NULL, NULL, 218c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard "xmlNewPattern : malloc failed\n"); 219c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard return(NULL); 220c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard } 221b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(cur); 222b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 223b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 224b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 225b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePattern: 226b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: an XSLT comp 227b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 228b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @comp 229b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 230b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid 231b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePattern(xmlPatternPtr comp) { 232b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlStepOpPtr op; 233b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int i; 234b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 235b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (comp == NULL) 236b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 237f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (comp->next != NULL) 238f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlFreePattern(comp->next); 2392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->stream != NULL) 2402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFreeStreamComp(comp->stream); 241b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (comp->pattern != NULL) 242b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlFree((xmlChar *)comp->pattern); 243c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard if (comp->steps != NULL) { 2442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->dict == NULL) { 2452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard for (i = 0;i < comp->nbStep;i++) { 2462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard op = &comp->steps[i]; 2472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (op->value != NULL) 2482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree((xmlChar *) op->value); 2492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (op->value2 != NULL) 2502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree((xmlChar *) op->value2); 2512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 252c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard } 253c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard xmlFree(comp->steps); 254b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 2552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->dict != NULL) 2562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlDictFree(comp->dict); 2572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 258b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard memset(comp, -1, sizeof(xmlPattern)); 259b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlFree(comp); 260b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 261b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 262b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 263b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatternList: 264b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: an XSLT comp list 265b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 266b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by all the elements of @comp 267b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 268b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardvoid 269b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatternList(xmlPatternPtr comp) { 270b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatternPtr cur; 271b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 272b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while (comp != NULL) { 273b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur = comp; 274b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp = comp->next; 275fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard cur->next = NULL; 276b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlFreePattern(cur); 277b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 278b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 279b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 280b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 281b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlNewPatParserContext: 282b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern: the pattern context 283fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * @dict: the inherited dictionary or NULL 2842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] terminated 2852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * with [NULL, NULL] or NULL if no namespace is used 286b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 287b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Create a new XML pattern parser context 288b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 289b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the newly allocated xmlPatParserContextPtr or NULL in case of error 290b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 291b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlPatParserContextPtr 292ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel VeillardxmlNewPatParserContext(const xmlChar *pattern, xmlDictPtr dict, 293ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard const xmlChar **namespaces) { 294b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatParserContextPtr cur; 295b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 296b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (pattern == NULL) 297b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 298b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 299b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur = (xmlPatParserContextPtr) xmlMalloc(sizeof(xmlPatParserContext)); 300b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (cur == NULL) { 301b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ERROR(NULL, NULL, NULL, 302b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "xmlNewPatParserContext : malloc failed\n"); 303b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 304b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 305b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard memset(cur, 0, sizeof(xmlPatParserContext)); 306b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur->dict = dict; 307b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur->cur = pattern; 308b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur->base = pattern; 309ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard if (namespaces != NULL) { 310ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard int i; 311cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber for (i = 0;namespaces[2 * i] != NULL;i++) 312cedf84d35ab127dd24f9bcbf8b8339518d0e8928Nico Weber ; 313ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard cur->nb_namespaces = i; 314ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard } else { 315ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard cur->nb_namespaces = 0; 316ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard } 317ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard cur->namespaces = namespaces; 318b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(cur); 319b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 320b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 321b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 322b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlFreePatParserContext: 323b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: an XSLT parser context 324b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 325b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Free up the memory allocated by @ctxt 326b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 327b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void 328b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlFreePatParserContext(xmlPatParserContextPtr ctxt) { 329b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (ctxt == NULL) 330f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard return; 331b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard memset(ctxt, -1, sizeof(xmlPatParserContext)); 332b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlFree(ctxt); 333b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 334b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 335b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 336b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternAdd: 337b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the compiled match expression 338b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @op: an op 339b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value: the first value 340b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @value2: the second value 341b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 342fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Add a step to an XSLT Compiled Match 343b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 344b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns -1 in case of failure, 0 otherwise. 345b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 346b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int 347b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternAdd(xmlPatParserContextPtr ctxt ATTRIBUTE_UNUSED, 348b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatternPtr comp, 349b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatOp op, xmlChar * value, xmlChar * value2) 350b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{ 351c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard if (comp->nbStep >= comp->maxStep) { 352c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard xmlStepOpPtr temp; 353c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 * 354c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard sizeof(xmlStepOp)); 355c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard if (temp == NULL) { 356c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard ERROR(ctxt, NULL, NULL, 357c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard "xmlPatternAdd: realloc failed\n"); 358c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard return (-1); 359c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard } 360c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard comp->steps = temp; 361c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard comp->maxStep *= 2; 362b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 363b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[comp->nbStep].op = op; 364b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[comp->nbStep].value = value; 365b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[comp->nbStep].value2 = value2; 366b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->nbStep++; 367b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return (0); 368b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 369b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 370b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0 371b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 372b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xsltSwapTopPattern: 373b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the compiled match expression 374b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 375b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse the two top steps. 376b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 377b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void 378b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxsltSwapTopPattern(xmlPatternPtr comp) { 379b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int i; 380b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int j = comp->nbStep - 1; 381b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 382b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (j > 0) { 383b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard register const xmlChar *tmp; 384b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard register xmlPatOp op; 385b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard i = j - 1; 386b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard tmp = comp->steps[i].value; 387b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[i].value = comp->steps[j].value; 388b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[j].value = tmp; 389b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard tmp = comp->steps[i].value2; 390b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[i].value2 = comp->steps[j].value2; 391b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[j].value2 = tmp; 392b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard op = comp->steps[i].op; 393b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[i].op = comp->steps[j].op; 394b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[j].op = op; 395b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 396b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 397b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif 398b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 399b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 400b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlReversePattern: 401b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the compiled match expression 402b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 403b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * reverse all the stack of expressions 404c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard * 405c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard * returns 0 in case of success and -1 in case of error. 406b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 407c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillardstatic int 408b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlReversePattern(xmlPatternPtr comp) { 40956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int i, j; 41056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 41156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 41256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * remove the leading // for //a or .//a 41356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 41456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((comp->nbStep > 0) && (comp->steps[0].op == XML_OP_ANCESTOR)) { 41556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard for (i = 0, j = 1;j < comp->nbStep;i++,j++) { 41656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->steps[i].value = comp->steps[j].value; 41756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->steps[i].value2 = comp->steps[j].value2; 41856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->steps[i].op = comp->steps[j].op; 41956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 42056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->nbStep--; 42156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 422c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard if (comp->nbStep >= comp->maxStep) { 423c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard xmlStepOpPtr temp; 424c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard temp = (xmlStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 * 425c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard sizeof(xmlStepOp)); 426c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard if (temp == NULL) { 427c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard ERROR(ctxt, NULL, NULL, 428c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard "xmlReversePattern: realloc failed\n"); 429c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard return (-1); 430c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard } 431c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard comp->steps = temp; 432c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard comp->maxStep *= 2; 433c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard } 43456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard i = 0; 43556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard j = comp->nbStep - 1; 436b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while (j > i) { 437b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard register const xmlChar *tmp; 438b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard register xmlPatOp op; 439b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard tmp = comp->steps[i].value; 440b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[i].value = comp->steps[j].value; 441b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[j].value = tmp; 442b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard tmp = comp->steps[i].value2; 443b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[i].value2 = comp->steps[j].value2; 444b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[j].value2 = tmp; 445b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard op = comp->steps[i].op; 446b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[i].op = comp->steps[j].op; 447b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[j].op = op; 448b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard j--; 449b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard i++; 450b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 451c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard comp->steps[comp->nbStep].value = NULL; 452c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard comp->steps[comp->nbStep].value2 = NULL; 453b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard comp->steps[comp->nbStep++].op = XML_OP_END; 454c7c9fb19a43347ef6134016e842405bd4d957902Daniel Veillard return(0); 455b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 456b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 457b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************ 458f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 459f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * The interpreter for the precompiled patterns * 460f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * * 461b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/ 462b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 463d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardstatic int 464d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel VeillardxmlPatPushState(xmlStepStates *states, int step, xmlNodePtr node) { 465d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard if ((states->states == NULL) || (states->maxstates <= 0)) { 466d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard states->maxstates = 4; 467d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard states->nbstates = 0; 468d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard states->states = xmlMalloc(4 * sizeof(xmlStepState)); 469d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard } 470d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard else if (states->maxstates <= states->nbstates) { 471d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard xmlStepState *tmp; 472d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard 473d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard tmp = (xmlStepStatePtr) xmlRealloc(states->states, 474d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard 2 * states->maxstates * sizeof(xmlStepState)); 475d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard if (tmp == NULL) 476d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard return(-1); 477d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard states->states = tmp; 478d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard states->maxstates *= 2; 479d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard } 480d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard states->states[states->nbstates].step = step; 481d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard states->states[states->nbstates++].node = node; 482d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#if 0 483d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard fprintf(stderr, "Push: %d, %s\n", step, node->name); 484d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#endif 485d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard return(0); 486d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard} 487d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard 488b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 489b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatMatch: 490b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern 491b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node 492b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 493fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Test whether the node matches the pattern 494b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 495b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure 496b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 497b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic int 498b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatMatch(xmlPatternPtr comp, xmlNodePtr node) { 499b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int i; 500b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlStepOpPtr step; 501d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard xmlStepStates states = {0, 0, NULL}; /* // may require backtrack */ 502b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 503b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((comp == NULL) || (node == NULL)) return(-1); 504d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard i = 0; 505d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardrestart: 506d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard for (;i < comp->nbStep;i++) { 507b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard step = &comp->steps[i]; 508b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard switch (step->op) { 509b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_END: 510d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto found; 511b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_ROOT: 5122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (node->type == XML_NAMESPACE_DECL) 513d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 5142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard node = node->parent; 515b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((node->type == XML_DOCUMENT_NODE) || 516b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED 517b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type == XML_DOCB_DOCUMENT_NODE) || 518b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif 519b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type == XML_HTML_DOCUMENT_NODE)) 520b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard continue; 521d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 522b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_ELEM: 523b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->type != XML_ELEMENT_NODE) 524d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 525b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value == NULL) 526b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard continue; 527b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value[0] != node->name[0]) 528d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 529b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!xmlStrEqual(step->value, node->name)) 530d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 531b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 532b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard /* Namespace test */ 533b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->ns == NULL) { 534b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value2 != NULL) 535d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 536b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if (node->ns->href != NULL) { 537b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value2 == NULL) 538d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 539b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!xmlStrEqual(step->value2, node->ns->href)) 540d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 541b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 542b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard continue; 543b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_CHILD: { 544b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlNodePtr lst; 545b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 546b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((node->type != XML_ELEMENT_NODE) && 547b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type != XML_DOCUMENT_NODE) && 548b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED 549b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type != XML_DOCB_DOCUMENT_NODE) && 550b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif 551b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type != XML_HTML_DOCUMENT_NODE)) 552d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 553b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 554b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard lst = node->children; 555b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 556b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value != NULL) { 557b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while (lst != NULL) { 558b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((lst->type == XML_ELEMENT_NODE) && 559b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (step->value[0] == lst->name[0]) && 560b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (xmlStrEqual(step->value, lst->name))) 561b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard break; 562b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard lst = lst->next; 563b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 564b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (lst != NULL) 565b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard continue; 566b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 567d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 568b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 569b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_ATTR: 570b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->type != XML_ATTRIBUTE_NODE) 571d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 572b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value != NULL) { 573b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value[0] != node->name[0]) 574d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 575b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!xmlStrEqual(step->value, node->name)) 576d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 577b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 578b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard /* Namespace test */ 579b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->ns == NULL) { 580b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value2 != NULL) 581d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 582b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if (step->value2 != NULL) { 583b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!xmlStrEqual(step->value2, node->ns->href)) 584d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 585b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 586b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard continue; 587b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_PARENT: 588b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((node->type == XML_DOCUMENT_NODE) || 589b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type == XML_HTML_DOCUMENT_NODE) || 590b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED 591b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type == XML_DOCB_DOCUMENT_NODE) || 592b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif 593b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type == XML_NAMESPACE_DECL)) 594d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 595b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard node = node->parent; 596b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node == NULL) 597d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 598b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value == NULL) 599b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard continue; 600b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value[0] != node->name[0]) 601d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 602b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!xmlStrEqual(step->value, node->name)) 603d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 604b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard /* Namespace test */ 605b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->ns == NULL) { 606b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value2 != NULL) 607d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 608b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if (node->ns->href != NULL) { 609b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value2 == NULL) 610d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 611b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!xmlStrEqual(step->value2, node->ns->href)) 612d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 613b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 614b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard continue; 615b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_ANCESTOR: 616b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard /* TODO: implement coalescing of ANCESTOR/NODE ops */ 617b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value == NULL) { 618b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard i++; 619b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard step = &comp->steps[i]; 620b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->op == XML_OP_ROOT) 621d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto found; 622b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->op != XML_OP_ELEM) 623d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 624b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value == NULL) 625b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(-1); 626b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 627b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node == NULL) 628d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 629b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((node->type == XML_DOCUMENT_NODE) || 630b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type == XML_HTML_DOCUMENT_NODE) || 631b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#ifdef LIBXML_DOCB_ENABLED 632b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type == XML_DOCB_DOCUMENT_NODE) || 633b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif 634b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (node->type == XML_NAMESPACE_DECL)) 635d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 636b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard node = node->parent; 637b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while (node != NULL) { 638b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((node->type == XML_ELEMENT_NODE) && 639b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (step->value[0] == node->name[0]) && 640b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (xmlStrEqual(step->value, node->name))) { 641b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard /* Namespace test */ 642b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->ns == NULL) { 643b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value2 == NULL) 644b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard break; 645b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if (node->ns->href != NULL) { 646b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((step->value2 != NULL) && 647b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (xmlStrEqual(step->value2, node->ns->href))) 648b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard break; 649b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 650b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 651b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard node = node->parent; 652b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 653b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node == NULL) 654d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 655d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard /* 656d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard * prepare a potential rollback from here 657d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard * for ancestors of that node. 658d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard */ 659d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard if (step->op == XML_OP_ANCESTOR) 660d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard xmlPatPushState(&states, i, node); 661d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard else 662d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard xmlPatPushState(&states, i - 1, node); 663b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard continue; 664b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_NS: 665b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->type != XML_ELEMENT_NODE) 666d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 667b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->ns == NULL) { 668b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value != NULL) 669d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 670b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if (node->ns->href != NULL) { 671b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (step->value == NULL) 672d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 673b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!xmlStrEqual(step->value, node->ns->href)) 674d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 675b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 676b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard break; 677b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard case XML_OP_ALL: 678b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (node->type != XML_ELEMENT_NODE) 679d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto rollback; 680b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard break; 681b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 682b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 683d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardfound: 684d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard if (states.states != NULL) { 685d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard /* Free the rollback states */ 686d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard xmlFree(states.states); 687d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard } 688b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(1); 689d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillardrollback: 690d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard /* got an error try to rollback */ 691d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard if (states.states == NULL) 692d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard return(0); 693d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard if (states.nbstates <= 0) { 694d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard xmlFree(states.states); 695d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard return(0); 696d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard } 697d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard states.nbstates--; 698d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard i = states.states[states.nbstates].step; 699d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard node = states.states[states.nbstates].node; 700d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#if 0 701d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard fprintf(stderr, "Pop: %d, %s\n", i, node->name); 702d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard#endif 703d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard goto restart; 704b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 705b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 706b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************ 707b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * * 708b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Dedicated parser for templates * 709b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * * 710b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/ 711b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 712f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define TODO \ 713b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlGenericError(xmlGenericErrorContext, \ 714b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "Unimplemented block at %s:%d\n", \ 715b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard __FILE__, __LINE__); 716b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR (*ctxt->cur) 717b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define SKIP(val) ctxt->cur += (val) 718b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NXT(val) ctxt->cur[(val)] 719940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik#define PEEKPREV(val) ctxt->cur[-(val)] 720b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CUR_PTR ctxt->cur 721b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 722f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define SKIP_BLANKS \ 723427174fbf2544b44071c1039720e6634fb154f84Daniel Veillard while (IS_BLANK_CH(CUR)) NEXT 724b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 725b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define CURRENT (*ctxt->cur) 726b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) 727b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 728b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 729f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#define PUSH(op, val, val2) \ 730b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (xmlPatternAdd(ctxt, ctxt->comp, (op), (val), (val2))) goto error; 731b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 732b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR(X) \ 733ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack { xsltError(ctxt, __FILE__, __LINE__, X); \ 734b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = (X); return; } 735b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 736b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#define XSLT_ERROR0(X) \ 737ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack { xsltError(ctxt, __FILE__, __LINE__, X); \ 738b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = (X); return(0); } 739b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 740b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0 741b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 742b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanLiteral: 743b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: the XPath Parser context 744b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 745b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse an XPath Litteral: 746b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 747b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [29] Literal ::= '"' [^"]* '"' 748b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * | "'" [^']* "'" 749b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 750b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Literal parsed or NULL 751b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 752b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 753b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar * 754b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanLiteral(xmlPatParserContextPtr ctxt) { 755b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard const xmlChar *q, *cur; 756b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *ret = NULL; 757b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int val, len; 758b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 759b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 760b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '"') { 761b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 762b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur = q = CUR_PTR; 763b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard val = xmlStringCurrentChar(NULL, cur, &len); 764b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while ((IS_CHAR(val)) && (val != '"')) { 765b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur += len; 766b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard val = xmlStringCurrentChar(NULL, cur, &len); 767b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 768b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!IS_CHAR(val)) { 769b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 770b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 771b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 7726ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (ctxt->dict) 7736ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q); 7746ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik else 775f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ret = xmlStrndup(q, cur - q); 776b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 777b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur += len; 778b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard CUR_PTR = cur; 779b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if (CUR == '\'') { 780b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 781b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur = q = CUR_PTR; 782b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard val = xmlStringCurrentChar(NULL, cur, &len); 783b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while ((IS_CHAR(val)) && (val != '\'')) { 784b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur += len; 785b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard val = xmlStringCurrentChar(NULL, cur, &len); 786b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 787b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!IS_CHAR(val)) { 788b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 789b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 790b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 7916ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (ctxt->dict) 7926ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q); 7936ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik else 794f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ret = xmlStrndup(q, cur - q); 795b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 796b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur += len; 797b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard CUR_PTR = cur; 798b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 799b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard /* XP_ERROR(XPATH_START_LITERAL_ERROR); */ 800b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 801b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 802b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 803b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(ret); 804b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 805b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif 806b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 807b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 808b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanName: 809b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: the XPath Parser context 810b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 811f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [4] NameChar ::= Letter | Digit | '.' | '-' | '_' | 812b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * CombiningChar | Extender 813b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 814b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [5] Name ::= (Letter | '_' | ':') (NameChar)* 815b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 816b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [6] Names ::= Name (S Name)* 817b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 818b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL 819b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 820b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 821b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar * 822b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanName(xmlPatParserContextPtr ctxt) { 823b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard const xmlChar *q, *cur; 824b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *ret = NULL; 825b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int val, len; 826b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 827b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 828b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 829b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur = q = CUR_PTR; 830b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard val = xmlStringCurrentChar(NULL, cur, &len); 831b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!IS_LETTER(val) && (val != '_') && (val != ':')) 832b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 833b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 834b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while ((IS_LETTER(val)) || (IS_DIGIT(val)) || 835b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (val == '.') || (val == '-') || 836f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard (val == '_') || 837b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (IS_COMBINING(val)) || 838b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (IS_EXTENDER(val))) { 839b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur += len; 840b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard val = xmlStringCurrentChar(NULL, cur, &len); 841b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 8426ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (ctxt->dict) 8436ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q); 8446ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik else 845f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ret = xmlStrndup(q, cur - q); 846b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard CUR_PTR = cur; 847b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(ret); 848b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 849b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 850b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 851b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanNCName: 852b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: the XPath Parser context 853b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 854b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parses a non qualified name 855b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 856b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL 857b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 858b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 859b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar * 860b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanNCName(xmlPatParserContextPtr ctxt) { 861b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard const xmlChar *q, *cur; 862b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *ret = NULL; 863b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard int val, len; 864b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 865b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 866b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 867b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur = q = CUR_PTR; 868b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard val = xmlStringCurrentChar(NULL, cur, &len); 869b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (!IS_LETTER(val) && (val != '_')) 870b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 871b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 872b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while ((IS_LETTER(val)) || (IS_DIGIT(val)) || 873b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (val == '.') || (val == '-') || 874b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (val == '_') || 875b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (IS_COMBINING(val)) || 876b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard (IS_EXTENDER(val))) { 877b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard cur += len; 878b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard val = xmlStringCurrentChar(NULL, cur, &len); 879b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 8806ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (ctxt->dict) 8816ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ret = (xmlChar *) xmlDictLookup(ctxt->dict, q, cur - q); 8826ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik else 8836ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ret = xmlStrndup(q, cur - q); 884b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard CUR_PTR = cur; 885b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(ret); 886b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 887b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 888b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#if 0 889b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 890b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatScanQName: 891b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: the XPath Parser context 892b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @prefix: the place to store the prefix 893b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 894b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Parse a qualified name 895b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 896b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns the Name parsed or NULL 897b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 898b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 899b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic xmlChar * 900b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatScanQName(xmlPatParserContextPtr ctxt, xmlChar **prefix) { 901b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *ret = NULL; 902b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 903b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *prefix = NULL; 904b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ret = xmlPatScanNCName(ctxt); 905b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == ':') { 906b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard *prefix = ret; 907b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 908b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ret = xmlPatScanNCName(ctxt); 909b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 910b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(ret); 911b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 912b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif 913b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 914b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 9152a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * xmlCompileAttributeTest: 9162a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @ctxt: the compilation context 9172a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * 9182a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Compile an attribute test. 9192a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 9202a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikstatic void 9212a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlCompileAttributeTest(xmlPatParserContextPtr ctxt) { 9222a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlChar *token = NULL; 9232a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlChar *name = NULL; 9242a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlChar *URL = NULL; 925f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 926940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 9272a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik name = xmlPatScanNCName(ctxt); 9282a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (name == NULL) { 9292a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == '*') { 9302a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ATTR, NULL, NULL); 9319ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik NEXT; 9322a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 9332a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ERROR(NULL, NULL, NULL, 9342a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik "xmlCompileAttributeTest : Name expected\n"); 9352a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ctxt->error = 1; 9362a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9372a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 9382a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9392a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == ':') { 9402a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik int i; 9412a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlChar *prefix = name; 942f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 9432a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 944940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 945f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (IS_BLANK_CH(CUR)) { 946940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL); 9476ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, prefix); 948940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 949940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 950940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 9512a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik /* 9522a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * This is a namespace match 9532a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 9542a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik token = xmlPatScanName(ctxt); 955627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if ((prefix[0] == 'x') && 956627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[1] == 'm') && 957627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[2] == 'l') && 9586ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (prefix[3] == 0)) 9596ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 960f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE); 961627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } else { 962627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik for (i = 0;i < ctxt->nb_namespaces;i++) { 963627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) { 964f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i]) 965627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik break; 966627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 967627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 968627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (i >= ctxt->nb_namespaces) { 969627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 970627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik "xmlCompileAttributeTest : no namespace bound to prefix %s\n", 971627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik prefix); 972f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ctxt->error = 1; 973627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik goto error; 9742a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9752a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9766ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, prefix); 9772a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (token == NULL) { 9782a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == '*') { 9792a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 9802a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ATTR, NULL, URL); 9812a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 9822a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ERROR(NULL, NULL, NULL, 9832a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik "xmlCompileAttributeTest : Name expected\n"); 9842a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ctxt->error = 1; 9852a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 986f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 9872a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 9882a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ATTR, token, URL); 9892a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9902a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 9912a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ATTR, name, NULL); 9922a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9932a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 9942a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikerror: 9952a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (URL != NULL) 996f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_FREE_STRING(ctxt, URL) 9972a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (token != NULL) 9986ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, token); 9992a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik} 10002a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 10012a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/** 1002b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompileStepPattern: 1003b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: the compilation context 1004b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 1005b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Step Pattern and generates a precompiled 1006b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching. 1007b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 1008b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [3] Step ::= '.' | NameTest 1009f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [4] NameTest ::= QName | '*' | NCName ':' '*' 1010b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 1011b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 1012b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void 1013b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompileStepPattern(xmlPatParserContextPtr ctxt) { 1014b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *token = NULL; 1015b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *name = NULL; 1016b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *URL = NULL; 1017940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik int hasBlanks = 0; 1018b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 1019b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 1020b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '.') { 1021940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1022940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Context node. 1023940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1024b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1025b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ELEM, NULL, NULL); 1026b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1027b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1028940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '@') { 1029940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1030940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Attribute test. 1031940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1032940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) { 1033940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1034940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected attribute axis in '%s'.\n", ctxt->base); 1035940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1036940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1037940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1038940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1039940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik xmlCompileAttributeTest(ctxt); 1040f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt->error != 0) 1041940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1042940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1043940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1044b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard name = xmlPatScanNCName(ctxt); 1045b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (name == NULL) { 1046b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '*') { 1047b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1048b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ALL, NULL, NULL); 1049b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1050b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1051b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ERROR(NULL, NULL, NULL, 1052b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "xmlCompileStepPattern : Name expected\n"); 1053b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 1054b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1055b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1056b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1057940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (IS_BLANK_CH(CUR)) { 1058940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik hasBlanks = 1; 1059940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1060940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1061b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == ':') { 1062b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1063b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR != ':') { 1064b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *prefix = name; 1065f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard int i; 1066b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 1067940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (hasBlanks || IS_BLANK_CH(CUR)) { 1068940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL); 1069940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1070940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1071940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1072b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard /* 1073b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * This is a namespace match 1074b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 1075b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard token = xmlPatScanName(ctxt); 1076627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if ((prefix[0] == 'x') && 1077627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[1] == 'm') && 1078627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[2] == 'l') && 10796ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (prefix[3] == 0)) 10806ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 10816ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE) 1082627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } else { 1083627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik for (i = 0;i < ctxt->nb_namespaces;i++) { 1084627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) { 10856ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i]) 1086627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik break; 1087627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 1088627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 1089627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (i >= ctxt->nb_namespaces) { 1090627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1091627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik "xmlCompileStepPattern : no namespace bound to prefix %s\n", 1092627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik prefix); 1093627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ctxt->error = 1; 1094627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik goto error; 1095d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard } 1096b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 10976ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, prefix); 10983108ba92b7a7a03bb4f913a59e2bbece6322275aRob Richards name = NULL; 1099b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (token == NULL) { 1100b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '*') { 1101b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1102b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_NS, URL, NULL); 1103b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1104b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ERROR(NULL, NULL, NULL, 1105b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "xmlCompileStepPattern : Name expected\n"); 1106b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 1107b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard goto error; 1108b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1109b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1110b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ELEM, token, URL); 1111b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1112b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1113b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1114f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (xmlStrEqual(name, (const xmlChar *) "child")) { 11156ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, name); 11162a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik name = xmlPatScanName(ctxt); 11172a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (name == NULL) { 11182a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == '*') { 11192a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 11202a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ALL, NULL, NULL); 11212a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 11222a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 11232a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ERROR(NULL, NULL, NULL, 1124b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "xmlCompileStepPattern : QName expected\n"); 11252a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ctxt->error = 1; 11262a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 1127b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1128b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 11292a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == ':') { 11302a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlChar *prefix = name; 11312a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik int i; 1132f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 11332a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 1134940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (IS_BLANK_CH(CUR)) { 1135940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL); 1136940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1137940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1138940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 11392a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik /* 11402a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * This is a namespace match 11412a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 11422a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik token = xmlPatScanName(ctxt); 1143627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if ((prefix[0] == 'x') && 1144627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[1] == 'm') && 1145627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[2] == 'l') && 11466ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (prefix[3] == 0)) 11476ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 1148f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE) 1149627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } else { 1150627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik for (i = 0;i < ctxt->nb_namespaces;i++) { 1151627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) { 1152f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i]) 1153627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik break; 1154627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 1155627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 1156627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (i >= ctxt->nb_namespaces) { 1157627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1158627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik "xmlCompileStepPattern : no namespace bound " 1159627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik "to prefix %s\n", prefix); 1160627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ctxt->error = 1; 1161627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik goto error; 11622a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 11632a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 11646ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, prefix); 11653108ba92b7a7a03bb4f913a59e2bbece6322275aRob Richards name = NULL; 11662a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (token == NULL) { 11672a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == '*') { 11682a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 11692a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_NS, URL, NULL); 11702a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 11712a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ERROR(NULL, NULL, NULL, 11722a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik "xmlCompileStepPattern : Name expected\n"); 11732a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ctxt->error = 1; 11742a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 11752a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 11762a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 11772a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_CHILD, token, URL); 11782a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 11792a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else 11802a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_CHILD, name, NULL); 11812a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 11822a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else if (xmlStrEqual(name, (const xmlChar *) "attribute")) { 11836ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, name) 11842a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik name = NULL; 1185940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) { 1186940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1187940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected attribute axis in '%s'.\n", ctxt->base); 1188940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1189940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1190940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 11912a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlCompileAttributeTest(ctxt); 11922a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (ctxt->error != 0) 1193b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard goto error; 11942a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 1195b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1196940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1197940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "The 'element' or 'attribute' axis is expected.\n", NULL); 1198b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 1199b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard goto error; 1200f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 1201b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1202b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if (CUR == '*') { 1203fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (name != NULL) { 1204fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard ctxt->error = 1; 1205fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard goto error; 1206fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 1207b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1208b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ALL, token, NULL); 1209b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1210b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ELEM, name, NULL); 1211b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1212b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1213b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror: 12142a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (URL != NULL) 1215f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_FREE_STRING(ctxt, URL) 1216b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (token != NULL) 12176ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, token) 1218b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (name != NULL) 12196ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, name) 1220b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 1221b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 1222b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 1223b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompilePathPattern: 1224b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: the compilation context 1225b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 1226b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Path Pattern and generates a precompiled 1227b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching. 1228b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 1229f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [5] Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest ) 1230b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 1231b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void 1232b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompilePathPattern(xmlPatParserContextPtr ctxt) { 1233b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 1234537f1173c39eb21f9c5e8ad3cbc9bed2a08f25e4William M. Brack if (CUR == '/') { 123556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->comp->flags |= PAT_FROM_ROOT; 1236ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) { 123756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->comp->flags |= PAT_FROM_CUR; 123856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1239f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 1240b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((CUR == '/') && (NXT(1) == '/')) { 124156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard PUSH(XML_OP_ANCESTOR, NULL, NULL); 1242b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1243b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1244b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) { 124556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard PUSH(XML_OP_ANCESTOR, NULL, NULL); 1246b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1247b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1248b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 124997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Check for incompleteness. */ 125097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik SKIP_BLANKS; 125197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (CUR == 0) { 125297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 125397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik "Incomplete expression '%s'.\n", ctxt->base); 125497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ctxt->error = 1; 125597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 125697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1257b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1258b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '@') { 12592a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 12602a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlCompileAttributeTest(ctxt); 12612a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik SKIP_BLANKS; 126297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* TODO: check for incompleteness */ 1263fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack if (CUR != 0) { 12642a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlCompileStepPattern(ctxt); 126597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ctxt->error != 0) 126697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 12672a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 1268b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 12692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (CUR == '/') { 12702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard PUSH(XML_OP_ROOT, NULL, NULL); 12712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard NEXT; 127297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Check for incompleteness. */ 127397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik SKIP_BLANKS; 127497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (CUR == 0) { 127597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 127697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik "Incomplete expression '%s'.\n", ctxt->base); 127797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ctxt->error = 1; 127897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 127997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 12802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 1281b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlCompileStepPattern(ctxt); 128297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ctxt->error != 0) 128397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1284b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 1285b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while (CUR == '/') { 1286fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack if (NXT(1) == '/') { 1287b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ANCESTOR, NULL, NULL); 1288b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1289b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1290b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 1291b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlCompileStepPattern(ctxt); 129297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ctxt->error != 0) 129397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1294b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1295b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_PARENT, NULL, NULL); 1296b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1297b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 129897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (CUR == 0) { 129997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 130097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik "Incomplete expression '%s'.\n", ctxt->base); 130197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ctxt->error = 1; 1302f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard goto error; 1303b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 130497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik xmlCompileStepPattern(ctxt); 130597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ctxt->error != 0) 130697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1307b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1308b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1309b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 131056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (CUR != 0) { 131156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ERROR5(NULL, NULL, NULL, 131256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard "Failed to compile pattern %s\n", ctxt->base); 131356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->error = 1; 131456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1315b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror: 1316b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1317b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 13182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 1319940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik/** 1320940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * xmlCompileIDCXPathPath: 1321940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * @ctxt: the compilation context 1322940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * 1323940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Compile the Path Pattern and generates a precompiled 1324940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * form suitable for fast matching. 1325940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * 1326f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [5] Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest ) 1327940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1328940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcikstatic void 1329940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. BuchcikxmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) { 1330940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1331940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '/') { 1332940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1333940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected selection of the document root in '%s'.\n", 1334940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->base); 1335940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1336940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1337940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->comp->flags |= PAT_FROM_CUR; 1338940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 1339940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '.') { 1340940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* "." - "self::node()" */ 1341940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1342940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1343940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == 0) { 1344940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1345940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Selection of the context node. 1346940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1347940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik PUSH(XML_OP_ELEM, NULL, NULL); 1348940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1349940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1350940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR != '/') { 1351940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* TODO: A more meaningful error message. */ 1352940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1353940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected token after '.' in '%s'.\n", ctxt->base); 1354940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1355940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1356940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* "./" - "self::node()/" */ 1357940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1358940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1359940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '/') { 1360940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (IS_BLANK_CH(PEEKPREV(1))) { 1361940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1362940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Disallow "./ /" 1363940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1364940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1365940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected '/' token in '%s'.\n", ctxt->base); 1366940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1367940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1368940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* ".//" - "self:node()/descendant-or-self::node()/" */ 1369940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik PUSH(XML_OP_ANCESTOR, NULL, NULL); 1370940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1371940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1372940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1373940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == 0) 1374940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error_unfinished; 1375940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1376940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1377940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Process steps. 1378940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1379940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik do { 1380940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik xmlCompileStepPattern(ctxt); 1381f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt->error != 0) 1382940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1383940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1384940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR != '/') 1385940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik break; 1386940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik PUSH(XML_OP_PARENT, NULL, NULL); 1387940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1388940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1389940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '/') { 1390940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1391940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Disallow subsequent '//'. 1392940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1393940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1394940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected subsequent '//' in '%s'.\n", 1395940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->base); 1396940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1397940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1398940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == 0) 1399940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error_unfinished; 1400f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 1401940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } while (CUR != 0); 1402940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 1403940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR != 0) { 1404940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1405940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Failed to compile expression '%s'.\n", ctxt->base); 1406940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1407940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1408940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1409940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcikerror: 1410940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1411940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1412940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 1413940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcikerror_unfinished: 1414940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1415940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1416f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard "Unfinished expression '%s'.\n", ctxt->base); 1417940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1418940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik} 1419940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 14202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/************************************************************************ 14212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * * 14222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * The streaming code * 14232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * * 14242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ************************************************************************/ 14252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING 14272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void 14282fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamComp(xmlStreamCompPtr stream) { 14292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int i; 14302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream == NULL) { 14322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("Stream: NULL\n"); 14332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return; 14342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("Stream: %d steps\n", stream->nbStep); 14362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard for (i = 0;i < stream->nbStep;i++) { 14372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].ns != NULL) { 14382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("{%s}", stream->steps[i].ns); 14392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].name == NULL) { 14412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("* "); 14422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } else { 14432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("%s ", stream->steps[i].name); 14442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].flags & XML_STREAM_STEP_ROOT) 14462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("root "); 14472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].flags & XML_STREAM_STEP_DESC) 14482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("// "); 14492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].flags & XML_STREAM_STEP_FINAL) 14502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("final "); 14512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("\n"); 14522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 14542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void 14552fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) { 14562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int i; 14572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (ctxt == NULL) { 14592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("Stream: NULL\n"); 14602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return; 14612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState); 14632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (match) 14642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("matches\n"); 14652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard else 14662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("\n"); 14672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard for (i = 0;i < ctxt->nbState;i++) { 14682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (ctxt->states[2 * i] < 0) 14692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf(" %d: free\n", i); 14702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard else { 14712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf(" %d: step %d, level %d", i, ctxt->states[2 * i], 14722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ctxt->states[(2 * i) + 1]); 14732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (ctxt->comp->steps[ctxt->states[2 * i]].flags & 14742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard XML_STREAM_STEP_DESC) 14752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf(" //\n"); 14762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard else 14772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("\n"); 14782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 14812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif 14822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 14832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamComp: 14842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected steps 14852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 14862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new compiled pattern for streaming 14872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 14882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error. 14892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 14902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCompPtr 14912fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamComp(int size) { 14922fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCompPtr cur; 14932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (size < 4) 14952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard size = 4; 14962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp)); 14982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur == NULL) { 14992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 15002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamComp: malloc failed\n"); 15012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 15022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard memset(cur, 0, sizeof(xmlStreamComp)); 15042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep)); 15052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur->steps == NULL) { 15062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(cur); 15072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 15082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamComp: malloc failed\n"); 15092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 15102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->nbStep = 0; 15122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->maxStep = size; 15132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(cur); 15142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 15152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 15172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamComp: 15182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming 15192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 15202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the compiled pattern for streaming 15212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 15222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void 15232fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamComp(xmlStreamCompPtr comp) { 15242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp != NULL) { 15252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->steps != NULL) 15262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(comp->steps); 15272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->dict != NULL) 15282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlDictFree(comp->dict); 15292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(comp); 15302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 15322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 15342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompAddStep: 15352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming 15362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the first string, the name, or NULL for * 15372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the second step, the namespace name 15382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @flags: the flags for that step 15392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 15402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new step to the compiled pattern 15412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 15422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the step index if successful 15432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 15442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int 15452fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name, 154697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik const xmlChar *ns, int nodeType, int flags) { 15472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamStepPtr cur; 15482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->nbStep >= comp->maxStep) { 15502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = (xmlStreamStepPtr) xmlRealloc(comp->steps, 15512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->maxStep * 2 * sizeof(xmlStreamStep)); 15522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur == NULL) { 15532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 15542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamComp: malloc failed\n"); 15552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 15562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->steps = cur; 15582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->maxStep *= 2; 15592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = &comp->steps[comp->nbStep++]; 15612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->flags = flags; 15622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->name = name; 15632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->ns = ns; 156497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik cur->nodeType = nodeType; 15652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(comp->nbStep - 1); 15662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 15672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 15692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompile: 15702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern 1571f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * 15722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Tries to stream compile a pattern 15732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 15742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of failure and 0 in case of success. 15752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 15762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int 15772fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompile(xmlPatternPtr comp) { 15782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCompPtr stream; 1579bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik int i, s = 0, root = 0, flags = 0, prevs = -1; 158097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik xmlStepOp step; 15812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if ((comp == NULL) || (comp->steps == NULL)) 15832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 158456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 158556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * special case for . 158656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 158756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((comp->nbStep == 1) && 158856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (comp->steps[0].op == XML_OP_ELEM) && 158956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (comp->steps[0].value == NULL) && 159056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (comp->steps[0].value2 == NULL)) { 159156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard stream = xmlNewStreamComp(0); 159256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (stream == NULL) 159356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 159497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Note that the stream will have no steps in this case. */ 159597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE; 159656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->stream = stream; 159756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(0); 159856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 159956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 16002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard stream = xmlNewStreamComp((comp->nbStep / 2) + 1); 16012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream == NULL) 16022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 16032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->dict != NULL) { 16042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard stream->dict = comp->dict; 16052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlDictReference(stream->dict); 16062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 1607fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard 1608f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard i = 0; 160997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (comp->flags & PAT_FROM_ROOT) 161097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik stream->flags |= XML_STREAM_FROM_ROOT; 161197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 1612fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard for (;i < comp->nbStep;i++) { 161397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik step = comp->steps[i]; 161497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik switch (step.op) { 16152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_END: 16162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 16172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_ROOT: 16182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (i != 0) 16192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard goto error; 16202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard root = 1; 16212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 16222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_NS: 162397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, NULL, step.value, 1624f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_ELEMENT_NODE, flags); 16252a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (s < 0) 16262a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 1627bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = s; 1628f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard flags = 0; 1629f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard break; 16302a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik case XML_OP_ATTR: 16312a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik flags |= XML_STREAM_STEP_ATTR; 1632bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = -1; 163397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, 163497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik step.value, step.value2, XML_ATTRIBUTE_NODE, flags); 16352a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik flags = 0; 16362a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (s < 0) 16372a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 16382a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik break; 1639f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case XML_OP_ELEM: 164097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((step.value == NULL) && (step.value2 == NULL)) { 164197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* 164297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * We have a "." or "self::node()" here. 164397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Eliminate redundant self::node() tests like in "/./." 164497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * or "//./" 164597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * The only case we won't eliminate is "//.", i.e. if 164697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * self::node() is the last node test and we had 164797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * continuation somewhere beforehand. 164897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 164997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((comp->nbStep == i + 1) && 165097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (flags & XML_STREAM_STEP_DESC)) { 165197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* 165297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Mark the special case where the expression resolves 165397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * to any type of node. 165497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 165597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (comp->nbStep == i + 1) { 165697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE; 165797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1658f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard flags |= XML_STREAM_STEP_NODE; 165997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, NULL, NULL, 166097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik XML_STREAM_ANY_NODE, flags); 166197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (s < 0) 166297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1663bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik flags = 0; 1664bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik /* 1665bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * If there was a previous step, mark it to be added to 1666bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * the result node-set; this is needed since only 1667bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * the last step will be marked as "final" and only 1668bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * "final" nodes are added to the resulting set. 1669bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik */ 1670bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik if (prevs != -1) { 1671bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik stream->steps[prevs].flags |= XML_STREAM_STEP_IN_SET; 1672bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = -1; 1673bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik } 1674f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard break; 167597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 167697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else { 167797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Just skip this one. */ 167897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik continue; 167997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 168097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1681f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard /* An element node. */ 168297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, step.value, step.value2, 1683f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_ELEMENT_NODE, flags); 168497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (s < 0) 168597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1686bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = s; 1687f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard flags = 0; 1688f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard break; 1689fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard case XML_OP_CHILD: 169097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* An element node child. */ 169197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, step.value, step.value2, 1692f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_ELEMENT_NODE, flags); 16932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (s < 0) 16942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard goto error; 1695bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = s; 1696bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik flags = 0; 1697f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard break; 16982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_ALL: 169997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, NULL, NULL, 1700f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_ELEMENT_NODE, flags); 17012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (s < 0) 17022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard goto error; 1703bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = s; 1704bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik flags = 0; 17052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 1706f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case XML_OP_PARENT: 17072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 17082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_ANCESTOR: 170997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Skip redundant continuations. */ 171097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (flags & XML_STREAM_STEP_DESC) 171197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik break; 17122a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik flags |= XML_STREAM_STEP_DESC; 17139ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 17149ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Mark the expression as having "//". 17159ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 17169ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((stream->flags & XML_STREAM_DESC) == 0) 17179ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->flags |= XML_STREAM_DESC; 17182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 17192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 1720f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 17219ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) { 17229ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 17239ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * If this should behave like a real pattern, we will mark 17249ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * the first step as having "//", to be reentrant on every 17259ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * tree level. 17269ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 17279ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((stream->flags & XML_STREAM_DESC) == 0) 17289ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->flags |= XML_STREAM_DESC; 17299ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 17309ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->nbStep > 0) { 17319ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0) 1732f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard stream->steps[0].flags |= XML_STREAM_STEP_DESC; 17339ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 17342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 173597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (stream->nbStep <= s) 173697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 17372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard stream->steps[s].flags |= XML_STREAM_STEP_FINAL; 17382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (root) 17392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard stream->steps[0].flags |= XML_STREAM_STEP_ROOT; 17402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING 17412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlDebugStreamComp(stream); 17422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif 17432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->stream = stream; 17442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(0); 17452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillarderror: 17462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFreeStreamComp(stream); 17472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(0); 17482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 17492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 17502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 17512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamCtxt: 17522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected states 17532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 17542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new stream context 17552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 17562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error. 17572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 17582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCtxtPtr 17592fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamCtxt(xmlStreamCompPtr stream) { 17602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCtxtPtr cur; 17612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 17622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt)); 17632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur == NULL) { 17642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 17652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamCtxt: malloc failed\n"); 17662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 17672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 17682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard memset(cur, 0, sizeof(xmlStreamCtxt)); 17692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int)); 17702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur->states == NULL) { 17712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(cur); 17722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 17732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamCtxt: malloc failed\n"); 17742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 17752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 17762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->nbState = 0; 17772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->maxState = 4; 17782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->level = 0; 17792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->comp = stream; 17809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik cur->blockLevel = -1; 17812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(cur); 17822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 17832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 17842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 17852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamCtxt: 17862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context 17872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 17882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the stream context 17892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 17902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardvoid 17912fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamCtxt(xmlStreamCtxtPtr stream) { 17922b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard xmlStreamCtxtPtr next; 17932b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard 17942b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard while (stream != NULL) { 17952b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard next = stream->next; 17962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->states != NULL) 17972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(stream->states); 17982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(stream); 17992b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard stream = next; 18002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 18022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 18032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 18042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCtxtAddState: 18052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the stream context 18062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @idx: the step index for that streaming state 18072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 18082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new state to the stream context 18092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 18102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the state index if successful 18112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 18122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int 18132fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) { 18142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int i; 18152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard for (i = 0;i < comp->nbState;i++) { 18162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->states[2 * i] < 0) { 18172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states[2 * i] = idx; 18182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states[2 * i + 1] = level; 18192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(i); 18202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->nbState >= comp->maxState) { 18232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int *cur; 18242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 18252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = (int *) xmlRealloc(comp->states, 18262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->maxState * 4 * sizeof(int)); 18272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur == NULL) { 18282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 18292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamCtxt: malloc failed\n"); 18302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 18312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states = cur; 18332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->maxState *= 2; 18342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states[2 * comp->nbState] = idx; 18362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states[2 * comp->nbState++ + 1] = level; 18372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(comp->nbState - 1); 18382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 18392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 18402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 18412a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * xmlStreamPushInternal: 18422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context 18432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the current name 18442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the namespace name 18452a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @nodeType: the type of the node 18462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 1847fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Push new data onto the stream. NOTE: if the call xmlPatterncompile() 1848fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * indicated a dictionary, then strings for name and ns will be expected 18492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * to come from the dictionary. 18502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Both @name and @ns being NULL means the / i.e. the root of the document. 18512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * This can also act as a reset. 18522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 18532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 1 if the current state in the stream is a 18542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * match and 0 otherwise. 18552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 18562a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikstatic int 18572a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPushInternal(xmlStreamCtxtPtr stream, 18582a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik const xmlChar *name, const xmlChar *ns, 185997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik int nodeType) { 18606ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik int ret = 0, err = 0, final = 0, tmp, i, m, match, stepNr, desc; 18612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCompPtr comp; 18626ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStreamStep step; 18632b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#ifdef DEBUG_STREAMING 18642b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard xmlStreamCtxtPtr orig = stream; 18652b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#endif 18662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 18672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if ((stream == NULL) || (stream->nbState < 0)) 18682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 1869f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 1870f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (stream != NULL) { 1871f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard comp = stream->comp; 187297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 187397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((nodeType == XML_ELEMENT_NODE) && 187497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (name == NULL) && (ns == NULL)) { 187597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* We have a document node here (or a reset). */ 1876f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->nbState = 0; 1877f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->level = 0; 18789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->blockLevel = -1; 187997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (comp->flags & XML_STREAM_FROM_ROOT) { 188097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (comp->nbStep == 0) { 188197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* TODO: We have a "/." here? */ 1882f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = 1; 188397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else { 188497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((comp->nbStep == 1) && 188597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (comp->steps[0].nodeType == XML_STREAM_ANY_NODE) && 188697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (comp->steps[0].flags & XML_STREAM_STEP_DESC)) 188797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik { 188897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* 188997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * In the case of "//." the document node will match 189097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * as well. 189197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 189297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ret = 1; 189397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) { 189497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* TODO: Do we need this ? */ 189597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik tmp = xmlStreamCtxtAddState(stream, 0, 0); 189697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (tmp < 0) 189797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik err++; 189897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 189997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 19002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 19012b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard stream = stream->next; 1902f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard continue; /* while */ 19032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 19042a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 19052a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik /* 19062a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Fast check for ".". 19072a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 19082a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (comp->nbStep == 0) { 190922678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik /* 1910f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * / and . are handled at the XPath node set creation 1911f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * level by checking min depth 1912f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard */ 1913f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (stream->flags & XML_PATTERN_XPATH) { 1914f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard stream = stream->next; 1915f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard continue; /* while */ 1916f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard } 1917f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard /* 1918ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack * For non-pattern like evaluation like XML Schema IDCs 1919ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack * or traditional XPath expressions, this will match if 1920ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack * we are at the first level only, otherwise on every level. 192122678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik */ 192297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((nodeType != XML_ATTRIBUTE_NODE) && 192322678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik (((stream->flags & XML_PATTERN_NOTPATTERN) == 0) || 192422678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik (stream->level == 0))) { 1925f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ret = 1; 192622678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik } 192722678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik stream->level++; 19282a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto stream_next; 19292a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 19309ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->blockLevel != -1) { 19319ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 19329ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Skip blocked expressions. 19339ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 1934f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard stream->level++; 19359ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto stream_next; 1936ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack } 193797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 193897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((nodeType != XML_ELEMENT_NODE) && 193997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (nodeType != XML_ATTRIBUTE_NODE) && 194097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ((comp->flags & XML_STREAM_FINAL_IS_ANY_NODE) == 0)) { 194197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* 194297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * No need to process nodes of other types if we don't 194397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * resolve to those types. 194497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * TODO: Do we need to block the context here? 194597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 194697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik stream->level++; 194797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto stream_next; 194897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 194997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 1950f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard /* 1951f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard * Check evolution of existing states 1952f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard */ 19539ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik i = 0; 1954f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard m = stream->nbState; 19559ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik while (i < m) { 19569ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((comp->flags & XML_STREAM_DESC) == 0) { 19579ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 19589ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * If there is no "//", then only the last 19599ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * added state is of interest. 19609ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 19616ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik stepNr = stream->states[2 * (stream->nbState -1)]; 19629ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 19639ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * TODO: Security check, should not happen, remove it. 19649ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 19659ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->states[(2 * (stream->nbState -1)) + 1] < 19669ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->level) { 19679ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik return (-1); 19689ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 19699ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik desc = 0; 19709ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* loop-stopper */ 19719ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik i = m; 19729ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } else { 19739ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 19749ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * If there are "//", then we need to process every "//" 19759ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * occuring in the states, plus any other state for this 19769ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * level. 1977f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 19786ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik stepNr = stream->states[2 * i]; 19799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 19809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* TODO: should not happen anymore: dead states */ 19816ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (stepNr < 0) 19829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto next_state; 19839ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 19849ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik tmp = stream->states[(2 * i) + 1]; 19859ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 19869ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* skip new states just added */ 19879ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (tmp > stream->level) 19889ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto next_state; 19899ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 19909ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* skip states at ancestor levels, except if "//" */ 19916ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik desc = comp->steps[stepNr].flags & XML_STREAM_STEP_DESC; 19929ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((tmp < stream->level) && (!desc)) 19939ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto next_state; 19949ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 1995f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard /* 19962a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Check for correct node-type. 19972a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 19986ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik step = comp->steps[stepNr]; 19996ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType != nodeType) { 20006ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType == XML_ATTRIBUTE_NODE) { 2001940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 2002940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Block this expression for deeper evaluation. 2003940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 2004940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if ((comp->flags & XML_STREAM_DESC) == 0) 2005940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik stream->blockLevel = stream->level +1; 200627820270838916fb8ee9192fb80af3adb9ca120bKasimier T. Buchcik goto next_state; 20076ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (step.nodeType != XML_STREAM_ANY_NODE) 200827820270838916fb8ee9192fb80af3adb9ca120bKasimier T. Buchcik goto next_state; 2009f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 20109ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 20119ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Compare local/namespace-name. 20129ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 20139ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik match = 0; 20146ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType == XML_STREAM_ANY_NODE) { 201597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik match = 1; 20166ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (step.name == NULL) { 20176ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.ns == NULL) { 20186ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik /* 20196ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * This lets through all elements/attributes. 20206ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik */ 20216ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = 1; 20226ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (ns != NULL) 20236ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = xmlStrEqual(step.ns, ns); 20246ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (((step.ns != NULL) == (ns != NULL)) && 20256ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (name != NULL) && 20266ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (step.name[0] == name[0]) && 20276ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStrEqual(step.name, name) && 20286ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ((step.ns == ns) || xmlStrEqual(step.ns, ns))) 20296ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 2030f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard match = 1; 2031f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 2032f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#if 0 20336ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik/* 20346ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik* TODO: Pointer comparison won't work, since not guaranteed that the given 20356ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik* values are in the same dict; especially if it's the namespace name, 20366ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik* normally coming from ns->href. We need a namespace dict mechanism ! 20376ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik*/ 203897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else if (comp->dict) { 20396ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.name == NULL) { 20406ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.ns == NULL) 2041f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard match = 1; 2042f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard else 20436ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = (step.ns == ns); 20442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } else { 20456ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = ((step.name == name) && (step.ns == ns)); 20462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 2047f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#endif /* if 0 ------------------------------------------------------- */ 2048f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (match) { 20496ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik final = step.flags & XML_STREAM_STEP_FINAL; 2050f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (desc) { 2051f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (final) { 2052f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = 1; 2053f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } else { 2054f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard /* descending match create a new state */ 20556ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStreamCtxtAddState(stream, stepNr + 1, 2056f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->level + 1); 2057f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2058f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } else { 2059f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (final) { 2060f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = 1; 2061f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } else { 20626ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStreamCtxtAddState(stream, stepNr + 1, 2063f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->level + 1); 2064f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 20652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 20666ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) { 2067bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik /* 2068bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * Check if we have a special case like "foo/bar//.", where 2069bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * "foo" is selected as well. 2070bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik */ 2071bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik ret = 1; 2072bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik } 2073f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 20749ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (((comp->flags & XML_STREAM_DESC) == 0) && 20759ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik ((! match) || final)) { 20769ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 20779ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Mark this expression as blocked for any evaluation at 20789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * deeper levels. Note that this includes "/foo" 20799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * expressions if the *pattern* behaviour is used. 20809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 20819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->blockLevel = stream->level +1; 20829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 20839ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchciknext_state: 20849ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik i++; 20852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 20862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 2087f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->level++; 20889ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 20892a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik /* 20909ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Re/enter the expression. 209197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Don't reenter if it's an absolute expression like "/foo", 209297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * except "//foo". 20932a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 20946ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik step = comp->steps[0]; 20956ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.flags & XML_STREAM_STEP_ROOT) 20969ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto stream_next; 20979ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 20986ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik desc = step.flags & XML_STREAM_STEP_DESC; 20999ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->flags & XML_PATTERN_NOTPATTERN) { 21009ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21019ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Re/enter the expression if it is a "descendant" one, 21029ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * or if we are at the 1st level of evaluation. 21039ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 2104f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 21059ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->level == 1) { 21069ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (XML_STREAM_XS_IDC(stream)) { 21079ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21089ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * XS-IDC: The missing "self::node()" will always 21099ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * match the first given node. 21109ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 21119ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto stream_next; 21129ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } else 21139ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto compare; 2114f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 21159ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21169ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * A "//" is always reentrant. 21179ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 21189ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (desc) 21199ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto compare; 2120285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik 21219ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21229ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * XS-IDC: Process the 2nd level, since the missing 21239ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * "self::node()" is responsible for the 2nd level being 2124f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * the real start level. 2125f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 21269ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((stream->level == 2) && XML_STREAM_XS_IDC(stream)) 21279ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto compare; 2128285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik 21299ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto stream_next; 21309ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 2131f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 21329ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcikcompare: 21339ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21349ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Check expected node-type. 2135285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik */ 21366ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType != nodeType) { 213797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (nodeType == XML_ATTRIBUTE_NODE) 213827820270838916fb8ee9192fb80af3adb9ca120bKasimier T. Buchcik goto stream_next; 21396ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik else if (step.nodeType != XML_STREAM_ANY_NODE) 2140f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard goto stream_next; 214127820270838916fb8ee9192fb80af3adb9ca120bKasimier T. Buchcik } 21429ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21439ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Compare local/namespace-name. 21449ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 21459ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik match = 0; 21466ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType == XML_STREAM_ANY_NODE) { 214797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik match = 1; 21486ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (step.name == NULL) { 21496ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.ns == NULL) { 21506ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik /* 21516ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * This lets through all elements/attributes. 21526ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik */ 21539ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik match = 1; 21546ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (ns != NULL) 21556ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = xmlStrEqual(step.ns, ns); 21566ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (((step.ns != NULL) == (ns != NULL)) && 21576ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (name != NULL) && 21586ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (step.name[0] == name[0]) && 21596ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStrEqual(step.name, name) && 21606ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ((step.ns == ns) || xmlStrEqual(step.ns, ns))) 21616ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 2162f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard match = 1; 2163f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 21646ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik final = step.flags & XML_STREAM_STEP_FINAL; 2165f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (match) { 21669ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (final) 21679ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik ret = 1; 21689ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik else 21699ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik xmlStreamCtxtAddState(stream, 1, stream->level); 21706ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) { 2171bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik /* 2172bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * Check if we have a special case like "foo//.", where 2173bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * "foo" is selected as well. 2174bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik */ 2175bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik ret = 1; 2176bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik } 21779ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 21789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (((comp->flags & XML_STREAM_DESC) == 0) && 21799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik ((! match) || final)) { 21809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Mark this expression as blocked for any evaluation at 21829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * deeper levels. 21839ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 21849ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->blockLevel = stream->level; 21859ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 2186940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 21872a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikstream_next: 2188f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream = stream->next; 2189f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } /* while stream != NULL */ 2190f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 2191f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (err > 0) 2192f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = -1; 21932b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#ifdef DEBUG_STREAMING 21942b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard xmlDebugStreamCtxt(orig, ret); 21952b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#endif 21962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(ret); 21972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 21982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 21992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 22002a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * xmlStreamPush: 22012a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @stream: the stream context 22022a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @name: the current name 22032a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @ns: the namespace name 22042a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * 2205fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Push new data onto the stream. NOTE: if the call xmlPatterncompile() 2206fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * indicated a dictionary, then strings for name and ns will be expected 22072a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * to come from the dictionary. 22082a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Both @name and @ns being NULL means the / i.e. the root of the document. 22092a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * This can also act as a reset. 221097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Otherwise the function will act as if it has been given an element-node. 22112a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * 22122a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Returns: -1 in case of error, 1 if the current state in the stream is a 22132a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * match and 0 otherwise. 22142a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 22152a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikint 22162a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPush(xmlStreamCtxtPtr stream, 22172a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik const xmlChar *name, const xmlChar *ns) { 221897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return (xmlStreamPushInternal(stream, name, ns, (int) XML_ELEMENT_NODE)); 221997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik} 222097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 222197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik/** 22226795260135a78da60182504a2d7efb4e3177eb57Daniel Veillard * xmlStreamPushNode: 222397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * @stream: the stream context 222497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * @name: the current name 222597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * @ns: the namespace name 222697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * @nodeType: the type of the node being pushed 222797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 222897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Push new data onto the stream. NOTE: if the call xmlPatterncompile() 222997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * indicated a dictionary, then strings for name and ns will be expected 223097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * to come from the dictionary. 223197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Both @name and @ns being NULL means the / i.e. the root of the document. 223297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * This can also act as a reset. 223397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Different from xmlStreamPush() this function can be fed with nodes of type: 223497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * element-, attribute-, text-, cdata-section-, comment- and 223597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * processing-instruction-node. 223697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 223797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Returns: -1 in case of error, 1 if the current state in the stream is a 223897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * match and 0 otherwise. 223997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 224097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcikint 224197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. BuchcikxmlStreamPushNode(xmlStreamCtxtPtr stream, 224297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik const xmlChar *name, const xmlChar *ns, 224397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik int nodeType) 224497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik{ 224597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return (xmlStreamPushInternal(stream, name, ns, 224697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik nodeType)); 22472a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik} 22482a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 22492a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/** 22502a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* xmlStreamPushAttr: 22512a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @stream: the stream context 22522a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @name: the current name 22532a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @ns: the namespace name 22542a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* 2255fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack* Push new attribute data onto the stream. NOTE: if the call xmlPatterncompile() 2256fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack* indicated a dictionary, then strings for name and ns will be expected 22572a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* to come from the dictionary. 22582a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* Both @name and @ns being NULL means the / i.e. the root of the document. 22592a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* This can also act as a reset. 226097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* Otherwise the function will act as if it has been given an attribute-node. 22612a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* 22622a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* Returns: -1 in case of error, 1 if the current state in the stream is a 22632a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* match and 0 otherwise. 22642a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik*/ 22652a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikint 22662a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPushAttr(xmlStreamCtxtPtr stream, 22672a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik const xmlChar *name, const xmlChar *ns) { 226897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return (xmlStreamPushInternal(stream, name, ns, (int) XML_ATTRIBUTE_NODE)); 22692a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik} 22702a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 22712a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/** 22722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamPop: 22732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context 22742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 22752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * push one level from the stream. 22762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 22772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 0 otherwise. 22782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 22792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardint 22802fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamPop(xmlStreamCtxtPtr stream) { 22819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik int i, lev; 2282f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 22832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream == NULL) 22842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 2285f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (stream != NULL) { 22869ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 22879ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Reset block-level. 22889ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 22899ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->blockLevel == stream->level) 22909ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->blockLevel = -1; 22919ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 2292f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack /* 2293f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack * stream->level can be zero when XML_FINAL_IS_ANY_NODE is set 2294f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack * (see the thread at 2295f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack * http://mail.gnome.org/archives/xslt/2008-July/msg00027.html) 2296f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack */ 2297f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack if (stream->level) 2298f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack stream->level--; 2299f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard /* 2300f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard * Check evolution of existing states 2301f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 23029ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik for (i = stream->nbState -1; i >= 0; i--) { 2303f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard /* discard obsoleted states */ 23049ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik lev = stream->states[(2 * i) + 1]; 23059ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (lev > stream->level) 23069ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->nbState--; 23079ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (lev <= stream->level) 23089ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik break; 2309f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2310f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream = stream->next; 23119740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard } 23122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(0); 23132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 23142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 231597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik/** 231697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * xmlStreamWantsAnyNode: 23176795260135a78da60182504a2d7efb4e3177eb57Daniel Veillard * @streamCtxt: the stream context 231897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 231997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Query if the streaming pattern additionally needs to be fed with 232097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * text-, cdata-section-, comment- and processing-instruction-nodes. 232197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * If the result is 0 then only element-nodes and attribute-nodes 232297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * need to be pushed. 232397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 232497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Returns: 1 in case of need of nodes of the above described types, 232597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 0 otherwise. -1 on API errors. 232697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 232797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcikint 232897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. BuchcikxmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt) 2329f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard{ 233097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (streamCtxt == NULL) 233197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return(-1); 233297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik while (streamCtxt != NULL) { 2333f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE) 233497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return(1); 233597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik streamCtxt = streamCtxt->next; 233697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 233797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return(0); 233897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik} 233997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 2340b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************ 2341b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * * 2342b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * The public interfaces * 2343b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * * 2344b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/ 2345b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2346b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 2347b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatterncompile: 2348b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern: the pattern to compile 2349fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * @dict: an optional dictionary for interned strings 2350ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard * @flags: compilation flags, see xmlPatternFlags 2351ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] or NULL 2352b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 2353ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * Compile a pattern. 2354b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 2355fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Returns the compiled form of the pattern or NULL in case of error 2356b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 2357b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternPtr 2358ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel VeillardxmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags, 2359ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard const xmlChar **namespaces) { 2360f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlPatternPtr ret = NULL, cur; 2361b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatParserContextPtr ctxt = NULL; 2362f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard const xmlChar *or, *start; 2363f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlChar *tmp = NULL; 2364fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard int type = 0; 2365fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard int streamable = 1; 2366f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2367f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (pattern == NULL) 2368f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(NULL); 2369f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2370f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard start = pattern; 23712b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard or = start; 2372f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (*or != 0) { 2373f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard tmp = NULL; 2374f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while ((*or != 0) && (*or != '|')) or++; 2375f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (*or == 0) 2376f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ctxt = xmlNewPatParserContext(start, dict, namespaces); 2377f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard else { 2378f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard tmp = xmlStrndup(start, or - start); 2379f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (tmp != NULL) { 2380f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ctxt = xmlNewPatParserContext(tmp, dict, namespaces); 2381f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2382f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard or++; 2383f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2384f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt == NULL) goto error; 2385f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard cur = xmlNewPattern(); 2386f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (cur == NULL) goto error; 23876ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik /* 23886ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * Assign string dict. 23896ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik */ 2390f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (dict) { 23916ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik cur->dict = dict; 23926ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlDictReference(dict); 23936ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } 2394f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (ret == NULL) 2395f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = cur; 2396f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard else { 2397f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard cur->next = ret->next; 2398f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret->next = cur; 2399f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2400285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik cur->flags = flags; 2401f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ctxt->comp = cur; 2402b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2403940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (XML_STREAM_XS_IDC(cur)) 2404940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik xmlCompileIDCXPathPath(ctxt); 2405940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik else 2406940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik xmlCompilePathPattern(ctxt); 240756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->error != 0) 240856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard goto error; 2409f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlFreePatParserContext(ctxt); 2410fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack ctxt = NULL; 2411b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2412b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2413fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (streamable) { 2414fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (type == 0) { 2415fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR); 2416fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } else if (type == PAT_FROM_ROOT) { 2417fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (cur->flags & PAT_FROM_CUR) 2418fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard streamable = 0; 2419fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } else if (type == PAT_FROM_CUR) { 2420fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (cur->flags & PAT_FROM_ROOT) 2421fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard streamable = 0; 2422fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2423fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2424fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (streamable) 2425fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard xmlStreamCompile(cur); 2426f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (xmlReversePattern(cur) < 0) 2427f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard goto error; 2428ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack if (tmp != NULL) { 2429f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlFree(tmp); 2430ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack tmp = NULL; 2431ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack } 24322b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard start = or; 2433f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2434fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (streamable == 0) { 2435fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard cur = ret; 2436fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard while (cur != NULL) { 2437fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (cur->stream != NULL) { 2438fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard xmlFreeStreamComp(cur->stream); 2439fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard cur->stream = NULL; 2440fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2441fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard cur = cur->next; 2442fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2443fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2444285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik 2445b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(ret); 2446b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror: 2447b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (ctxt != NULL) xmlFreePatParserContext(ctxt); 2448b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (ret != NULL) xmlFreePattern(ret); 2449f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (tmp != NULL) xmlFree(tmp); 2450b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 2451b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 2452b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2453b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 2454b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternMatch: 2455b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern 2456b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node 2457b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 2458fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Test whether the node matches the pattern 2459b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 2460b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure 2461b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 2462b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardint 2463b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node) 2464b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{ 2465f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard int ret = 0; 2466f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2467b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((comp == NULL) || (node == NULL)) 2468b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(-1); 2469f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2470f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (comp != NULL) { 2471f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = xmlPatMatch(comp, node); 2472f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (ret != 0) 2473f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(ret); 2474f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard comp = comp->next; 2475f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2476f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(ret); 2477b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 2478b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 24792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 24802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlPatternGetStreamCtxt: 24812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern 24822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 24832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Get a streaming context for that pattern 24842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Use xmlFreeStreamCtxt to free the context. 24852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 24862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns a pointer to the context or NULL in case of failure 24872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 24882fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtPtr 24892fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlPatternGetStreamCtxt(xmlPatternPtr comp) 24902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard{ 2491f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlStreamCtxtPtr ret = NULL, cur; 2492f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 24932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if ((comp == NULL) || (comp->stream == NULL)) 24942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 2495f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2496f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (comp != NULL) { 2497f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (comp->stream == NULL) 2498f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard goto failed; 2499f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard cur = xmlNewStreamCtxt(comp->stream); 2500f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (cur == NULL) 2501f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard goto failed; 2502f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (ret == NULL) 2503f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = cur; 2504f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard else { 2505f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard cur->next = ret->next; 2506f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret->next = cur; 2507f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2508285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik cur->flags = comp->flags; 2509f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard comp = comp->next; 2510f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2511f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(ret); 2512f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillardfailed: 2513f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlFreeStreamCtxt(ret); 2514f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(NULL); 25152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 25162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 251756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 251856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternStreamable: 251956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern 252056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 252156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check if the pattern is streamable i.e. xmlPatternGetStreamCtxt() 252256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * should work. 252356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 252456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns 1 if streamable, 0 if not and -1 in case of error. 252556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 252656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint 252756de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternStreamable(xmlPatternPtr comp) { 252856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp == NULL) 252956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 253056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (comp != NULL) { 253156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream == NULL) 253256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(0); 253356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = comp->next; 253456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 253556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(1); 253656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 253756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 253856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 253956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternMaxDepth: 254056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern 254156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 254256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check the maximum depth reachable by a pattern 254356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 254456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns -2 if no limit (using //), otherwise the depth, 254556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * and -1 in case of error 254656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 254756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint 254856de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternMaxDepth(xmlPatternPtr comp) { 254956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int ret = 0, i; 255056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp == NULL) 255156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 255256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (comp != NULL) { 255356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream == NULL) 255456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 255556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard for (i = 0;i < comp->stream->nbStep;i++) 255656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream->steps[i].flags & XML_STREAM_STEP_DESC) 255756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-2); 255856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream->nbStep > ret) 255956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ret = comp->stream->nbStep; 256056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = comp->next; 256156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 256256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(ret); 2563f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard} 256456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 2565f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard/** 2566f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * xmlPatternMinDepth: 2567f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * @comp: the precompiled pattern 2568f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * 2569f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * Check the minimum depth reachable by a pattern, 0 mean the / or . are 2570f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * part of the set. 2571f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * 2572f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * Returns -1 in case of error otherwise the depth, 2573f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * 2574f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard */ 2575f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillardint 2576f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel VeillardxmlPatternMinDepth(xmlPatternPtr comp) { 2577f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard int ret = 12345678; 2578f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (comp == NULL) 2579f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(-1); 2580f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard while (comp != NULL) { 2581f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (comp->stream == NULL) 2582f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(-1); 2583f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (comp->stream->nbStep < ret) 2584f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard ret = comp->stream->nbStep; 2585f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (ret == 0) 2586f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(0); 2587f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard comp = comp->next; 2588f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard } 2589f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(ret); 259056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 259156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 259256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 259356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternFromRoot: 259456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern 259556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 259656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check if the pattern must be looked at from the root. 259756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 259856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns 1 if true, 0 if false and -1 in case of error 259956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 260056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint 260156de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternFromRoot(xmlPatternPtr comp) { 260256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp == NULL) 260356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 260456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (comp != NULL) { 260556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream == NULL) 260656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 260756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->flags & PAT_FROM_ROOT) 260856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(1); 260956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = comp->next; 261056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 261156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(0); 261256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 261356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 26142a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 26155d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_pattern 26165d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 2617b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif /* LIBXML_PATTERN_ENABLED */ 2618