ReactOS 0.4.16-dev-2206-gc56950d
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#define IN_LIBXSLT
17#include "libxslt.h"
18
19#include <string.h>
20
21#include <libxml/xmlmemory.h>
22#include <libxml/tree.h>
23#include <libxml/xpath.h>
25#include "xslt.h"
26#include "xsltutils.h"
27#include "xsltInternals.h"
28#include "templates.h"
29
30#ifdef WITH_XSLT_DEBUG
31#define WITH_XSLT_DEBUG_AVT
32#endif
33
34#define MAX_AVT_SEG 10
35
36typedef struct _xsltAttrVT xsltAttrVT;
39 struct _xsltAttrVT *next; /* next xsltAttrVT */
40 int nb_seg; /* Number of segments */
41 int max_seg; /* max capacity before re-alloc needed */
42 int strstart; /* is the start a string */
43 /*
44 * the namespaces in scope
45 */
46 xmlNsPtr *nsList;
47 int nsNr;
48 /*
49 * the content is an alternate of string and xmlXPathCompExprPtr
50 */
51#if __STDC_VERSION__ >= 199901L
52 /* Using a C99 flexible array member avoids false positives under UBSan */
53 void *segments[];
54#else
55 void *segments[1];
56#endif
57};
58
67static xsltAttrVTPtr
70 size_t size = sizeof(xsltAttrVT) + MAX_AVT_SEG * sizeof(void*);
71
73 if (cur == NULL) {
75 "xsltNewAttrVTPtr : malloc failed\n");
76 if (style != NULL) style->errors++;
77 return(NULL);
78 }
79 memset(cur, 0, size);
80
81 cur->nb_seg = 0;
82 cur->max_seg = MAX_AVT_SEG;
83 cur->strstart = 0;
84 cur->next = style->attVTs;
85 /*
86 * Note: this pointer may be changed by a re-alloc within xsltCompileAttr,
87 * so that code may change the stylesheet pointer also!
88 */
89 style->attVTs = (xsltAttrVTPtr) cur;
90
91 return(cur);
92}
93
100static void
102 int i;
103
104 if (avt == NULL) return;
105
106 if (avt->strstart == 1) {
107 for (i = 0;i < avt->nb_seg; i += 2)
108 if (avt->segments[i] != NULL)
109 xmlFree((xmlChar *) avt->segments[i]);
110 for (i = 1;i < avt->nb_seg; i += 2)
111 xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
112 } else {
113 for (i = 0;i < avt->nb_seg; i += 2)
114 xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
115 for (i = 1;i < avt->nb_seg; i += 2)
116 if (avt->segments[i] != NULL)
117 xmlFree((xmlChar *) avt->segments[i]);
118 }
119 if (avt->nsList != NULL)
120 xmlFree(avt->nsList);
121 xmlFree(avt);
122}
123
130void
131xsltFreeAVTList(void *avt) {
133
134 while (cur != NULL) {
135 next = cur->next;
137 cur = next;
138 }
139}
152static xsltAttrVTPtr
154 if (avt->nb_seg >= avt->max_seg) {
155 size_t size = sizeof(xsltAttrVT) +
156 (avt->max_seg + MAX_AVT_SEG) * sizeof(void *);
157 avt = (xsltAttrVTPtr) xmlRealloc(avt, size);
158 if (avt == NULL)
159 return NULL;
160 memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *));
161 avt->max_seg += MAX_AVT_SEG;
162 }
163 avt->segments[avt->nb_seg++] = val;
164 return avt;
165}
166
176void
178 const xmlChar *str;
179 const xmlChar *cur;
180 xmlChar *ret = NULL;
181 xmlChar *expr = NULL;
182 xmlXPathCompExprPtr comp = NULL;
183 xsltAttrVTPtr avt, tmp;
184 int i = 0, lastavt = 0;
185
186 if ((style == NULL) || (attr == NULL) || (attr->children == NULL))
187 return;
188 if ((attr->children->type != XML_TEXT_NODE) ||
189 (attr->children->next != NULL)) {
191 "Attribute '%s': The content is expected to be a single text "
192 "node when compiling an AVT.\n", attr->name);
193 style->errors++;
194 return;
195 }
196 str = attr->children->content;
197 if ((xmlStrchr(str, '{') == NULL) &&
198 (xmlStrchr(str, '}') == NULL)) return;
199
200#ifdef WITH_XSLT_DEBUG_AVT
202 "Found AVT %s: %s\n", attr->name, str);
203#endif
204 if (attr->psvi != NULL) {
205#ifdef WITH_XSLT_DEBUG_AVT
207 "AVT %s: already compiled\n", attr->name);
208#endif
209 return;
210 }
211 /*
212 * Create a new AVT object.
213 */
214 avt = xsltNewAttrVT(style);
215 if (avt == NULL)
216 return;
217 attr->psvi = avt;
218
219 avt->nsList = xmlGetNsList(attr->doc, attr->parent);
220 if (avt->nsList != NULL) {
221 while (avt->nsList[i] != NULL)
222 i++;
223 }
224 avt->nsNr = i;
225
226 cur = str;
227 while (*cur != 0) {
228 if (*cur == '{') {
229 if (*(cur+1) == '{') { /* escaped '{' */
230 cur++;
231 ret = xmlStrncat(ret, str, cur - str);
232 cur++;
233 str = cur;
234 continue;
235 }
236 if (*(cur+1) == '}') { /* skip empty AVT */
237 ret = xmlStrncat(ret, str, cur - str);
238 cur += 2;
239 str = cur;
240 continue;
241 }
242 if ((ret != NULL) || (cur - str > 0)) {
243 ret = xmlStrncat(ret, str, cur - str);
244 str = cur;
245 if (avt->nb_seg == 0)
246 avt->strstart = 1;
247 if ((tmp = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
248 goto error;
249 avt = tmp;
250 ret = NULL;
251 lastavt = 0;
252 }
253
254 cur++;
255 while ((*cur != 0) && (*cur != '}')) {
256 /* Need to check for literal (bug539741) */
257 if ((*cur == '\'') || (*cur == '"')) {
258 char delim = *(cur++);
259 while ((*cur != 0) && (*cur != delim))
260 cur++;
261 if (*cur != 0)
262 cur++; /* skip the ending delimiter */
263 } else
264 cur++;
265 }
266 if (*cur == 0) {
268 "Attribute '%s': The AVT has an unmatched '{'.\n",
269 attr->name);
270 style->errors++;
271 goto error;
272 }
273 str++;
274 expr = xmlStrndup(str, cur - str);
275 if (expr == NULL) {
276 /*
277 * TODO: What needs to be done here?
278 */
280 goto error;
281 } else {
282 comp = xsltXPathCompile(style, expr);
283 if (comp == NULL) {
285 "Attribute '%s': Failed to compile the expression "
286 "'%s' in the AVT.\n", attr->name, expr);
287 style->errors++;
288 goto error;
289 }
290 if (avt->nb_seg == 0)
291 avt->strstart = 0;
292 if (lastavt == 1) {
293 if ((tmp = xsltSetAttrVTsegment(avt, NULL)) == NULL) {
295 "out of memory\n");
296 goto error;
297 }
298 avt = tmp;
299 }
300 if ((tmp = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL) {
302 "out of memory\n");
303 goto error;
304 }
305 avt = tmp;
306 lastavt = 1;
307 xmlFree(expr);
308 expr = NULL;
309 comp = NULL;
310 }
311 cur++;
312 str = cur;
313 } else if (*cur == '}') {
314 cur++;
315 if (*cur == '}') { /* escaped '}' */
316 ret = xmlStrncat(ret, str, cur - str);
317 cur++;
318 str = cur;
319 continue;
320 } else {
322 "Attribute '%s': The AVT has an unmatched '}'.\n",
323 attr->name);
324 goto error;
325 }
326 } else
327 cur++;
328 }
329 if ((ret != NULL) || (cur - str > 0)) {
330 ret = xmlStrncat(ret, str, cur - str);
331 str = cur;
332 if (avt->nb_seg == 0)
333 avt->strstart = 1;
334 if ((tmp = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
335 goto error;
336 avt = tmp;
337 ret = NULL;
338 }
339
340error:
341 if (avt == NULL) {
343 "xsltCompileAttr: malloc problem\n");
344 } else {
345 if (attr->psvi != avt) { /* may have changed from realloc */
346 attr->psvi = avt;
347 /*
348 * This is a "hack", but I can't see any clean method of
349 * doing it. If a re-alloc has taken place, then the pointer
350 * for this AVT may have changed. style->attVTs was set by
351 * xsltNewAttrVT, so it needs to be re-set to the new value!
352 */
353 style->attVTs = avt;
354 }
355 }
356 if (ret != NULL)
357 xmlFree(ret);
358 if (expr != NULL)
359 xmlFree(expr);
360 if (comp != NULL)
361 xmlXPathFreeCompExpr(comp);
362}
363
364
376xmlChar *
377xsltEvalAVT(xsltTransformContextPtr ctxt, void *avt, xmlNodePtr node) {
378 xmlChar *ret = NULL, *tmp;
379 xmlXPathCompExprPtr comp;
381 int i;
382 int str;
383
384 if ((ctxt == NULL) || (avt == NULL) || (node == NULL))
385 return(NULL);
386 str = cur->strstart;
387 for (i = 0;i < cur->nb_seg;i++) {
388 if (str) {
389 ret = xmlStrcat(ret, (const xmlChar *) cur->segments[i]);
390 } else {
391 comp = (xmlXPathCompExprPtr) cur->segments[i];
392 tmp = xsltEvalXPathStringNs(ctxt, comp, cur->nsNr, cur->nsList);
393 if (tmp != NULL) {
394 if (ret != NULL) {
395 ret = xmlStrcat(ret, tmp);
396 xmlFree(tmp);
397 } else {
398 ret = tmp;
399 }
400 }
401 }
402 str = !str;
403 }
404 return(ret);
405}
Arabic default style
Definition: afstyles.h:94
static xsltAttrVTPtr xsltNewAttrVT(xsltStylesheetPtr style)
Definition: attrvt.c:68
xsltAttrVT * xsltAttrVTPtr
Definition: attrvt.c:37
void xsltFreeAVTList(void *avt)
Definition: attrvt.c:131
static xsltAttrVTPtr xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val)
Definition: attrvt.c:153
static void xsltFreeAttrVT(xsltAttrVTPtr avt)
Definition: attrvt.c:101
void xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr)
Definition: attrvt.c:177
xmlChar * xsltEvalAVT(xsltTransformContextPtr ctxt, void *avt, xmlNodePtr node)
Definition: attrvt.c:377
#define MAX_AVT_SEG
Definition: attrvt.c:34
struct _xsltAttrVT xsltAttrVT
Definition: attrvt.c:36
#define NULL
Definition: types.h:112
return ret
Definition: mutex.c:146
FxCollectionEntry * cur
GLsizeiptr size
Definition: glext.h:5919
GLuint GLfloat * val
Definition: glext.h:7180
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 error(str)
Definition: mkdosfs.c:1605
static unsigned __int64 next
Definition: rand_nt.c:6
const WCHAR * str
xmlReallocFunc xmlRealloc
Definition: globals.c:214
xmlFreeFunc xmlFree
Definition: globals.c:184
xmlMallocFunc xmlMalloc
Definition: globals.c:193
#define memset(x, y, z)
Definition: compat.h:39
void * segments[1]
Definition: attrvt.c:55
int strstart
Definition: attrvt.c:42
struct _xsltAttrVT * next
Definition: attrvt.c:39
int max_seg
Definition: attrvt.c:41
xmlNsPtr * nsList
Definition: attrvt.c:46
int nsNr
Definition: attrvt.c:47
int nb_seg
Definition: attrvt.c:40
Definition: cookie.c:202
WCHAR * name
Definition: cookie.c:203
Definition: query.h:86
xmlChar * xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp, int nsNr, xmlNsPtr *nsList)
Definition: templates.c:123
Definition: dlist.c:348
XMLPUBFUN xmlChar * xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:45
XMLPUBFUN xmlChar * xmlStrncat(xmlChar *cur, const xmlChar *add, int len)
Definition: xmlstring.c:448
XMLPUBFUN xmlChar * xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524
XMLPUBFUN const xmlChar * xmlStrchr(const xmlChar *str, xmlChar val)
Definition: xmlstring.c:327
unsigned char xmlChar
Definition: xmlstring.h:28
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:762
xmlXPathCompExprPtr xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str)
Definition: xsltutils.c:2593
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:632
void * xsltGenericDebugContext
Definition: xsltutils.c:633
#define XSLT_TODO
Definition: xsltutils.h:31