ReactOS  0.4.13-dev-651-g5dbc677
keys.c File Reference
#include "precomp.h"
Include dependency graph for keys.c:

Go to the source code of this file.

Functions

: the key name or NULL

xsltGetKey: @ctxt: an XSLT transformation context

@nameURI: the name URI or NULL @value: the key value to look for

Looks up a key of the in current source doc (the document info on @ctxt->document). Computes the key if not already done for the current source doc.

Returns the nodeset resulting from the query or NULL

static int xsltInitDocKeyTable (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI)
 
static xsltKeyDefPtr xsltNewKeyDef (const xmlChar *name, const xmlChar *nameURI)
 
static void xsltFreeKeyDef (xsltKeyDefPtr keyd)
 
static void xsltFreeKeyDefList (xsltKeyDefPtr keyd)
 
static xsltKeyTablePtr xsltNewKeyTable (const xmlChar *name, const xmlChar *nameURI)
 
static void xsltFreeNodeSetEntry (void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
 
static void xsltFreeKeyTable (xsltKeyTablePtr keyt)
 
static void xsltFreeKeyTableList (xsltKeyTablePtr keyt)
 
void xsltFreeKeys (xsltStylesheetPtr style)
 
static int skipString (const xmlChar *cur, int end)
 
static int skipPredicate (const xmlChar *cur, int end)
 
int xsltAddKey (xsltStylesheetPtr style, const xmlChar *name, const xmlChar *nameURI, const xmlChar *match, const xmlChar *use, xmlNodePtr inst)
 
xmlNodeSetPtr xsltGetKey (xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI, const xmlChar *value)
 
int xsltInitAllDocKeys (xsltTransformContextPtr ctxt)
 
int xsltInitCtxtKey (xsltTransformContextPtr ctxt, xsltDocumentPtr idoc, xsltKeyDefPtr keyDef)
 
void xsltInitCtxtKeys (xsltTransformContextPtr ctxt, xsltDocumentPtr idoc)
 
void xsltFreeDocumentKeys (xsltDocumentPtr idoc)
 

Function Documentation

◆ skipPredicate()

static int skipPredicate ( const xmlChar cur,
int  end 
)
static

skipPredicate: @cur: the current pointer @end: the current offset

skip a predicate

Returns the byte after the predicate or -1 in case of error

Definition at line 225 of file keys.c.

225  {
226  if ((cur == NULL) || (end < 0)) return(-1);
227  if (cur[end] != '[') return(end);
228  end++;
229  while (cur[end] != 0) {
230  if ((cur[end] == '\'') || (cur[end] == '"')) {
231  end = skipString(cur, end);
232  if (end <= 0)
233  return(-1);
234  continue;
235  } else if (cur[end] == '[') {
236  end = skipPredicate(cur, end);
237  if (end <= 0)
238  return(-1);
239  continue;
240  } else if (cur[end] == ']')
241  return(end + 1);
242  end++;
243  }
244  return(-1);
245 }
GLuint GLuint end
Definition: gl.h:1545
static int skipPredicate(const xmlChar *cur, int end)
Definition: keys.c:225
smooth NULL
Definition: ftsmooth.c:416
static int skipString(const xmlChar *cur, int end)
Definition: keys.c:200

Referenced by xsltAddKey().

◆ skipString()

static int skipString ( const xmlChar cur,
int  end 
)
static

skipString: @cur: the current pointer @end: the current offset

skip a string delimited by " or '

Returns the byte after the string or -1 in case of error

Definition at line 200 of file keys.c.

200  {
201  xmlChar limit;
202 
203  if ((cur == NULL) || (end < 0)) return(-1);
204  if ((cur[end] == '\'') || (cur[end] == '"')) limit = cur[end];
205  else return(end);
206  end++;
207  while (cur[end] != 0) {
208  if (cur[end] == limit)
209  return(end + 1);
210  end++;
211  }
212  return(-1);
213 }
GLuint GLuint end
Definition: gl.h:1545
GLint limit
Definition: glext.h:10326
smooth NULL
Definition: ftsmooth.c:416
unsigned char xmlChar
Definition: xmlstring.h:28

Referenced by skipPredicate().

◆ xsltAddKey()

int xsltAddKey ( xsltStylesheetPtr  style,
const xmlChar name,
const xmlChar nameURI,
const xmlChar match,
const xmlChar use,
xmlNodePtr  inst 
)

Definition at line 261 of file keys.c.

263  {
265  xmlChar *pattern = NULL;
266  int current, end, start, i = 0;
267 
268  if ((style == NULL) || (name == NULL) || (match == NULL) || (use == NULL))
269  return(-1);
270 
271 #ifdef WITH_XSLT_DEBUG_KEYS
273  "Add key %s, match %s, use %s\n", name, match, use);
274 #endif
275 
276  key = xsltNewKeyDef(name, nameURI);
277  key->match = xmlStrdup(match);
278  key->use = xmlStrdup(use);
279  key->inst = inst;
280  key->nsList = xmlGetNsList(inst->doc, inst);
281  if (key->nsList != NULL) {
282  while (key->nsList[i] != NULL)
283  i++;
284  }
285  key->nsNr = i;
286 
287  /*
288  * Split the | and register it as as many keys
289  */
290  current = end = 0;
291  while (match[current] != 0) {
292  start = current;
293  while (IS_BLANK_CH(match[current]))
294  current++;
295  end = current;
296  while ((match[end] != 0) && (match[end] != '|')) {
297  if (match[end] == '[') {
299  if (end <= 0) {
301  "xsl:key : 'match' pattern is malformed: %s",
302  key->match);
303  if (style != NULL) style->errors++;
304  goto error;
305  }
306  } else
307  end++;
308  }
309  if (current == end) {
311  "xsl:key : 'match' pattern is empty\n");
312  if (style != NULL) style->errors++;
313  goto error;
314  }
315  if (match[start] != '/') {
316  pattern = xmlStrcat(pattern, (xmlChar *)"//");
317  if (pattern == NULL) {
318  if (style != NULL) style->errors++;
319  goto error;
320  }
321  }
323  if (pattern == NULL) {
324  if (style != NULL) style->errors++;
325  goto error;
326  }
327 
328  if (match[end] == '|') {
329  pattern = xmlStrcat(pattern, (xmlChar *)"|");
330  end++;
331  }
332  current = end;
333  }
334  if (pattern == NULL) {
336  "xsl:key : 'match' pattern is empty\n");
337  if (style != NULL) style->errors++;
338  goto error;
339  }
340 #ifdef WITH_XSLT_DEBUG_KEYS
342  " resulting pattern %s\n", pattern);
343 #endif
344  /*
345  * XSLT-1: "It is an error for the value of either the use
346  * attribute or the match attribute to contain a
347  * VariableReference."
348  * TODO: We should report a variable-reference at compile-time.
349  * Maybe a search for "$", if it occurs outside of quotation
350  * marks, could be sufficient.
351  */
352 #ifdef XML_XPATH_NOVAR
353  key->comp = xsltXPathCompileFlags(style, pattern, XML_XPATH_NOVAR);
354 #else
355  key->comp = xsltXPathCompile(style, pattern);
356 #endif
357  if (key->comp == NULL) {
359  "xsl:key : 'match' pattern compilation failed '%s'\n",
360  pattern);
361  if (style != NULL) style->errors++;
362  }
363 #ifdef XML_XPATH_NOVAR
364  key->usecomp = xsltXPathCompileFlags(style, use, XML_XPATH_NOVAR);
365 #else
366  key->usecomp = xsltXPathCompile(style, use);
367 #endif
368  if (key->usecomp == NULL) {
370  "xsl:key : 'use' expression compilation failed '%s'\n",
371  use);
372  if (style != NULL) style->errors++;
373  }
374 
375  /*
376  * Sometimes the stylesheet writer use the order to ease the
377  * resolution of keys when they are dependant, keep the provided
378  * order so add the new one at the end.
379  */
380  if (style->keys == NULL) {
381  style->keys = key;
382  } else {
383  xsltKeyDefPtr prev = style->keys;
384 
385  while (prev->next != NULL)
386  prev = prev->next;
387 
388  prev->next = key;
389  }
390  key->next = NULL;
391  key = NULL;
392 
393 error:
394  if (pattern != NULL)
395  xmlFree(pattern);
396  if (key != NULL)
398  return(0);
399 }
#define error(str)
Definition: mkdosfs.c:1605
Definition: match.c:28
static xsltKeyDefPtr xsltNewKeyDef(const xmlChar *name, const xmlChar *nameURI)
Definition: keys.c:38
xmlXPathCompExprPtr xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str)
Definition: xsltutils.c:2327
GLuint GLuint end
Definition: gl.h:1545
struct _xmlDoc * doc
Definition: tree.h:498
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
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:526
#define IS_BLANK_CH(c)
static int skipPredicate(const xmlChar *cur, int end)
Definition: keys.c:225
smooth NULL
Definition: ftsmooth.c:416
void * xsltGenericDebugContext
Definition: xsltutils.c:549
XMLPUBFUN xmlChar *XMLCALL xmlStrncat(xmlChar *cur, const xmlChar *add, int len)
Definition: xmlstring.c:448
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
HKEY key
Definition: reg.c:42
unsigned char xmlChar
Definition: xmlstring.h:28
static void xsltFreeKeyDef(xsltKeyDefPtr keyd)
Definition: keys.c:63
GLuint start
Definition: gl.h:1545
struct _xsltKeyDef * next
xmlXPathCompExprPtr xsltXPathCompileFlags(xsltStylesheetPtr style, const xmlChar *str, int flags)
Definition: xsltutils.c:2262
Definition: name.c:36
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
Arabic default style
Definition: afstyles.h:93
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66
struct task_struct * current
Definition: linux.c:32
GLubyte * pattern
Definition: glext.h:7787
Definition: path.c:42

