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); 9721f131f1133e1441ea159204d606fb4bbc394e14bNick Wellnhofer XML_PAT_FREE_STRING(ctxt, prefix); 973f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ctxt->error = 1; 974627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik goto error; 9752a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9762a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9776ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, prefix); 9782a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (token == NULL) { 9792a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == '*') { 9802a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 9812a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ATTR, NULL, URL); 9822a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 9832a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ERROR(NULL, NULL, NULL, 9842a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik "xmlCompileAttributeTest : Name expected\n"); 9852a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ctxt->error = 1; 9862a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 987f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 9882a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 9892a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ATTR, token, URL); 9902a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9912a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 9922a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ATTR, name, NULL); 9932a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 9942a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 9952a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikerror: 9962a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (URL != NULL) 997f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_FREE_STRING(ctxt, URL) 9982a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (token != NULL) 9996ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, token); 10002a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik} 10012a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 10022a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/** 1003b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompileStepPattern: 1004b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: the compilation context 1005b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 1006b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Step Pattern and generates a precompiled 1007b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching. 1008b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 1009b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * [3] Step ::= '.' | NameTest 1010f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [4] NameTest ::= QName | '*' | NCName ':' '*' 1011b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 1012b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 1013b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void 1014b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompileStepPattern(xmlPatParserContextPtr ctxt) { 1015b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *token = NULL; 1016b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *name = NULL; 1017b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *URL = NULL; 1018940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik int hasBlanks = 0; 1019b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 1020b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 1021b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '.') { 1022940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1023940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Context node. 1024940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1025b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1026b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ELEM, NULL, NULL); 1027b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1028b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1029940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '@') { 1030940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1031940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Attribute test. 1032940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1033940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) { 1034940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1035940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected attribute axis in '%s'.\n", ctxt->base); 1036940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1037940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1038940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1039940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1040940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik xmlCompileAttributeTest(ctxt); 1041f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt->error != 0) 1042940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1043940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1044940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1045b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard name = xmlPatScanNCName(ctxt); 1046b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (name == NULL) { 1047b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '*') { 1048b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1049b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ALL, NULL, NULL); 1050b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1051b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1052b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ERROR(NULL, NULL, NULL, 1053b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "xmlCompileStepPattern : Name expected\n"); 1054b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 1055b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1056b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1057b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1058940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (IS_BLANK_CH(CUR)) { 1059940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik hasBlanks = 1; 1060940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1061940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1062b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == ':') { 1063b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1064b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR != ':') { 1065b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlChar *prefix = name; 1066f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard int i; 1067b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 1068940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (hasBlanks || IS_BLANK_CH(CUR)) { 1069940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL); 1070940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1071940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1072940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1073b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard /* 1074b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * This is a namespace match 1075b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 1076b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard token = xmlPatScanName(ctxt); 1077627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if ((prefix[0] == 'x') && 1078627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[1] == 'm') && 1079627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[2] == 'l') && 10806ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (prefix[3] == 0)) 10816ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 10826ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE) 1083627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } else { 1084627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik for (i = 0;i < ctxt->nb_namespaces;i++) { 1085627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) { 10866ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i]) 1087627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik break; 1088627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 1089627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 1090627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (i >= ctxt->nb_namespaces) { 1091627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1092627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik "xmlCompileStepPattern : no namespace bound to prefix %s\n", 1093627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik prefix); 1094627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ctxt->error = 1; 1095627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik goto error; 1096d4301aba26ab6d415be85a80b084bd91b3cfcc05Daniel Veillard } 1097b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 10986ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, prefix); 10993108ba92b7a7a03bb4f913a59e2bbece6322275aRob Richards name = NULL; 1100b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (token == NULL) { 1101b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '*') { 1102b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1103b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_NS, URL, NULL); 1104b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1105b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ERROR(NULL, NULL, NULL, 1106b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "xmlCompileStepPattern : Name expected\n"); 1107b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 1108b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard goto error; 1109b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1110b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1111b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ELEM, token, URL); 1112b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1113b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1114b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1115f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (xmlStrEqual(name, (const xmlChar *) "child")) { 11166ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, name); 11172a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik name = xmlPatScanName(ctxt); 11182a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (name == NULL) { 11192a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == '*') { 11202a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 11212a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_ALL, NULL, NULL); 11222a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 11232a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 11242a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ERROR(NULL, NULL, NULL, 1125b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard "xmlCompileStepPattern : QName expected\n"); 11262a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ctxt->error = 1; 11272a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 1128b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1129b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 11302a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == ':') { 11312a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlChar *prefix = name; 11322a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik int i; 1133f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 11342a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 1135940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (IS_BLANK_CH(CUR)) { 1136940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, "Invalid QName.\n", NULL); 1137940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1138940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1139940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 11402a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik /* 11412a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * This is a namespace match 11422a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 11432a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik token = xmlPatScanName(ctxt); 1144627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if ((prefix[0] == 'x') && 1145627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[1] == 'm') && 1146627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik (prefix[2] == 'l') && 11476ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (prefix[3] == 0)) 11486ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 1149f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_COPY_NSNAME(ctxt, URL, XML_XML_NAMESPACE) 1150627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } else { 1151627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik for (i = 0;i < ctxt->nb_namespaces;i++) { 1152627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (xmlStrEqual(ctxt->namespaces[2 * i + 1], prefix)) { 1153f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_COPY_NSNAME(ctxt, URL, ctxt->namespaces[2 * i]) 1154627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik break; 1155627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 1156627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik } 1157627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik if (i >= ctxt->nb_namespaces) { 1158627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1159627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik "xmlCompileStepPattern : no namespace bound " 1160627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik "to prefix %s\n", prefix); 1161627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik ctxt->error = 1; 1162627e9a934b692768f1d2715a9429315e0b04b94eKasimier T. Buchcik goto error; 11632a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 11642a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 11656ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, prefix); 11663108ba92b7a7a03bb4f913a59e2bbece6322275aRob Richards name = NULL; 11672a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (token == NULL) { 11682a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (CUR == '*') { 11692a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 11702a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_NS, URL, NULL); 11712a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 11722a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ERROR(NULL, NULL, NULL, 11732a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik "xmlCompileStepPattern : Name expected\n"); 11742a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik ctxt->error = 1; 11752a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 11762a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 11772a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else { 11782a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_CHILD, token, URL); 11792a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 11802a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else 11812a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik PUSH(XML_OP_CHILD, name, NULL); 11822a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 11832a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } else if (xmlStrEqual(name, (const xmlChar *) "attribute")) { 11846ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, name) 11852a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik name = NULL; 1186940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (XML_STREAM_XS_IDC_SEL(ctxt->comp)) { 1187940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1188940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected attribute axis in '%s'.\n", ctxt->base); 1189940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1190940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1191940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 11922a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlCompileAttributeTest(ctxt); 11932a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (ctxt->error != 0) 1194b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard goto error; 11952a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik return; 1196b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1197940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1198940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "The 'element' or 'attribute' axis is expected.\n", NULL); 1199b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ctxt->error = 1; 1200b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard goto error; 1201f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 1202b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1203b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if (CUR == '*') { 1204fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (name != NULL) { 1205fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard ctxt->error = 1; 1206fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard goto error; 1207fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 1208b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1209b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ALL, token, NULL); 1210b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1211b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ELEM, name, NULL); 1212b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1213b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1214b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror: 12152a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (URL != NULL) 1216f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_PAT_FREE_STRING(ctxt, URL) 1217b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (token != NULL) 12186ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, token) 1219b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (name != NULL) 12206ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik XML_PAT_FREE_STRING(ctxt, name) 1221b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 1222b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 1223b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 1224b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlCompilePathPattern: 1225b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @ctxt: the compilation context 1226b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 1227b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Compile the Path Pattern and generates a precompiled 1228b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * form suitable for fast matching. 1229b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 1230f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [5] Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest ) 1231b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 1232b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardstatic void 1233b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlCompilePathPattern(xmlPatParserContextPtr ctxt) { 1234b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 1235537f1173c39eb21f9c5e8ad3cbc9bed2a08f25e4William M. Brack if (CUR == '/') { 123656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->comp->flags |= PAT_FROM_ROOT; 1237ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack } else if ((CUR == '.') || (ctxt->comp->flags & XML_PATTERN_NOTPATTERN)) { 123856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->comp->flags |= PAT_FROM_CUR; 123956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1240f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 1241b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((CUR == '/') && (NXT(1) == '/')) { 124256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard PUSH(XML_OP_ANCESTOR, NULL, NULL); 1243b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1244b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1245b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else if ((CUR == '.') && (NXT(1) == '/') && (NXT(2) == '/')) { 124656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard PUSH(XML_OP_ANCESTOR, NULL, NULL); 1247b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1248b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1249b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 125097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Check for incompleteness. */ 125197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik SKIP_BLANKS; 125297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (CUR == 0) { 125397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 125497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik "Incomplete expression '%s'.\n", ctxt->base); 125597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ctxt->error = 1; 125697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 125797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1258b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1259b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (CUR == '@') { 12602a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik NEXT; 12612a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlCompileAttributeTest(ctxt); 12622a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik SKIP_BLANKS; 126397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* TODO: check for incompleteness */ 1264fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack if (CUR != 0) { 12652a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik xmlCompileStepPattern(ctxt); 126697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ctxt->error != 0) 126797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 12682a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 1269b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 12702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (CUR == '/') { 12712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard PUSH(XML_OP_ROOT, NULL, NULL); 12722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard NEXT; 127397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Check for incompleteness. */ 127497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik SKIP_BLANKS; 127597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (CUR == 0) { 127697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 127797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik "Incomplete expression '%s'.\n", ctxt->base); 127897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ctxt->error = 1; 127997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 128097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 12812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 1282b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlCompileStepPattern(ctxt); 128397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ctxt->error != 0) 128497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1285b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 1286b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard while (CUR == '/') { 1287fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack if (NXT(1) == '/') { 1288b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_ANCESTOR, NULL, NULL); 1289b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1290b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1291b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 1292b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlCompileStepPattern(ctxt); 129397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ctxt->error != 0) 129497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1295b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } else { 1296b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard PUSH(XML_OP_PARENT, NULL, NULL); 1297b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard NEXT; 1298b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard SKIP_BLANKS; 129997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (CUR == 0) { 130097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ERROR5(NULL, NULL, NULL, 130197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik "Incomplete expression '%s'.\n", ctxt->base); 130297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ctxt->error = 1; 1303f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard goto error; 1304b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 130597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik xmlCompileStepPattern(ctxt); 130697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (ctxt->error != 0) 130797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1308b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1309b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 1310b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard } 131156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (CUR != 0) { 131256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ERROR5(NULL, NULL, NULL, 131356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard "Failed to compile pattern %s\n", ctxt->base); 131456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ctxt->error = 1; 131556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 1316b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror: 1317b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return; 1318b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 13192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 1320940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik/** 1321940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * xmlCompileIDCXPathPath: 1322940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * @ctxt: the compilation context 1323940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * 1324940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Compile the Path Pattern and generates a precompiled 1325940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * form suitable for fast matching. 1326940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * 1327f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * [5] Path ::= ('.//')? ( Step '/' )* ( Step | '@' NameTest ) 1328940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1329940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcikstatic void 1330940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. BuchcikxmlCompileIDCXPathPath(xmlPatParserContextPtr ctxt) { 1331940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1332940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '/') { 1333940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1334940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected selection of the document root in '%s'.\n", 1335940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->base); 1336940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1337940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1338940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->comp->flags |= PAT_FROM_CUR; 1339940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 1340940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '.') { 1341940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* "." - "self::node()" */ 1342940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1343940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1344940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == 0) { 1345940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1346940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Selection of the context node. 1347940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1348940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik PUSH(XML_OP_ELEM, NULL, NULL); 1349940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1350940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1351940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR != '/') { 1352940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* TODO: A more meaningful error message. */ 1353940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1354940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected token after '.' in '%s'.\n", ctxt->base); 1355940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1356940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1357940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* "./" - "self::node()/" */ 1358940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1359940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1360940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '/') { 1361940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (IS_BLANK_CH(PEEKPREV(1))) { 1362940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1363940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Disallow "./ /" 1364940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1365940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1366940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected '/' token in '%s'.\n", ctxt->base); 1367940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1368940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1369940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* ".//" - "self:node()/descendant-or-self::node()/" */ 1370940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik PUSH(XML_OP_ANCESTOR, NULL, NULL); 1371940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1372940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1373940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1374940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == 0) 1375940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error_unfinished; 1376940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1377940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1378940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Process steps. 1379940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1380940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik do { 1381940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik xmlCompileStepPattern(ctxt); 1382f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt->error != 0) 1383940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1384940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1385940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR != '/') 1386940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik break; 1387940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik PUSH(XML_OP_PARENT, NULL, NULL); 1388940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik NEXT; 1389940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik SKIP_BLANKS; 1390940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == '/') { 1391940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 1392940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Disallow subsequent '//'. 1393940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 1394940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1395940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Unexpected subsequent '//' in '%s'.\n", 1396940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->base); 1397940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error; 1398940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1399940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR == 0) 1400940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik goto error_unfinished; 1401f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 1402940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } while (CUR != 0); 1403940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 1404940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (CUR != 0) { 1405940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1406940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik "Failed to compile expression '%s'.\n", ctxt->base); 1407940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1408940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik } 1409940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1410940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcikerror: 1411940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1412940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1413940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 1414940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcikerror_unfinished: 1415940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ctxt->error = 1; 1416940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik ERROR5(NULL, NULL, NULL, 1417f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard "Unfinished expression '%s'.\n", ctxt->base); 1418940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik return; 1419940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik} 1420940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 14212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/************************************************************************ 14222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * * 14232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * The streaming code * 14242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * * 14252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ************************************************************************/ 14262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING 14282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void 14292fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamComp(xmlStreamCompPtr stream) { 14302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int i; 14312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream == NULL) { 14332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("Stream: NULL\n"); 14342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return; 14352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("Stream: %d steps\n", stream->nbStep); 14372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard for (i = 0;i < stream->nbStep;i++) { 14382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].ns != NULL) { 14392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("{%s}", stream->steps[i].ns); 14402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].name == NULL) { 14422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("* "); 14432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } else { 14442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("%s ", stream->steps[i].name); 14452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].flags & XML_STREAM_STEP_ROOT) 14472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("root "); 14482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].flags & XML_STREAM_STEP_DESC) 14492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("// "); 14502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->steps[i].flags & XML_STREAM_STEP_FINAL) 14512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("final "); 14522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("\n"); 14532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 14552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void 14562fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlDebugStreamCtxt(xmlStreamCtxtPtr ctxt, int match) { 14572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int i; 14582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (ctxt == NULL) { 14602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("Stream: NULL\n"); 14612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return; 14622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("Stream: level %d, %d states: ", ctxt->level, ctxt->nbState); 14642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (match) 14652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("matches\n"); 14662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard else 14672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("\n"); 14682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard for (i = 0;i < ctxt->nbState;i++) { 14692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (ctxt->states[2 * i] < 0) 14702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf(" %d: free\n", i); 14712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard else { 14722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf(" %d: step %d, level %d", i, ctxt->states[2 * i], 14732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ctxt->states[(2 * i) + 1]); 14742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (ctxt->comp->steps[ctxt->states[2 * i]].flags & 14752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard XML_STREAM_STEP_DESC) 14762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf(" //\n"); 14772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard else 14782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard printf("\n"); 14792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 14812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 14822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif 14832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 14842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamComp: 14852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected steps 14862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 14872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new compiled pattern for streaming 14882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 14892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error. 14902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 14912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCompPtr 14922fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamComp(int size) { 14932fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCompPtr cur; 14942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (size < 4) 14962fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard size = 4; 14972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 14982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = (xmlStreamCompPtr) xmlMalloc(sizeof(xmlStreamComp)); 14992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur == NULL) { 15002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 15012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamComp: malloc failed\n"); 15022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 15032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard memset(cur, 0, sizeof(xmlStreamComp)); 15052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->steps = (xmlStreamStepPtr) xmlMalloc(size * sizeof(xmlStreamStep)); 15062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur->steps == NULL) { 15072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(cur); 15082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 15092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamComp: malloc failed\n"); 15102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 15112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->nbStep = 0; 15132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->maxStep = size; 15142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(cur); 15152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 15162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 15182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamComp: 15192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming 15202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 15212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the compiled pattern for streaming 15222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 15232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic void 15242fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamComp(xmlStreamCompPtr comp) { 15252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp != NULL) { 15262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->steps != NULL) 15272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(comp->steps); 15282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->dict != NULL) 15292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlDictFree(comp->dict); 15302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(comp); 15312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 15332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 15352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompAddStep: 15362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the compiled pattern for streaming 15372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the first string, the name, or NULL for * 15382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the second step, the namespace name 15392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @flags: the flags for that step 15402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 15412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new step to the compiled pattern 15422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 15432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the step index if successful 15442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 15452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int 15462fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompAddStep(xmlStreamCompPtr comp, const xmlChar *name, 154797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik const xmlChar *ns, int nodeType, int flags) { 15482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamStepPtr cur; 15492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->nbStep >= comp->maxStep) { 15512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = (xmlStreamStepPtr) xmlRealloc(comp->steps, 15522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->maxStep * 2 * sizeof(xmlStreamStep)); 15532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur == NULL) { 15542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 15552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamComp: malloc failed\n"); 15562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 15572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->steps = cur; 15592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->maxStep *= 2; 15602fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 15612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = &comp->steps[comp->nbStep++]; 15622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->flags = flags; 15632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->name = name; 15642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->ns = ns; 156597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik cur->nodeType = nodeType; 15662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(comp->nbStep - 1); 15672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 15682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 15702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCompile: 15712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern 1572f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * 15732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Tries to stream compile a pattern 15742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 15752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of failure and 0 in case of success. 15762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 15772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int 15782fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCompile(xmlPatternPtr comp) { 15792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCompPtr stream; 1580bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik int i, s = 0, root = 0, flags = 0, prevs = -1; 158197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik xmlStepOp step; 15822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 15832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if ((comp == NULL) || (comp->steps == NULL)) 15842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 158556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard /* 158656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * special case for . 158756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 158856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if ((comp->nbStep == 1) && 158956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (comp->steps[0].op == XML_OP_ELEM) && 159056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (comp->steps[0].value == NULL) && 159156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard (comp->steps[0].value2 == NULL)) { 159256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard stream = xmlNewStreamComp(0); 159356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (stream == NULL) 159456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 159597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Note that the stream will have no steps in this case. */ 159697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE; 159756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp->stream = stream; 159856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(0); 159956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 160056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 16012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard stream = xmlNewStreamComp((comp->nbStep / 2) + 1); 16022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream == NULL) 16032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 16042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->dict != NULL) { 16052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard stream->dict = comp->dict; 16062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlDictReference(stream->dict); 16072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 1608fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard 1609f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard i = 0; 161097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (comp->flags & PAT_FROM_ROOT) 161197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik stream->flags |= XML_STREAM_FROM_ROOT; 161297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 1613fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard for (;i < comp->nbStep;i++) { 161497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik step = comp->steps[i]; 161597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik switch (step.op) { 16162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_END: 16172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 16182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_ROOT: 16192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (i != 0) 16202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard goto error; 16212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard root = 1; 16222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 16232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_NS: 162497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, NULL, step.value, 1625f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_ELEMENT_NODE, flags); 16262a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (s < 0) 16272a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 1628bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = s; 1629f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard flags = 0; 1630f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard break; 16312a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik case XML_OP_ATTR: 16322a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik flags |= XML_STREAM_STEP_ATTR; 1633bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = -1; 163497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, 163597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik step.value, step.value2, XML_ATTRIBUTE_NODE, flags); 16362a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik flags = 0; 16372a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (s < 0) 16382a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto error; 16392a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik break; 1640f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case XML_OP_ELEM: 164197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((step.value == NULL) && (step.value2 == NULL)) { 164297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* 164397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * We have a "." or "self::node()" here. 164497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Eliminate redundant self::node() tests like in "/./." 164597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * or "//./" 164697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * The only case we won't eliminate is "//.", i.e. if 164797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * self::node() is the last node test and we had 164897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * continuation somewhere beforehand. 164997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 165097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((comp->nbStep == i + 1) && 165197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (flags & XML_STREAM_STEP_DESC)) { 165297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* 165397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Mark the special case where the expression resolves 165497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * to any type of node. 165597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 165697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (comp->nbStep == i + 1) { 165797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik stream->flags |= XML_STREAM_FINAL_IS_ANY_NODE; 165897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1659f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard flags |= XML_STREAM_STEP_NODE; 166097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, NULL, NULL, 166197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik XML_STREAM_ANY_NODE, flags); 166297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (s < 0) 166397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1664bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik flags = 0; 1665bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik /* 1666bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * If there was a previous step, mark it to be added to 1667bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * the result node-set; this is needed since only 1668bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * the last step will be marked as "final" and only 1669bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * "final" nodes are added to the resulting set. 1670bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik */ 1671bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik if (prevs != -1) { 1672bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik stream->steps[prevs].flags |= XML_STREAM_STEP_IN_SET; 1673bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = -1; 1674bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik } 1675f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard break; 167697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 167797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else { 167897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Just skip this one. */ 167997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik continue; 168097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 168197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 1682f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard /* An element node. */ 168397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, step.value, step.value2, 1684f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_ELEMENT_NODE, flags); 168597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (s < 0) 168697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 1687bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = s; 1688f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard flags = 0; 1689f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard break; 1690fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard case XML_OP_CHILD: 169197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* An element node child. */ 169297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, step.value, step.value2, 1693f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_ELEMENT_NODE, flags); 16942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (s < 0) 16952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard goto error; 1696bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = s; 1697bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik flags = 0; 1698f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard break; 16992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_ALL: 170097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik s = xmlStreamCompAddStep(stream, NULL, NULL, 1701f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard XML_ELEMENT_NODE, flags); 17022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (s < 0) 17032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard goto error; 1704bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik prevs = s; 1705bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik flags = 0; 17062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 1707f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard case XML_OP_PARENT: 17082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 17092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard case XML_OP_ANCESTOR: 171097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* Skip redundant continuations. */ 171197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (flags & XML_STREAM_STEP_DESC) 171297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik break; 17132a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik flags |= XML_STREAM_STEP_DESC; 17149ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 17159ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Mark the expression as having "//". 17169ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 17179ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((stream->flags & XML_STREAM_DESC) == 0) 17189ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->flags |= XML_STREAM_DESC; 17192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard break; 17202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 1721f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 17229ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((! root) && (comp->flags & XML_PATTERN_NOTPATTERN) == 0) { 17239ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 17249ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * If this should behave like a real pattern, we will mark 17259ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * the first step as having "//", to be reentrant on every 17269ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * tree level. 17279ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 17289ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((stream->flags & XML_STREAM_DESC) == 0) 17299ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->flags |= XML_STREAM_DESC; 17309ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 17319ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->nbStep > 0) { 17329ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((stream->steps[0].flags & XML_STREAM_STEP_DESC) == 0) 1733f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard stream->steps[0].flags |= XML_STREAM_STEP_DESC; 17349ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 17352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 173697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (stream->nbStep <= s) 173797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto error; 17382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard stream->steps[s].flags |= XML_STREAM_STEP_FINAL; 17392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (root) 17402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard stream->steps[0].flags |= XML_STREAM_STEP_ROOT; 17412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#ifdef DEBUG_STREAMING 17422fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlDebugStreamComp(stream); 17432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard#endif 17442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->stream = stream; 17452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(0); 17462fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillarderror: 17472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFreeStreamComp(stream); 17482fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(0); 17492fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 17502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 17512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 17522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlNewStreamCtxt: 17532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @size: the number of expected states 17542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 17552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * build a new stream context 17562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 17572fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns the new structure or NULL in case of error. 17582fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 17592fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic xmlStreamCtxtPtr 17602fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlNewStreamCtxt(xmlStreamCompPtr stream) { 17612fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCtxtPtr cur; 17622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 17632fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = (xmlStreamCtxtPtr) xmlMalloc(sizeof(xmlStreamCtxt)); 17642fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur == NULL) { 17652fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 17662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamCtxt: malloc failed\n"); 17672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 17682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 17692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard memset(cur, 0, sizeof(xmlStreamCtxt)); 17702fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->states = (int *) xmlMalloc(4 * 2 * sizeof(int)); 17712fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur->states == NULL) { 17722fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(cur); 17732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 17742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamCtxt: malloc failed\n"); 17752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 17762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 17772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->nbState = 0; 17782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->maxState = 4; 17792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->level = 0; 17802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur->comp = stream; 17819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik cur->blockLevel = -1; 17822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(cur); 17832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 17842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 17852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 17862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlFreeStreamCtxt: 17872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context 17882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 17892fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Free the stream context 17902fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 17912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardvoid 17922fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlFreeStreamCtxt(xmlStreamCtxtPtr stream) { 17932b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard xmlStreamCtxtPtr next; 17942b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard 17952b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard while (stream != NULL) { 17962b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard next = stream->next; 17972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream->states != NULL) 17982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(stream->states); 17992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlFree(stream); 18002b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard stream = next; 18012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18022fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 18032fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 18042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 18052fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamCtxtAddState: 18062fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the stream context 18072fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @idx: the step index for that streaming state 18082fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 18092fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Add a new state to the stream context 18102fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 18112fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns -1 in case of error or the state index if successful 18122fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 18132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardstatic int 18142fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtAddState(xmlStreamCtxtPtr comp, int idx, int level) { 18152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int i; 18162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard for (i = 0;i < comp->nbState;i++) { 18172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->states[2 * i] < 0) { 18182fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states[2 * i] = idx; 18192fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states[2 * i + 1] = level; 18202fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(i); 18212fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18222fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18232fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (comp->nbState >= comp->maxState) { 18242fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard int *cur; 18252fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 18262fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard cur = (int *) xmlRealloc(comp->states, 18272fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->maxState * 4 * sizeof(int)); 18282fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (cur == NULL) { 18292fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard ERROR(NULL, NULL, NULL, 18302fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard "xmlNewStreamCtxt: malloc failed\n"); 18312fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 18322fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18332fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states = cur; 18342fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->maxState *= 2; 18352fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 18362fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states[2 * comp->nbState] = idx; 18372fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard comp->states[2 * comp->nbState++ + 1] = level; 18382fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(comp->nbState - 1); 18392fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 18402fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 18412fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 18422a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * xmlStreamPushInternal: 18432fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context 18442fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @name: the current name 18452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @ns: the namespace name 18462a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @nodeType: the type of the node 18472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 1848fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Push new data onto the stream. NOTE: if the call xmlPatterncompile() 1849fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * indicated a dictionary, then strings for name and ns will be expected 18502fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * to come from the dictionary. 18512fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Both @name and @ns being NULL means the / i.e. the root of the document. 18522fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * This can also act as a reset. 18532fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 18542fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 1 if the current state in the stream is a 18552fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * match and 0 otherwise. 18562fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 18572a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikstatic int 18582a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPushInternal(xmlStreamCtxtPtr stream, 18592a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik const xmlChar *name, const xmlChar *ns, 186097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik int nodeType) { 18616ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik int ret = 0, err = 0, final = 0, tmp, i, m, match, stepNr, desc; 18622fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard xmlStreamCompPtr comp; 18636ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStreamStep step; 18642b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#ifdef DEBUG_STREAMING 18652b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard xmlStreamCtxtPtr orig = stream; 18662b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#endif 18672fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 18682fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if ((stream == NULL) || (stream->nbState < 0)) 18692fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 1870f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 1871f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (stream != NULL) { 1872f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard comp = stream->comp; 187397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 187497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((nodeType == XML_ELEMENT_NODE) && 187597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (name == NULL) && (ns == NULL)) { 187697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* We have a document node here (or a reset). */ 1877f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->nbState = 0; 1878f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->level = 0; 18799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->blockLevel = -1; 188097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (comp->flags & XML_STREAM_FROM_ROOT) { 188197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (comp->nbStep == 0) { 188297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* TODO: We have a "/." here? */ 1883f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = 1; 188497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else { 188597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((comp->nbStep == 1) && 188697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (comp->steps[0].nodeType == XML_STREAM_ANY_NODE) && 188797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (comp->steps[0].flags & XML_STREAM_STEP_DESC)) 188897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik { 188997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* 189097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * In the case of "//." the document node will match 189197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * as well. 189297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 189397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ret = 1; 189497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else if (comp->steps[0].flags & XML_STREAM_STEP_ROOT) { 189597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* TODO: Do we need this ? */ 189697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik tmp = xmlStreamCtxtAddState(stream, 0, 0); 189797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (tmp < 0) 189897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik err++; 189997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 190097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 19012fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 19022b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard stream = stream->next; 1903f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard continue; /* while */ 19042fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 19052a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 19062a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik /* 19072a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Fast check for ".". 19082a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 19092a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik if (comp->nbStep == 0) { 191022678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik /* 1911f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * / and . are handled at the XPath node set creation 1912f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * level by checking min depth 1913f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard */ 1914f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (stream->flags & XML_PATTERN_XPATH) { 1915f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard stream = stream->next; 1916f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard continue; /* while */ 1917f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard } 1918f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard /* 1919ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack * For non-pattern like evaluation like XML Schema IDCs 1920ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack * or traditional XPath expressions, this will match if 1921ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack * we are at the first level only, otherwise on every level. 192222678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik */ 192397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((nodeType != XML_ATTRIBUTE_NODE) && 192422678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik (((stream->flags & XML_PATTERN_NOTPATTERN) == 0) || 192522678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik (stream->level == 0))) { 1926f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard ret = 1; 192722678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik } 192822678566b81e8b026470e4caf37ecb28c9b6f5ceKasimier T. Buchcik stream->level++; 19292a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik goto stream_next; 19302a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik } 19319ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->blockLevel != -1) { 19329ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 19339ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Skip blocked expressions. 19349ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 1935f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard stream->level++; 19369ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto stream_next; 1937ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack } 193897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 193997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if ((nodeType != XML_ELEMENT_NODE) && 194097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik (nodeType != XML_ATTRIBUTE_NODE) && 194197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik ((comp->flags & XML_STREAM_FINAL_IS_ANY_NODE) == 0)) { 194297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik /* 194397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * No need to process nodes of other types if we don't 194497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * resolve to those types. 194597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * TODO: Do we need to block the context here? 194697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 194797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik stream->level++; 194897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik goto stream_next; 194997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 195097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 1951f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard /* 1952f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard * Check evolution of existing states 1953f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard */ 19549ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik i = 0; 1955f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard m = stream->nbState; 19569ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik while (i < m) { 19579ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((comp->flags & XML_STREAM_DESC) == 0) { 19589ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 19599ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * If there is no "//", then only the last 19609ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * added state is of interest. 19619ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 19626ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik stepNr = stream->states[2 * (stream->nbState -1)]; 19639ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 19649ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * TODO: Security check, should not happen, remove it. 19659ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 19669ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->states[(2 * (stream->nbState -1)) + 1] < 19679ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->level) { 19689ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik return (-1); 19699ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 19709ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik desc = 0; 19719ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* loop-stopper */ 19729ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik i = m; 19739ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } else { 19749ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 19759ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * If there are "//", then we need to process every "//" 19769ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * occuring in the states, plus any other state for this 19779ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * level. 1978f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 19796ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik stepNr = stream->states[2 * i]; 19809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 19819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* TODO: should not happen anymore: dead states */ 19826ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (stepNr < 0) 19839ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto next_state; 19849ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 19859ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik tmp = stream->states[(2 * i) + 1]; 19869ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 19879ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* skip new states just added */ 19889ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (tmp > stream->level) 19899ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto next_state; 19909ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 19919ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* skip states at ancestor levels, except if "//" */ 19926ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik desc = comp->steps[stepNr].flags & XML_STREAM_STEP_DESC; 19939ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((tmp < stream->level) && (!desc)) 19949ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto next_state; 19959ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 1996f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard /* 19972a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Check for correct node-type. 19982a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 19996ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik step = comp->steps[stepNr]; 20006ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType != nodeType) { 20016ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType == XML_ATTRIBUTE_NODE) { 2002940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik /* 2003940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik * Block this expression for deeper evaluation. 2004940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik */ 2005940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if ((comp->flags & XML_STREAM_DESC) == 0) 2006940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik stream->blockLevel = stream->level +1; 200727820270838916fb8ee9192fb80af3adb9ca120bKasimier T. Buchcik goto next_state; 20086ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (step.nodeType != XML_STREAM_ANY_NODE) 200927820270838916fb8ee9192fb80af3adb9ca120bKasimier T. Buchcik goto next_state; 2010f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 20119ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 20129ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Compare local/namespace-name. 20139ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 20149ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik match = 0; 20156ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType == XML_STREAM_ANY_NODE) { 201697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik match = 1; 20176ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (step.name == NULL) { 20186ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.ns == NULL) { 20196ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik /* 20206ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * This lets through all elements/attributes. 20216ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik */ 20226ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = 1; 20236ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (ns != NULL) 20246ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = xmlStrEqual(step.ns, ns); 20256ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (((step.ns != NULL) == (ns != NULL)) && 20266ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (name != NULL) && 20276ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (step.name[0] == name[0]) && 20286ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStrEqual(step.name, name) && 20296ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ((step.ns == ns) || xmlStrEqual(step.ns, ns))) 20306ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 2031f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard match = 1; 2032f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 2033f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#if 0 20346ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik/* 20356ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik* TODO: Pointer comparison won't work, since not guaranteed that the given 20366ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik* values are in the same dict; especially if it's the namespace name, 20376ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik* normally coming from ns->href. We need a namespace dict mechanism ! 20386ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik*/ 203997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } else if (comp->dict) { 20406ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.name == NULL) { 20416ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.ns == NULL) 2042f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard match = 1; 2043f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard else 20446ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = (step.ns == ns); 20452fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } else { 20466ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = ((step.name == name) && (step.ns == ns)); 20472fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 2048f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard#endif /* if 0 ------------------------------------------------------- */ 2049f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (match) { 20506ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik final = step.flags & XML_STREAM_STEP_FINAL; 2051f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (desc) { 2052f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (final) { 2053f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = 1; 2054f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } else { 2055f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard /* descending match create a new state */ 20566ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStreamCtxtAddState(stream, stepNr + 1, 2057f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->level + 1); 2058f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2059f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } else { 2060f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (final) { 2061f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = 1; 2062f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } else { 20636ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStreamCtxtAddState(stream, stepNr + 1, 2064f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->level + 1); 2065f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 20662fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 20676ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) { 2068bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik /* 2069bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * Check if we have a special case like "foo/bar//.", where 2070bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * "foo" is selected as well. 2071bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik */ 2072bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik ret = 1; 2073bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik } 2074f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 20759ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (((comp->flags & XML_STREAM_DESC) == 0) && 20769ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik ((! match) || final)) { 20779ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 20789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Mark this expression as blocked for any evaluation at 20799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * deeper levels. Note that this includes "/foo" 20809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * expressions if the *pattern* behaviour is used. 20819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 20829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->blockLevel = stream->level +1; 20839ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 20849ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchciknext_state: 20859ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik i++; 20862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard } 20872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 2088f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream->level++; 20899ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 20902a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik /* 20919ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Re/enter the expression. 209297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Don't reenter if it's an absolute expression like "/foo", 209397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * except "//foo". 20942a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 20956ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik step = comp->steps[0]; 20966ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.flags & XML_STREAM_STEP_ROOT) 20979ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto stream_next; 20989ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 20996ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik desc = step.flags & XML_STREAM_STEP_DESC; 21009ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->flags & XML_PATTERN_NOTPATTERN) { 21019ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21029ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Re/enter the expression if it is a "descendant" one, 21039ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * or if we are at the 1st level of evaluation. 21049ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 2105f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 21069ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->level == 1) { 21079ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (XML_STREAM_XS_IDC(stream)) { 21089ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21099ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * XS-IDC: The missing "self::node()" will always 21109ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * match the first given node. 21119ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 21129ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto stream_next; 21139ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } else 21149ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto compare; 2115f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 21169ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21179ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * A "//" is always reentrant. 21189ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 21199ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (desc) 21209ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto compare; 2121285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik 21229ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21239ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * XS-IDC: Process the 2nd level, since the missing 21249ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * "self::node()" is responsible for the 2nd level being 2125f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * the real start level. 2126f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 21279ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if ((stream->level == 2) && XML_STREAM_XS_IDC(stream)) 21289ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto compare; 2129285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik 21309ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik goto stream_next; 21319ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 2132f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 21339ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcikcompare: 21349ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21359ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Check expected node-type. 2136285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik */ 21376ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType != nodeType) { 213897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (nodeType == XML_ATTRIBUTE_NODE) 213927820270838916fb8ee9192fb80af3adb9ca120bKasimier T. Buchcik goto stream_next; 21406ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik else if (step.nodeType != XML_STREAM_ANY_NODE) 2141f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard goto stream_next; 214227820270838916fb8ee9192fb80af3adb9ca120bKasimier T. Buchcik } 21439ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21449ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Compare local/namespace-name. 21459ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 21469ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik match = 0; 21476ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.nodeType == XML_STREAM_ANY_NODE) { 214897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik match = 1; 21496ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (step.name == NULL) { 21506ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if (step.ns == NULL) { 21516ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik /* 21526ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * This lets through all elements/attributes. 21536ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik */ 21549ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik match = 1; 21556ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (ns != NULL) 21566ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik match = xmlStrEqual(step.ns, ns); 21576ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } else if (((step.ns != NULL) == (ns != NULL)) && 21586ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (name != NULL) && 21596ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik (step.name[0] == name[0]) && 21606ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlStrEqual(step.name, name) && 21616ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik ((step.ns == ns) || xmlStrEqual(step.ns, ns))) 21626ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik { 2163f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard match = 1; 2164f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard } 21656ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik final = step.flags & XML_STREAM_STEP_FINAL; 2166f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (match) { 21679ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (final) 21689ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik ret = 1; 21699ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik else 21709ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik xmlStreamCtxtAddState(stream, 1, stream->level); 21716ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik if ((ret != 1) && (step.flags & XML_STREAM_STEP_IN_SET)) { 2172bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik /* 2173bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * Check if we have a special case like "foo//.", where 2174bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik * "foo" is selected as well. 2175bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik */ 2176bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik ret = 1; 2177bb80f544d4c431bcfbc267d573b6578806c617e5Kasimier T. Buchcik } 21789ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 21799ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (((comp->flags & XML_STREAM_DESC) == 0) && 21809ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik ((! match) || final)) { 21819ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 21829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Mark this expression as blocked for any evaluation at 21839ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * deeper levels. 21849ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 21859ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->blockLevel = stream->level; 21869ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik } 2187940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik 21882a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikstream_next: 2189f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream = stream->next; 2190f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } /* while stream != NULL */ 2191f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 2192f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (err > 0) 2193f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = -1; 21942b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#ifdef DEBUG_STREAMING 21952b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard xmlDebugStreamCtxt(orig, ret); 21962b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard#endif 21972fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(ret); 21982fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 21992fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 22002fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 22012a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * xmlStreamPush: 22022a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @stream: the stream context 22032a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @name: the current name 22042a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * @ns: the namespace name 22052a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * 2206fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Push new data onto the stream. NOTE: if the call xmlPatterncompile() 2207fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * indicated a dictionary, then strings for name and ns will be expected 22082a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * to come from the dictionary. 22092a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Both @name and @ns being NULL means the / i.e. the root of the document. 22102a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * This can also act as a reset. 221197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Otherwise the function will act as if it has been given an element-node. 22122a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * 22132a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * Returns: -1 in case of error, 1 if the current state in the stream is a 22142a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik * match and 0 otherwise. 22152a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik */ 22162a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikint 22172a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPush(xmlStreamCtxtPtr stream, 22182a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik const xmlChar *name, const xmlChar *ns) { 221997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return (xmlStreamPushInternal(stream, name, ns, (int) XML_ELEMENT_NODE)); 222097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik} 222197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 222297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik/** 22236795260135a78da60182504a2d7efb4e3177eb57Daniel Veillard * xmlStreamPushNode: 222497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * @stream: the stream context 222597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * @name: the current name 222697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * @ns: the namespace name 222797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * @nodeType: the type of the node being pushed 222897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 222997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Push new data onto the stream. NOTE: if the call xmlPatterncompile() 223097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * indicated a dictionary, then strings for name and ns will be expected 223197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * to come from the dictionary. 223297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Both @name and @ns being NULL means the / i.e. the root of the document. 223397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * This can also act as a reset. 223497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Different from xmlStreamPush() this function can be fed with nodes of type: 223597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * element-, attribute-, text-, cdata-section-, comment- and 223697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * processing-instruction-node. 223797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 223897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Returns: -1 in case of error, 1 if the current state in the stream is a 223997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * match and 0 otherwise. 224097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 224197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcikint 224297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. BuchcikxmlStreamPushNode(xmlStreamCtxtPtr stream, 224397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik const xmlChar *name, const xmlChar *ns, 224497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik int nodeType) 224597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik{ 224697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return (xmlStreamPushInternal(stream, name, ns, 224797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik nodeType)); 22482a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik} 22492a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 22502a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/** 22512a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* xmlStreamPushAttr: 22522a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @stream: the stream context 22532a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @name: the current name 22542a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* @ns: the namespace name 22552a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* 2256fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack* Push new attribute data onto the stream. NOTE: if the call xmlPatterncompile() 2257fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack* indicated a dictionary, then strings for name and ns will be expected 22582a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* to come from the dictionary. 22592a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* Both @name and @ns being NULL means the / i.e. the root of the document. 22602a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* This can also act as a reset. 226197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik* Otherwise the function will act as if it has been given an attribute-node. 22622a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* 22632a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* Returns: -1 in case of error, 1 if the current state in the stream is a 22642a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik* match and 0 otherwise. 22652a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik*/ 22662a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcikint 22672a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. BuchcikxmlStreamPushAttr(xmlStreamCtxtPtr stream, 22682a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik const xmlChar *name, const xmlChar *ns) { 226997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return (xmlStreamPushInternal(stream, name, ns, (int) XML_ATTRIBUTE_NODE)); 22702a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik} 22712a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 22722a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik/** 22732fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlStreamPop: 22742fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @stream: the stream context 22752fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 22762fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * push one level from the stream. 22772fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 22782fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns: -1 in case of error, 0 otherwise. 22792fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 22802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillardint 22812fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamPop(xmlStreamCtxtPtr stream) { 22829ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik int i, lev; 2283f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard 22842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if (stream == NULL) 22852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(-1); 2286f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (stream != NULL) { 22879ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik /* 22889ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik * Reset block-level. 22899ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik */ 22909ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (stream->blockLevel == stream->level) 22919ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->blockLevel = -1; 22929ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik 2293f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack /* 2294f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack * stream->level can be zero when XML_FINAL_IS_ANY_NODE is set 2295f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack * (see the thread at 2296f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack * http://mail.gnome.org/archives/xslt/2008-July/msg00027.html) 2297f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack */ 2298f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack if (stream->level) 2299f8477005ab036338fb1af8781037f7a9f5f3911cWilliam M. Brack stream->level--; 2300f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard /* 2301f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard * Check evolution of existing states 2302f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard */ 23039ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik for (i = stream->nbState -1; i >= 0; i--) { 2304f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard /* discard obsoleted states */ 23059ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik lev = stream->states[(2 * i) + 1]; 23069ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (lev > stream->level) 23079ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik stream->nbState--; 23089ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik if (lev <= stream->level) 23099ca11bfc3dcd4616cad1c90a025591ebba940839Kasimier T. Buchcik break; 2310f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2311f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard stream = stream->next; 23129740d1d42595ec01cafcfe49c7217229fd8b5bb8Daniel Veillard } 23132fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(0); 23142fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 23152fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 231697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik/** 231797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * xmlStreamWantsAnyNode: 23186795260135a78da60182504a2d7efb4e3177eb57Daniel Veillard * @streamCtxt: the stream context 231997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 232097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Query if the streaming pattern additionally needs to be fed with 232197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * text-, cdata-section-, comment- and processing-instruction-nodes. 232297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * If the result is 0 then only element-nodes and attribute-nodes 232397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * need to be pushed. 232497258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 232597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * Returns: 1 in case of need of nodes of the above described types, 232697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik * 0 otherwise. -1 on API errors. 232797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik */ 232897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcikint 232997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. BuchcikxmlStreamWantsAnyNode(xmlStreamCtxtPtr streamCtxt) 2330f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard{ 233197258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik if (streamCtxt == NULL) 233297258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return(-1); 233397258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik while (streamCtxt != NULL) { 2334f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (streamCtxt->comp->flags & XML_STREAM_FINAL_IS_ANY_NODE) 233597258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return(1); 233697258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik streamCtxt = streamCtxt->next; 233797258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik } 233897258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik return(0); 233997258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik} 234097258713d37a6a9f42dd7e2b5a99b26f3e80789dKasimier T. Buchcik 2341b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/************************************************************************ 2342b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * * 2343b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * The public interfaces * 2344b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * * 2345b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard ************************************************************************/ 2346b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2347b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 2348b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatterncompile: 2349b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @pattern: the pattern to compile 2350fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * @dict: an optional dictionary for interned strings 2351ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel Veillard * @flags: compilation flags, see xmlPatternFlags 2352ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * @namespaces: the prefix definitions, array of [URI, prefix] or NULL 2353b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 2354ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard * Compile a pattern. 2355b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 2356fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Returns the compiled form of the pattern or NULL in case of error 2357b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 2358b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternPtr 2359ed6c54971fdb7fa37c183b1a36c2e581c750984bDaniel VeillardxmlPatterncompile(const xmlChar *pattern, xmlDict *dict, int flags, 2360ffa7b7e2ba3841a80f9c5a69e89cc4b4e457840bDaniel Veillard const xmlChar **namespaces) { 2361f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlPatternPtr ret = NULL, cur; 2362b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard xmlPatParserContextPtr ctxt = NULL; 2363f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard const xmlChar *or, *start; 2364f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlChar *tmp = NULL; 2365fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard int type = 0; 2366fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard int streamable = 1; 2367f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2368f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (pattern == NULL) 2369f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(NULL); 2370f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2371f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard start = pattern; 23722b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard or = start; 2373f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (*or != 0) { 2374f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard tmp = NULL; 2375f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while ((*or != 0) && (*or != '|')) or++; 2376f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (*or == 0) 2377f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ctxt = xmlNewPatParserContext(start, dict, namespaces); 2378f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard else { 2379f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard tmp = xmlStrndup(start, or - start); 2380f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (tmp != NULL) { 2381f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ctxt = xmlNewPatParserContext(tmp, dict, namespaces); 2382f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2383f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard or++; 2384f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2385f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (ctxt == NULL) goto error; 2386f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard cur = xmlNewPattern(); 2387f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (cur == NULL) goto error; 23886ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik /* 23896ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik * Assign string dict. 23906ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik */ 2391f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard if (dict) { 23926ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik cur->dict = dict; 23936ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik xmlDictReference(dict); 23946ed2eb47fcf485283c6dc2dbd0ba0270f22a23b6Kasimier T. Buchcik } 2395f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (ret == NULL) 2396f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = cur; 2397f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard else { 2398f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard cur->next = ret->next; 2399f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret->next = cur; 2400f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2401285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik cur->flags = flags; 2402f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ctxt->comp = cur; 2403b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2404940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik if (XML_STREAM_XS_IDC(cur)) 2405940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik xmlCompileIDCXPathPath(ctxt); 2406940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik else 2407940ab0c67628bee90b60e3e80362e2425f248bd7Kasimier T. Buchcik xmlCompilePathPattern(ctxt); 240856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (ctxt->error != 0) 240956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard goto error; 2410f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlFreePatParserContext(ctxt); 2411fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack ctxt = NULL; 2412b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2413b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2414fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (streamable) { 2415fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (type == 0) { 2416fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard type = cur->flags & (PAT_FROM_ROOT | PAT_FROM_CUR); 2417fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } else if (type == PAT_FROM_ROOT) { 2418fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (cur->flags & PAT_FROM_CUR) 2419fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard streamable = 0; 2420fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } else if (type == PAT_FROM_CUR) { 2421fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (cur->flags & PAT_FROM_ROOT) 2422fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard streamable = 0; 2423fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2424fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2425fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (streamable) 2426fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard xmlStreamCompile(cur); 2427f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (xmlReversePattern(cur) < 0) 2428f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard goto error; 2429ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack if (tmp != NULL) { 2430f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlFree(tmp); 2431ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack tmp = NULL; 2432ea152c05b3f3d9e47b282b88ffdb16fcb8c779c1William M. Brack } 24332b2e02d6bb15ae7c4dc14c1a468158f0b8c3f367Daniel Veillard start = or; 2434f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2435fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (streamable == 0) { 2436fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard cur = ret; 2437fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard while (cur != NULL) { 2438fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard if (cur->stream != NULL) { 2439fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard xmlFreeStreamComp(cur->stream); 2440fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard cur->stream = NULL; 2441fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2442fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard cur = cur->next; 2443fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2444fa1f77f2f04d6960b934f9ebf7cdb20bb8f5e8fdDaniel Veillard } 2445285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik 2446b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(ret); 2447b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillarderror: 2448b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (ctxt != NULL) xmlFreePatParserContext(ctxt); 2449b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if (ret != NULL) xmlFreePattern(ret); 2450f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (tmp != NULL) xmlFree(tmp); 2451b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(NULL); 2452b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 2453b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 2454b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard/** 2455b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * xmlPatternMatch: 2456b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @comp: the precompiled pattern 2457b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * @node: a node 2458b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 2459fbb619f4762fd50630e3ec22589838d089cd2f08William M. Brack * Test whether the node matches the pattern 2460b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * 2461b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure 2462b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard */ 2463b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillardint 2464b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel VeillardxmlPatternMatch(xmlPatternPtr comp, xmlNodePtr node) 2465b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard{ 2466f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard int ret = 0; 2467f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2468b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard if ((comp == NULL) || (node == NULL)) 2469b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard return(-1); 2470f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2471f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (comp != NULL) { 2472f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = xmlPatMatch(comp, node); 2473f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (ret != 0) 2474f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(ret); 2475f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard comp = comp->next; 2476f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2477f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(ret); 2478b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard} 2479b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard 24802fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard/** 24812fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * xmlPatternGetStreamCtxt: 24822fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * @comp: the precompiled pattern 24832fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 24842fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Get a streaming context for that pattern 24852fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Use xmlFreeStreamCtxt to free the context. 24862fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * 24872fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard * Returns a pointer to the context or NULL in case of failure 24882fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard */ 24892fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlStreamCtxtPtr 24902fc6df95cc021fb16debe942697eda86eeba39aeDaniel VeillardxmlPatternGetStreamCtxt(xmlPatternPtr comp) 24912fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard{ 2492f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlStreamCtxtPtr ret = NULL, cur; 2493f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 24942fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard if ((comp == NULL) || (comp->stream == NULL)) 24952fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard return(NULL); 2496f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard 2497f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard while (comp != NULL) { 2498f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (comp->stream == NULL) 2499f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard goto failed; 2500f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard cur = xmlNewStreamCtxt(comp->stream); 2501f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (cur == NULL) 2502f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard goto failed; 2503f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard if (ret == NULL) 2504f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret = cur; 2505f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard else { 2506f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard cur->next = ret->next; 2507f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard ret->next = cur; 2508f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2509285ebabb07c93921a60e4ab2dbefcbc0c49fb334Kasimier T. Buchcik cur->flags = comp->flags; 2510f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard comp = comp->next; 2511f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard } 2512f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(ret); 2513f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillardfailed: 2514f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard xmlFreeStreamCtxt(ret); 2515f1f08cf8dc28095860998f28e392c08ea620bb60Daniel Veillard return(NULL); 25162fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard} 25172fc6df95cc021fb16debe942697eda86eeba39aeDaniel Veillard 251856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 251956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternStreamable: 252056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern 252156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 252256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check if the pattern is streamable i.e. xmlPatternGetStreamCtxt() 252356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * should work. 252456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 252556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns 1 if streamable, 0 if not and -1 in case of error. 252656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 252756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint 252856de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternStreamable(xmlPatternPtr comp) { 252956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp == NULL) 253056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 253156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (comp != NULL) { 253256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream == NULL) 253356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(0); 253456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = comp->next; 253556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 253656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(1); 253756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 253856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 253956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 254056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternMaxDepth: 254156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern 254256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 254356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check the maximum depth reachable by a pattern 254456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 254556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns -2 if no limit (using //), otherwise the depth, 254656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * and -1 in case of error 254756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 254856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint 254956de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternMaxDepth(xmlPatternPtr comp) { 255056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard int ret = 0, i; 255156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp == NULL) 255256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 255356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (comp != NULL) { 255456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream == NULL) 255556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 255656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard for (i = 0;i < comp->stream->nbStep;i++) 255756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream->steps[i].flags & XML_STREAM_STEP_DESC) 255856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-2); 255956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream->nbStep > ret) 256056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard ret = comp->stream->nbStep; 256156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = comp->next; 256256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 256356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(ret); 2564f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard} 256556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 2566f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard/** 2567f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * xmlPatternMinDepth: 2568f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * @comp: the precompiled pattern 2569f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * 2570f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * Check the minimum depth reachable by a pattern, 0 mean the / or . are 2571f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * part of the set. 2572f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * 2573f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard * Returns -1 in case of error otherwise the depth, 2574f8e3db0445a1bc8cfe3f77326b07ec161482caa2Daniel Veillard * 2575f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard */ 2576f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillardint 2577f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel VeillardxmlPatternMinDepth(xmlPatternPtr comp) { 2578f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard int ret = 12345678; 2579f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (comp == NULL) 2580f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(-1); 2581f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard while (comp != NULL) { 2582f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (comp->stream == NULL) 2583f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(-1); 2584f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (comp->stream->nbStep < ret) 2585f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard ret = comp->stream->nbStep; 2586f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard if (ret == 0) 2587f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(0); 2588f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard comp = comp->next; 2589f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard } 2590f03a8cdacdce917d09972c65371953e8a57a2ac3Daniel Veillard return(ret); 259156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 259256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 259356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard/** 259456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * xmlPatternFromRoot: 259556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * @comp: the precompiled pattern 259656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 259756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Check if the pattern must be looked at from the root. 259856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * 259956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard * Returns 1 if true, 0 if false and -1 in case of error 260056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard */ 260156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillardint 260256de87ee0d147d04a041eb1ec95048566375bc3fDaniel VeillardxmlPatternFromRoot(xmlPatternPtr comp) { 260356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp == NULL) 260456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 260556de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard while (comp != NULL) { 260656de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->stream == NULL) 260756de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(-1); 260856de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard if (comp->flags & PAT_FROM_ROOT) 260956de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(1); 261056de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard comp = comp->next; 261156de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard } 261256de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard return(0); 261356de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard 261456de87ee0d147d04a041eb1ec95048566375bc3fDaniel Veillard} 26152a0fdd9101204b9b8ce68050b50cdd1e0ec71049Kasimier T. Buchcik 26165d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#define bottom_pattern 26175d4644ef6e38479a648615eca758c5e962a141d5Daniel Veillard#include "elfgcchack.h" 2618b3de70c28294f6c7f7ef8ec0033fb302b0dfbe26Daniel Veillard#endif /* LIBXML_PATTERN_ENABLED */ 2619