ReactOS 0.4.16-dev-197-g92996da
pattern.c File Reference
#include "precomp.h"
Include dependency graph for pattern.c:

Go to the source code of this file.

Classes

struct  _xsltStepState
 
struct  _xsltStepStates
 
struct  _xsltStepOp
 
struct  _xsltCompMatch
 
struct  _xsltParserContext
 

Typedefs

typedef struct _xsltStepState xsltStepState
 
typedef xsltStepStatexsltStepStatePtr
 
typedef struct _xsltStepStates xsltStepStates
 
typedef xsltStepStatesxsltStepStatesPtr
 
typedef struct _xsltStepOp xsltStepOp
 
typedef xsltStepOpxsltStepOpPtr
 
typedef struct _xsltParserContext xsltParserContext
 
typedef xsltParserContextxsltParserContextPtr
 

Enumerations

enum  xsltOp {
  XSLT_OP_END =0 , XSLT_OP_ROOT , XSLT_OP_ELEM , XSLT_OP_ATTR ,
  XSLT_OP_PARENT , XSLT_OP_ANCESTOR , XSLT_OP_ID , XSLT_OP_KEY ,
  XSLT_OP_NS , XSLT_OP_ALL , XSLT_OP_PI , XSLT_OP_COMMENT ,
  XSLT_OP_TEXT , XSLT_OP_NODE , XSLT_OP_PREDICATE
}
 
enum  xsltAxis { AXIS_CHILD =1 , AXIS_ATTRIBUTE }
 

Functions

static xsltCompMatchPtr xsltNewCompMatch (void)
 
static void xsltFreeCompMatch (xsltCompMatchPtr comp)
 
void xsltFreeCompMatchList (xsltCompMatchPtr comp)
 
static void xsltFreeCompMatchListEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
 

: template match name

xsltNormalizeCompSteps: @payload: pointer to template hash table entry @data: pointer to the stylesheet

This is a hashtable scanner function to normalize the compiled steps of an imported stylesheet.

#define CUR   (*ctxt->cur)
 
#define SKIP(val)   ctxt->cur += (val)
 
#define NXT(val)   ctxt->cur[(val)]
 
#define CUR_PTR   ctxt->cur
 
#define SKIP_BLANKS    while (xmlIsBlank_ch(CUR)) NEXT
 
#define CURRENT   (*ctxt->cur)
 
#define NEXT   ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)
 
#define PUSH(op, val, val2, novar)    if (xsltCompMatchAdd(ctxt, ctxt->comp, (op), (val), (val2), (novar))) goto error;
 
#define SWAP()    xsltSwapTopCompMatch(ctxt->comp);
 
#define XSLT_ERROR(X)
 
#define XSLT_ERROR0(X)
 
void xsltNormalizeCompSteps (void *payload, void *data, const xmlChar *name ATTRIBUTE_UNUSED)
 
static xsltParserContextPtr xsltNewParserContext (xsltStylesheetPtr style, xsltTransformContextPtr ctxt)
 
static void xsltFreeParserContext (xsltParserContextPtr ctxt)
 
static int xsltCompMatchAdd (xsltParserContextPtr ctxt, xsltCompMatchPtr comp, xsltOp op, xmlChar *value, xmlChar *value2, int novar)
 
static void xsltSwapTopCompMatch (xsltCompMatchPtr comp)
 
static void xsltReverseCompMatch (xsltParserContextPtr ctxt, xsltCompMatchPtr comp)
 
static int xsltPatPushState (xsltTransformContextPtr ctxt, xsltStepStates *states, int step, xmlNodePtr node)
 
static void xmlXPathFreeObjectWrapper (void *obj)
 
static int xsltTestCompMatchDirect (xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, xmlNodePtr node, xmlNsPtr *nsList, int nsNr)
 
static int xsltTestStepMatch (xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStepOpPtr step)
 
static int xsltTestPredicateMatch (xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, xmlNodePtr node, xsltStepOpPtr step, xsltStepOpPtr sel)
 
static int xsltTestCompMatch (xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, xmlNodePtr matchNode, const xmlChar *mode, const xmlChar *modeURI)
 
int xsltTestCompMatchList (xsltTransformContextPtr ctxt, xmlNodePtr node, xsltCompMatchPtr comp)
 
void xsltCompMatchClearCache (xsltTransformContextPtr ctxt, xsltCompMatchPtr comp)
 
static xmlCharxsltScanLiteral (xsltParserContextPtr ctxt)
 
static xmlCharxsltScanNCName (xsltParserContextPtr ctxt)
 
static void xsltCompileIdKeyPattern (xsltParserContextPtr ctxt, xmlChar *name, int aid, int novar, xsltAxis axis)
 
static void xsltCompileStepPattern (xsltParserContextPtr ctxt, xmlChar *token, int novar)
 
static void xsltCompileRelativePathPattern (xsltParserContextPtr ctxt, xmlChar *token, int novar)
 
static void xsltCompileLocationPathPattern (xsltParserContextPtr ctxt, int novar)
 
static xsltCompMatchPtr xsltCompilePatternInternal (const xmlChar *pattern, xmlDocPtr doc, xmlNodePtr node, xsltStylesheetPtr style, xsltTransformContextPtr runtime, int novar)
 
xsltCompMatchPtr xsltCompilePattern (const xmlChar *pattern, xmlDocPtr doc, xmlNodePtr node, xsltStylesheetPtr style, xsltTransformContextPtr runtime)
 
int xsltAddTemplate (xsltStylesheetPtr style, xsltTemplatePtr cur, const xmlChar *mode, const xmlChar *modeURI)
 
static int xsltComputeAllKeys (xsltTransformContextPtr ctxt, xmlNodePtr contextNode)
 
xsltTemplatePtr xsltGetTemplate (xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStylesheetPtr style)
 
void xsltCleanupTemplates (xsltStylesheetPtr style ATTRIBUTE_UNUSED)
 
void xsltFreeTemplateHashes (xsltStylesheetPtr style)
 

Macro Definition Documentation

◆ CUR

#define CUR   (*ctxt->cur)

Definition at line 1170 of file pattern.c.

◆ CUR_PTR

#define CUR_PTR   ctxt->cur

Definition at line 1173 of file pattern.c.

◆ CURRENT

#define CURRENT   (*ctxt->cur)

Definition at line 1178 of file pattern.c.

◆ NEXT

#define NEXT   ((*ctxt->cur) ? ctxt->cur++: ctxt->cur)

Definition at line 1179 of file pattern.c.

◆ NXT

#define NXT (   val)    ctxt->cur[(val)]

Definition at line 1172 of file pattern.c.

◆ PUSH

#define PUSH (   op,
  val,
  val2,
  novar 
)     if (xsltCompMatchAdd(ctxt, ctxt->comp, (op), (val), (val2), (novar))) goto error;

Definition at line 1182 of file pattern.c.

◆ SKIP

#define SKIP (   val)    ctxt->cur += (val)

Definition at line 1171 of file pattern.c.

◆ SKIP_BLANKS

#define SKIP_BLANKS    while (xmlIsBlank_ch(CUR)) NEXT

Definition at line 1175 of file pattern.c.

◆ SWAP

#define SWAP ( )     xsltSwapTopCompMatch(ctxt->comp);

Definition at line 1185 of file pattern.c.

◆ XSLT_ERROR