Referenced by xsltParseStylesheetKey().

◆ xsltFreeDocumentKeys()

void xsltFreeDocumentKeys ( xsltDocumentPtr  idoc)

xsltFreeDocumentKeys: @idoc: a XSLT document

Free the keys associated to a document

Definition at line 920 of file keys.c.

920  {
921  if (idoc != NULL)
922  xsltFreeKeyTableList(idoc->keys);
923 }
smooth NULL
Definition: ftsmooth.c:416
static void xsltFreeKeyTableList(xsltKeyTablePtr keyt)
Definition: keys.c:161

Referenced by xsltFreeDocuments(), xsltFreeRVTs(), xsltFreeStyleDocuments(), xsltReleaseRVT(), and xsltTransformCacheFree().

◆ xsltFreeKeyDef()

static void xsltFreeKeyDef ( xsltKeyDefPtr  keyd)
static

xsltFreeKeyDef: @keyd: an XSLT key definition

Free up the memory allocated by @keyd

Definition at line 63 of file keys.c.

63  {
64  if (keyd == NULL)
65  return;
66  if (keyd->comp != NULL)
67  xmlXPathFreeCompExpr(keyd->comp);
68  if (keyd->usecomp != NULL)
69  xmlXPathFreeCompExpr(keyd->usecomp);
70  if (keyd->name != NULL)
71  xmlFree(keyd->name);
72  if (keyd->nameURI != NULL)
73  xmlFree(keyd->nameURI);
74  if (keyd->match != NULL)
75  xmlFree(keyd->match);
76  if (keyd->use != NULL)
77  xmlFree(keyd->use);
78  if (keyd->nsList != NULL)
79  xmlFree(keyd->nsList);
80  memset(keyd, -1, sizeof(xsltKeyDef));
81  xmlFree(keyd);
82 }
xmlNsPtr * nsList
xmlXPathCompExprPtr usecomp
xmlChar * use
smooth NULL
Definition: ftsmooth.c:416
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
xmlChar * match
xmlChar * nameURI
xmlChar * name
#define memset(x, y, z)
Definition: compat.h:39
xmlXPathCompExprPtr comp

