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