#define XSLT_ERROR (   X)
Value:
{ xsltError(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return; }
#define X(b, s)

Definition at line 1188 of file pattern.c.

◆ XSLT_ERROR0

#define XSLT_ERROR0 (   X)
Value:
{ xsltError(ctxt, __FILE__, __LINE__, X); \
ctxt->error = (X); return(0); }

Definition at line 1192 of file pattern.c.

Typedef Documentation

◆ xsltParserContext

Definition at line 99 of file pattern.c.

◆ xsltParserContextPtr

Definition at line 100 of file pattern.c.

◆ xsltStepOp

Definition at line 65 of file pattern.c.

◆ xsltStepOpPtr

Definition at line 66 of file pattern.c.

◆ xsltStepState

Definition at line 50 of file pattern.c.

◆ xsltStepStatePtr

Definition at line 51 of file pattern.c.

◆ xsltStepStates

Definition at line 57 of file pattern.c.

◆ xsltStepStatesPtr

Definition at line 58 of file pattern.c.

Enumeration Type Documentation

◆ xsltAxis

Enumerator
AXIS_CHILD 
AXIS_ATTRIBUTE 

Definition at line 45 of file pattern.c.

45 {
46 AXIS_CHILD=1,
48} xsltAxis;
xsltAxis
Definition: pattern.c:45
@ AXIS_CHILD
Definition: pattern.c:46
@ AXIS_ATTRIBUTE
Definition: pattern.c:47

◆ xsltOp

Enumerator
XSLT_OP_END 
XSLT_OP_ROOT 
XSLT_OP_ELEM 
XSLT_OP_ATTR 
XSLT_OP_PARENT 
XSLT_OP_ANCESTOR 
XSLT_OP_ID 
XSLT_OP_KEY 
XSLT_OP_NS 
XSLT_OP_ALL 
XSLT_OP_PI 
XSLT_OP_COMMENT 
XSLT_OP_TEXT 
XSLT_OP_NODE 
XSLT_OP_PREDICATE 

Definition at line 27 of file pattern.c.

27 {
43} xsltOp;
xsltOp
Definition: pattern.c:27
@ XSLT_OP_PREDICATE
Definition: pattern.c:42
@ XSLT_OP_PARENT
Definition: pattern.c:32
@ XSLT_OP_TEXT
Definition: pattern.c:40
@ XSLT_OP_END
Definition: pattern.c:28
@ XSLT_OP_ID
Definition: pattern.c:34
@ XSLT_OP_ALL
Definition: pattern.c:37
@ XSLT_OP_ELEM
Definition: pattern.c:30
@ XSLT_OP_NODE
Definition: pattern.c:41
@ XSLT_OP_ATTR
Definition: pattern.c:31
@ XSLT_OP_PI
Definition: pattern.c:38
@ XSLT_OP_COMMENT
Definition: pattern.c:39
@ XSLT_OP_KEY
Definition: pattern.c:35
@ XSLT_OP_ANCESTOR
Definition: pattern.c:33
@ XSLT_OP_ROOT
Definition: pattern.c:29
@ XSLT_OP_NS
Definition: pattern.c:36

Function Documentation

◆ xmlXPathFreeObjectWrapper()

static void xmlXPathFreeObjectWrapper ( void obj)
static

Definition at line 495 of file pattern.c.

495 {
496 xmlXPathFreeObject((xmlXPathObjectPtr) obj);
497}

Referenced by xsltTestCompMatchDirect().

◆ xsltAddTemplate()

int xsltAddTemplate ( xsltStylesheetPtr  style,
xsltTemplatePtr  cur,
const xmlChar mode,
const xmlChar modeURI 
)

xsltAddTemplate: @style: an XSLT stylesheet @cur: an XSLT template @mode: the mode name or NULL @modeURI: the mode URI or NULL

Register the XSLT pattern associated to @cur

Returns -1 in case of error, 0 otherwise

Definition at line 2016 of file pattern.c.

2017 {
2019 /*
2020 * 'top' will point to style->xxxMatch ptr - declaring as 'void'
2021 * avoids gcc 'type-punned pointer' warning.
2022 */
2024 const xmlChar *name = NULL;
2025 float priority; /* the priority */
2026
2027 if ((style == NULL) || (cur == NULL))
2028 return(-1);
2029
2030 if (cur->next != NULL)
2031 cur->position = cur->next->position + 1;
2032
2033 /* Register named template */
2034 if (cur->name != NULL) {
2035 if (style->namedTemplates == NULL) {
2036 style->namedTemplates = xmlHashCreate(10);
2037 if (style->namedTemplates == NULL)
2038 return(-1);
2039 }
2040 else {
2041 void *dup = xmlHashLookup2(style->namedTemplates, cur->name,
2042 cur->nameURI);
2043 if (dup != NULL) {
2045 "xsl:template: error duplicate name '%s'\n",
2046 cur->name);
2047 style->errors++;
2048 return(-1);
2049 }
2050 }
2051
2052 xmlHashAddEntry2(style->namedTemplates, cur->name, cur->nameURI, cur);
2053 }
2054
2055 if (cur->match == NULL) {
2056 if (cur->name == NULL) {
2058 "xsl:template: need to specify match or name attribute\n");
2059 style->errors++;
2060 return(-1);
2061 }
2062 return(0);
2063 }
2064
2065 priority = cur->priority;
2066 pat = xsltCompilePatternInternal(cur->match, style->doc, cur->elem,
2067 style, NULL, 1);
2068 if (pat == NULL)
2069 return(-1);
2070 while (pat) {
2071 next = pat->next;
2072 pat->next = NULL;
2073 name = NULL;
2074
2075 pat->template = cur;
2076 if (mode != NULL)
2077 pat->mode = xmlDictLookup(style->dict, mode, -1);
2078 if (modeURI != NULL)
2079 pat->modeURI = xmlDictLookup(style->dict, modeURI, -1);
2081 pat->priority = priority;
2082
2083 /*
2084 * insert it in the hash table list corresponding to its lookup name
2085 */
2086 switch (pat->steps[0].op) {
2087 case XSLT_OP_ATTR:
2088 if (pat->steps[0].value != NULL)
2089 name = pat->steps[0].value;
2090 else
2091 top = &(style->attrMatch);
2092 break;
2093 case XSLT_OP_PARENT:
2094 case XSLT_OP_ANCESTOR:
2095 top = &(style->elemMatch);
2096 break;
2097 case XSLT_OP_ROOT:
2098 top = &(style->rootMatch);
2099 break;
2100 case XSLT_OP_KEY:
2101 top = &(style->keyMatch);
2102 break;
2103 case XSLT_OP_ID:
2104 /* TODO optimize ID !!! */
2105 case XSLT_OP_NS:
2106 case XSLT_OP_ALL:
2107 top = &(style->elemMatch);
2108 break;
2109 case XSLT_OP_END:
2110 case XSLT_OP_PREDICATE:
2112 "xsltAddTemplate: invalid compiled pattern\n");
2113 xsltFreeCompMatch(pat);
2114 return(-1);
2115 /*
2116 * TODO: some flags at the top level about type based patterns
2117 * would be faster than inclusion in the hash table.
2118 */
2119 case XSLT_OP_PI:
2120 if (pat->steps[0].value != NULL)
2121 name = pat->steps[0].value;
2122 else
2123 top = &(style->piMatch);
2124 break;
2125 case XSLT_OP_COMMENT:
2126 top = &(style->commentMatch);
2127 break;
2128 case XSLT_OP_TEXT:
2129 top = &(style->textMatch);
2130 break;
2131 case XSLT_OP_ELEM:
2132 case XSLT_OP_NODE:
2133 if (pat->steps[0].value != NULL)
2134 name = pat->steps[0].value;
2135 else
2136 top = &(style->elemMatch);
2137 break;
2138 }
2139 if (name != NULL) {
2140 if (style->templatesHash == NULL) {
2141 style->templatesHash = xmlHashCreate(1024);
2142 if (style->templatesHash == NULL) {
2143 xsltFreeCompMatch(pat);
2144 return(-1);
2145 }
2146 xmlHashAddEntry3(style->templatesHash, name, mode, modeURI, pat);
2147 } else {
2148 list = (xsltCompMatchPtr) xmlHashLookup3(style->templatesHash,
2149 name, mode, modeURI);
2150 if (list == NULL) {
2151 xmlHashAddEntry3(style->templatesHash, name,
2152 mode, modeURI, pat);
2153 } else {
2154 /*
2155 * Note '<=' since one must choose among the matching
2156 * template rules that are left, the one that occurs
2157 * last in the stylesheet
2158 */
2159 if (list->priority <= pat->priority) {
2160 pat->next = list;
2161 xmlHashUpdateEntry3(style->templatesHash, name,
2162 mode, modeURI, pat, NULL);
2163 } else {
2164 while (list->next != NULL) {
2165 if (list->next->priority <= pat->priority)
2166 break;
2167 list = list->next;
2168 }
2169 pat->next = list->next;
2170 list->next = pat;
2171 }
2172 }
2173 }
2174 } else if (top != NULL) {
2175 list = *top;
2176 if (list == NULL) {
2177 *top = pat;
2178 pat->next = NULL;
2179 } else if (list->priority <= pat->priority) {
2180 pat->next = list;
2181 *top = pat;
2182 } else {
2183 while (list->next != NULL) {
2184 if (list->next->priority <= pat->priority)
2185 break;
2186 list = list->next;
2187 }
2188 pat->next = list->next;
2189 list->next = pat;
2190 }
2191 } else {
2193 "xsltAddTemplate: invalid compiled pattern\n");
2194 xsltFreeCompMatch(pat);
2195 return(-1);
2196 }
2197#ifdef WITH_XSLT_DEBUG_PATTERN
2198 if (mode)
2200 "added pattern : '%s' mode '%s' priority %f\n",
2201 pat->pattern, pat->mode, pat->priority);
2202 else
2204 "added pattern : '%s' priority %f\n",
2205 pat->pattern, pat->priority);
2206#endif
2207
2208 pat = next;
2209 }
2210 return(0);
2211}
Arabic default style
Definition: afstyles.h:94
Definition: list.h:37
struct list * next
Definition: list.h:38
#define NULL
Definition: types.h:112
static xsltCompMatchPtr xsltCompilePatternInternal(const xmlChar *pattern, xmlDocPtr doc, xmlNodePtr node, xsltStylesheetPtr style, xsltTransformContextPtr runtime, int novar)
Definition: pattern.c:1816
static void xsltFreeCompMatch(xsltCompMatchPtr comp)
Definition: pattern.c:159
FxCollectionEntry * cur
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLenum mode
Definition: glext.h:6217
#define dup
Definition: syshdrs.h:51
xsltCompMatch * xsltCompMatchPtr
Definition: pattern.h:29
static int priority
Definition: timer.c:163
static unsigned __int64 next
Definition: rand_nt.c:6
#define list
Definition: rosglue.h:35
XMLPUBFUN const xmlChar *XMLCALL xmlDictLookup(xmlDictPtr dict, const xmlChar *name, int len)
Definition: dict.c:867
XMLPUBFUN int XMLCALL xmlHashAddEntry2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, void *userdata)
Definition: hash.c:406
XMLPUBFUN void *XMLCALL xmlHashLookup3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3)
Definition: hash.c:769
XMLPUBFUN int XMLCALL xmlHashUpdateEntry3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3, void *userdata, xmlHashDeallocator f)
Definition: hash.c:647
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreate(int size)
Definition: hash.c:176
XMLPUBFUN void *XMLCALL xmlHashLookup2(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2)
Definition: hash.c:476
XMLPUBFUN int XMLCALL xmlHashAddEntry3(xmlHashTablePtr table, const xmlChar *name, const xmlChar *name2, const xmlChar *name3, void *userdata)
Definition: hash.c:531
const xmlChar * pattern
Definition: pattern.c:84
struct _xsltCompMatch * next
Definition: pattern.c:82
xsltTemplatePtr template
Definition: pattern.c:87
xsltStepOpPtr steps
Definition: pattern.c:96
const xmlChar * mode
Definition: pattern.c:85
float priority
Definition: pattern.c:83
const xmlChar * modeURI
Definition: pattern.c:86
xmlChar * value
Definition: pattern.c:69
xsltOp op
Definition: pattern.c:68
Definition: name.c:39
unsigned char xmlChar
Definition: xmlstring.h:28
#define XSLT_PAT_NO_PRIORITY
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
void * xsltGenericDebugContext
Definition: xsltutils.c:549

Referenced by xsltParseStylesheetProcess(), and xsltParseStylesheetTemplate().

◆ xsltCleanupTemplates()

void xsltCleanupTemplates ( xsltStylesheetPtr style  ATTRIBUTE_UNUSED)

xsltCleanupTemplates: @style: an XSLT stylesheet

Cleanup the state of the templates used by the stylesheet and the ones it imports.

Definition at line 2517 of file pattern.c.

2517 {
2518}

Referenced by xsltApplyStylesheetInternal().

◆ xsltCompileIdKeyPattern()

static void xsltCompileIdKeyPattern ( xsltParserContextPtr  ctxt,
xmlChar name,
int  aid,
int  novar,
xsltAxis  axis 
)
static

Definition at line 1308 of file pattern.c.

1309 {
1310 xmlChar *lit = NULL;
1311 xmlChar *lit2 = NULL;
1312
1313 if (CUR != '(') {
1315 "xsltCompileIdKeyPattern : ( expected\n");
1316 ctxt->error = 1;
1317 return;
1318 }
1319 if ((aid) && (xmlStrEqual(name, (const xmlChar *)"id"))) {
1320 if (axis != 0) {
1322 "xsltCompileIdKeyPattern : NodeTest expected\n");
1323 ctxt->error = 1;
1324 return;
1325 }
1326 NEXT;
1328 lit = xsltScanLiteral(ctxt);
1329 if (ctxt->error) {
1331 "xsltCompileIdKeyPattern : Literal expected\n");
1332 xmlFree(lit);
1333 return;
1334 }
1336 if (CUR != ')') {
1338 "xsltCompileIdKeyPattern : ) expected\n");
1339 xmlFree(lit);
1340 ctxt->error = 1;
1341 return;
1342 }
1343 NEXT;
1344 PUSH(XSLT_OP_ID, lit, NULL, novar);
1345 lit = NULL;
1346 } else if ((aid) && (xmlStrEqual(name, (const xmlChar *)"key"))) {
1347 if (axis != 0) {
1349 "xsltCompileIdKeyPattern : NodeTest expected\n");
1350 ctxt->error = 1;
1351 return;
1352 }
1353 NEXT;
1355 lit = xsltScanLiteral(ctxt);
1356 if (ctxt->error) {
1358 "xsltCompileIdKeyPattern : Literal expected\n");
1359 xmlFree(lit);
1360 return;
1361 }
1363 if (CUR != ',') {
1365 "xsltCompileIdKeyPattern : , expected\n");
1366 xmlFree(lit);
1367 ctxt->error = 1;
1368 return;
1369 }
1370 NEXT;
1372 lit2 = xsltScanLiteral(ctxt);
1373 if (ctxt->error) {
1375 "xsltCompileIdKeyPattern : Literal expected\n");
1376 xmlFree(lit);
1377 return;
1378 }
1380 if (CUR != ')') {
1382 "xsltCompileIdKeyPattern : ) expected\n");
1383 xmlFree(lit);
1384 xmlFree(lit2);
1385 ctxt->error = 1;
1386 return;
1387 }
1388 NEXT;
1389 /* URGENT TODO: support namespace in keys */
1390 PUSH(XSLT_OP_KEY, lit, lit2, novar);
1391 lit = NULL;
1392 lit2 = NULL;
1393 } else if (xmlStrEqual(name, (const xmlChar *)"processing-instruction")) {
1394 NEXT;
1396 if (CUR != ')') {
1397 lit = xsltScanLiteral(ctxt);
1398 if (ctxt->error) {
1400 "xsltCompileIdKeyPattern : Literal expected\n");
1401 xmlFree(lit);
1402 return;
1403 }
1405 if (CUR != ')') {
1407 "xsltCompileIdKeyPattern : ) expected\n");
1408 ctxt->error = 1;
1409 xmlFree(lit);
1410 return;
1411 }
1412 }
1413 NEXT;
1414 PUSH(XSLT_OP_PI, lit, NULL, novar);
1415 lit = NULL;
1416 } else if (xmlStrEqual(name, (const xmlChar *)"text")) {
1417 NEXT;
1419 if (CUR != ')') {
1421 "xsltCompileIdKeyPattern : ) expected\n");
1422 ctxt->error = 1;
1423 return;
1424 }
1425 NEXT;
1426 PUSH(XSLT_OP_TEXT, NULL, NULL, novar);
1427 } else if (xmlStrEqual(name, (const xmlChar *)"comment")) {
1428 NEXT;
1430 if (CUR != ')') {
1432 "xsltCompileIdKeyPattern : ) expected\n");
1433 ctxt->error = 1;
1434 return;
1435 }
1436 NEXT;
1437 PUSH(XSLT_OP_COMMENT, NULL, NULL, novar);
1438 } else if (xmlStrEqual(name, (const xmlChar *)"node")) {
1439 NEXT;
1441 if (CUR != ')') {
1443 "xsltCompileIdKeyPattern : ) expected\n");
1444 ctxt->error = 1;
1445 return;
1446 }
1447 NEXT;
1448 if (axis == AXIS_ATTRIBUTE) {
1449 PUSH(XSLT_OP_ATTR, NULL, NULL, novar);
1450 }
1451 else {
1452 PUSH(XSLT_OP_NODE, NULL, NULL, novar);
1453 }
1454 } else if (aid) {
1456 "xsltCompileIdKeyPattern : expecting 'key' or 'id' or node type\n");
1457 ctxt->error = 1;
1458 return;
1459 } else {
1461 "xsltCompileIdKeyPattern : node type\n");
1462 ctxt->error = 1;
1463 return;
1464 }
1465error:
1466 return;
1467}
static xmlChar * xsltScanLiteral(xsltParserContextPtr ctxt)
Definition: pattern.c:1209
#define NEXT
Definition: pattern.c:1179
#define SKIP_BLANKS
Definition: pattern.c:1175
#define PUSH(op, val, val2, novar)
Definition: pattern.c:1182
#define CUR
Definition: pattern.c:1170
#define error(str)
Definition: mkdosfs.c:1605
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:160