Referenced by xsltAddKey(), and xsltFreeKeyDefList().

◆ xsltFreeKeyDefList()

static void xsltFreeKeyDefList ( xsltKeyDefPtr  keyd)
static

xsltFreeKeyDefList: @keyd: an XSLT key definition list

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

Definition at line 91 of file keys.c.

91  {
92  xsltKeyDefPtr cur;
93 
94  while (keyd != NULL) {
95  cur = keyd;
96  keyd = keyd->next;
97  xsltFreeKeyDef(cur);
98  }
99 }
smooth NULL
Definition: ftsmooth.c:416
static void xsltFreeKeyDef(xsltKeyDefPtr keyd)
Definition: keys.c:63
struct _xsltKeyDef * next

Referenced by xsltFreeKeys().

◆ xsltFreeKeys()

void xsltFreeKeys ( xsltStylesheetPtr  style)

xsltFreeKeys: @style: an XSLT stylesheet

Free up the memory used by XSLT keys in a stylesheet

Definition at line 185 of file keys.c.

185  {
186  if (style->keys)
188 }
static void xsltFreeKeyDefList(xsltKeyDefPtr keyd)
Definition: keys.c:91
Arabic default style
Definition: afstyles.h:93

Referenced by xsltFreeStylesheet().

◆ xsltFreeKeyTable()

static void xsltFreeKeyTable ( xsltKeyTablePtr  keyt)
static

xsltFreeKeyTable: @keyt: an XSLT key table

Free up the memory allocated by @keyt

Definition at line 141 of file keys.c.

141  {
142  if (keyt == NULL)
143  return;
144  if (keyt->name != NULL)
145  xmlFree(keyt->name);
146  if (keyt->nameURI != NULL)
147  xmlFree(keyt->nameURI);
148  if (keyt->keys != NULL)
150  memset(keyt, -1, sizeof(xsltKeyTable));
151  xmlFree(keyt);
152 }
XMLPUBFUN void XMLCALL xmlHashFree(xmlHashTablePtr table, xmlHashDeallocator f)
Definition: hash.c:320
xmlHashTablePtr keys
smooth NULL
Definition: ftsmooth.c:416
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
xmlChar * name
static void xsltFreeNodeSetEntry(void *payload, const xmlChar *name ATTRIBUTE_UNUSED)
Definition: keys.c:130
#define memset(x, y, z)
Definition: compat.h:39
xmlChar * nameURI

Referenced by xsltFreeKeyTableList().

◆ xsltFreeKeyTableList()

static void xsltFreeKeyTableList ( xsltKeyTablePtr  keyt)
static

xsltFreeKeyTableList: @keyt: an XSLT key table list

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

Definition at line 161 of file keys.c.

161  {
162  xsltKeyTablePtr cur;
163 
164  while (keyt != NULL) {
165  cur = keyt;
166  keyt = keyt->next;
167  xsltFreeKeyTable(cur);
168  }
169 }
struct _xsltKeyTable * next
smooth NULL
Definition: ftsmooth.c:416
static void xsltFreeKeyTable(xsltKeyTablePtr keyt)
Definition: keys.c:141

