15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * pattern.c: Implemetation of the template match compilation and lookup 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Reference: 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * http://www.w3.org/TR/1999/REC-xslt-19991116 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * See Copyright for the status of this software. 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * daniel@veillard.com 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: handle pathological cases like *[*[@a="b"]] 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: detect [number] at compilation, optimize accordingly 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define IN_LIBXSLT 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "libxslt.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string.h> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlmemory.h> 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/tree.h> 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/valid.h> 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/hash.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/xmlerror.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <libxml/parserInternals.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xslt.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltInternals.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "xsltutils.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "imports.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "templates.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "keys.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "pattern.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "documents.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define WITH_XSLT_DEBUG_PATTERN 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Types are private: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_END=0, 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_ROOT, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_ELEM, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_ATTR, 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_PARENT, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_ANCESTOR, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_ID, 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_KEY, 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_NS, 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_ALL, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_PI, 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_COMMENT, 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_TEXT, 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_NODE, 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_OP_PREDICATE 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xsltOp; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef enum { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AXIS_CHILD=1, 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AXIS_ATTRIBUTE 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} xsltAxis; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xsltStepState xsltStepState; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xsltStepState *xsltStepStatePtr; 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltStepState { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int step; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xsltStepStates xsltStepStates; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xsltStepStates *xsltStepStatesPtr; 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltStepStates { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbstates; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxstates; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStepStatePtr states; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xsltStepOp xsltStepOp; 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xsltStepOp *xsltStepOpPtr; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltStepOp { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltOp op; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *value; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *value2; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *value3; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathCompExprPtr comp; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Optimisations for count 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int previousExtra; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int indexExtra; 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int lenExtra; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltCompMatch { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct _xsltCompMatch *next; /* siblings in the name hash */ 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float priority; /* the priority */ 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *pattern; /* the pattern */ 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *mode; /* the mode */ 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *modeURI; /* the mode URI */ 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTemplatePtr template; /* the associated template */ 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int direct; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO fix the statically allocated size steps[] */ 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nbStep; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int maxStep; 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr *nsList; /* the namespaces in scope */ 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nsNr; /* the number of namespaces in scope */ 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStepOpPtr steps; /* ops for computation */ 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef struct _xsltParserContext xsltParserContext; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef xsltParserContext *xsltParserContextPtr; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct _xsltParserContext { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStylesheetPtr style; /* the stylesheet */ 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr ctxt; /* the transformation or NULL */ 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *cur; /* the current char being parsed */ 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *base; /* the full expression */ 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; /* the source document */ 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr elem; /* the source element */ 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error; /* error code */ 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchPtr comp; /* the result */ 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Type functions * 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltNewCompMatch: 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new XSLT CompMatch 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly allocated xsltCompMatchPtr or NULL in case of error 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xsltCompMatchPtr 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltNewCompMatch(void) { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchPtr cur; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = (xsltCompMatchPtr) xmlMalloc(sizeof(xsltCompMatch)); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == NULL) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltNewCompMatch : out of memory error\n"); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(cur, 0, sizeof(xsltCompMatch)); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->maxStep = 10; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->nbStep = 0; 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur-> steps = (xsltStepOpPtr) xmlMalloc(sizeof(xsltStepOp) * 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->maxStep); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur->steps == NULL) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltNewCompMatch : out of memory error\n"); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(cur); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->nsNr = 0; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->nsList = NULL; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->direct = 0; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(cur); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeCompMatch: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: an XSLT comp 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory allocated by @comp 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeCompMatch(xsltCompMatchPtr comp) { 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStepOpPtr op; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp == NULL) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->pattern != NULL) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((xmlChar *)comp->pattern); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->nsList != NULL) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(comp->nsList); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < comp->nbStep;i++) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = &comp->steps[i]; 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (op->value != NULL) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(op->value); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (op->value2 != NULL) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(op->value2); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (op->value3 != NULL) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(op->value3); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (op->comp != NULL) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeCompExpr(op->comp); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(comp->steps); 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(comp, -1, sizeof(xsltCompMatch)); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(comp); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeCompMatchList: 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: an XSLT comp list 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory allocated by all the elements of @comp 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeCompMatchList(xsltCompMatchPtr comp) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchPtr cur; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (comp != NULL) { 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = comp; 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp = comp->next; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatch(cur); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltNormalizeCompSteps: 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @payload: pointer to template hash table entry 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @data: pointer to the stylesheet 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: template match name 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a hashtable scanner function to normalize the compiled 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * steps of an imported stylesheet. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void xsltNormalizeCompSteps(void *payload, 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void *data, const xmlChar *name ATTRIBUTE_UNUSED) { 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchPtr comp = payload; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStylesheetPtr style = data; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ix; 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (ix = 0; ix < comp->nbStep; ix++) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[ix].previousExtra += style->extrasNr; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[ix].indexExtra += style->extrasNr; 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[ix].lenExtra += style->extrasNr; 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltNewParserContext: 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: the stylesheet 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the transformation context, if done at run-time 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Create a new XSLT ParserContext 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the newly allocated xsltParserContextPtr or NULL in case of error 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xsltParserContextPtr 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltNewParserContext(xsltStylesheetPtr style, xsltTransformContextPtr ctxt) { 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltParserContextPtr cur; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = (xsltParserContextPtr) xmlMalloc(sizeof(xsltParserContext)); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur == NULL) { 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltNewParserContext : malloc failed\n"); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(cur, 0, sizeof(xsltParserContext)); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->style = style; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur->ctxt = ctxt; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(cur); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeParserContext: 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: an XSLT parser context 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory allocated by @ctxt 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeParserContext(xsltParserContextPtr ctxt) { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(ctxt, -1, sizeof(xsltParserContext)); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(ctxt); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompMatchAdd: 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the compiled match expression 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @op: an op 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value: the first value 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @value2: the second value 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar: flag to set XML_XPATH_NOVAR 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Add an step to an XSLT Compiled Match 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of failure, 0 otherwise. 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp, 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltOp op, xmlChar * value, xmlChar * value2, int novar) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->nbStep >= comp->maxStep) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStepOpPtr tmp; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xsltStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 * 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sizeof(xsltStepOp)); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericError(xsltGenericErrorContext, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompMatchAdd: memory re-allocation failure.\n"); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->style != NULL) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->style->errors++; 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (-1); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->maxStep *= 2; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps = tmp; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].op = op; 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].value = value; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].value2 = value2; 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].value3 = NULL; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].comp = NULL; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->ctxt != NULL) { 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].previousExtra = 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltAllocateExtraCtxt(ctxt->ctxt); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].indexExtra = 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltAllocateExtraCtxt(ctxt->ctxt); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].lenExtra = 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltAllocateExtraCtxt(ctxt->ctxt); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].previousExtra = 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltAllocateExtra(ctxt->style); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].indexExtra = 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltAllocateExtra(ctxt->style); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].lenExtra = 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltAllocateExtra(ctxt->style); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (op == XSLT_OP_PREDICATE) { 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathContextPtr xctxt; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->style != NULL) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xctxt = xmlXPathNewContext(ctxt->style->doc); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xctxt = xmlXPathNewContext(NULL); 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef XML_XPATH_NOVAR 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (novar != 0) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xctxt->flags = XML_XPATH_NOVAR; 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->style != NULL) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xctxt->dict = ctxt->style->dict; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[comp->nbStep].comp = xmlXPathCtxtCompile(xctxt, value); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeContext(xctxt); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->steps[comp->nbStep].comp == NULL) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, ctxt->style, ctxt->elem, 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Failed to compile predicate\n"); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->style != NULL) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->style->errors++; 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->nbStep++; 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (0); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltSwapTopCompMatch: 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the compiled match expression 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reverse the two top steps. 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltSwapTopCompMatch(xsltCompMatchPtr comp) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j = comp->nbStep - 1; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j > 0) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register xmlChar *tmp; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register xsltOp op; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register xmlXPathCompExprPtr expr; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int t; 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = j - 1; 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = comp->steps[i].value; 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].value = comp->steps[j].value; 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].value = tmp; 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = comp->steps[i].value2; 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].value2 = comp->steps[j].value2; 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].value2 = tmp; 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = comp->steps[i].value3; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].value3 = comp->steps[j].value3; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].value3 = tmp; 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = comp->steps[i].op; 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].op = comp->steps[j].op; 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].op = op; 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expr = comp->steps[i].comp; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].comp = comp->steps[j].comp; 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].comp = expr; 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = comp->steps[i].previousExtra; 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].previousExtra = comp->steps[j].previousExtra; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].previousExtra = t; 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = comp->steps[i].indexExtra; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].indexExtra = comp->steps[j].indexExtra; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].indexExtra = t; 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = comp->steps[i].lenExtra; 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].lenExtra = comp->steps[j].lenExtra; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].lenExtra = t; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltReverseCompMatch: 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the parser context 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the compiled match expression 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * reverse all the stack of expressions 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = 0; 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int j = comp->nbStep - 1; 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (j > i) { 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register xmlChar *tmp; 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register xsltOp op; 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register xmlXPathCompExprPtr expr; 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) register int t; 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = comp->steps[i].value; 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].value = comp->steps[j].value; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].value = tmp; 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = comp->steps[i].value2; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].value2 = comp->steps[j].value2; 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].value2 = tmp; 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = comp->steps[i].value3; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].value3 = comp->steps[j].value3; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].value3 = tmp; 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) op = comp->steps[i].op; 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].op = comp->steps[j].op; 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].op = op; 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expr = comp->steps[i].comp; 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].comp = comp->steps[j].comp; 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].comp = expr; 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = comp->steps[i].previousExtra; 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].previousExtra = comp->steps[j].previousExtra; 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].previousExtra = t; 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = comp->steps[i].indexExtra; 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].indexExtra = comp->steps[j].indexExtra; 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].indexExtra = t; 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) t = comp->steps[i].lenExtra; 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[i].lenExtra = comp->steps[j].lenExtra; 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->steps[j].lenExtra = t; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j--; 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i++; 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchAdd(ctxt, comp, XSLT_OP_END, NULL, NULL, 0); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * detect consecutive XSLT_OP_PREDICATE indicating a direct 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * matching should be done. 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (i = 0;i < comp->nbStep - 1;i++) { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((comp->steps[i].op == XSLT_OP_PREDICATE) && 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (comp->steps[i + 1].op == XSLT_OP_PREDICATE)) { 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->direct = 1; 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->pattern[0] != '/') { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *query; 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) query = xmlStrdup((const xmlChar *)"//"); 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) query = xmlStrcat(query, comp->pattern); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree((xmlChar *) comp->pattern); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->pattern = query; 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The interpreter for the precompiled patterns * 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states, 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int step, xmlNodePtr node) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((states->states == NULL) || (states->maxstates <= 0)) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states->maxstates = 4; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states->nbstates = 0; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states->states = xmlMalloc(4 * sizeof(xsltStepState)); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (states->maxstates <= states->nbstates) { 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStepState *tmp; 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tmp = (xsltStepStatePtr) xmlRealloc(states->states, 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2 * states->maxstates * sizeof(xsltStepState)); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (tmp == NULL) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericError(xsltGenericErrorContext, 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltPatPushState: memory re-allocation failure.\n"); 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = XSLT_STATE_STOPPED; 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states->states = tmp; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states->maxstates *= 2; 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states->states[states->nbstates].step = step; 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states->states[states->nbstates++].node = node; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Push: %d, %s\n", step, node->name); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltTestCompMatchDirect: 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a XSLT process context 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the precompiled pattern 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: a node 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nsList: the namespaces in scope 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @nsNr: the number of namespaces in scope 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Test whether the node matches the pattern, do a direct evalutation 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * and not a step by step evaluation. 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node, xmlNsPtr *nsList, int nsNr) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStepOpPtr sel = NULL; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr prevdoc; 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr list; 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ix, j; 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int nocache = 0; 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isRVT; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = node->doc; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (XSLT_IS_RES_TREE_FRAG(doc)) 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isRVT = 1; 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isRVT = 0; 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sel = &comp->steps[0]; /* store extra in first step arbitrarily */ 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prevdoc = (xmlDocPtr) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = (xmlXPathObjectPtr) 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((list == NULL) || (prevdoc != doc)) { 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathObjectPtr newlist; 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr parent = node->parent; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr olddoc; 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr oldnode; 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int oldNsNr; 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr *oldNamespaces; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldnode = ctxt->xpathCtxt->node; 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) olddoc = ctxt->xpathCtxt->doc; 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldNsNr = ctxt->xpathCtxt->nsNr; 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldNamespaces = ctxt->xpathCtxt->namespaces; 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->node = node; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->doc = doc; 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->namespaces = nsList; 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->nsNr = nsNr; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) newlist = xmlXPathEval(comp->pattern, ctxt->xpathCtxt); 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->node = oldnode; 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->doc = olddoc; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->namespaces = oldNamespaces; 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->nsNr = oldNsNr; 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newlist == NULL) 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (newlist->type != XPATH_NODESET) { 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(newlist); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ix = 0; 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((parent == NULL) || (node->doc == NULL) || isRVT) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nocache = 1; 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nocache == 0) { 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list != NULL) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(list); 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = newlist; 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra) = 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void *) list; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (void *) doc; 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 0; 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA_FREE(ctxt, sel->lenExtra) = 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlFreeFunc) xmlXPathFreeObject; 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = newlist; 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((list->nodesetval == NULL) || 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (list->nodesetval->nodeNr <= 0)) { 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nocache == 1) 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(list); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: store the index and use it for the scan */ 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ix == 0) { 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (j = 0;j < list->nodesetval->nodeNr;j++) { 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list->nodesetval->nodeTab[j] == node) { 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nocache == 1) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(list); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (nocache == 1) 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlXPathFreeObject(list); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltTestCompMatch: 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a XSLT process context 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the precompiled pattern 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: a node 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @mode: the mode name or NULL 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @modeURI: the mode URI or NULL 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Test whether the node matches the pattern 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node, const xmlChar *mode, 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *modeURI) { 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i; 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStepOpPtr step, sel = NULL; 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStepStates states = {0, 0, NULL}; /* // may require backtrack */ 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((comp == NULL) || (node == NULL) || (ctxt == NULL)) { 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(ctxt, NULL, node, 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltTestCompMatch: null arg\n"); 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mode != NULL) { 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->mode == NULL) 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * both mode strings must be interned on the stylesheet dictionary 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->mode != mode) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->mode != NULL) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modeURI != NULL) { 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->modeURI == NULL) 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * both modeURI strings must be interned on the stylesheet dictionary 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->modeURI != modeURI) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->modeURI != NULL) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = 0; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)restart: 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (;i < comp->nbStep;i++) { 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) step = &comp->steps[i]; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->op != XSLT_OP_PREDICATE) 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sel = step; 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (step->op) { 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_END: 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto found; 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ROOT: 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->type == XML_DOCUMENT_NODE) || 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DOCB_ENABLED 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_DOCB_DOCUMENT_NODE) || 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_HTML_DOCUMENT_NODE)) 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->type == XML_ELEMENT_NODE) && (node->name[0] == ' ')) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ELEM: 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->type != XML_ELEMENT_NODE) 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value == NULL) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value[0] != node->name[0]) 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(step->value, node->name)) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Namespace test */ 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->ns == NULL) { 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value2 != NULL) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (node->ns->href != NULL) { 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value2 == NULL) 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(step->value2, node->ns->href)) 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ATTR: 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->type != XML_ATTRIBUTE_NODE) 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value != NULL) { 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value[0] != node->name[0]) 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(step->value, node->name)) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Namespace test */ 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->ns == NULL) { 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value2 != NULL) 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (step->value2 != NULL) { 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(step->value2, node->ns->href)) 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_PARENT: 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->type == XML_DOCUMENT_NODE) || 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_HTML_DOCUMENT_NODE) || 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DOCB_ENABLED 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_DOCB_DOCUMENT_NODE) || 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_NAMESPACE_DECL)) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = node->parent; 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == NULL) 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value == NULL) 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value[0] != node->name[0]) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(step->value, node->name)) 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Namespace test */ 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->ns == NULL) { 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value2 != NULL) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (node->ns->href != NULL) { 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value2 == NULL) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(step->value2, node->ns->href)) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ANCESTOR: 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO: implement coalescing of ANCESTOR/NODE ops */ 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value == NULL) { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) step = &comp->steps[i+1]; 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->op == XSLT_OP_ROOT) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto found; 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* added NS, ID and KEY as a result of bug 168208 */ 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((step->op != XSLT_OP_ELEM) && 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (step->op != XSLT_OP_ALL) && 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (step->op != XSLT_OP_NS) && 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (step->op != XSLT_OP_ID) && 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (step->op != XSLT_OP_KEY)) 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == NULL) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->type == XML_DOCUMENT_NODE) || 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_HTML_DOCUMENT_NODE) || 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef LIBXML_DOCB_ENABLED 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_DOCB_DOCUMENT_NODE) || 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_NAMESPACE_DECL)) 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = node->parent; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((step->op != XSLT_OP_ELEM) && step->op != XSLT_OP_ALL) { 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltPatPushState(ctxt, &states, i, node); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i++; 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value == NULL) { 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltPatPushState(ctxt, &states, i - 1, node); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (node != NULL) { 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->type == XML_ELEMENT_NODE) && 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (step->value[0] == node->name[0]) && 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(step->value, node->name))) { 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Namespace test */ 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->ns == NULL) { 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value2 == NULL) 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (node->ns->href != NULL) { 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((step->value2 != NULL) && 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(step->value2, node->ns->href))) 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = node->parent; 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node == NULL) 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltPatPushState(ctxt, &states, i - 1, node); 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ID: { 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO Handle IDs decently, must be done differently */ 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAttrPtr id; 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->type != XML_ELEMENT_NODE) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) id = xmlGetID(node->doc, step->value); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((id == NULL) || (id->parent != node)) 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_KEY: { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodeSetPtr list; 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int indx; 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = xsltGetKey(ctxt, step->value, 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) step->value3, step->value2); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list == NULL) 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (indx = 0;indx < list->nodeNr;indx++) 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list->nodeTab[indx] == node) 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (indx >= list->nodeNr) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_NS: 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->type != XML_ELEMENT_NODE) 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->ns == NULL) { 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value != NULL) 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (node->ns->href != NULL) { 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value == NULL) 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(step->value, node->ns->href)) 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ALL: 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->type != XML_ELEMENT_NODE) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_PREDICATE: { 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr oldNode; 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int oldCS, oldCP; 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int pos = 0, len = 0; 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int isRVT; 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * when there is cascading XSLT_OP_PREDICATE, then use a 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * direct computation approach. It's not done directly 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * at the beginning of the routine to filter out as much 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * as possible this costly computation. 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (comp->direct) { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (states.states != NULL) { 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Free the rollback states */ 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(states.states); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(xsltTestCompMatchDirect(ctxt, comp, node, 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->nsList, comp->nsNr)); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = node->doc; 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (XSLT_IS_RES_TREE_FRAG(doc)) 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isRVT = 1; 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) isRVT = 0; 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Depending on the last selection, one may need to 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * recompute contextSize and proximityPosition. 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldCS = ctxt->xpathCtxt->contextSize; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldCP = ctxt->xpathCtxt->proximityPosition; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((sel != NULL) && 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sel->op == XSLT_OP_ELEM) && 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sel->value != NULL) && 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_ELEMENT_NODE) && 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->parent != NULL)) { 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr previous; 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ix, nocache = 0; 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous = (xmlNodePtr) 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((previous != NULL) && 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (previous->parent == node->parent)) { 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * just walk back to adjust the index 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int indx = 0; 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr sibling = node; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (sibling != NULL) { 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling == previous) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((previous->type == XML_ELEMENT_NODE) && 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (previous->name != NULL) && 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sibling->name != NULL) && 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (previous->name[0] == sibling->name[0]) && 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(previous->name, sibling->name))) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((sel->value2 == NULL) || 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((sibling->ns != NULL) && 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(sel->value2, 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sibling->ns->href)))) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indx++; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sibling = sibling->prev; 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling == NULL) { 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* hum going backward in document order ... */ 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indx = 0; 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sibling = node; 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (sibling != NULL) { 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling == previous) 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((previous->type == XML_ELEMENT_NODE) && 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (previous->name != NULL) && 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (sibling->name != NULL) && 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (previous->name[0] == sibling->name[0]) && 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(previous->name, sibling->name))) 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((sel->value2 == NULL) || 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((sibling->ns != NULL) && 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(sel->value2, 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sibling->ns->href)))) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indx--; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sibling = sibling->next; 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling != NULL) { 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = ix + indx; 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the node is in a Value Tree we need to 9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * save len, but cannot cache the node! 9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * (bugs 153137 and 158840) 9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->doc != NULL) { 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = XSLT_RUNTIME_EXTRA(ctxt, 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sel->lenExtra, ival); 9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!isRVT) { 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sel->previousExtra, ptr) = node; 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sel->indexExtra, ival) = pos; 9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ix = pos; 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = 0; 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * recompute the index 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr parent = node->parent; 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr siblings = NULL; 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent) siblings = parent->children; 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (siblings != NULL) { 9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (siblings->type == XML_ELEMENT_NODE) { 9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (siblings == node) { 9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len++; 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = len; 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((node->name != NULL) && 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (siblings->name != NULL) && 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->name[0] == siblings->name[0]) && 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(node->name, siblings->name))) { 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((sel->value2 == NULL) || 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((siblings->ns != NULL) && 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlStrEqual(sel->value2, 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) siblings->ns->href)))) 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len++; 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) siblings = siblings->next; 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((parent == NULL) || (node->doc == NULL)) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nocache = 1; 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (parent->parent != NULL) 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = parent->parent; 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((parent->type != XML_DOCUMENT_NODE) && 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (parent->type != XML_HTML_DOCUMENT_NODE)) || 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (parent != (xmlNodePtr) node->doc)) 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nocache = 1; 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pos != 0) { 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->contextSize = len; 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->proximityPosition = pos; 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the node is in a Value Tree we cannot 10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cache it ! 10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((!isRVT) && (node->doc != NULL) && 10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (nocache == 0)) { 10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = 10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node; 10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = 10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos; 10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) = 10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len; 10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((sel != NULL) && (sel->op == XSLT_OP_ALL) && 10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_ELEMENT_NODE)) { 10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr previous; 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ix, nocache = 0; 10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous = (xmlNodePtr) 10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival); 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((previous != NULL) && 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (previous->parent == node->parent)) { 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * just walk back to adjust the index 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int indx = 0; 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr sibling = node; 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (sibling != NULL) { 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling == previous) 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling->type == XML_ELEMENT_NODE) 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indx++; 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sibling = sibling->prev; 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling == NULL) { 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* hum going backward in document order ... */ 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indx = 0; 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sibling = node; 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (sibling != NULL) { 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling == previous) 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling->type == XML_ELEMENT_NODE) 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) indx--; 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sibling = sibling->next; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (sibling != NULL) { 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = ix + indx; 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the node is in a Value Tree we cannot 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cache it ! 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->doc != NULL) && !isRVT) { 10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len = XSLT_RUNTIME_EXTRA(ctxt, 10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sel->lenExtra, ival); 10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sel->previousExtra, ptr) = node; 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sel->indexExtra, ival) = pos; 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = 0; 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 10695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * recompute the index 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr parent = node->parent; 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr siblings = NULL; 10735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (parent) siblings = parent->children; 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (siblings != NULL) { 10775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (siblings->type == XML_ELEMENT_NODE) { 10785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len++; 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (siblings == node) { 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos = len; 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) siblings = siblings->next; 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((parent == NULL) || (node->doc == NULL)) 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nocache = 1; 10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (parent->parent != NULL) 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) parent = parent->parent; 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((parent->type != XML_DOCUMENT_NODE) && 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (parent->type != XML_HTML_DOCUMENT_NODE)) || 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (parent != (xmlNodePtr) node->doc)) 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) nocache = 1; 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pos != 0) { 10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->contextSize = len; 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->proximityPosition = pos; 10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * If the node is in a Value Tree we cannot 11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * cache it ! 11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->doc != NULL) && (nocache == 0) && !isRVT) { 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->previousExtra, ptr) = 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node; 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pos; 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) = 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) len; 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) oldNode = ctxt->node; 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->node = node; 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value == NULL) 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto wrong_index; 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->comp == NULL) 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto wrong_index; 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xsltEvalXPathPredicate(ctxt, step->comp, comp->nsList, 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp->nsNr)) 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto wrong_index; 11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pos != 0) { 11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->contextSize = oldCS; 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->proximityPosition = oldCP; 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->node = oldNode; 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)wrong_index: 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pos != 0) { 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->contextSize = oldCS; 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->xpathCtxt->proximityPosition = oldCP; 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->node = oldNode; 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_PI: 11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->type != XML_PI_NODE) 11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (step->value != NULL) { 11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!xmlStrEqual(step->value, node->name)) 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_COMMENT: 11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->type != XML_COMMENT_NODE) 11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_TEXT: 11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->type != XML_TEXT_NODE) && 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type != XML_CDATA_SECTION_NODE)) 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_NODE: 11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (node->type) { 11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ELEMENT_NODE: 11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_CDATA_SECTION_NODE: 11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_PI_NODE: 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_COMMENT_NODE: 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_TEXT_NODE: 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto rollback; 11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)found: 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (states.states != NULL) { 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Free the rollback states */ 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(states.states); 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)rollback: 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* got an error try to rollback */ 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (states.states == NULL) 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (states.nbstates <= 0) { 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(states.states); 11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) states.nbstates--; 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) i = states.states[states.nbstates].step; 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) node = states.states[states.nbstates].node; 11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if 0 11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fprintf(stderr, "Pop: %d, %s\n", i, node->name); 11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto restart; 11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 11945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltTestCompMatchList: 11955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a XSLT process context 11965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: a node 11975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the precompiled pattern list 11985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 11995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Test whether the node matches one of the patterns in the list 12005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns 1 if it matches, 0 if it doesn't and -1 in case of failure 12025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 12045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltTestCompMatchList(xsltTransformContextPtr ctxt, xmlNodePtr node, 12055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchPtr comp) { 12065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ret; 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (node == NULL)) 12095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 12105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (comp != NULL) { 12115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xsltTestCompMatch(ctxt, comp, node, NULL, NULL); 12125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret == 1) 12135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(1); 12145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) comp = comp->next; 12155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Dedicated parser for templates * 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR (*ctxt->cur) 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SKIP(val) ctxt->cur += (val) 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NXT(val) ctxt->cur[(val)] 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CUR_PTR ctxt->cur 12295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SKIP_BLANKS \ 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (IS_BLANK_CH(CUR)) NEXT 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CURRENT (*ctxt->cur) 12345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define NEXT ((*ctxt->cur) ? ctxt->cur++: ctxt->cur) 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define PUSH(op, val, val2, novar) \ 12385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltCompMatchAdd(ctxt, ctxt->comp, (op), (val), (val2), (novar))) goto error; 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SWAP() \ 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltSwapTopCompMatch(ctxt->comp); 12425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XSLT_ERROR(X) \ 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { xsltError(ctxt, __FILE__, __LINE__, X); \ 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = (X); return; } 12465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define XSLT_ERROR0(X) \ 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { xsltError(ctxt, __FILE__, __LINE__, X); \ 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = (X); return(0); } 12505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 12525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltScanLiteral: 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 12545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parse an XPath Litteral: 12565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [29] Literal ::= '"' [^"]* '"' 12585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | "'" [^']* "'" 12595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 12605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the Literal parsed or NULL 12615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 12625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlChar * 12645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltScanLiteral(xsltParserContextPtr ctxt) { 12655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *q, *cur; 12665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *ret = NULL; 12675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int val, len; 12685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 12705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '"') { 12715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 12725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = q = CUR_PTR; 12735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = xmlStringCurrentChar(NULL, cur, &len); 12745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((IS_CHAR(val)) && (val != '"')) { 12755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += len; 12765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = xmlStringCurrentChar(NULL, cur, &len); 12775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_CHAR(val)) { 12795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 12805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 12815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrndup(q, cur - q); 12835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += len; 12855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CUR_PTR = cur; 12865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '\'') { 12875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 12885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = q = CUR_PTR; 12895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = xmlStringCurrentChar(NULL, cur, &len); 12905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((IS_CHAR(val)) && (val != '\'')) { 12915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += len; 12925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = xmlStringCurrentChar(NULL, cur, &len); 12935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 12945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_CHAR(val)) { 12955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 12965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 12975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 12985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrndup(q, cur - q); 12995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += len; 13015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CUR_PTR = cur; 13025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 13035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* XP_ERROR(XPATH_START_LITERAL_ERROR); */ 13045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 13055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 13065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 13085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 13115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltScanNCName: 13125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the XPath Parser context 13135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Parses a non qualified name 13155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the Name parsed or NULL 13175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xmlChar * 13205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltScanNCName(xsltParserContextPtr ctxt) { 13215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *q, *cur; 13225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *ret = NULL; 13235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int val, len; 13245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 13265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur = q = CUR_PTR; 13285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = xmlStringCurrentChar(NULL, cur, &len); 13295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!IS_LETTER(val) && (val != '_')) 13305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 13315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((IS_LETTER(val)) || (IS_DIGIT(val)) || 13335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (val == '.') || (val == '-') || 13345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (val == '_') || 13355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (IS_COMBINING(val)) || 13365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (IS_EXTENDER(val))) { 13375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cur += len; 13385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) val = xmlStringCurrentChar(NULL, cur, &len); 13395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrndup(q, cur - q); 13415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CUR_PTR = cur; 13425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 13435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 13445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* 13465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompileIdKeyPattern: 13475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the compilation context 13485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @name: a preparsed name 13495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @aid: whether id/key are allowed there 13505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar: flag to prohibit xslt var 13515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT LocationIdKeyPattern 13535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [3] IdKeyPattern ::= 'id' '(' Literal ')' 13545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | 'key' '(' Literal ',' Literal ')' 13555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * also handle NodeType and PI from: 13575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 13585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [7] NodeTest ::= NameTest 13595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | NodeType '(' ')' 13605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | 'processing-instruction' '(' Literal ')' 13615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 13625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 13635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name, 13645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int aid, int novar, xsltAxis axis) { 13655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *lit = NULL; 13665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *lit2 = NULL; 13675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != '(') { 13695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 13705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : ( expected\n"); 13715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 13725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((aid) && (xmlStrEqual(name, (const xmlChar *)"id"))) { 13755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (axis != 0) { 13765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 13775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : NodeTest expected\n"); 13785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 13795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 13825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 13835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lit = xsltScanLiteral(ctxt); 13845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 13855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 13875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ')') { 13885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 13895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : ) expected\n"); 13905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 13915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 13925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 13935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 13945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ID, lit, NULL, novar); 13955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((aid) && (xmlStrEqual(name, (const xmlChar *)"key"))) { 13965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (axis != 0) { 13975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 13985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : NodeTest expected\n"); 13995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lit = xsltScanLiteral(ctxt); 14055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 14065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ',') { 14095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 14105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : , expected\n"); 14115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lit2 = xsltScanLiteral(ctxt); 14175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 14185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ')') { 14215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 14225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : ) expected\n"); 14235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* URGENT TODO: support namespace in keys */ 14285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_KEY, lit, lit2, novar); 14295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (xmlStrEqual(name, (const xmlChar *)"processing-instruction")) { 14305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ')') { 14335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) lit = xsltScanLiteral(ctxt); 14345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 14355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ')') { 14385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 14395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : ) expected\n"); 14405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_PI, lit, NULL, novar); 14465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (xmlStrEqual(name, (const xmlChar *)"text")) { 14475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ')') { 14505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 14515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : ) expected\n"); 14525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_TEXT, NULL, NULL, novar); 14575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (xmlStrEqual(name, (const xmlChar *)"comment")) { 14585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ')') { 14615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 14625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : ) expected\n"); 14635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_COMMENT, NULL, NULL, novar); 14685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (xmlStrEqual(name, (const xmlChar *)"node")) { 14695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 14715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ')') { 14725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 14735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : ) expected\n"); 14745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 14785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (axis == AXIS_ATTRIBUTE) { 14795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ATTR, NULL, NULL, novar); 14805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 14825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_NODE, NULL, NULL, novar); 14835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (aid) { 14855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 14865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : expecting 'key' or 'id' or node type\n"); 14875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 14905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 14915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileIdKeyPattern : node type\n"); 14925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 14935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 14945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 14955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 14965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name != NULL) 14975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(name); 14985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 14995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 15015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompileStepPattern: 15025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the compilation context 15035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: a posible precompiled name 15045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar: flag to prohibit xslt variables from pattern 15055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT StepPattern and generates a precompiled 15075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * form suitable for fast matching. 15085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 15095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [5] StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate* 15105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [6] ChildOrAttributeAxisSpecifier ::= AbbreviatedAxisSpecifier 15115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | ('child' | 'attribute') '::' 15125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * from XPath 15135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [7] NodeTest ::= NameTest 15145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | NodeType '(' ')' 15155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | 'processing-instruction' '(' Literal ')' 15165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [8] Predicate ::= '[' PredicateExpr ']' 15175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [9] PredicateExpr ::= Expr 15185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [13] AbbreviatedAxisSpecifier ::= '@'? 15195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [37] NameTest ::= '*' | NCName ':' '*' | QName 15205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 15235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) { 15245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *name = NULL; 15255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *URI = NULL; 15265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *URL = NULL; 15275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int level; 15285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltAxis axis = 0; 15295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 15315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((token == NULL) && (CUR == '@')) { 15325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 15335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) axis = AXIS_ATTRIBUTE; 15345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parse_node_test: 15365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (token == NULL) 15375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token = xsltScanNCName(ctxt); 15385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (token == NULL) { 15395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '*') { 15405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 15415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (axis == AXIS_ATTRIBUTE) { 15425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ATTR, NULL, NULL, novar); 15435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 15455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ALL, NULL, NULL, novar); 15465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto parse_predicate; 15485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 15505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileStepPattern : Name expected\n"); 15515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 15525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 15535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 15585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '(') { 15595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileIdKeyPattern(ctxt, token, 0, novar, axis); 15605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 15615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 15625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == ':') { 15635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 15645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR != ':') { 15655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *prefix = token; 15665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNsPtr ns; 15675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 15695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * This is a namespace match 15705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 15715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token = xsltScanNCName(ctxt); 15725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix); 15735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ns == NULL) { 15745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 15755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileStepPattern : no namespace bound to prefix %s\n", 15765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) prefix); 15775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(prefix); 15785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 15795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 15805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URL = xmlStrdup(ns->href); 15825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(prefix); 15845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (token == NULL) { 15855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '*') { 15865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 15875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (axis == AXIS_ATTRIBUTE) { 15885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ATTR, NULL, URL, novar); 15895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 15915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_NS, URL, NULL, novar); 15925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 15945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 15955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileStepPattern : Name expected\n"); 15965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 15975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 15985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 15995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (axis == AXIS_ATTRIBUTE) { 16015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ATTR, token, URL, novar); 16025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 16045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ELEM, token, URL, novar); 16055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (axis != 0) { 16095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 16105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileStepPattern : NodeTest expected\n"); 16115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 16125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 16135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 16155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xmlStrEqual(token, (const xmlChar *) "child")) { 16165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) axis = AXIS_CHILD; 16175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (xmlStrEqual(token, (const xmlChar *) "attribute")) { 16185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) axis = AXIS_ATTRIBUTE; 16195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 16215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileStepPattern : 'child' or 'attribute' expected\n"); 16225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 16235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 16245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(token); 16265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 16275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) token = xsltScanNCName(ctxt); 16285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto parse_node_test; 16295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 16315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URI = xsltGetQNameURI(ctxt->elem, &token); 16325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (token == NULL) { 16335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 16345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 16355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (URI != NULL) 16375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) URL = xmlStrdup(URI); 16385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (axis == AXIS_ATTRIBUTE) { 16395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ATTR, token, URL, novar); 16405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else { 16425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ELEM, token, URL, novar); 16435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)parse_predicate: 16465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 16475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level = 0; 16485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (CUR == '[') { 16495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *q; 16505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *ret = NULL; 16515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level++; 16535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 16545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) q = CUR_PTR; 16555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (CUR != 0) { 16565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* Skip over nested predicates */ 16575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == '[') 16585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level++; 16595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (CUR == ']') { 16605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level--; 16615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (level == 0) 16625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 16635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '"') { 16645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 16655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((CUR != 0) && (CUR != '"')) 16665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 16675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '\'') { 16685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 16695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((CUR != 0) && (CUR != '\'')) 16705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 16715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 16735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (CUR == 0) { 16755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 16765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileStepPattern : ']' expected\n"); 16775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 16785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = xmlStrndup(q, CUR_PTR - q); 16815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_PREDICATE, ret, NULL, novar); 16825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* push the predicate lower than local test */ 16835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SWAP(); 16845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 16855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 16865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 16875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 16885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 16895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (token != NULL) 16905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(token); 16915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name != NULL) 16925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlFree(name); 16935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 16945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 16955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 16965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompileRelativePathPattern: 16975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @comp: the compilation context 16985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @token: a posible precompiled name 16995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar: flag to prohibit xslt variables 17005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT RelativePathPattern and generates a precompiled 17025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * form suitable for fast matching. 17035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [4] RelativePathPattern ::= StepPattern 17055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | RelativePathPattern '/' StepPattern 17065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | RelativePathPattern '//' StepPattern 17075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 17095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompileRelativePathPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar) { 17105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileStepPattern(ctxt, token, novar); 17115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 17125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 17135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 17145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((CUR != 0) && (CUR != '|')) { 17155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((CUR == '/') && (NXT(1) == '/')) { 17165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar); 17175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 17185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 17195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 17205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileStepPattern(ctxt, NULL, novar); 17215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '/') { 17225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_PARENT, NULL, NULL, novar); 17235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 17245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 17255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((CUR != 0) && (CUR != '|')) { 17265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileRelativePathPattern(ctxt, NULL, novar); 17275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 17305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 17325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 17335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 17345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 17365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 17385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 17395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 17405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompileLocationPathPattern: 17415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: the compilation context 17425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar: flag to prohibit xslt variables 17435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT LocationPathPattern and generates a precompiled 17455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * form suitable for fast matching. 17465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 17475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [2] LocationPathPattern ::= '/' RelativePathPattern? 17485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | IdKeyPattern (('/' | '//') RelativePathPattern)? 17495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * | '//'? RelativePathPattern 17505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static void 17525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompileLocationPathPattern(xsltParserContextPtr ctxt, int novar) { 17535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 17545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((CUR == '/') && (NXT(1) == '/')) { 17555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 17565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * since we reverse the query 17575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * a leading // can be safely ignored 17585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 17605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 17615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->comp->priority = 0.5; /* '//' means not 0 priority */ 17625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileRelativePathPattern(ctxt, NULL, novar); 17635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '/') { 17645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 17655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * We need to find root as the parent 17665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 17675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 17685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 17695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ROOT, NULL, NULL, novar); 17705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((CUR != 0) && (CUR != '|')) { 17715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_PARENT, NULL, NULL, novar); 17725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileRelativePathPattern(ctxt, NULL, novar); 17735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '*') { 17755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileRelativePathPattern(ctxt, NULL, novar); 17765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '@') { 17775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileRelativePathPattern(ctxt, NULL, novar); 17785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 17795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlChar *name; 17805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = xsltScanNCName(ctxt); 17815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name == NULL) { 17825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, NULL, 17835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompileLocationPathPattern : Name expected\n"); 17845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->error = 1; 17855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 17875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 17885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((CUR == '(') && !xmlXPathIsNodeType(name)) { 17895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileIdKeyPattern(ctxt, name, 1, novar, 0); 17905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) 17915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 17925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((CUR == '/') && (NXT(1) == '/')) { 17935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar); 17945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 17955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 17965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 17975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileRelativePathPattern(ctxt, NULL, novar); 17985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (CUR == '/') { 17995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PUSH(XSLT_OP_PARENT, NULL, NULL, novar); 18005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NEXT; 18015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SKIP_BLANKS; 18025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileRelativePathPattern(ctxt, NULL, novar); 18035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileRelativePathPattern(ctxt, name, novar); 18075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 18095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 18105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 18115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 18135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompilePatternInternal: 18145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @pattern: an XSLT pattern 18155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @doc: the containing document 18165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the containing element 18175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: the stylesheet 18185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @runtime: the transformation context, if done at run-time 18195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @novar: flag to prohibit xslt variables 18205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT pattern and generates a list of precompiled form suitable 18225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for fast matching. 18235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [1] Pattern ::= LocationPathPattern | Pattern '|' LocationPathPattern 18255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 18265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the generated pattern list or NULL in case of failure 18275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 18285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static xsltCompMatchPtr 18305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc, 18315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node, xsltStylesheetPtr style, 18325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr runtime, int novar) { 18335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltParserContextPtr ctxt = NULL; 18345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchPtr element, first = NULL, previous = NULL; 18355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int current, start, end, level, j; 18365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pattern == NULL) { 18385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, node, 18395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompilePattern : NULL pattern\n"); 18405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 18415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt = xsltNewParserContext(style, runtime); 18445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt == NULL) 18455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 18465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->doc = doc; 18475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->elem = node; 18485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current = end = 0; 18495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pattern[current] != 0) { 18505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = current; 18515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (IS_BLANK_CH(pattern[current])) 18525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current++; 18535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end = current; 18545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level = 0; 18555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((pattern[end] != 0) && ((pattern[end] != '|') || (level != 0))) { 18565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pattern[end] == '[') 18575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level++; 18585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (pattern[end] == ']') 18595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) level--; 18605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (pattern[end] == '\'') { 18615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end++; 18625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((pattern[end] != 0) && (pattern[end] != '\'')) 18635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end++; 18645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (pattern[end] == '"') { 18655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end++; 18665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((pattern[end] != 0) && (pattern[end] != '"')) 18675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end++; 18685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pattern[end] == 0) 18705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 18715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end++; 18725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (current == end) { 18745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, NULL, node, 18755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompilePattern : NULL pattern\n"); 18765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 18775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element = xsltNewCompMatch(); 18795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element == NULL) { 18805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 18815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 18825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first == NULL) 18835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first = element; 18845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (previous != NULL) 18855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous->next = element; 18865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) previous = element; 18875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 18885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->comp = element; 18895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->base = xmlStrndup(&pattern[start], end - start); 18905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->base == NULL) 18915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 18925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->cur = &(ctxt->base)[current - start]; 18935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->pattern = ctxt->base; 18945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->nsList = xmlGetNsList(doc, node); 18955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j = 0; 18965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element->nsList != NULL) { 18975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (element->nsList[j] != NULL) 18985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) j++; 18995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->nsNr = j; 19015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG_PATTERN 19045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericDebug(xsltGenericDebugContext, 19055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompilePattern : parsing '%s'\n", 19065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->pattern); 19075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 19095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Preset default priority to be zero. 19105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) This may be changed by xsltCompileLocationPathPattern. 19115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->priority = 0; 19135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompileLocationPathPattern(ctxt, novar); 19145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->error) { 19155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 19165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompilePattern : failed to compile '%s'\n", 19175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->pattern); 19185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style != NULL) style->errors++; 19195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 19205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 19235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Reverse for faster interpretation. 19245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltReverseCompMatch(ctxt, element); 19265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 19285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Set-up the priority 19295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 19305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (element->priority == 0) { /* if not yet determined */ 19315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((element->steps[0].op == XSLT_OP_ELEM) || 19325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].op == XSLT_OP_ATTR) || 19335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].op == XSLT_OP_PI)) && 19345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].value != NULL) && 19355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[1].op == XSLT_OP_END)) { 19365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ; /* previously preset */ 19375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((element->steps[0].op == XSLT_OP_ATTR) && 19385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].value2 != NULL) && 19395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[1].op == XSLT_OP_END)) { 19405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->priority = -0.25; 19415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((element->steps[0].op == XSLT_OP_NS) && 19425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].value != NULL) && 19435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[1].op == XSLT_OP_END)) { 19445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->priority = -0.25; 19455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((element->steps[0].op == XSLT_OP_ATTR) && 19465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].value == NULL) && 19475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].value2 == NULL) && 19485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[1].op == XSLT_OP_END)) { 19495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->priority = -0.5; 19505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (((element->steps[0].op == XSLT_OP_PI) || 19515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].op == XSLT_OP_TEXT) || 19525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].op == XSLT_OP_ALL) || 19535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].op == XSLT_OP_NODE) || 19545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[0].op == XSLT_OP_COMMENT)) && 19555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (element->steps[1].op == XSLT_OP_END)) { 19565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->priority = -0.5; 19575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 19585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->priority = 0.5; 19595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG_PATTERN 19625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericDebug(xsltGenericDebugContext, 19635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompilePattern : parsed %s, default priority %f\n", 19645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) element->pattern, element->priority); 19655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 19665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pattern[end] == '|') 19675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) end++; 19685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current = end; 19695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (end == 0) { 19715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, node, 19725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltCompilePattern : NULL pattern\n"); 19735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style != NULL) style->errors++; 19745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 19755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 19765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeParserContext(ctxt); 19785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(first); 19795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 19815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt != NULL) 19825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeParserContext(ctxt); 19835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (first != NULL) 19845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(first); 19855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 19865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 19875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 19885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 19895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCompilePattern: 19905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @pattern: an XSLT pattern 19915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @doc: the containing document 19925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the containing element 19935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: the stylesheet 19945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @runtime: the transformation context, if done at run-time 19955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 19965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compile the XSLT pattern and generates a list of precompiled form suitable 19975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * for fast matching. 19985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 19995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * [1] Pattern ::= LocationPathPattern | Pattern '|' LocationPathPattern 20005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 20015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the generated pattern list or NULL in case of failure 20025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompMatchPtr 20055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCompilePattern(const xmlChar *pattern, xmlDocPtr doc, 20065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlNodePtr node, xsltStylesheetPtr style, 20075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformContextPtr runtime) { 20085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (xsltCompilePatternInternal(pattern, doc, node, style, runtime, 0)); 20095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 20105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/************************************************************************ 20125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 20135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Module interfaces * 20145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * * 20155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ************************************************************************/ 20165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 20185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltAddTemplate: 20195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: an XSLT stylesheet 20205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @cur: an XSLT template 20215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @mode: the mode name or NULL 20225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @modeURI: the mode URI or NULL 20235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 20245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Register the XSLT pattern associated to @cur 20255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 20265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns -1 in case of error, 0 otherwise 20275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int 20295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltAddTemplate(xsltStylesheetPtr style, xsltTemplatePtr cur, 20305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *mode, const xmlChar *modeURI) { 20315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchPtr pat, list, next; 20325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 20335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 'top' will point to style->xxxMatch ptr - declaring as 'void' 20345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * avoids gcc 'type-punned pointer' warning. 20355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void **top = NULL; 20375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name = NULL; 20385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float priority; /* the priority */ 20395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((style == NULL) || (cur == NULL) || (cur->match == NULL)) 20415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 20425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority = cur->priority; 20445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat = xsltCompilePatternInternal(cur->match, style->doc, cur->elem, 20455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) style, NULL, 1); 20465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pat == NULL) 20475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 20485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (pat) { 20495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next = pat->next; 20505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->next = NULL; 20515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = NULL; 20525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->template = cur; 20545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mode != NULL) 20555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->mode = xmlDictLookup(style->dict, mode, -1); 20565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (modeURI != NULL) 20575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->modeURI = xmlDictLookup(style->dict, modeURI, -1); 20585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (priority != XSLT_PAT_NO_PRIORITY) 20595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->priority = priority; 20605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 20615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 20625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * insert it in the hash table list corresponding to its lookup name 20635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (pat->steps[0].op) { 20655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ATTR: 20665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pat->steps[0].value != NULL) 20675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = pat->steps[0].value; 20685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 20695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->attrMatch); 20705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_PARENT: 20725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ANCESTOR: 20735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->elemMatch); 20745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ROOT: 20765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->rootMatch); 20775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_KEY: 20795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->keyMatch); 20805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ID: 20825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO optimize ID !!! */ 20835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_NS: 20845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ALL: 20855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->elemMatch); 20865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 20875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_END: 20885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_PREDICATE: 20895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, NULL, 20905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltAddTemplate: invalid compiled pattern\n"); 20915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatch(pat); 20925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 20935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 20945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * TODO: some flags at the top level about type based patterns 20955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * would be faster than inclusion in the hash table. 20965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 20975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_PI: 20985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pat->steps[0].value != NULL) 20995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = pat->steps[0].value; 21005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 21015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->piMatch); 21025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_COMMENT: 21045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->commentMatch); 21055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_TEXT: 21075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->textMatch); 21085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_ELEM: 21105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XSLT_OP_NODE: 21115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (pat->steps[0].value != NULL) 21125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = pat->steps[0].value; 21135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 21145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) top = &(style->elemMatch); 21155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name != NULL) { 21185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->templatesHash == NULL) { 21195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) style->templatesHash = xmlHashCreate(1024); 21205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->templatesHash == NULL) { 21215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatch(pat); 21225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 21235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHashAddEntry3(style->templatesHash, name, mode, modeURI, pat); 21255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = (xsltCompMatchPtr) xmlHashLookup3(style->templatesHash, 21275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, mode, modeURI); 21285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list == NULL) { 21295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHashAddEntry3(style->templatesHash, name, 21305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mode, modeURI, pat); 21315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 21335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Note '<=' since one must choose among the matching 21345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * template rules that are left, the one that occurs 21355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * last in the stylesheet 21365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 21375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list->priority <= pat->priority) { 21385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->next = list; 21395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHashUpdateEntry3(style->templatesHash, name, 21405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mode, modeURI, pat, NULL); 21415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (list->next != NULL) { 21435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list->next->priority <= pat->priority) 21445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = list->next; 21465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->next = list->next; 21485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list->next = pat; 21495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (top != NULL) { 21535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = *top; 21545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list == NULL) { 21555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *top = pat; 21565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->next = NULL; 21575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (list->priority <= pat->priority) { 21585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->next = list; 21595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *top = pat; 21605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (list->next != NULL) { 21625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (list->next->priority <= pat->priority) 21635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 21645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = list->next; 21655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->next = list->next; 21675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list->next = pat; 21685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 21705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(NULL, style, NULL, 21715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "xsltAddTemplate: invalid compiled pattern\n"); 21725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatch(pat); 21735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 21745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef WITH_XSLT_DEBUG_PATTERN 21765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (mode) 21775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericDebug(xsltGenericDebugContext, 21785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "added pattern : '%s' mode '%s' priority %f\n", 21795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->pattern, pat->mode, pat->priority); 21805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 21815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltGenericDebug(xsltGenericDebugContext, 21825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "added pattern : '%s' priority %f\n", 21835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat->pattern, pat->priority); 21845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 21855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pat = next; 21875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 21885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(0); 21895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 21905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 21915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static int 21925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltComputeAllKeys(xsltTransformContextPtr ctxt, xmlNodePtr contextNode) 21935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 21945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (contextNode == NULL)) { 21955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(ctxt, NULL, ctxt->inst, 21965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Internal error in xsltComputeAllKeys(): " 21975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Bad arguments.\n"); 21985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 21995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->document == NULL) { 22025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 22035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * The document info will only be NULL if we have a RTF. 22045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (contextNode->doc->_private != NULL) 22065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto doc_info_mismatch; 22075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 22085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * On-demand creation of the document info (needed for keys). 22095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->document = xsltNewDocument(ctxt, contextNode->doc); 22115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ctxt->document == NULL) 22125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 22135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return xsltInitAllDocKeys(ctxt); 22155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)doc_info_mismatch: 22175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTransformError(ctxt, NULL, ctxt->inst, 22185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Internal error in xsltComputeAllKeys(): " 22195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "The context's document info doesn't match the " 22205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "document info of the current result tree.\n"); 22215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->state = XSLT_STATE_STOPPED; 22225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(-1); 22235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 22245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 22265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltGetTemplate: 22275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @ctxt: a XSLT process context 22285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @node: the node being processed 22295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: the current style 22305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 22315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Finds the template applying to this node, if @style is non-NULL 22325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * it means one needs to look for the next imported template in scope. 22335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 22345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Returns the xsltTemplatePtr or NULL if not found 22355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltTemplatePtr 22375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltGetTemplate(xsltTransformContextPtr ctxt, xmlNodePtr node, 22385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStylesheetPtr style) 22395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles){ 22405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltStylesheetPtr curstyle; 22415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltTemplatePtr ret = NULL; 22425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const xmlChar *name = NULL; 22435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltCompMatchPtr list = NULL; 22445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float priority; 22455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int keyed = 0; 22465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((ctxt == NULL) || (node == NULL)) 22485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 22495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style == NULL) { 22515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curstyle = ctxt->style; 22525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 22535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curstyle = xsltNextImport(style); 22545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((curstyle != NULL) && (curstyle != style)) { 22575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority = XSLT_PAT_NO_PRIORITY; 22585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* TODO : handle IDs/keys here ! */ 22595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (curstyle->templatesHash != NULL) { 22605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 22615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Use the top name as selector 22625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (node->type) { 22645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ELEMENT_NODE: 22655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->name[0] == ' ') 22665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ATTRIBUTE_NODE: 22685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_PI_NODE: 22695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name = node->name; 22705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DOCUMENT_NODE: 22725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_HTML_DOCUMENT_NODE: 22735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_TEXT_NODE: 22745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_CDATA_SECTION_NODE: 22755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_COMMENT_NODE: 22765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ENTITY_REF_NODE: 22775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ENTITY_NODE: 22785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DOCUMENT_TYPE_NODE: 22795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DOCUMENT_FRAG_NODE: 22805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_NOTATION_NODE: 22815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DTD_NODE: 22825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ELEMENT_DECL: 22835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ATTRIBUTE_DECL: 22845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ENTITY_DECL: 22855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_NAMESPACE_DECL: 22865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_XINCLUDE_START: 22875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_XINCLUDE_END: 22885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 22895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 22905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 22915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 22945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (name != NULL) { 22955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 22965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * find the list of applicable expressions based on the name 22975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 22985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = (xsltCompMatchPtr) xmlHashLookup3(curstyle->templatesHash, 22995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) name, ctxt->mode, ctxt->modeURI); 23005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else 23015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = NULL; 23025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (list != NULL) { 23035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltTestCompMatch(ctxt, list, node, 23045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->mode, ctxt->modeURI)) { 23055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = list->template; 23065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority = list->priority; 23075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = list->next; 23105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = NULL; 23125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 23145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * find alternate generic matches 23155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 23165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (node->type) { 23175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ELEMENT_NODE: 23185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->name[0] == ' ') 23195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->rootMatch; 23205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else 23215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->elemMatch; 23225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->psvi != NULL) keyed = 1; 23235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ATTRIBUTE_NODE: { 23255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlAttrPtr attr; 23265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->attrMatch; 23285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) attr = (xmlAttrPtr) node; 23295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (attr->psvi != NULL) keyed = 1; 23305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_PI_NODE: 23335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->piMatch; 23345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->psvi != NULL) keyed = 1; 23355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DOCUMENT_NODE: 23375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_HTML_DOCUMENT_NODE: { 23385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlDocPtr doc; 23395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 23405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->rootMatch; 23415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) doc = (xmlDocPtr) node; 23425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (doc->psvi != NULL) keyed = 1; 23435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_TEXT_NODE: 23465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_CDATA_SECTION_NODE: 23475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->textMatch; 23485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->psvi != NULL) keyed = 1; 23495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_COMMENT_NODE: 23515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->commentMatch; 23525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->psvi != NULL) keyed = 1; 23535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ENTITY_REF_NODE: 23555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ENTITY_NODE: 23565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DOCUMENT_TYPE_NODE: 23575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DOCUMENT_FRAG_NODE: 23585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_NOTATION_NODE: 23595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DTD_NODE: 23605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ELEMENT_DECL: 23615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ATTRIBUTE_DECL: 23625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ENTITY_DECL: 23635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_NAMESPACE_DECL: 23645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_XINCLUDE_START: 23655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_XINCLUDE_END: 23665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 23685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((list != NULL) && 23715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((ret == NULL) || (list->priority > priority))) { 23725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltTestCompMatch(ctxt, list, node, 23735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->mode, ctxt->modeURI)) { 23745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = list->template; 23755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority = list->priority; 23765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = list->next; 23795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 23815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Some of the tests for elements can also apply to documents 23825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 23835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if ((node->type == XML_DOCUMENT_NODE) || 23845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_HTML_DOCUMENT_NODE) || 23855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_TEXT_NODE)) { 23865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->elemMatch; 23875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((list != NULL) && 23885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((ret == NULL) || (list->priority > priority))) { 23895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltTestCompMatch(ctxt, list, node, 23905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->mode, ctxt->modeURI)) { 23915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = list->template; 23925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority = list->priority; 23935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 23945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = list->next; 23965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 23975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if ((node->type == XML_PI_NODE) || 23985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (node->type == XML_COMMENT_NODE)) { 23995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->elemMatch; 24005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((list != NULL) && 24015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((ret == NULL) || (list->priority > priority))) { 24025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltTestCompMatch(ctxt, list, node, 24035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->mode, ctxt->modeURI)) { 24045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = list->template; 24055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority = list->priority; 24065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = list->next; 24095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)keyed_match: 24135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keyed) { 24145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = curstyle->keyMatch; 24155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while ((list != NULL) && 24165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((ret == NULL) || (list->priority > priority))) { 24175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltTestCompMatch(ctxt, list, node, 24185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ctxt->mode, ctxt->modeURI)) { 24195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ret = list->template; 24205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority = list->priority; 24215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list = list->next; 24245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) else if (ctxt->hasTemplKeyPatterns && 24275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ((ctxt->document == NULL) || 24285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (ctxt->document->nbKeysComputed < ctxt->nbKeys))) 24295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 24305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 24315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Compute all remaining keys for this document. 24325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 24335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * REVISIT TODO: I think this could be further optimized. 24345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 24355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (xsltComputeAllKeys(ctxt, node) == -1) 24365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto error; 24375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (node->type) { 24395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ELEMENT_NODE: 24405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->psvi != NULL) keyed = 1; 24415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_ATTRIBUTE_NODE: 24435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((xmlAttrPtr) node)->psvi != NULL) keyed = 1; 24445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_TEXT_NODE: 24465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_CDATA_SECTION_NODE: 24475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_COMMENT_NODE: 24485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_PI_NODE: 24495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (node->psvi != NULL) keyed = 1; 24505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_DOCUMENT_NODE: 24525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case XML_HTML_DOCUMENT_NODE: 24535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (((xmlDocPtr) node)->psvi != NULL) keyed = 1; 24545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 24565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 24575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (keyed) 24595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) goto keyed_match; 24605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ret != NULL) 24625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(ret); 24635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) /* 24655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Cycle on next curstylesheet import. 24665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 24675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) curstyle = xsltNextImport(curstyle); 24685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 24695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)error: 24715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return(NULL); 24725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 24755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltCleanupTemplates: 24765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: an XSLT stylesheet 24775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 24785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Cleanup the state of the templates used by the stylesheet and 24795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * the ones it imports. 24805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 24815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 24825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltCleanupTemplates(xsltStylesheetPtr style ATTRIBUTE_UNUSED) { 24835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 24845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/** 24865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * xsltFreeTemplateHashes: 24875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * @style: an XSLT stylesheet 24885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * 24895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) * Free up the memory used by xsltAddTemplate/xsltGetTemplate mechanism 24905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) */ 24915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void 24925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)xsltFreeTemplateHashes(xsltStylesheetPtr style) { 24935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->templatesHash != NULL) 24945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xmlHashFree((xmlHashTablePtr) style->templatesHash, 24955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (xmlHashDeallocator) xsltFreeCompMatchList); 24965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->rootMatch != NULL) 24975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(style->rootMatch); 24985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->keyMatch != NULL) 24995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(style->keyMatch); 25005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->elemMatch != NULL) 25015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(style->elemMatch); 25025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->attrMatch != NULL) 25035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(style->attrMatch); 25045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->parentMatch != NULL) 25055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(style->parentMatch); 25065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->textMatch != NULL) 25075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(style->textMatch); 25085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->piMatch != NULL) 25095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(style->piMatch); 25105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (style->commentMatch != NULL) 25115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) xsltFreeCompMatchList(style->commentMatch); 25125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 25135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2514