Referenced by xsltCompileLocationPathPattern(), and xsltCompileStepPattern().

◆ xsltCompileLocationPathPattern()

static void xsltCompileLocationPathPattern ( xsltParserContextPtr  ctxt,
int  novar 
)
static

xsltCompileLocationPathPattern: @ctxt: the compilation context @novar: flag to prohibit xslt variables

Compile the XSLT LocationPathPattern and generates a precompiled form suitable for fast matching.

[2] LocationPathPattern ::= '/' RelativePathPattern? | IdKeyPattern (('/' | '//') RelativePathPattern)? | '//'? RelativePathPattern

Definition at line 1736 of file pattern.c.

1736 {
1738 if ((CUR == '/') && (NXT(1) == '/')) {
1739 /*
1740 * since we reverse the query
1741 * a leading // can be safely ignored
1742 */
1743 NEXT;
1744 NEXT;
1745 ctxt->comp->priority = 0.5; /* '//' means not 0 priority */
1747 } else if (CUR == '/') {
1748 /*
1749 * We need to find root as the parent
1750 */
1751 NEXT;
1753 PUSH(XSLT_OP_ROOT, NULL, NULL, novar);
1754 if ((CUR != 0) && (CUR != '|')) {
1755 PUSH(XSLT_OP_PARENT, NULL, NULL, novar);
1757 }
1758 } else if (CUR == '*') {
1760 } else if (CUR == '@') {
1762 } else {
1763 xmlChar *name;
1764 name = xsltScanNCName(ctxt);
1765 if (name == NULL) {
1767 "xsltCompileLocationPathPattern : Name expected\n");
1768 ctxt->error = 1;
1769 return;
1770 }
1772 if ((CUR == '(') && !xmlXPathIsNodeType(name)) {
1773 xsltCompileIdKeyPattern(ctxt, name, 1, novar, 0);
1774 xmlFree(name);
1775 name = NULL;
1776 if (ctxt->error)
1777 return;
1778 if ((CUR == '/') && (NXT(1) == '/')) {
1779 PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar);
1780 NEXT;
1781 NEXT;
1784 } else if (CUR == '/') {
1785 PUSH(XSLT_OP_PARENT, NULL, NULL, novar);
1786 NEXT;
1789 }
1790 return;
1791 }
1793 }
1794error:
1795 return;
1796}
static void xsltCompileRelativePathPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar)
Definition: pattern.c:1695
static void xsltCompileIdKeyPattern(xsltParserContextPtr ctxt, xmlChar *name, int aid, int novar, xsltAxis axis)
Definition: pattern.c:1308
static xmlChar * xsltScanNCName(xsltParserContextPtr ctxt)
Definition: pattern.c:1264
#define NXT(val)
Definition: pattern.c:1172
xsltCompMatchPtr comp
Definition: pattern.c:109

Referenced by xsltCompilePatternInternal().

◆ xsltCompilePattern()

xsltCompMatchPtr xsltCompilePattern ( const xmlChar pattern,
xmlDocPtr  doc,
xmlNodePtr  node,
xsltStylesheetPtr  style,
xsltTransformContextPtr  runtime 
)

xsltCompilePattern: @pattern: an XSLT pattern @doc: the containing document @node: the containing element @style: the stylesheet @runtime: the transformation context, if done at run-time

Compile the XSLT pattern and generates a list of precompiled form suitable for fast matching.

[1] Pattern ::= LocationPathPattern | Pattern '|' LocationPathPattern

Returns the generated pattern list or NULL in case of failure

Definition at line 1992 of file pattern.c.

1994 {
1995 return (xsltCompilePatternInternal(pattern, doc, node, style, runtime, 0));
1996}
GLubyte * pattern
Definition: glext.h:7787
Definition: dlist.c:348

Referenced by xsltNumberComp().

◆ xsltCompilePatternInternal()

static xsltCompMatchPtr xsltCompilePatternInternal ( const xmlChar pattern,
xmlDocPtr  doc,
xmlNodePtr  node,
xsltStylesheetPtr  style,
xsltTransformContextPtr  runtime,
int  novar 
)
static

xsltCompilePatternInternal: @pattern: an XSLT pattern @doc: the containing document @node: the containing element @style: the stylesheet @runtime: the transformation context, if done at run-time @novar: flag to prohibit xslt variables

Compile the XSLT pattern and generates a list of precompiled form suitable for fast matching.

[1] Pattern ::= LocationPathPattern | Pattern '|' LocationPathPattern

Returns the generated pattern list or NULL in case of failure

Definition at line 1816 of file pattern.c.

1818 {
1820 xsltCompMatchPtr element, first = NULL, previous = NULL;
1821 int current, start, end, level, j;
1822
1823 if (pattern == NULL) {
1825 "xsltCompilePattern : NULL pattern\n");
1826 return(NULL);
1827 }
1828
1829 ctxt = xsltNewParserContext(style, runtime);
1830 if (ctxt == NULL)
1831 return(NULL);
1832 ctxt->doc = doc;
1833 ctxt->elem = node;
1834 current = end = 0;
1835 while (pattern[current] != 0) {
1836 start = current;
1837 while (xmlIsBlank_ch(pattern[current]))
1838 current++;
1839 end = current;
1840 level = 0;
1841 while ((pattern[end] != 0) && ((pattern[end] != '|') || (level != 0))) {
1842 if (pattern[end] == '[')
1843 level++;
1844 else if (pattern[end] == ']')
1845 level--;
1846 else if (pattern[end] == '\'') {
1847 end++;
1848 while ((pattern[end] != 0) && (pattern[end] != '\''))
1849 end++;
1850 } else if (pattern[end] == '"') {
1851 end++;
1852 while ((pattern[end] != 0) && (pattern[end] != '"'))
1853 end++;
1854 }
1855 if (pattern[end] == 0)
1856 break;
1857 end++;
1858 }
1859 if (current == end) {
1861 "xsltCompilePattern : NULL pattern\n");
1862 goto error;
1863 }
1865 if (element == NULL) {
1866 goto error;
1867 }
1868 if (first == NULL)
1869 first = element;
1870 else if (previous != NULL)
1871 previous->next = element;
1872 previous = element;
1873
1874 ctxt->comp = element;
1875 ctxt->base = xmlStrndup(&pattern[start], end - start);
1876 if (ctxt->base == NULL)
1877 goto error;
1878 ctxt->cur = &(ctxt->base)[current - start];
1879 element->pattern = ctxt->base;
1880 element->node = node;
1881 element->nsList = xmlGetNsList(doc, node);
1882 j = 0;
1883 if (element->nsList != NULL) {
1884 while (element->nsList[j] != NULL)
1885 j++;
1886 }
1887 element->nsNr = j;
1888
1889
1890#ifdef WITH_XSLT_DEBUG_PATTERN
1892 "xsltCompilePattern : parsing '%s'\n",
1893 element->pattern);
1894#endif
1895 /*
1896 Preset default priority to be zero.
1897 This may be changed by xsltCompileLocationPathPattern.
1898 */
1899 element->priority = 0;
1900 xsltCompileLocationPathPattern(ctxt, novar);
1901 if (ctxt->error) {
1903 "xsltCompilePattern : failed to compile '%s'\n",
1904 element->pattern);
1905 if (style != NULL) style->errors++;
1906 goto error;
1907 }
1908
1909 /*
1910 * Reverse for faster interpretation.
1911 */
1913
1914 /*
1915 * Set-up the priority
1916 */
1917 if (element->priority == 0) { /* if not yet determined */
1918 if (((element->steps[0].op == XSLT_OP_ELEM) ||
1919 (element->steps[0].op == XSLT_OP_ATTR) ||
1920 (element->steps[0].op == XSLT_OP_PI)) &&
1921 (element->steps[0].value != NULL) &&
1922 (element->steps[1].op == XSLT_OP_END)) {
1923 ; /* previously preset */
1924 } else if ((element->steps[0].op == XSLT_OP_ATTR) &&
1925 (element->steps[0].value2 != NULL) &&
1926 (element->steps[1].op == XSLT_OP_END)) {
1927 element->priority = -0.25;
1928 } else if ((element->steps[0].op == XSLT_OP_NS) &&
1929 (element->steps[0].value != NULL) &&
1930 (element->steps[1].op == XSLT_OP_END)) {
1931 element->priority = -0.25;
1932 } else if ((element->steps[0].op == XSLT_OP_ATTR) &&
1933 (element->steps[0].value == NULL) &&
1934 (element->steps[0].value2 == NULL) &&
1935 (element->steps[1].op == XSLT_OP_END)) {
1936 element->priority = -0.5;
1937 } else if (((element->steps[0].op == XSLT_OP_PI) ||
1938 (element->steps[0].op == XSLT_OP_TEXT) ||
1939 (element->steps[0].op == XSLT_OP_ALL) ||
1940 (element->steps[0].op == XSLT_OP_NODE) ||
1941 (element->steps[0].op == XSLT_OP_COMMENT)) &&
1942 (element->steps[1].op == XSLT_OP_END)) {
1943 element->priority = -0.5;
1944 } else {
1945 element->priority = 0.5;
1946 }
1947 }
1948#ifdef WITH_XSLT_DEBUG_PATTERN
1950 "xsltCompilePattern : parsed %s, default priority %f\n",
1951 element->pattern, element->priority);
1952#endif
1953 if (pattern[end] == '|')
1954 end++;
1955 current = end;
1956 }
1957 if (end == 0) {
1959 "xsltCompilePattern : NULL pattern\n");
1960 if (style != NULL) style->errors++;
1961 goto error;
1962 }
1963
1965 return(first);
1966
1967error:
1968 if (ctxt != NULL)
1970 if (first != NULL)
1972 return(NULL);
1973}
#define xmlIsBlank_ch(c)
Definition: chvalid.h:88
static void xsltFreeParserContext(xsltParserContextPtr ctxt)
Definition: pattern.c:262
static xsltCompMatchPtr xsltNewCompMatch(void)
Definition: pattern.c:126
static void xsltReverseCompMatch(xsltParserContextPtr ctxt, xsltCompMatchPtr comp)
Definition: pattern.c:396
static xsltParserContextPtr xsltNewParserContext(xsltStylesheetPtr style, xsltTransformContextPtr ctxt)
Definition: pattern.c:240
void xsltFreeCompMatchList(xsltCompMatchPtr comp)
Definition: pattern.c:192
static void xsltCompileLocationPathPattern(xsltParserContextPtr ctxt, int novar)
Definition: pattern.c:1736
GLuint start
Definition: gl.h:1545
GLint level
Definition: gl.h:1546
GLuint GLuint end
Definition: gl.h:1545
const GLint * first
Definition: glext.h:5794
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
struct task_struct * current
Definition: linux.c:32
xmlDocPtr doc
Definition: pattern.c:106
const xmlChar * cur
Definition: pattern.c:104
const xmlChar * base
Definition: pattern.c:105
xmlNodePtr elem
Definition: pattern.c:107
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42

Referenced by xsltAddTemplate(), and xsltCompilePattern().

◆ xsltCompileRelativePathPattern()

static void xsltCompileRelativePathPattern ( xsltParserContextPtr  ctxt,
xmlChar token,
int  novar 
)
static

xsltCompileRelativePathPattern: @comp: the compilation context @token: a posible precompiled name @novar: flag to prohibit xslt variables

Compile the XSLT RelativePathPattern and generates a precompiled form suitable for fast matching.

[4] RelativePathPattern ::= StepPattern | RelativePathPattern '/' StepPattern | RelativePathPattern '//' StepPattern

Definition at line 1695 of file pattern.c.

1695 {
1696 xsltCompileStepPattern(ctxt, token, novar);
1697 if (ctxt->error)
1698 goto error;
1700 while ((CUR != 0) && (CUR != '|')) {
1701 if ((CUR == '/') && (NXT(1) == '/')) {
1702 PUSH(XSLT_OP_ANCESTOR, NULL, NULL, novar);
1703 NEXT;
1704 NEXT;
1706 xsltCompileStepPattern(ctxt, NULL, novar);
1707 } else if (CUR == '/') {
1708 PUSH(XSLT_OP_PARENT, NULL, NULL, novar);
1709 NEXT;
1711 xsltCompileStepPattern(ctxt, NULL, novar);
1712 } else {
1713 ctxt->error = 1;
1714 }
1715 if (ctxt->error)
1716 goto error;
1718 }
1719error:
1720 return;
1721}
static void xsltCompileStepPattern(xsltParserContextPtr ctxt, xmlChar *token, int novar)
Definition: pattern.c:1492
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat token
Definition: glfuncs.h:210