Referenced by xsltFreeDocumentKeys().

◆ xsltFreeNodeSetEntry()

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

Definition at line 130 of file keys.c.

130  {
131  xmlXPathFreeNodeSet((xmlNodeSetPtr) payload);
132 }

Referenced by xsltFreeKeyTable().

◆ xsltGetKey()

xmlNodeSetPtr xsltGetKey ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar nameURI,
const xmlChar value 
)

Definition at line 415 of file keys.c.

416  {
417  xmlNodeSetPtr ret;
419  int init_table = 0;
420 
421  if ((ctxt == NULL) || (name == NULL) || (value == NULL) ||
422  (ctxt->document == NULL))
423  return(NULL);
424 
425 #ifdef WITH_XSLT_DEBUG_KEYS
427  "Get key %s, value %s\n", name, value);
428 #endif
429 
430  /*
431  * keys are computed only on-demand on first key access for a document
432  */
433  if ((ctxt->document->nbKeysComputed < ctxt->nbKeys) &&
434  (ctxt->keyInitLevel == 0)) {
435  /*
436  * If non-recursive behaviour, just try to initialize all keys
437  */
438  if (xsltInitAllDocKeys(ctxt))
439  return(NULL);
440  }
441 
442 retry:
443  table = (xsltKeyTablePtr) ctxt->document->keys;
444  while (table != NULL) {
445  if (((nameURI != NULL) == (table->nameURI != NULL)) &&
446  xmlStrEqual(table->name, name) &&
447  xmlStrEqual(table->nameURI, nameURI))
448  {
449  ret = (xmlNodeSetPtr)xmlHashLookup(table->keys, value);
450  return(ret);
451  }
452  table = table->next;
453  }
454 
455  if ((ctxt->keyInitLevel != 0) && (init_table == 0)) {
456  /*
457  * Apparently one key is recursive and this one is needed,
458  * initialize just it, that time and retry
459  */
460  xsltInitDocKeyTable(ctxt, name, nameURI);
461  init_table = 1;
462  goto retry;
463  }
464 
465  return(NULL);
466 }
static int xsltInitDocKeyTable(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI)
Definition: keys.c:477
const WCHAR * name
xsltKeyTable * xsltKeyTablePtr
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
while(1)
Definition: macro.lex.yy.c:740
smooth NULL
Definition: ftsmooth.c:416
xsltDocumentPtr document
void * xsltGenericDebugContext
Definition: xsltutils.c:549
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
int ret
int xsltInitAllDocKeys(xsltTransformContextPtr ctxt)
Definition: keys.c:533
Definition: name.c:36
XMLPUBFUN void *XMLCALL xmlHashLookup(xmlHashTablePtr table, const xmlChar *name)
Definition: hash.c:459
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157

Referenced by xsltKeyFunction(), and xsltTestCompMatch().

◆ xsltInitAllDocKeys()

int xsltInitAllDocKeys ( xsltTransformContextPtr  ctxt)

xsltInitAllDocKeys: @ctxt: transformation context

INTERNAL ROUTINE ONLY

Check if any keys on the current document need to be computed

Returns 0 in case of success, -1 in case of failure

Definition at line 533 of file keys.c.

534 {
536  xsltKeyDefPtr keyd;
538 
539  if (ctxt == NULL)
540  return(-1);
541 
542 #ifdef KEY_INIT_DEBUG
543 fprintf(stderr, "xsltInitAllDocKeys %d %d\n",
544  ctxt->document->nbKeysComputed, ctxt->nbKeys);
545 #endif
546 
547  if (ctxt->document->nbKeysComputed == ctxt->nbKeys)
548  return(0);
549 
550 
551  /*
552  * TODO: This could be further optimized
553  */
554  style = ctxt->style;
555  while (style) {
556  keyd = (xsltKeyDefPtr) style->keys;
557  while (keyd != NULL) {
558 #ifdef KEY_INIT_DEBUG
559 fprintf(stderr, "Init key %s\n", keyd->name);
560 #endif
561  /*
562  * Check if keys with this QName have been already
563  * computed.
564  */
565  table = (xsltKeyTablePtr) ctxt->document->keys;
566  while (table) {
567  if (((keyd->nameURI != NULL) == (table->nameURI != NULL)) &&
568  xmlStrEqual(keyd->name, table->name) &&
569  xmlStrEqual(keyd->nameURI, table->nameURI))
570  {
571  break;
572  }
573  table = table->next;
574  }
575  if (table == NULL) {
576  /*
577  * Keys with this QName have not been yet computed.
578  */
579  xsltInitDocKeyTable(ctxt, keyd->name, keyd->nameURI);
580  }
581  keyd = keyd->next;
582  }
584  }
585 #ifdef KEY_INIT_DEBUG
586 fprintf(stderr, "xsltInitAllDocKeys: done\n");
587 #endif
588  return(0);
589 }
static int xsltInitDocKeyTable(xsltTransformContextPtr ctxt, const xmlChar *name, const xmlChar *nameURI)
Definition: keys.c:477
const WCHAR * name
xsltKeyTable * xsltKeyTablePtr
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:250
xsltKeyDef * xsltKeyDefPtr
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
while(1)
Definition: macro.lex.yy.c:740
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
smooth NULL
Definition: ftsmooth.c:416
xsltDocumentPtr document
xmlChar * nameURI
xsltStylesheetPtr style
xmlChar * name
struct _xsltKeyDef * next
FILE * stderr
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
Arabic default style
Definition: afstyles.h:93

