ReactOS  0.4.14-dev-315-gbb6fece
attrvt.c
Go to the documentation of this file.
1 /*
2  * attrvt.c: Implementation of the XSL Transformation 1.0 engine
3  * attribute value template handling part.
4  *
5  * References:
6  * http://www.w3.org/TR/1999/REC-xslt-19991116
7  *
8  * Michael Kay "XSLT Programmer's Reference" pp 637-643
9  * Writing Multiple Output Files
10  *
11  * See Copyright for the status of this software.
12  *
13  * daniel@veillard.com
14  */
15 
16 #include "precomp.h"
17 
18 #ifdef WITH_XSLT_DEBUG
19 #define WITH_XSLT_DEBUG_AVT
20 #endif
21 
22 #define MAX_AVT_SEG 10
23 
24 typedef struct _xsltAttrVT xsltAttrVT;
26 struct _xsltAttrVT {
27  struct _xsltAttrVT *next; /* next xsltAttrVT */
28  int nb_seg; /* Number of segments */
29  int max_seg; /* max capacity before re-alloc needed */
30  int strstart; /* is the start a string */
31  /*
32  * the namespaces in scope
33  */
35  int nsNr;
36  /*
37  * the content is an alternate of string and xmlXPathCompExprPtr
38  */
40 };
41 
50 static xsltAttrVTPtr
52  xsltAttrVTPtr cur;
53 
54  cur = (xsltAttrVTPtr) xmlMalloc(sizeof(xsltAttrVT));
55  if (cur == NULL) {
57  "xsltNewAttrVTPtr : malloc failed\n");
58  if (style != NULL) style->errors++;
59  return(NULL);
60  }
61  memset(cur, 0, sizeof(xsltAttrVT));
62 
63  cur->nb_seg = 0;
64  cur->max_seg = MAX_AVT_SEG;
65  cur->strstart = 0;
66  cur->next = style->attVTs;
67  /*
68  * Note: this pointer may be changed by a re-alloc within xsltCompileAttr,
69  * so that code may change the stylesheet pointer also!
70  */
71  style->attVTs = (xsltAttrVTPtr) cur;
72 
73  return(cur);
74 }
75 
82 static void
84  int i;
85 
86  if (avt == NULL) return;
87 
88  if (avt->strstart == 1) {
89  for (i = 0;i < avt->nb_seg; i += 2)
90  if (avt->segments[i] != NULL)
91  xmlFree((xmlChar *) avt->segments[i]);
92  for (i = 1;i < avt->nb_seg; i += 2)
93  xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
94  } else {
95  for (i = 0;i < avt->nb_seg; i += 2)
96  xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
97  for (i = 1;i < avt->nb_seg; i += 2)
98  if (avt->segments[i] != NULL)
99  xmlFree((xmlChar *) avt->segments[i]);
100  }
101  if (avt->nsList != NULL)
102  xmlFree(avt->nsList);
103  xmlFree(avt);
104 }
105 
112 void
113 xsltFreeAVTList(void *avt) {
114  xsltAttrVTPtr cur = (xsltAttrVTPtr) avt, next;
115 
116  while (cur != NULL) {
117  next = cur->next;
118  xsltFreeAttrVT(cur);
119  cur = next;
120  }
121 }
134 static xsltAttrVTPtr
136  if (avt->nb_seg >= avt->max_seg) {
137  avt = (xsltAttrVTPtr) xmlRealloc(avt, sizeof(xsltAttrVT) +
138  avt->max_seg * sizeof(void *));
139  if (avt == NULL) {
140  return NULL;
141  }
142  memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *));
143  avt->max_seg += MAX_AVT_SEG;
144  }
145  avt->segments[avt->nb_seg++] = val;
146  return avt;
147 }
148 
158 void
160  const xmlChar *str;
161  const xmlChar *cur;
162  xmlChar *ret = NULL;
163  xmlChar *expr = NULL;
164  xsltAttrVTPtr avt;
165  int i = 0, lastavt = 0;
166 
167  if ((style == NULL) || (attr == NULL) || (attr->children == NULL))
168  return;
169  if ((attr->children->type != XML_TEXT_NODE) ||
170  (attr->children->next != NULL)) {
171  xsltTransformError(NULL, style, attr->parent,
172  "Attribute '%s': The content is expected to be a single text "
173  "node when compiling an AVT.\n", attr->name);
174  style->errors++;
175  return;
176  }
177  str = attr->children->content;
178  if ((xmlStrchr(str, '{') == NULL) &&
179  (xmlStrchr(str, '}') == NULL)) return;
180 
181 #ifdef WITH_XSLT_DEBUG_AVT
183  "Found AVT %s: %s\n", attr->name, str);
184 #endif
185  if (attr->psvi != NULL) {
186 #ifdef WITH_XSLT_DEBUG_AVT
188  "AVT %s: already compiled\n", attr->name);
189 #endif
190  return;
191  }
192  /*
193  * Create a new AVT object.
194  */
195  avt = xsltNewAttrVT(style);
196  if (avt == NULL)
197  return;
198  attr->psvi = avt;
199 
200  avt->nsList = xmlGetNsList(attr->doc, attr->parent);
201  if (avt->nsList != NULL) {
202  while (avt->nsList[i] != NULL)
203  i++;
204  }
205  avt->nsNr = i;
206 
207  cur = str;
208  while (*cur != 0) {
209  if (*cur == '{') {
210  if (*(cur+1) == '{') { /* escaped '{' */
211  cur++;
212  ret = xmlStrncat(ret, str, cur - str);
213  cur++;
214  str = cur;
215  continue;
216  }
217  if (*(cur+1) == '}') { /* skip empty AVT */
218  ret = xmlStrncat(ret, str, cur - str);
219  cur += 2;
220  str = cur;
221  continue;
222  }
223  if ((ret != NULL) || (cur - str > 0)) {
224  ret = xmlStrncat(ret, str, cur - str);
225  str = cur;
226  if (avt->nb_seg == 0)
227  avt->strstart = 1;
228  if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
229  goto error;
230  ret = NULL;
231  lastavt = 0;
232  }
233 
234  cur++;
235  while ((*cur != 0) && (*cur != '}')) {
236  /* Need to check for literal (bug539741) */
237  if ((*cur == '\'') || (*cur == '"')) {
238  char delim = *(cur++);
239  while ((*cur != 0) && (*cur != delim))
240  cur++;
241  if (*cur != 0)
242  cur++; /* skip the ending delimiter */
243  } else
244  cur++;
245  }
246  if (*cur == 0) {
247  xsltTransformError(NULL, style, attr->parent,
248  "Attribute '%s': The AVT has an unmatched '{'.\n",
249  attr->name);
250  style->errors++;
251  goto error;
252  }
253  str++;
254  expr = xmlStrndup(str, cur - str);
255  if (expr == NULL) {
256  /*
257  * TODO: What needs to be done here?
258  */
259  XSLT_TODO
260  goto error;
261  } else {
262  xmlXPathCompExprPtr comp;
263 
264  comp = xsltXPathCompile(style, expr);
265  if (comp == NULL) {
266  xsltTransformError(NULL, style, attr->parent,
267  "Attribute '%s': Failed to compile the expression "
268  "'%s' in the AVT.\n", attr->name, expr);
269  style->errors++;
270  goto error;
271  }
272  if (avt->nb_seg == 0)
273  avt->strstart = 0;
274  if (lastavt == 1) {
275  if ((avt = xsltSetAttrVTsegment(avt, NULL)) == NULL)
276  goto error;
277  }
278  if ((avt = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL)
279  goto error;
280  lastavt = 1;
281  xmlFree(expr);
282  expr = NULL;
283  }
284  cur++;
285  str = cur;
286  } else if (*cur == '}') {
287  cur++;
288  if (*cur == '}') { /* escaped '}' */
289  ret = xmlStrncat(ret, str, cur - str);
290  cur++;
291  str = cur;
292  continue;
293  } else {
294  xsltTransformError(NULL, style, attr->parent,
295  "Attribute '%s': The AVT has an unmatched '}'.\n",
296  attr->name);
297  goto error;
298  }
299  } else
300  cur++;
301  }
302  if ((ret != NULL) || (cur - str > 0)) {
303  ret = xmlStrncat(ret, str, cur - str);
304  str = cur;
305  if (avt->nb_seg == 0)
306  avt->strstart = 1;
307  if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
308  goto error;
309  ret = NULL;
310  }
311 
312 error:
313  if (avt == NULL) {
314  xsltTransformError(NULL, style, attr->parent,
315  "xsltCompileAttr: malloc problem\n");
316  } else {
317  if (attr->psvi != avt) { /* may have changed from realloc */
318  attr->psvi = avt;
319  /*
320  * This is a "hack", but I can't see any clean method of
321  * doing it. If a re-alloc has taken place, then the pointer
322  * for this AVT may have changed. style->attVTs was set by
323  * xsltNewAttrVT, so it needs to be re-set to the new value!
324  */
325  style->attVTs = avt;
326  }
327  }
328  if (ret != NULL)
329  xmlFree(ret);
330  if (expr != NULL)
331  xmlFree(expr);
332 }
333 
334 
346 xmlChar *
348  xmlChar *ret = NULL, *tmp;
349  xmlXPathCompExprPtr comp;
350  xsltAttrVTPtr cur = (xsltAttrVTPtr) avt;
351  int i;
352  int str;
353 
354  if ((ctxt == NULL) || (avt == NULL) || (node == NULL))
355  return(NULL);
356  str = cur->strstart;
357  for (i = 0;i < cur->nb_seg;i++) {
358  if (str) {
359  ret = xmlStrcat(ret, (const xmlChar *) cur->segments[i]);
360  } else {
361  comp = (xmlXPathCompExprPtr) cur->segments[i];
362  tmp = xsltEvalXPathStringNs(ctxt, comp, cur->nsNr, cur->nsList);
363  if (tmp != NULL) {
364  if (ret != NULL) {
365  ret = xmlStrcat(ret, tmp);
366  xmlFree(tmp);
367  } else {
368  ret = tmp;
369  }
370  }
371  }
372  str = !str;
373  }
374  return(ret);
375 }
#define MAX_AVT_SEG
Definition: attrvt.c:22
#define error(str)
Definition: mkdosfs.c:1605
Definition: tree.h:389
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:41
xmlXPathCompExprPtr xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str)
Definition: xsltutils.c:2327
struct _xsltAttrVT * next
Definition: attrvt.c:27
int nb_seg
Definition: attrvt.c:28
XMLPUBFUN const xmlChar *XMLCALL xmlStrchr(const xmlChar *str, xmlChar val)
Definition: xmlstring.c:321
Definition: query.h:86
int strstart
Definition: attrvt.c:30
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
xmlChar * xsltEvalAVT(xsltTransformContextPtr ctxt, void *avt, xmlNodePtr node)
Definition: attrvt.c:347
const WCHAR * str
smooth NULL
Definition: ftsmooth.c:416
int max_seg
Definition: attrvt.c:29
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:249
GLuint GLfloat * val
Definition: glext.h:7180
#define XSLT_TODO
Definition: xsltutils.h:34
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
Definition: cookie.c:170
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
static void xsltFreeAttrVT(xsltAttrVTPtr avt)
Definition: attrvt.c:83
Definition: tree.h:489
int ret
static xsltAttrVTPtr xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val)
Definition: attrvt.c:135
unsigned char xmlChar
Definition: xmlstring.h:28
void * segments[MAX_AVT_SEG]
Definition: attrvt.c:39
xmlNsPtr * nsList
Definition: attrvt.c:34
static unsigned __int64 next
Definition: rand_nt.c:6
void xsltFreeAVTList(void *avt)
Definition: attrvt.c:113
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:247
Definition: tree.h:434
WCHAR * name
Definition: cookie.c:172
xmlChar * xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp, int nsNr, xmlNsPtr *nsList)
Definition: templates.c:105
xsltAttrVT * xsltAttrVTPtr
Definition: attrvt.c:25
static xsltAttrVTPtr xsltNewAttrVT(xsltStylesheetPtr style)
Definition: attrvt.c:51
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
Arabic default style
Definition: afstyles.h:93
#define memset(x, y, z)
Definition: compat.h:39
int nsNr
Definition: attrvt.c:35
Definition: dlist.c:348
void xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr)
Definition: attrvt.c:159