Referenced by xsltCompileLocationPathPattern().

◆ xsltCompileStepPattern()

static void xsltCompileStepPattern ( xsltParserContextPtr  ctxt,
xmlChar token,
int  novar 
)
static

xsltCompileStepPattern: @ctxt: the compilation context @token: a posible precompiled name @novar: flag to prohibit xslt variables from pattern

Compile the XSLT StepPattern and generates a precompiled form suitable for fast matching.

[5] StepPattern ::= ChildOrAttributeAxisSpecifier NodeTest Predicate* [6] ChildOrAttributeAxisSpecifier ::= AbbreviatedAxisSpecifier | ('child' | 'attribute') '::' from XPath [7] NodeTest ::= NameTest | NodeType '(' ')' | 'processing-instruction' '(' Literal ')' [8] Predicate ::= '[' PredicateExpr ']' [9] PredicateExpr ::= Expr [13] AbbreviatedAxisSpecifier ::= '@'? [37] NameTest ::= '*' | NCName ':' '*' | QName

Definition at line 1492 of file pattern.c.

1492 {
1493 xmlChar *name = NULL;
1494 const xmlChar *URI = NULL;
1495 xmlChar *URL = NULL;
1496 int level;
1497 xsltAxis axis = 0;
1498
1500 if ((token == NULL) && (CUR == '@')) {
1501 NEXT;
1502 axis = AXIS_ATTRIBUTE;
1503 }
1504parse_node_test:
1505 if (token == NULL)
1506 token = xsltScanNCName(ctxt);
1507 if (token == NULL) {
1508 if (CUR == '*') {
1509 NEXT;
1510 if (axis == AXIS_ATTRIBUTE) {
1511 PUSH(XSLT_OP_ATTR, NULL, NULL, novar);
1512 }
1513 else {
1514 PUSH(XSLT_OP_ALL, NULL, NULL, novar);
1515 }
1516 goto parse_predicate;
1517 } else {
1519 "xsltCompileStepPattern : Name expected\n");
1520 ctxt->error = 1;
1521 goto error;
1522 }
1523 }
1524
1525
1527 if (CUR == '(') {
1528 xsltCompileIdKeyPattern(ctxt, token, 0, novar, axis);
1529 xmlFree(token);
1530 token = NULL;
1531 if (ctxt->error)
1532 goto error;
1533 } else if (CUR == ':') {
1534 NEXT;
1535 if (CUR != ':') {
1536 xmlChar *prefix = token;
1537 xmlNsPtr ns;
1538
1539 /*
1540 * This is a namespace match
1541 */
1542 token = xsltScanNCName(ctxt);
1543 ns = xmlSearchNs(ctxt->doc, ctxt->elem, prefix);
1544 if (ns == NULL) {
1546 "xsltCompileStepPattern : no namespace bound to prefix %s\n",
1547 prefix);
1548 xmlFree(prefix);
1549 prefix=NULL;
1550 ctxt->error = 1;
1551 goto error;
1552 } else {
1553 URL = xmlStrdup(ns->href);
1554 }
1555 xmlFree(prefix);
1556 prefix=NULL;
1557 if (token == NULL) {
1558 if (CUR == '*') {
1559 NEXT;
1560 if (axis == AXIS_ATTRIBUTE) {
1561 PUSH(XSLT_OP_ATTR, NULL, URL, novar);
1562 URL = NULL;
1563 }
1564 else {
1565 PUSH(XSLT_OP_NS, URL, NULL, novar);
1566 URL = NULL;
1567 }
1568 } else {
1570 "xsltCompileStepPattern : Name expected\n");
1571 ctxt->error = 1;
1572 xmlFree(URL);
1573 goto error;
1574 }
1575 } else {
1576 if (axis == AXIS_ATTRIBUTE) {
1577 PUSH(XSLT_OP_ATTR, token, URL, novar);
1578 token = NULL;
1579 URL = NULL;
1580 }
1581 else {
1582 PUSH(XSLT_OP_ELEM, token, URL, novar);
1583 token = NULL;
1584 URL = NULL;
1585 }
1586 }
1587 } else {
1588 if (axis != 0) {
1590 "xsltCompileStepPattern : NodeTest expected\n");
1591 ctxt->error = 1;
1592 goto error;
1593 }
1594 NEXT;
1595 if (xmlStrEqual(token, (const xmlChar *) "child")) {
1596 axis = AXIS_CHILD;
1597 } else if (xmlStrEqual(token, (const xmlChar *) "attribute")) {
1598 axis = AXIS_ATTRIBUTE;
1599 } else {
1601 "xsltCompileStepPattern : 'child' or 'attribute' expected\n");
1602 ctxt->error = 1;
1603 goto error;
1604 }
1605 xmlFree(token);
1606 token = NULL;
1608 token = xsltScanNCName(ctxt);
1609 goto parse_node_test;
1610 }
1611 } else {
1612 URI = xsltGetQNameURI(ctxt->elem, &token);
1613 if (token == NULL) {
1614 ctxt->error = 1;
1615 goto error;
1616 }
1617 if (URI != NULL)
1618 URL = xmlStrdup(URI);
1619 if (axis == AXIS_ATTRIBUTE) {
1620 PUSH(XSLT_OP_ATTR, token, URL, novar);
1621 token = NULL;
1622 URL = NULL;
1623 }
1624 else {
1625 PUSH(XSLT_OP_ELEM, token, URL, novar);
1626 token = NULL;
1627 URL = NULL;
1628 }
1629 }
1630parse_predicate:
1632 level = 0;
1633 while (CUR == '[') {
1634 const xmlChar *q;
1635 xmlChar *ret = NULL;
1636
1637 level++;
1638 NEXT;
1639 q = CUR_PTR;
1640 while (CUR != 0) {
1641 /* Skip over nested predicates */
1642 if (CUR == '[')
1643 level++;
1644 else if (CUR == ']') {
1645 level--;
1646 if (level == 0)
1647 break;
1648 } else if (CUR == '"') {
1649 NEXT;
1650 while ((CUR != 0) && (CUR != '"'))
1651 NEXT;
1652 } else if (CUR == '\'') {
1653 NEXT;
1654 while ((CUR != 0) && (CUR != '\''))
1655 NEXT;
1656 }
1657 NEXT;
1658 }
1659 if (CUR == 0) {
1661 "xsltCompileStepPattern : ']' expected\n");
1662 ctxt->error = 1;
1663 return;
1664 }
1665 ret = xmlStrndup(q, CUR_PTR - q);
1666 PUSH(XSLT_OP_PREDICATE, ret, NULL, novar);
1667 ret = NULL;
1668 /* push the predicate lower than local test */
1669 SWAP();
1670 NEXT;
1672 }
1673 return;
1674error:
1675 if (token != NULL)
1676 xmlFree(token);
1677 if (name != NULL)
1678 xmlFree(name);
1679}
#define SWAP()
Definition: pattern.c:1185
#define CUR_PTR
Definition: pattern.c:1173
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
XMLPUBFUN xmlNsPtr XMLCALL xmlSearchNs(xmlDocPtr doc, xmlNodePtr node, const xmlChar *nameSpace)
Definition: tree.h:389
Definition: mxnamespace.c:45
int ret
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:67
const xmlChar * xsltGetQNameURI(xmlNodePtr node, xmlChar **name)
Definition: xsltutils.c:753

Referenced by xsltCompileRelativePathPattern().

◆ xsltCompMatchAdd()

static int xsltCompMatchAdd ( xsltParserContextPtr  ctxt,
xsltCompMatchPtr  comp,
xsltOp  op,
xmlChar value,
xmlChar value2,
int  novar 
)
static

xsltCompMatchAdd: @comp: the compiled match expression @op: an op @value: the first value @value2: the second value @novar: flag to set XML_XPATH_NOVAR

Add an step to an XSLT Compiled Match

Returns -1 in case of failure, 0 otherwise.

Definition at line 282 of file pattern.c.

284{
285 if (comp->nbStep >= comp->maxStep) {
286 xsltStepOpPtr tmp;
287
288 tmp = (xsltStepOpPtr) xmlRealloc(comp->steps, comp->maxStep * 2 *
289 sizeof(xsltStepOp));
290 if (tmp == NULL) {
292 "xsltCompMatchAdd: memory re-allocation failure.\n");
293 if (ctxt->style != NULL)
294 ctxt->style->errors++;
295 if (value)
296 xmlFree(value);
297 if (value2)
298 xmlFree(value2);
299 return (-1);
300 }
301 comp->maxStep *= 2;
302 comp->steps = tmp;
303 }
304 comp->steps[comp->nbStep].op = op;
305 comp->steps[comp->nbStep].value = value;
306 comp->steps[comp->nbStep].value2 = value2;
307 comp->steps[comp->nbStep].value3 = NULL;
308 comp->steps[comp->nbStep].comp = NULL;
309 if (ctxt->ctxt != NULL) {
310 comp->steps[comp->nbStep].previousExtra =
312 comp->steps[comp->nbStep].indexExtra =
314 comp->steps[comp->nbStep].lenExtra =
316 } else {
317 comp->steps[comp->nbStep].previousExtra =
319 comp->steps[comp->nbStep].indexExtra =
321 comp->steps[comp->nbStep].lenExtra =
323 }
324 if (op == XSLT_OP_PREDICATE) {
325 int flags = 0;
326
327#ifdef XML_XPATH_NOVAR
328 if (novar != 0)
329 flags = XML_XPATH_NOVAR;
330#endif
331 comp->steps[comp->nbStep].comp = xsltXPathCompileFlags(ctxt->style,
332 value, flags);
333 if (comp->steps[comp->nbStep].comp == NULL) {
334 xsltTransformError(NULL, ctxt->style, ctxt->elem,
335 "Failed to compile predicate\n");
336 if (ctxt->style != NULL)
337 ctxt->style->errors++;
338 }
339 }
340 comp->nbStep++;
341 return (0);
342}
xsltStepOp * xsltStepOpPtr
Definition: pattern.c:66
UINT op
Definition: effect.c:236
GLbitfield flags
Definition: glext.h:7161
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
xsltStylesheetPtr style
Definition: pattern.c:102
xsltTransformContextPtr ctxt
Definition: pattern.c:103
int indexExtra
Definition: pattern.c:77
int lenExtra
Definition: pattern.c:78
int previousExtra
Definition: pattern.c:76
xmlXPathCompExprPtr comp
Definition: pattern.c:72
xmlChar * value2
Definition: pattern.c:70
xmlChar * value3
Definition: pattern.c:71
Definition: pdh_main.c:94
int xsltAllocateExtraCtxt(xsltTransformContextPtr ctxt)
Definition: xslt.c:825
int xsltAllocateExtra(xsltStylesheetPtr style)
Definition: xslt.c:809
xmlXPathCompExprPtr xsltXPathCompileFlags(xsltStylesheetPtr style, const xmlChar *str, int flags)
Definition: xsltutils.c:2313
xmlGenericErrorFunc xsltGenericError
Definition: xsltutils.c:502
void * xsltGenericErrorContext
Definition: xsltutils.c:503

Referenced by xsltReverseCompMatch().

◆ xsltCompMatchClearCache()

void xsltCompMatchClearCache ( xsltTransformContextPtr  ctxt,
xsltCompMatchPtr  comp 
)

xsltCompMatchClearCache: @ctxt: a XSLT process context @comp: the precompiled pattern list

Clear pattern match cache.

Definition at line 1144 of file pattern.c.

1144 {
1145 xsltStepOpPtr sel;
1146 xmlXPathObjectPtr list;
1147
1148 if ((ctxt == NULL) || (comp == NULL))
1149 return;
1150
1151 sel = &comp->steps[0];
1152 list = (xmlXPathObjectPtr) XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra);
1153
1154 if (list != NULL) {
1155 xmlXPathFreeObject(list);
1156
1157 XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra) = NULL;
1159 XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = 0;
1161 }
1162}
static PVOID ptr
Definition: dispmode.c:27
#define XSLT_RUNTIME_EXTRA(ctxt, nr, typ)
#define XSLT_RUNTIME_EXTRA_LST(ctxt, nr)
#define XSLT_RUNTIME_EXTRA_FREE(ctxt, nr)

Referenced by xsltNumberFormat().

◆ xsltComputeAllKeys()

static int xsltComputeAllKeys ( xsltTransformContextPtr  ctxt,
xmlNodePtr  contextNode 
)
static

Definition at line 2214 of file pattern.c.