Referenced by xsltComputeAllKeys(), and xsltGetKey().

◆ xsltInitCtxtKey()

int xsltInitCtxtKey ( xsltTransformContextPtr  ctxt,
xsltDocumentPtr  idoc,
xsltKeyDefPtr  keyDef 
)

xsltInitCtxtKey: @ctxt: an XSLT transformation context @idoc: the document information (holds key values) @keyDef: the key definition

Computes the key tables this key and for the current input document.

Returns: 0 on success, -1 on error

Multiple key definitions for the same name are allowed, so we must check if the key is already present for this doc

If the key was not previously defined, create it now and chain it to the list of keys for the doc

Definition at line 602 of file keys.c.

604 {
605  int i, len, k;
606  xmlNodeSetPtr matchList = NULL, keylist;
607  xmlXPathObjectPtr matchRes = NULL, useRes = NULL;
608  xmlChar *str = NULL;
610  xmlNodePtr oldInst, cur;
611  xmlNodePtr oldContextNode;
612  xsltDocumentPtr oldDocInfo;
613  int oldXPPos, oldXPSize;
614  xmlDocPtr oldXPDoc;
615  int oldXPNsNr;
616  xmlNsPtr *oldXPNamespaces;
617  xmlXPathContextPtr xpctxt;
618 
619 #ifdef KEY_INIT_DEBUG
620 fprintf(stderr, "xsltInitCtxtKey %s : %d\n", keyDef->name, ctxt->keyInitLevel);
621 #endif
622 
623  if ((keyDef->comp == NULL) || (keyDef->usecomp == NULL))
624  return(-1);
625 
626  /*
627  * Detect recursive keys
628  */
629  if (ctxt->keyInitLevel > ctxt->nbKeys) {
630 #ifdef WITH_XSLT_DEBUG_KEYS
633  "xsltInitCtxtKey: key definition of %s is recursive\n",
634  keyDef->name));
635 #endif
636  xsltTransformError(ctxt, NULL, keyDef->inst,
637  "Key definition for %s is recursive\n", keyDef->name);
638  ctxt->state = XSLT_STATE_STOPPED;
639  return(-1);
640  }
641  ctxt->keyInitLevel++;
642 
643  xpctxt = ctxt->xpathCtxt;
644  idoc->nbKeysComputed++;
645  /*
646  * Save context state.
647  */
648  oldInst = ctxt->inst;
649  oldDocInfo = ctxt->document;
650  oldContextNode = ctxt->node;
651 
652  oldXPDoc = xpctxt->doc;
653  oldXPPos = xpctxt->proximityPosition;
654  oldXPSize = xpctxt->contextSize;
655  oldXPNsNr = xpctxt->nsNr;
656  oldXPNamespaces = xpctxt->namespaces;
657 
658  /*
659  * Set up contexts.
660  */
661  ctxt->document = idoc;
662  ctxt->node = (xmlNodePtr) idoc->doc;
663  ctxt->inst = keyDef->inst;
664 
665  xpctxt->doc = idoc->doc;
666  xpctxt->node = (xmlNodePtr) idoc->doc;
667  /* TODO : clarify the use of namespaces in keys evaluation */
668  xpctxt->namespaces = keyDef->nsList;
669  xpctxt->nsNr = keyDef->nsNr;
670 
671  /*
672  * Evaluate the 'match' expression of the xsl:key.
673  * TODO: The 'match' is a *pattern*.
674  */
675  matchRes = xmlXPathCompiledEval(keyDef->comp, xpctxt);
676  if (matchRes == NULL) {
677 
678 #ifdef WITH_XSLT_DEBUG_KEYS
680  "xsltInitCtxtKey: %s evaluation failed\n", keyDef->match));
681 #endif
682  xsltTransformError(ctxt, NULL, keyDef->inst,
683  "Failed to evaluate the 'match' expression.\n");
684  ctxt->state = XSLT_STATE_STOPPED;
685  goto error;
686  } else {
687  if (matchRes->type == XPATH_NODESET) {
688  matchList = matchRes->nodesetval;
689 
690 #ifdef WITH_XSLT_DEBUG_KEYS
691  if (matchList != NULL)
693  "xsltInitCtxtKey: %s evaluates to %d nodes\n",
694  keyDef->match, matchList->nodeNr));
695 #endif
696  } else {
697  /*
698  * Is not a node set, but must be.
699  */
700 #ifdef WITH_XSLT_DEBUG_KEYS
702  "xsltInitCtxtKey: %s is not a node set\n", keyDef->match));
703 #endif
704  xsltTransformError(ctxt, NULL, keyDef->inst,
705  "The 'match' expression did not evaluate to a node set.\n");
706  ctxt->state = XSLT_STATE_STOPPED;
707  goto error;
708  }
709  }
710  if ((matchList == NULL) || (matchList->nodeNr <= 0))
711  goto exit;
712 
717  table = (xsltKeyTablePtr) idoc->keys;
718  while (table != NULL) {
719  if (xmlStrEqual(table->name, keyDef->name) &&
720  (((keyDef->nameURI == NULL) && (table->nameURI == NULL)) ||
721  ((keyDef->nameURI != NULL) && (table->nameURI != NULL) &&
722  (xmlStrEqual(table->nameURI, keyDef->nameURI)))))
723  break;
724  table = table->next;
725  }
730  if (table == NULL) {
731  table = xsltNewKeyTable(keyDef->name, keyDef->nameURI);
732  if (table == NULL)
733  goto error;
734  table->next = idoc->keys;
735  idoc->keys = table;
736  }
737 
738  /*
739  * SPEC XSLT 1.0 (XSLT 2.0 does not clarify the context size!)
740  * "...the use attribute of the xsl:key element is evaluated with x as
741  " the current node and with a node list containing just x as the
742  * current node list"
743  */
744  xpctxt->contextSize = 1;
745  xpctxt->proximityPosition = 1;
746 
747  for (i = 0; i < matchList->nodeNr; i++) {
748  cur = matchList->nodeTab[i];
749  if (! IS_XSLT_REAL_NODE(cur))
750  continue;
751  ctxt->node = cur;
752  xpctxt->node = cur;
753  /*
754  * Process the 'use' of the xsl:key.
755  * SPEC XSLT 1.0:
756  * "The use attribute is an expression specifying the values of
757  * the key; the expression is evaluated once for each node that
758  * matches the pattern."
759  */
760  if (useRes != NULL)
761  xmlXPathFreeObject(useRes);
762  useRes = xmlXPathCompiledEval(keyDef->usecomp, xpctxt);
763  if (useRes == NULL) {
764  xsltTransformError(ctxt, NULL, keyDef->inst,
765  "Failed to evaluate the 'use' expression.\n");
766  ctxt->state = XSLT_STATE_STOPPED;
767  break;
768  }
769  if (useRes->type == XPATH_NODESET) {
770  if ((useRes->nodesetval != NULL) &&
771  (useRes->nodesetval->nodeNr != 0))
772  {
773  len = useRes->nodesetval->nodeNr;
774  str = xmlXPathCastNodeToString(useRes->nodesetval->nodeTab[0]);
775  } else {
776  continue;
777  }
778  } else {
779  len = 1;
780  if (useRes->type == XPATH_STRING) {
781  /*
782  * Consume the string value.
783  */
784  str = useRes->stringval;
785  useRes->stringval = NULL;
786  } else {
787  str = xmlXPathCastToString(useRes);
788  }
789  }
790  /*
791  * Process all strings.
792  */
793  k = 0;
794  while (1) {
795  if (str == NULL)
796  goto next_string;
797 
798 #ifdef WITH_XSLT_DEBUG_KEYS
800  "xsl:key : node associated to ('%s', '%s')\n", keyDef->name, str));
801 #endif
802 
803  keylist = xmlHashLookup(table->keys, str);
804  if (keylist == NULL) {
805  keylist = xmlXPathNodeSetCreate(cur);
806  if (keylist == NULL)
807  goto error;
808  xmlHashAddEntry(table->keys, str, keylist);
809  } else {
810  /*
811  * TODO: How do we know if this function failed?
812  */
813  xmlXPathNodeSetAdd(keylist, cur);
814  }
815  switch (cur->type) {
816  case XML_ELEMENT_NODE:
817  case XML_TEXT_NODE:
819  case XML_PI_NODE:
820  case XML_COMMENT_NODE:
821  cur->psvi = keyDef;
822  break;
823  case XML_ATTRIBUTE_NODE:
824  ((xmlAttrPtr) cur)->psvi = keyDef;
825  break;
826  case XML_DOCUMENT_NODE:
828  ((xmlDocPtr) cur)->psvi = keyDef;
829  break;
830  default:
831  break;
832  }
833  xmlFree(str);
834  str = NULL;
835 
836 next_string:
837  k++;
838  if (k >= len)
839  break;
840  str = xmlXPathCastNodeToString(useRes->nodesetval->nodeTab[k]);
841  }
842  }
843 
844 exit:
845 error:
846  ctxt->keyInitLevel--;
847  /*
848  * Restore context state.
849  */
850  xpctxt->doc = oldXPDoc;
851  xpctxt->nsNr = oldXPNsNr;
852  xpctxt->namespaces = oldXPNamespaces;
853  xpctxt->proximityPosition = oldXPPos;
854  xpctxt->contextSize = oldXPSize;
855 
856  ctxt->node = oldContextNode;
857  ctxt->document = oldDocInfo;
858  ctxt->inst = oldInst;
859 
860  if (str)
861  xmlFree(str);
862  if (useRes != NULL)
863  xmlXPathFreeObject(useRes);
864  if (matchRes != NULL)
865  xmlXPathFreeObject(matchRes);
866  return(0);
867 }
void * psvi
Definition: tree.h:505
const WCHAR * name
#define error(str)
Definition: mkdosfs.c:1605
xmlNsPtr * nsList
xsltKeyTable * xsltKeyTablePtr
xmlXPathCompExprPtr usecomp
Definition: tree.h:389
GLenum GLsizei GLenum GLenum const GLvoid * table
Definition: glext.h:5644
XMLPUBFUN int XMLCALL xmlHashAddEntry(xmlHashTablePtr table, const xmlChar *name, void *userdata)
Definition: hash.c:387
xmlDocPtr doc
struct _xmlDoc * doc
Definition: tree.h:498
struct _xmlDoc * doc
Definition: tree.h:560
while(1)
Definition: macro.lex.yy.c:740
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
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
xsltTransformState state
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
xmlNode * xmlNodePtr
Definition: tree.h:488
xsltDocumentPtr document
xmlXPathContextPtr xpathCtxt
void * xsltGenericDebugContext
Definition: xsltutils.c:549
#define IS_XSLT_REAL_NODE(n)
Definition: xsltutils.h:71
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:250
xmlChar * match
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
Definition: tree.h:489
xmlAttr * xmlAttrPtr
Definition: tree.h:433
unsigned char xmlChar
Definition: xmlstring.h:28
GLenum GLsizei len
Definition: glext.h:6722
#define XSLT_TRACE(ctxt, code, call)
Definition: xsltutils.h:128
xmlChar * nameURI
xmlElementType type
Definition: tree.h:491
xmlDoc * xmlDocPtr
Definition: tree.h:550
static xsltKeyTablePtr xsltNewKeyTable(const xmlChar *name, const xmlChar *nameURI)
Definition: keys.c:111
xmlChar * name
Definition: tree.h:551
FILE * stderr
XMLPUBFUN void *XMLCALL xmlHashLookup(xmlHashTablePtr table, const xmlChar *name)
Definition: hash.c:459
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
void exit(int exitcode)
Definition: _exit.c:33
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
xmlXPathCompExprPtr comp
int k
Definition: mpi.c:3369
Definition: path.c:35
xmlNodePtr inst