2215{
2216 if ((ctxt == NULL) || (contextNode == NULL)) {
2217 xsltTransformError(ctxt, NULL, ctxt->inst,
2218 "Internal error in xsltComputeAllKeys(): "
2219 "Bad arguments.\n");
2220 return(-1);
2221 }
2222
2223 if (ctxt->document == NULL) {
2224 /*
2225 * The document info will only be NULL if we have a RTF.
2226 */
2227 if (contextNode->doc->_private != NULL)
2228 goto doc_info_mismatch;
2229 /*
2230 * On-demand creation of the document info (needed for keys).
2231 */
2232 ctxt->document = xsltNewDocument(ctxt, contextNode->doc);
2233 if (ctxt->document == NULL)
2234 return(-1);
2235 }
2236 return xsltInitAllDocKeys(ctxt);
2237
2238doc_info_mismatch:
2239 xsltTransformError(ctxt, NULL, ctxt->inst,
2240 "Internal error in xsltComputeAllKeys(): "
2241 "The context's document info doesn't match the "
2242 "document info of the current result tree.\n");
2243 ctxt->state = XSLT_STATE_STOPPED;
2244 return(-1);
2245}
xsltDocumentPtr xsltNewDocument(xsltTransformContextPtr ctxt, xmlDocPtr doc)
Definition: documents.c:127
int xsltInitAllDocKeys(xsltTransformContextPtr ctxt)
Definition: keys.c:535
struct _xmlDoc * doc
Definition: tree.h:498
xsltTransformState state
xsltDocumentPtr document
@ XSLT_STATE_STOPPED

Referenced by xsltGetTemplate().

◆ xsltFreeCompMatch()

static void xsltFreeCompMatch ( xsltCompMatchPtr  comp)
static

xsltFreeCompMatch: @comp: an XSLT comp

Free up the memory allocated by @comp

Definition at line 159 of file pattern.c.

159 {
161 int i;
162
163 if (comp == NULL)
164 return;
165 if (comp->pattern != NULL)
166 xmlFree((xmlChar *)comp->pattern);
167 if (comp->nsList != NULL)
168 xmlFree(comp->nsList);
169 for (i = 0;i < comp->nbStep;i++) {
170 op = &comp->steps[i];
171 if (op->value != NULL)
172 xmlFree(op->value);
173 if (op->value2 != NULL)
174 xmlFree(op->value2);
175 if (op->value3 != NULL)
176 xmlFree(op->value3);
177 if (op->comp != NULL)
178 xmlXPathFreeCompExpr(op->comp);
179 }
180 xmlFree(comp->steps);
181 memset(comp, -1, sizeof(xsltCompMatch));
182 xmlFree(comp);
183}
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define memset(x, y, z)
Definition: compat.h:39
xmlNsPtr * nsList
Definition: pattern.c:94

Referenced by xsltAddTemplate(), and xsltFreeCompMatchList().

◆ xsltFreeCompMatchList()

void xsltFreeCompMatchList ( xsltCompMatchPtr  comp)

xsltFreeCompMatchList: @comp: an XSLT comp list

Free up the memory allocated by all the elements of @comp

Definition at line 192 of file pattern.c.

192 {
194
195 while (comp != NULL) {
196 cur = comp;
197 comp = comp->next;
199 }
200}

Referenced by xsltCompilePatternInternal(), xsltFreeCompMatchListEntry(), xsltFreeStylePreComp(), and xsltFreeTemplateHashes().

◆ xsltFreeCompMatchListEntry()

static void xsltFreeCompMatchListEntry ( void payload,
const xmlChar *name  ATTRIBUTE_UNUSED 
)
static

Definition at line 203 of file pattern.c.

204 {
206}

Referenced by xsltFreeTemplateHashes().

◆ xsltFreeParserContext()

static void xsltFreeParserContext ( xsltParserContextPtr  ctxt)
static

xsltFreeParserContext: @ctxt: an XSLT parser context

Free up the memory allocated by @ctxt

Definition at line 262 of file pattern.c.

262 {
263 if (ctxt == NULL)
264 return;
265 memset(ctxt, -1, sizeof(xsltParserContext));
266 xmlFree(ctxt);
267}

Referenced by xsltCompilePatternInternal().

◆ xsltFreeTemplateHashes()

void xsltFreeTemplateHashes ( xsltStylesheetPtr  style)

xsltFreeTemplateHashes: @style: an XSLT stylesheet

Free up the memory used by xsltAddTemplate/xsltGetTemplate mechanism

Definition at line 2527 of file pattern.c.

2527 {
2528 if (style->templatesHash != NULL)
2530 if (style->rootMatch != NULL)
2531 xsltFreeCompMatchList(style->rootMatch);
2532 if (style->keyMatch != NULL)
2533 xsltFreeCompMatchList(style->keyMatch);
2534 if (style->elemMatch != NULL)
2535 xsltFreeCompMatchList(style->elemMatch);
2536 if (style->attrMatch != NULL)
2537 xsltFreeCompMatchList(style->attrMatch);
2538 if (style->parentMatch != NULL)
2539 xsltFreeCompMatchList(style->parentMatch);
2540 if (style->textMatch != NULL)
2541 xsltFreeCompMatchList(style->textMatch);
2542 if (style->piMatch != NULL)
2543 xsltFreeCompMatchList(style->piMatch);
2544 if (style->commentMatch != NULL)
2545 xsltFreeCompMatchList(style->commentMatch);
2546 if (style->namedTemplates != NULL)
2547 xmlHashFree(style->namedTemplates, NULL);
2548}
static void xsltFreeCompMatchListEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
Definition: pattern.c:203
XMLPUBFUN void XMLCALL xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f)
Definition: hash.c:322

Referenced by xsltFreeStylesheet().

◆ xsltGetTemplate()

xsltTemplatePtr xsltGetTemplate ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xsltStylesheetPtr  style 
)

xsltGetTemplate: @ctxt: a XSLT process context @node: the node being processed @style: the current style

Finds the template applying to this node, if @style is non-NULL it means one needs to look for the next imported template in scope.

Returns the xsltTemplatePtr or NULL if not found

Definition at line 2259 of file pattern.c.

2261{
2262 xsltStylesheetPtr curstyle;
2264 const xmlChar *name = NULL;
2266 float priority;
2267 int keyed = 0;
2268
2269 if ((ctxt == NULL) || (node == NULL))
2270 return(NULL);
2271
2272 if (style == NULL) {
2273 curstyle = ctxt->style;
2274 } else {
2275 curstyle = xsltNextImport(style);
2276 }
2277
2278 while ((curstyle != NULL) && (curstyle != style)) {
2280 /* TODO : handle IDs/keys here ! */
2281 if (curstyle->templatesHash != NULL) {
2282 /*
2283 * Use the top name as selector
2284 */
2285 switch (node->type) {
2286 case XML_ELEMENT_NODE:
2287 if (node->name[0] == ' ')
2288 break;
2289 /* Intentional fall-through */
2290 case XML_ATTRIBUTE_NODE:
2291 case XML_PI_NODE:
2292 name = node->name;
2293 break;
2294 case XML_DOCUMENT_NODE:
2296 case XML_TEXT_NODE:
2298 case XML_COMMENT_NODE:
2300 case XML_ENTITY_NODE:
2303 case XML_NOTATION_NODE:
2304 case XML_DTD_NODE:
2305 case XML_ELEMENT_DECL:
2306 case XML_ATTRIBUTE_DECL:
2307 case XML_ENTITY_DECL:
2308 case XML_NAMESPACE_DECL:
2309 case XML_XINCLUDE_START:
2310 case XML_XINCLUDE_END:
2311 break;
2312 default:
2313 return(NULL);
2314
2315 }
2316 }
2317 if (name != NULL) {
2318 /*
2319 * find the list of applicable expressions based on the name
2320 */
2322 name, ctxt->mode, ctxt->modeURI);
2323 } else
2324 list = NULL;
2325 while (list != NULL) {
2326 if (xsltTestCompMatch(ctxt, list, node,
2327 ctxt->mode, ctxt->modeURI) == 1) {
2328 ret = list->template;
2329 priority = list->priority;
2330 break;
2331 }
2332 list = list->next;
2333 }
2334 list = NULL;
2335
2336 /*
2337 * find alternate generic matches
2338 */
2339 switch (node->type) {
2340 case XML_ELEMENT_NODE:
2341 if (node->name[0] == ' ')
2342 list = curstyle->rootMatch;
2343 else
2344 list = curstyle->elemMatch;
2345 if (node->psvi != NULL) keyed = 1;
2346 break;
2347 case XML_ATTRIBUTE_NODE: {
2349
2350 list = curstyle->attrMatch;
2351 attr = (xmlAttrPtr) node;
2352 if (attr->psvi != NULL) keyed = 1;
2353 break;
2354 }
2355 case XML_PI_NODE:
2356 list = curstyle->piMatch;
2357 if (node->psvi != NULL) keyed = 1;
2358 break;
2359 case XML_DOCUMENT_NODE:
2361 xmlDocPtr doc;
2362
2363 list = curstyle->rootMatch;
2364 doc = (xmlDocPtr) node;
2365 if (doc->psvi != NULL) keyed = 1;
2366 break;
2367 }
2368 case XML_TEXT_NODE:
2370 list = curstyle->textMatch;
2371 if (node->psvi != NULL) keyed = 1;
2372 break;
2373 case XML_COMMENT_NODE:
2374 list = curstyle->commentMatch;
2375 if (node->psvi != NULL) keyed = 1;
2376 break;
2378 case XML_ENTITY_NODE:
2381 case XML_NOTATION_NODE:
2382 case XML_DTD_NODE:
2383 case XML_ELEMENT_DECL:
2384 case XML_ATTRIBUTE_DECL:
2385 case XML_ENTITY_DECL:
2386 case XML_NAMESPACE_DECL:
2387 case XML_XINCLUDE_START:
2388 case XML_XINCLUDE_END:
2389 break;
2390 default:
2391 break;
2392 }
2393 while ((list != NULL) &&
2394 ((ret == NULL) ||
2395 (list->priority > priority) ||
2396 ((list->priority == priority) &&
2397 (list->template->position > ret->position)))) {
2398 if (xsltTestCompMatch(ctxt, list, node,
2399 ctxt->mode, ctxt->modeURI) == 1) {
2400 ret = list->template;
2401 priority = list->priority;
2402 break;
2403 }
2404 list = list->next;
2405 }
2406 /*
2407 * Some of the tests for elements can also apply to documents
2408 */
2409 if ((node->type == XML_DOCUMENT_NODE) ||
2410 (node->type == XML_HTML_DOCUMENT_NODE) ||
2411 (node->type == XML_TEXT_NODE)) {
2412 list = curstyle->elemMatch;
2413 while ((list != NULL) &&
2414 ((ret == NULL) ||
2415 (list->priority > priority) ||
2416 ((list->priority == priority) &&
2417 (list->template->position > ret->position)))) {
2418 if (xsltTestCompMatch(ctxt, list, node,
2419 ctxt->mode, ctxt->modeURI) == 1) {
2420 ret = list->template;
2421 priority = list->priority;
2422 break;
2423 }
2424 list = list->next;
2425 }
2426 } else if ((node->type == XML_PI_NODE) ||
2427 (node->type == XML_COMMENT_NODE)) {
2428 list = curstyle->elemMatch;
2429 while ((list != NULL) &&
2430 ((ret == NULL) ||
2431 (list->priority > priority) ||
2432 ((list->priority == priority) &&
2433 (list->template->position > ret->position)))) {
2434 if (xsltTestCompMatch(ctxt, list, node,
2435 ctxt->mode, ctxt->modeURI) == 1) {
2436 ret = list->template;
2437 priority = list->priority;
2438 break;
2439 }
2440 list = list->next;
2441 }
2442 }
2443
2444keyed_match:
2445 if (keyed) {
2446 list = curstyle->keyMatch;
2447 while ((list != NULL) &&
2448 ((ret == NULL) ||
2449 (list->priority > priority) ||
2450 ((list->priority == priority) &&
2451 (list->template->position > ret->position)))) {
2452 if (xsltTestCompMatch(ctxt, list, node,
2453 ctxt->mode, ctxt->modeURI) == 1) {
2454 ret = list->template;
2455 priority = list->priority;
2456 break;
2457 }
2458 list = list->next;
2459 }
2460 }
2461 else if (ctxt->hasTemplKeyPatterns &&
2462 ((ctxt->document == NULL) ||
2463 (ctxt->document->nbKeysComputed < ctxt->nbKeys)))
2464 {
2465 /*
2466 * Compute all remaining keys for this document.
2467 *
2468 * REVISIT TODO: I think this could be further optimized.
2469 */
2470 if (xsltComputeAllKeys(ctxt, node) == -1)
2471 goto error;
2472
2473 switch (node->type) {
2474 case XML_ELEMENT_NODE:
2475 if (node->psvi != NULL) keyed = 1;
2476 break;
2477 case XML_ATTRIBUTE_NODE:
2478 if (((xmlAttrPtr) node)->psvi != NULL) keyed = 1;
2479 break;
2480 case XML_TEXT_NODE:
2482 case XML_COMMENT_NODE:
2483 case XML_PI_NODE:
2484 if (node->psvi != NULL) keyed = 1;
2485 break;
2486 case XML_DOCUMENT_NODE:
2488 if (((xmlDocPtr) node)->psvi != NULL) keyed = 1;
2489 break;
2490 default:
2491 break;
2492 }
2493 if (keyed)
2494 goto keyed_match;
2495 }
2496 if (ret != NULL)
2497 return(ret);
2498
2499 /*
2500 * Cycle on next curstylesheet import.
2501 */
2502 curstyle = xsltNextImport(curstyle);
2503 }
2504
2505error:
2506 return(NULL);
2507}
static int xsltComputeAllKeys(xsltTransformContextPtr ctxt, xmlNodePtr contextNode)
Definition: pattern.c:2214
static int xsltTestCompMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, xmlNodePtr matchNode, const xmlChar *mode, const xmlChar *modeURI)
Definition: pattern.c:926
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:251
xmlDoc * xmlDocPtr
Definition: tree.h:550
@ XML_DOCUMENT_TYPE_NODE
Definition: tree.h:169
@ XML_ATTRIBUTE_NODE
Definition: tree.h:161
@ XML_ENTITY_DECL
Definition: tree.h:176
@ XML_DOCUMENT_NODE
Definition: tree.h:168
@ XML_CDATA_SECTION_NODE
Definition: tree.h:163
@ XML_TEXT_NODE
Definition: tree.h:162
@ XML_XINCLUDE_START
Definition: tree.h:178
@ XML_ENTITY_NODE
Definition: tree.h:165
@ XML_PI_NODE
Definition: tree.h:166
@ XML_XINCLUDE_END
Definition: tree.h:179
@ XML_DOCUMENT_FRAG_NODE
Definition: tree.h:170
@ XML_COMMENT_NODE
Definition: tree.h:167
@ XML_DTD_NODE
Definition: tree.h:173
@ XML_NAMESPACE_DECL
Definition: tree.h:177
@ XML_HTML_DOCUMENT_NODE
Definition: tree.h:172
@ XML_ELEMENT_NODE
Definition: tree.h:160
@ XML_ELEMENT_DECL
Definition: tree.h:174
@ XML_ENTITY_REF_NODE
Definition: tree.h:164
@ XML_NOTATION_NODE
Definition: tree.h:171
@ XML_ATTRIBUTE_DECL
Definition: tree.h:175
xmlAttr * xmlAttrPtr
Definition: tree.h:433
Definition: tree.h:434
Definition: tree.h:551
void * psvi
Definition: tree.h:581
struct _xsltCompMatch * rootMatch
struct _xsltCompMatch * textMatch
struct _xsltCompMatch * elemMatch
struct _xsltCompMatch * piMatch
xmlHashTablePtr templatesHash
struct _xsltCompMatch * attrMatch
struct _xsltCompMatch * commentMatch
struct _xsltCompMatch * keyMatch
const xmlChar * modeURI
xsltStylesheetPtr style
const xmlChar * mode
Definition: cookie.c:202