Referenced by xsltInitCtxtKeys(), and xsltInitDocKeyTable().

◆ xsltInitCtxtKeys()

void xsltInitCtxtKeys ( xsltTransformContextPtr  ctxt,
xsltDocumentPtr  idoc 
)

xsltInitCtxtKeys: @ctxt: an XSLT transformation context @idoc: a document info

Computes all the keys tables for the current input document. Should be done before global varibales are initialized. NOTE: Not used anymore in the refactored code.

Definition at line 879 of file keys.c.

879  {
881  xsltKeyDefPtr keyDef;
882 
883  if ((ctxt == NULL) || (idoc == NULL))
884  return;
885 
886 #ifdef KEY_INIT_DEBUG
887 fprintf(stderr, "xsltInitCtxtKeys on document\n");
888 #endif
889 
890 #ifdef WITH_XSLT_DEBUG_KEYS
891  if ((idoc->doc != NULL) && (idoc->doc->URL != NULL))
892  XSLT_TRACE(ctxt,XSLT_TRACE_KEYS,xsltGenericDebug(xsltGenericDebugContext, "Initializing keys on %s\n",
893  idoc->doc->URL));
894 #endif
895  style = ctxt->style;
896  while (style != NULL) {
897  keyDef = (xsltKeyDefPtr) style->keys;
898  while (keyDef != NULL) {
899  xsltInitCtxtKey(ctxt, idoc, keyDef);
900 
901  keyDef = keyDef->next;
902  }
903 
905  }
906 
907 #ifdef KEY_INIT_DEBUG
908 fprintf(stderr, "xsltInitCtxtKeys on document: done\n");
909 #endif
910 
911 }
const xmlChar * URL
Definition: tree.h:577
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:250
xsltKeyDef * xsltKeyDefPtr
int xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr idoc, xsltKeyDefPtr keyDef)
Definition: keys.c:602
xmlDocPtr doc
while(1)
Definition: macro.lex.yy.c:740
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
smooth NULL
Definition: ftsmooth.c:416
void * xsltGenericDebugContext
Definition: xsltutils.c:549
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
#define XSLT_TRACE(ctxt, code, call)
Definition: xsltutils.h:128
xsltStylesheetPtr style
struct _xsltKeyDef * next
FILE * stderr
Arabic default style
Definition: afstyles.h:93