Referenced by xsltApplyImports(), xsltDefaultProcessOneNode(), and xsltProcessOneNode().

◆ xsltNewCompMatch()

static xsltCompMatchPtr xsltNewCompMatch ( void  )
static

xsltNewCompMatch:

Create a new XSLT CompMatch

Returns the newly allocated xsltCompMatchPtr or NULL in case of error

Definition at line 126 of file pattern.c.

126 {
128
130 if (cur == NULL) {
132 "xsltNewCompMatch : out of memory error\n");
133 return(NULL);
134 }
135 memset(cur, 0, sizeof(xsltCompMatch));
136 cur->maxStep = 10;
137 cur->nbStep = 0;
139 cur->maxStep);
140 if (cur->steps == NULL) {
142 "xsltNewCompMatch : out of memory error\n");
143 xmlFree(cur);
144 return(NULL);
145 }
146 cur->nsNr = 0;
147 cur->nsList = NULL;
148 cur->direct = 0;
149 return(cur);
150}
static DWORD DWORD DWORD DWORD * steps
Definition: cursoricon.c:1638
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248

Referenced by xsltCompilePatternInternal().

◆ xsltNewParserContext()

static xsltParserContextPtr xsltNewParserContext ( xsltStylesheetPtr  style,
xsltTransformContextPtr  ctxt 
)
static

xsltNewParserContext: @style: the stylesheet @ctxt: the transformation context, if done at run-time

Create a new XSLT ParserContext

Returns the newly allocated xsltParserContextPtr or NULL in case of error

Definition at line 240 of file pattern.c.

240 {
242
244 if (cur == NULL) {
246 "xsltNewParserContext : malloc failed\n");
247 return(NULL);
248 }
249 memset(cur, 0, sizeof(xsltParserContext));
250 cur->style = style;
251 cur->ctxt = ctxt;
252 return(cur);
253}
xsltParserContext * xsltParserContextPtr
Definition: pattern.c:100

Referenced by xsltCompilePatternInternal().

◆ xsltNormalizeCompSteps()

void xsltNormalizeCompSteps ( void payload,
void data,
const xmlChar *name  ATTRIBUTE_UNUSED 
)

Definition at line 217 of file pattern.c.

218 {
219 xsltCompMatchPtr comp = payload;
221 int ix;
222
223 for (ix = 0; ix < comp->nbStep; ix++) {
224 comp->steps[ix].previousExtra += style->extrasNr;
225 comp->steps[ix].indexExtra += style->extrasNr;
226 comp->steps[ix].lenExtra += style->extrasNr;
227 }
228}
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950

Referenced by xsltFixImportedCompSteps().

◆ xsltPatPushState()

static int xsltPatPushState ( xsltTransformContextPtr  ctxt,
xsltStepStates states,
int  step,
xmlNodePtr  node 
)
static

Definition at line 465 of file pattern.c.

466 {
467 if ((states->states == NULL) || (states->maxstates <= 0)) {
468 states->maxstates = 4;
469 states->nbstates = 0;
470 states->states = xmlMalloc(4 * sizeof(xsltStepState));
471 }
472 else if (states->maxstates <= states->nbstates) {
473 xsltStepState *tmp;
474
475 tmp = (xsltStepStatePtr) xmlRealloc(states->states,
476 2 * states->maxstates * sizeof(xsltStepState));
477 if (tmp == NULL) {
479 "xsltPatPushState: memory re-allocation failure.\n");
481 return(-1);
482 }
483 states->states = tmp;
484 states->maxstates *= 2;
485 }
486 states->states[states->nbstates].step = step;
487 states->states[states->nbstates++].node = node;
488#if 0
489 fprintf(stderr, "Push: %d, %s\n", step, node->name);
490#endif
491 return(0);
492}
xsltStepState * xsltStepStatePtr
Definition: pattern.c:51
#define stderr
Definition: stdio.h:100
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
xmlNodePtr node
Definition: pattern.c:54
xsltStepStatePtr states
Definition: pattern.c:62

Referenced by xsltTestCompMatch().

◆ xsltReverseCompMatch()

static void xsltReverseCompMatch ( xsltParserContextPtr  ctxt,
xsltCompMatchPtr  comp 
)
static

xsltReverseCompMatch: @ctxt: the parser context @comp: the compiled match expression

reverse all the stack of expressions

Definition at line 396 of file pattern.c.

396 {
397 int i = 0;
398 int j = comp->nbStep - 1;
399
400 while (j > i) {
401 register xmlChar *tmp;
402 register xsltOp op;
403 register xmlXPathCompExprPtr expr;
404 register int t;
405
406 tmp = comp->steps[i].value;
407 comp->steps[i].value = comp->steps[j].value;
408 comp->steps[j].value = tmp;
409 tmp = comp->steps[i].value2;
410 comp->steps[i].value2 = comp->steps[j].value2;
411 comp->steps[j].value2 = tmp;
412 tmp = comp->steps[i].value3;
413 comp->steps[i].value3 = comp->steps[j].value3;
414 comp->steps[j].value3 = tmp;
415 op = comp->steps[i].op;
416 comp->steps[i].op = comp->steps[j].op;
417 comp->steps[j].op = op;
418 expr = comp->steps[i].comp;
419 comp->steps[i].comp = comp->steps[j].comp;
420 comp->steps[j].comp = expr;
421 t = comp->steps[i].previousExtra;
422 comp->steps[i].previousExtra = comp->steps[j].previousExtra;
423 comp->steps[j].previousExtra = t;
424 t = comp->steps[i].indexExtra;
425 comp->steps[i].indexExtra = comp->steps[j].indexExtra;
426 comp->steps[j].indexExtra = t;
427 t = comp->steps[i].lenExtra;
428 comp->steps[i].lenExtra = comp->steps[j].lenExtra;
429 comp->steps[j].lenExtra = t;
430 j--;
431 i++;
432 }
433 xsltCompMatchAdd(ctxt, comp, XSLT_OP_END, NULL, NULL, 0);
434
435 /*
436 * Detect consecutive XSLT_OP_PREDICATE indicating a direct matching
437 * should be done.
438 */
439 for (i = 0;i < comp->nbStep - 1;i++) {
440 if ((comp->steps[i].op == XSLT_OP_PREDICATE) &&
441 (comp->steps[i + 1].op == XSLT_OP_PREDICATE)) {
442
443 comp->direct = 1;
444 if (comp->pattern[0] != '/') {
445 xmlChar *query;
446
447 query = xmlStrdup((const xmlChar *)"//");
448 query = xmlStrcat(query, comp->pattern);
449
450 xmlFree((xmlChar *) comp->pattern);
451 comp->pattern = query;
452 }
453 break;
454 }
455 }
456}
static int xsltCompMatchAdd(xsltParserContextPtr ctxt, xsltCompMatchPtr comp, xsltOp op, xmlChar *value, xmlChar *value2, int novar)
Definition: pattern.c:282
GLdouble GLdouble t
Definition: gl.h:2047
Definition: query.h:86
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524

Referenced by xsltCompilePatternInternal().

◆ xsltScanLiteral()

static xmlChar * xsltScanLiteral ( xsltParserContextPtr  ctxt)
static

xsltScanLiteral: @ctxt: the XPath Parser context

Parse an XPath Litteral:

[29] Literal ::= '"' [^"]* '"' | "'" [^']* "'"

Returns the Literal parsed or NULL

Definition at line 1209 of file pattern.c.

1209 {
1210 const xmlChar *q, *cur;
1211 xmlChar *ret = NULL;
1212 int val, len;
1213
1215 if (CUR == '"') {
1216 NEXT;
1217 cur = q = CUR_PTR;
1219 while ((xmlIsCharQ(val)) && (val != '"')) {
1220 cur += len;
1222 }
1223 if (!xmlIsCharQ(val)) {
1224 ctxt->error = 1;
1225 return(NULL);
1226 } else {
1227 ret = xmlStrndup(q, cur - q);
1228 }
1229 cur += len;
1230 CUR_PTR = cur;
1231 } else if (CUR == '\'') {
1232 NEXT;
1233 cur = q = CUR_PTR;
1235 while ((xmlIsCharQ(val)) && (val != '\'')) {
1236 cur += len;
1238 }
1239 if (!xmlIsCharQ(val)) {
1240 ctxt->error = 1;
1241 return(NULL);
1242 } else {
1243 ret = xmlStrndup(q, cur - q);
1244 }
1245 cur += len;
1246 CUR_PTR = cur;
1247 } else {
1248 ctxt->error = 1;
1249 return(NULL);
1250 }
1251 return(ret);
1252}
#define xmlIsCharQ(c)
Definition: chvalid.h:118
GLuint GLfloat * val
Definition: glext.h:7180
GLenum GLsizei len
Definition: glext.h:6722
XMLPUBFUN int XMLCALL xmlStringCurrentChar(xmlParserCtxtPtr ctxt, const xmlChar *cur, int *len)

Referenced by xsltCompileIdKeyPattern().

◆ xsltScanNCName()

static xmlChar * xsltScanNCName ( xsltParserContextPtr  ctxt)
static

xsltScanNCName: @ctxt: the XPath Parser context

Parses a non qualified name

Returns the Name parsed or NULL

Definition at line 1264 of file pattern.c.

1264 {
1265 const xmlChar *q, *cur;
1266 xmlChar *ret = NULL;
1267 int val, len;
1268
1270
1271 cur = q = CUR_PTR;
1273 if (!xmlIsBaseCharQ(val) && !xmlIsIdeographicQ(val) && (val != '_'))
1274 return(NULL);
1275
1277 xmlIsDigitQ(val) ||
1278 (val == '.') || (val == '-') ||
1279 (val == '_') ||
1282 cur += len;
1284 }
1285 ret = xmlStrndup(q, cur - q);
1286 CUR_PTR = cur;
1287 return(ret);
1288}
#define xmlIsCombiningQ(c)
Definition: chvalid.h:132
#define xmlIsDigitQ(c)
Definition: chvalid.h:152
#define xmlIsIdeographicQ(c)
Definition: chvalid.h:184
#define xmlIsExtenderQ(c)
Definition: chvalid.h:172
#define xmlIsBaseCharQ(c)
Definition: chvalid.h:76

Referenced by xsltCompileLocationPathPattern(), and xsltCompileStepPattern().

◆ xsltSwapTopCompMatch()

static void xsltSwapTopCompMatch ( xsltCompMatchPtr  comp)
static

xsltSwapTopCompMatch: @comp: the compiled match expression

reverse the two top steps.

Definition at line 351 of file pattern.c.

351 {
352 int i;
353 int j = comp->nbStep - 1;
354
355 if (j > 0) {
356 register xmlChar *tmp;
357 register xsltOp op;
358 register xmlXPathCompExprPtr expr;
359 register int t;
360 i = j - 1;
361 tmp = comp->steps[i].value;
362 comp->steps[i].value = comp->steps[j].value;
363 comp->steps[j].value = tmp;
364 tmp = comp->steps[i].value2;
365 comp->steps[i].value2 = comp->steps[j].value2;
366 comp->steps[j].value2 = tmp;
367 tmp = comp->steps[i].value3;
368 comp->steps[i].value3 = comp->steps[j].value3;
369 comp->steps[j].value3 = tmp;
370 op = comp->steps[i].op;
371 comp->steps[i].op = comp->steps[j].op;
372 comp->steps[j].op = op;
373 expr = comp->steps[i].comp;
374 comp->steps[i].comp = comp->steps[j].comp;
375 comp->steps[j].comp = expr;
376 t = comp->steps[i].previousExtra;
377 comp->steps[i].previousExtra = comp->steps[j].previousExtra;
378 comp->steps[j].previousExtra = t;
379 t = comp->steps[i].indexExtra;
380 comp->steps[i].indexExtra = comp->steps[j].indexExtra;
381 comp->steps[j].indexExtra = t;
382 t = comp->steps[i].lenExtra;
383 comp->steps[i].lenExtra = comp->steps[j].lenExtra;
384 comp->steps[j].lenExtra = t;
385 }
386}

◆ xsltTestCompMatch()

static int xsltTestCompMatch ( xsltTransformContextPtr  ctxt,
xsltCompMatchPtr  comp,
xmlNodePtr  matchNode,
const xmlChar mode,
const xmlChar modeURI 
)
static

xsltTestCompMatch: @ctxt: a XSLT process context @comp: the precompiled pattern @node: a node @mode: the mode name or NULL @modeURI: the mode URI or NULL

Test whether the node matches the pattern

Returns 1 if it matches, 0 if it doesn't and -1 in case of failure

Definition at line 926 of file pattern.c.

928 {
929 int i;
930 int found = 0;
931 xmlNodePtr node = matchNode;
932 xmlNodePtr oldInst;
933 xsltStepOpPtr step, sel = NULL;
934 xsltStepStates states = {0, 0, NULL}; /* // may require backtrack */
935
936 if ((comp == NULL) || (node == NULL) || (ctxt == NULL)) {
938 "xsltTestCompMatch: null arg\n");
939 return(-1);
940 }
941 if (mode != NULL) {
942 if (comp->mode == NULL)
943 return(0);
944 /*
945 * both mode strings must be interned on the stylesheet dictionary
946 */
947 if (comp->mode != mode)
948 return(0);
949 } else {
950 if (comp->mode != NULL)
951 return(0);
952 }
953 if (modeURI != NULL) {
954 if (comp->modeURI == NULL)
955 return(0);
956 /*
957 * both modeURI strings must be interned on the stylesheet dictionary
958 */
959 if (comp->modeURI != modeURI)
960 return(0);
961 } else {
962 if (comp->modeURI != NULL)
963 return(0);
964 }
965
966 /* Some XPath functions rely on inst being set correctly. */
967 oldInst = ctxt->inst;
968 ctxt->inst = comp->node;
969
970 i = 0;
971restart:
972 for (;i < comp->nbStep;i++) {
973 step = &comp->steps[i];
974 if (step->op != XSLT_OP_PREDICATE)
975 sel = step;
976 switch (step->op) {
977 case XSLT_OP_END:
978 goto found;
979 case XSLT_OP_PARENT:
980 if ((node->type == XML_DOCUMENT_NODE) ||
981 (node->type == XML_HTML_DOCUMENT_NODE) ||
982#ifdef LIBXML_DOCB_ENABLED
983 (node->type == XML_DOCB_DOCUMENT_NODE) ||
984#endif
985 (node->type == XML_NAMESPACE_DECL))
986 goto rollback;
987 node = node->parent;
988 if (node == NULL)
989 goto rollback;
990 if (step->value == NULL)
991 continue;
992 if (step->value[0] != node->name[0])
993 goto rollback;
994 if (!xmlStrEqual(step->value, node->name))
995 goto rollback;
996 /* Namespace test */
997 if (node->ns == NULL) {
998 if (step->value2 != NULL)
999 goto rollback;
1000 } else if (node->ns->href != NULL) {
1001 if (step->value2 == NULL)
1002 goto rollback;
1003 if (!xmlStrEqual(step->value2, node->ns->href))
1004 goto rollback;
1005 }
1006 continue;
1007 case XSLT_OP_ANCESTOR:
1008 /* TODO: implement coalescing of ANCESTOR/NODE ops */
1009 if (step->value == NULL) {
1010 step = &comp->steps[i+1];
1011 if (step->op == XSLT_OP_ROOT)
1012 goto found;
1013 /* added NS, ID and KEY as a result of bug 168208 */
1014 if ((step->op != XSLT_OP_ELEM) &&
1015 (step->op != XSLT_OP_ALL) &&
1016 (step->op != XSLT_OP_NS) &&
1017 (step->op != XSLT_OP_ID) &&
1018 (step->op != XSLT_OP_KEY))
1019 goto rollback;
1020 }
1021 if (node == NULL)
1022 goto rollback;
1023 if ((node->type == XML_DOCUMENT_NODE) ||
1024 (node->type == XML_HTML_DOCUMENT_NODE) ||
1025#ifdef LIBXML_DOCB_ENABLED
1026 (node->type == XML_DOCB_DOCUMENT_NODE) ||
1027#endif
1028 (node->type == XML_NAMESPACE_DECL))
1029 goto rollback;
1030 node = node->parent;
1031 if ((step->op != XSLT_OP_ELEM) && step->op != XSLT_OP_ALL) {
1032 xsltPatPushState(ctxt, &states, i, node);
1033 continue;
1034 }
1035 i++;
1036 sel = step;
1037 if (step->value == NULL) {
1038 xsltPatPushState(ctxt, &states, i - 1, node);
1039 continue;
1040 }
1041 while (node != NULL) {
1042 if ((node->type == XML_ELEMENT_NODE) &&
1043 (step->value[0] == node->name[0]) &&
1044 (xmlStrEqual(step->value, node->name))) {
1045 /* Namespace test */
1046 if (node->ns == NULL) {
1047 if (step->value2 == NULL)
1048 break;
1049 } else if (node->ns->href != NULL) {
1050 if ((step->value2 != NULL) &&
1051 (xmlStrEqual(step->value2, node->ns->href)))
1052 break;
1053 }
1054 }
1055 node = node->parent;
1056 }
1057 if (node == NULL)
1058 goto rollback;
1059 xsltPatPushState(ctxt, &states, i - 1, node);
1060 continue;
1061 case XSLT_OP_PREDICATE: {
1062 /*
1063 * When there is cascading XSLT_OP_PREDICATE or a predicate
1064 * after an op which hasn't been optimized yet, then use a
1065 * direct computation approach. It's not done directly
1066 * at the beginning of the routine to filter out as much
1067 * as possible this costly computation.
1068 */
1069 if (comp->direct) {
1070 found = xsltTestCompMatchDirect(ctxt, comp, matchNode,
1071 comp->nsList, comp->nsNr);
1072 goto exit;
1073 }
1074
1075 if (!xsltTestPredicateMatch(ctxt, comp, node, step, sel))
1076 goto rollback;
1077
1078 break;
1079 }
1080 default:
1081 if (xsltTestStepMatch(ctxt, node, step) != 1)
1082 goto rollback;
1083 break;
1084 }
1085 }
1086found:
1087 found = 1;
1088exit:
1089 ctxt->inst = oldInst;
1090 if (states.states != NULL) {
1091 /* Free the rollback states */
1092 xmlFree(states.states);
1093 }
1094 return found;
1095rollback:
1096 /* got an error try to rollback */
1097 if (states.states == NULL || states.nbstates <= 0) {
1098 found = 0;
1099 goto exit;
1100 }
1101 states.nbstates--;
1102 i = states.states[states.nbstates].step;
1103 node = states.states[states.nbstates].node;
1104#if 0
1105 fprintf(stderr, "Pop: %d, %s\n", i, node->name);
1106#endif
1107 goto restart;
1108}
void restart(int argc, const char *argv[])
Definition: cmds.c:2115
_In_ fcb _In_ chunk _In_ uint64_t _In_ uint64_t _In_ bool _In_opt_ void _In_opt_ PIRP _In_ LIST_ENTRY * rollback
Definition: btrfs_drv.h:1365
static int xsltTestPredicateMatch(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, xmlNodePtr node, xsltStepOpPtr step, xsltStepOpPtr sel)
Definition: pattern.c:769
static int xsltTestCompMatchDirect(xsltTransformContextPtr ctxt, xsltCompMatchPtr comp, xmlNodePtr node, xmlNsPtr *nsList, int nsNr)
Definition: pattern.c:513
static int xsltPatPushState(xsltTransformContextPtr ctxt, xsltStepStates *states, int step, xmlNodePtr node)
Definition: pattern.c:465
static int xsltTestStepMatch(xsltTransformContextPtr ctxt, xmlNodePtr node, xsltStepOpPtr step)
Definition: pattern.c:621
#define XML_DOCB_DOCUMENT_NODE
Definition: tree.h:184
#define exit(n)
Definition: config.h:202
Definition: tree.h:489
xmlNodePtr node
Definition: pattern.c:88

Referenced by xsltGetTemplate(), and xsltTestCompMatchList().

◆ xsltTestCompMatchDirect()

static int xsltTestCompMatchDirect ( xsltTransformContextPtr  ctxt,
xsltCompMatchPtr  comp,
xmlNodePtr  node,
xmlNsPtr nsList,
int  nsNr 
)
static

xsltTestCompMatchDirect: @ctxt: a XSLT process context @comp: the precompiled pattern @node: a node @nsList: the namespaces in scope @nsNr: the number of namespaces in scope

Test whether the node matches the pattern, do a direct evalutation and not a step by step evaluation.

Returns 1 if it matches, 0 if it doesn't and -1 in case of failure

Definition at line 513 of file pattern.c.