◆ xsltInitDocKeyTable()

static int xsltInitDocKeyTable ( xsltTransformContextPtr  ctxt,
const xmlChar name,
const xmlChar nameURI 
)
static

xsltInitDocKeyTable:

INTERNAL ROUTINE ONLY

Check if any keys on the current document need to be computed

Definition at line 477 of file keys.c.

479 {
481  xsltKeyDefPtr keyd = NULL;
482  int found = 0;
483 
484 #ifdef KEY_INIT_DEBUG
485 fprintf(stderr, "xsltInitDocKeyTable %s\n", name);
486 #endif
487 
488  style = ctxt->style;
489  while (style != NULL) {
490  keyd = (xsltKeyDefPtr) style->keys;
491  while (keyd != NULL) {
492  if (((keyd->nameURI != NULL) ==
493  (nameURI != NULL)) &&
494  xmlStrEqual(keyd->name, name) &&
495  xmlStrEqual(keyd->nameURI, nameURI))
496  {
497  xsltInitCtxtKey(ctxt, ctxt->document, keyd);
498  if (ctxt->document->nbKeysComputed == ctxt->nbKeys)
499  return(0);
500  found = 1;
501  }
502  keyd = keyd->next;
503  }
505  }
506  if (found == 0) {
507 #ifdef WITH_XSLT_DEBUG_KEYS
509  "xsltInitDocKeyTable: did not found %s\n", name));
510 #endif
511  xsltTransformError(ctxt, NULL, keyd? keyd->inst : NULL,
512  "Failed to find key definition for %s\n", name);
513  ctxt->state = XSLT_STATE_STOPPED;
514  return(-1);
515  }
516 #ifdef KEY_INIT_DEBUG
517 fprintf(stderr, "xsltInitDocKeyTable %s done\n", name);
518 #endif
519  return(0);
520 }
xsltStylesheetPtr xsltNextImport(xsltStylesheetPtr cur)
Definition: imports.c:250
xsltKeyDef * xsltKeyDefPtr
int xsltInitCtxtKey(xsltTransformContextPtr ctxt, xsltDocumentPtr idoc, xsltKeyDefPtr keyDef)
Definition: keys.c:602
while(1)
Definition: macro.lex.yy.c:740
_Check_return_opt_ _CRTIMP int __cdecl fprintf(_Inout_ FILE *_File, _In_z_ _Printf_format_string_ const char *_Format,...)
xsltTransformState state
smooth NULL
Definition: ftsmooth.c:416
xsltDocumentPtr document
void * xsltGenericDebugContext
Definition: xsltutils.c:549
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
#define XSLT_TRACE(ctxt, code, call)
Definition: xsltutils.h:128
xmlChar * nameURI
xsltStylesheetPtr style
xmlChar * name
struct _xsltKeyDef * next
Definition: name.c:36
FILE * stderr
XMLPUBFUN int XMLCALL xmlStrEqual(const xmlChar *str1, const xmlChar *str2)
Definition: xmlstring.c:157
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
Arabic default style
Definition: afstyles.h:93
xmlNodePtr inst