514 {
515 xsltStepOpPtr sel = NULL;
516 xmlDocPtr prevdoc;
517 xmlDocPtr doc;
518 xmlXPathObjectPtr list;
519 int ix, j;
520 int nocache = 0;
521 int isRVT;
522
523 doc = node->doc;
524 if (XSLT_IS_RES_TREE_FRAG(doc))
525 isRVT = 1;
526 else
527 isRVT = 0;
528 sel = &comp->steps[0]; /* store extra in first step arbitrarily */
529
530 prevdoc = (xmlDocPtr)
532 ix = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival);
533 list = (xmlXPathObjectPtr)
535
536 if ((list == NULL) || (prevdoc != doc)) {
537 xmlXPathObjectPtr newlist;
538 xmlNodePtr parent = node->parent;
539 xmlDocPtr olddoc;
540 xmlNodePtr oldnode;
541 int oldNsNr, oldContextSize, oldProximityPosition;
542 xmlNsPtr *oldNamespaces;
543
544 oldnode = ctxt->xpathCtxt->node;
545 olddoc = ctxt->xpathCtxt->doc;
546 oldNsNr = ctxt->xpathCtxt->nsNr;
547 oldNamespaces = ctxt->xpathCtxt->namespaces;
548 oldContextSize = ctxt->xpathCtxt->contextSize;
549 oldProximityPosition = ctxt->xpathCtxt->proximityPosition;
550 ctxt->xpathCtxt->node = node;
551 ctxt->xpathCtxt->doc = doc;
552 ctxt->xpathCtxt->namespaces = nsList;
553 ctxt->xpathCtxt->nsNr = nsNr;
554 newlist = xmlXPathEval(comp->pattern, ctxt->xpathCtxt);
555 ctxt->xpathCtxt->node = oldnode;
556 ctxt->xpathCtxt->doc = olddoc;
557 ctxt->xpathCtxt->namespaces = oldNamespaces;
558 ctxt->xpathCtxt->nsNr = oldNsNr;
559 ctxt->xpathCtxt->contextSize = oldContextSize;
560 ctxt->xpathCtxt->proximityPosition = oldProximityPosition;
561 if (newlist == NULL)
562 return(-1);
563 if (newlist->type != XPATH_NODESET) {
564 xmlXPathFreeObject(newlist);
565 return(-1);
566 }
567 ix = 0;
568
569 if ((parent == NULL) || (node->doc == NULL) || isRVT)
570 nocache = 1;
571
572 if (nocache == 0) {
573 if (list != NULL)
574 xmlXPathFreeObject(list);
575 list = newlist;
576
577 XSLT_RUNTIME_EXTRA_LST(ctxt, sel->lenExtra) =
578 (void *) list;
580 (void *) doc;
581 XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) =
582 0;
585 } else
586 list = newlist;
587 }
588 if ((list->nodesetval == NULL) ||
589 (list->nodesetval->nodeNr <= 0)) {
590 if (nocache == 1)
591 xmlXPathFreeObject(list);
592 return(0);
593 }
594 /* TODO: store the index and use it for the scan */
595 if (ix == 0) {
596 for (j = 0;j < list->nodesetval->nodeNr;j++) {
597 if (list->nodesetval->nodeTab[j] == node) {
598 if (nocache == 1)
599 xmlXPathFreeObject(list);
600 return(1);
601 }
602 }
603 } else {
604 }
605 if (nocache == 1)
606 xmlXPathFreeObject(list);
607 return(0);
608}
static void xmlXPathFreeObjectWrapper(void *obj)
Definition: pattern.c:495
r parent
Definition: btrfs.c:3010
xmlXPathContextPtr xpathCtxt
#define XSLT_IS_RES_TREE_FRAG(n)
Definition: xsltInternals.h:56

Referenced by xsltTestCompMatch().

◆ xsltTestCompMatchList()

int xsltTestCompMatchList ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xsltCompMatchPtr  comp 
)

xsltTestCompMatchList: @ctxt: a XSLT process context @node: a node @comp: the precompiled pattern list

Test whether the node matches one of the patterns in the list

Returns 1 if it matches, 0 if it doesn't and -1 in case of failure

Definition at line 1121 of file pattern.c.

1122 {
1123 int ret;
1124
1125 if ((ctxt == NULL) || (node == NULL))
1126 return(-1);
1127 while (comp != NULL) {
1128 ret = xsltTestCompMatch(ctxt, comp, node, NULL, NULL);
1129 if (ret == 1)
1130 return(1);
1131 comp = comp->next;
1132 }
1133 return(0);
1134}

Referenced by xsltNumberFormatGetAnyLevel(), xsltNumberFormatGetMultipleLevel(), and xsltTestCompMatchCount().

◆ xsltTestPredicateMatch()

static int xsltTestPredicateMatch ( xsltTransformContextPtr  ctxt,
xsltCompMatchPtr  comp,
xmlNodePtr  node,
xsltStepOpPtr  step,
xsltStepOpPtr  sel 
)
static

xsltTestPredicateMatch: @ctxt: a XSLT process context @comp: the precompiled pattern @node: a node @step: the predicate step @sel: the previous step

Test whether the node matches the predicate

Returns 1 if it matches, 0 if it doesn't and -1 in case of failure

Definition at line 769 of file pattern.c.

771 {
772 xmlNodePtr oldNode;
773 xmlDocPtr doc;
774 int oldCS, oldCP;
775 int pos = 0, len = 0;
776 int isRVT;
777 int match;
778
779 if (step->value == NULL)
780 return(0);
781 if (step->comp == NULL)
782 return(0);
783 if (sel == NULL)
784 return(0);
785
786 doc = node->doc;
787 if (XSLT_IS_RES_TREE_FRAG(doc))
788 isRVT = 1;
789 else
790 isRVT = 0;
791
792 /*
793 * Recompute contextSize and proximityPosition.
794 *
795 * This could be improved in the following ways:
796 *
797 * - Skip recomputation if predicates don't use position() or last()
798 * - Keep data for multiple parents. This would require a hash table
799 * or an unused member in xmlNode.
800 * - Store node test results in a bitmap to avoid computing them twice.
801 */
802 oldCS = ctxt->xpathCtxt->contextSize;
803 oldCP = ctxt->xpathCtxt->proximityPosition;
804 {
805 xmlNodePtr previous;
806 int nocache = 0;
807
808 previous = (xmlNodePtr)
810 if ((previous != NULL) &&
811 (previous->parent == node->parent)) {
812 /*
813 * just walk back to adjust the index
814 */
815 int indx = 0;
816 xmlNodePtr sibling = node;
817
818 while (sibling != NULL) {
819 if (sibling == previous)
820 break;
821 if (xsltTestStepMatch(ctxt, sibling, sel))
822 indx++;
823 sibling = sibling->prev;
824 }
825 if (sibling == NULL) {
826 /* hum going backward in document order ... */
827 indx = 0;
828 sibling = node;
829 while (sibling != NULL) {
830 if (sibling == previous)
831 break;
832 if (xsltTestStepMatch(ctxt, sibling, sel))
833 indx--;
834 sibling = sibling->next;
835 }
836 }
837 if (sibling != NULL) {
838 pos = XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) + indx;
839 /*
840 * If the node is in a Value Tree we need to
841 * save len, but cannot cache the node!
842 * (bugs 153137 and 158840)
843 */
844 if (node->doc != NULL) {
845 len = XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival);
846 if (!isRVT) {
848 sel->previousExtra, ptr) = node;
849 XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = pos;
850 }
851 }
852 } else
853 pos = 0;
854 } else {
855 /*
856 * recompute the index
857 */
858 xmlNodePtr parent = node->parent;
859 xmlNodePtr siblings = NULL;
860
861 if (parent) siblings = parent->children;
862
863 while (siblings != NULL) {
864 if (siblings == node) {
865 len++;
866 pos = len;
867 } else if (xsltTestStepMatch(ctxt, siblings, sel)) {
868 len++;
869 }
870 siblings = siblings->next;
871 }
872 if ((parent == NULL) || (node->doc == NULL))
873 nocache = 1;
874 else {
875 while (parent->parent != NULL)
876 parent = parent->parent;
877 if (((parent->type != XML_DOCUMENT_NODE) &&
878 (parent->type != XML_HTML_DOCUMENT_NODE)) ||
879 (parent != (xmlNodePtr) node->doc))
880 nocache = 1;
881 }
882 }
883 if (pos != 0) {
884 ctxt->xpathCtxt->contextSize = len;
885 ctxt->xpathCtxt->proximityPosition = pos;
886 /*
887 * If the node is in a Value Tree we cannot
888 * cache it !
889 */
890 if ((!isRVT) && (node->doc != NULL) &&
891 (nocache == 0)) {
893 XSLT_RUNTIME_EXTRA(ctxt, sel->indexExtra, ival) = pos;
894 XSLT_RUNTIME_EXTRA(ctxt, sel->lenExtra, ival) = len;
895 }
896 }
897 }
898
899 oldNode = ctxt->node;
900 ctxt->node = node;
901
902 match = xsltEvalXPathPredicate(ctxt, step->comp, comp->nsList, comp->nsNr);
903
904 if (pos != 0) {
905 ctxt->xpathCtxt->contextSize = oldCS;
906 ctxt->xpathCtxt->proximityPosition = oldCP;
907 }
908 ctxt->node = oldNode;
909
910 return match;
911}
xmlNode * xmlNodePtr
Definition: tree.h:488
struct _xmlNode * next
Definition: tree.h:496
struct _xmlNode * parent
Definition: tree.h:495
struct _xmlNode * prev
Definition: tree.h:497
Definition: match.c:28
int xsltEvalXPathPredicate(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp, xmlNsPtr *nsList, int nsNr)
Definition: templates.c:39

Referenced by xsltTestCompMatch().

◆ xsltTestStepMatch()

static int xsltTestStepMatch ( xsltTransformContextPtr  ctxt,
xmlNodePtr  node,
xsltStepOpPtr  step 
)
static

xsltTestStepMatch: @ctxt: a XSLT process context @node: a node @step: the step

Test whether the node matches the step.

Returns 1 if it matches, 0 if it doesn't and -1 in case of failure

Definition at line 621 of file pattern.c.

622 {
623 switch (step->op) {
624 case XSLT_OP_ROOT:
625 if ((node->type == XML_DOCUMENT_NODE) ||
626#ifdef LIBXML_DOCB_ENABLED
627 (node->type == XML_DOCB_DOCUMENT_NODE) ||
628#endif
629 (node->type == XML_HTML_DOCUMENT_NODE))
630 return(1);
631 if ((node->type == XML_ELEMENT_NODE) && (node->name[0] == ' '))
632 return(1);
633 return(0);
634 case XSLT_OP_ELEM:
635 if (node->type != XML_ELEMENT_NODE)
636 return(0);
637 if (step->value == NULL)
638 return(1);
639 if (step->value[0] != node->name[0])
640 return(0);
641 if (!xmlStrEqual(step->value, node->name))
642 return(0);
643
644 /* Namespace test */
645 if (node->ns == NULL) {
646 if (step->value2 != NULL)
647 return(0);
648 } else if (node->ns->href != NULL) {
649 if (step->value2 == NULL)
650 return(0);
651 if (!xmlStrEqual(step->value2, node->ns->href))
652 return(0);
653 }
654 return(1);
655 case XSLT_OP_ATTR:
656 if (node->type != XML_ATTRIBUTE_NODE)
657 return(0);
658 if (step->value != NULL) {
659 if (step->value[0] != node->name[0])
660 return(0);
661 if (!xmlStrEqual(step->value, node->name))
662 return(0);
663 }
664 /* Namespace test */
665 if (node->ns == NULL) {
666 if (step->value2 != NULL)
667 return(0);
668 } else if (step->value2 != NULL) {
669 if (!xmlStrEqual(step->value2, node->ns->href))
670 return(0);
671 }
672 return(1);
673 case XSLT_OP_ID: {
674 /* TODO Handle IDs decently, must be done differently */
676
677 if (node->type != XML_ELEMENT_NODE)
678 return(0);
679
680 id = xmlGetID(node->doc, step->value);
681 if ((id == NULL) || (id->parent != node))
682 return(0);
683 break;
684 }
685 case XSLT_OP_KEY: {
686 xmlNodeSetPtr list;
687 int indx;
688
689 list = xsltGetKey(ctxt, step->value,
690 step->value3, step->value2);
691 if (list == NULL)
692 return(0);
693 for (indx = 0;indx < list->nodeNr;indx++)
694 if (list->nodeTab[indx] == node)
695 break;
696 if (indx >= list->nodeNr)
697 return(0);
698 break;
699 }
700 case XSLT_OP_NS:
701 if (node->type != XML_ELEMENT_NODE)
702 return(0);
703 if (node->ns == NULL) {
704 if (step->value != NULL)
705 return(0);
706 } else if (node->ns->href != NULL) {
707 if (step->value == NULL)
708 return(0);
709 if (!xmlStrEqual(step->value, node->ns->href))
710 return(0);
711 }
712 break;
713 case XSLT_OP_ALL:
714 if (node->type != XML_ELEMENT_NODE)
715 return(0);
716 break;
717 case XSLT_OP_PI:
718 if (node->type != XML_PI_NODE)
719 return(0);
720 if (step->value != NULL) {
721 if (!xmlStrEqual(step->value, node->name))
722 return(0);
723 }
724 break;
725 case XSLT_OP_COMMENT:
726 if (node->type != XML_COMMENT_NODE)
727 return(0);
728 break;
729 case XSLT_OP_TEXT:
730 if ((node->type != XML_TEXT_NODE) &&
731 (node->type != XML_CDATA_SECTION_NODE))
732 return(0);
733 break;
734 case XSLT_OP_NODE:
735 switch (node->type) {
736 case XML_ELEMENT_NODE:
738 case XML_PI_NODE:
739 case XML_COMMENT_NODE:
740 case XML_TEXT_NODE:
741 break;
742 default:
743 return(0);
744 }
745 break;
746 default:
748 "xsltTestStepMatch: unexpected step op %d\n",
749 step->op);
750 return(-1);
751 }
752
753 return(1);
754}
GLuint id
Definition: glext.h:5910
xmlNodeSetPtr xsltGetKey(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI, const xmlChar *value)
Definition: keys.c:417
XMLPUBFUN xmlAttrPtr XMLCALL xmlGetID(xmlDocPtr doc, const xmlChar *ID)
Definition: valid.c:2874

Referenced by xsltTestCompMatch(), and xsltTestPredicateMatch().