Referenced by xsltGetKey(), and xsltInitAllDocKeys().

◆ xsltNewKeyDef()

static xsltKeyDefPtr xsltNewKeyDef ( const xmlChar name,
const xmlChar nameURI 
)
static

Definition at line 38 of file keys.c.

38  {
39  xsltKeyDefPtr cur;
40 
41  cur = (xsltKeyDefPtr) xmlMalloc(sizeof(xsltKeyDef));
42  if (cur == NULL) {
44  "xsltNewKeyDef : malloc failed\n");
45  return(NULL);
46  }
47  memset(cur, 0, sizeof(xsltKeyDef));
48  if (name != NULL)
49  cur->name = xmlStrdup(name);
50  if (nameURI != NULL)
51  cur->nameURI = xmlStrdup(nameURI);
52  cur->nsList = NULL;
53  return(cur);
54 }
xmlNsPtr * nsList
xsltKeyDef * xsltKeyDefPtr
smooth NULL
Definition: ftsmooth.c:416
xmlChar * nameURI
xmlChar * name
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:247
Definition: name.c:36
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
#define memset(x, y, z)
Definition: compat.h:39
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66

Referenced by xsltAddKey().

◆ xsltNewKeyTable()

static xsltKeyTablePtr xsltNewKeyTable ( const xmlChar name,
const xmlChar nameURI 
)
static

Definition at line 111 of file keys.c.

111  {
112  xsltKeyTablePtr cur;
113 
114  cur = (xsltKeyTablePtr) xmlMalloc(sizeof(xsltKeyTable));
115  if (cur == NULL) {
117  "xsltNewKeyTable : malloc failed\n");
118  return(NULL);
119  }
120  memset(cur, 0, sizeof(xsltKeyTable));
121  if (name != NULL)
122  cur->name = xmlStrdup(name);
123  if (nameURI != NULL)
124  cur->nameURI = xmlStrdup(nameURI);
125  cur->keys = xmlHashCreate(0);
126  return(cur);
127 }
xsltKeyTable * xsltKeyTablePtr
xmlHashTablePtr keys
smooth NULL
Definition: ftsmooth.c:416
XMLPUBFUN xmlHashTablePtr XMLCALL xmlHashCreate(int size)
Definition: hash.c:174
xmlChar * name
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:247
Definition: name.c:36
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
#define memset(x, y, z)
Definition: compat.h:39
xmlChar * nameURI
XMLPUBFUN xmlChar *XMLCALL xmlStrdup(const xmlChar *cur)
Definition: xmlstring.c:66

Referenced by xsltInitCtxtKey().