ReactOS 0.4.15-dev-7842-g558ab78
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
24typedef struct _xsltAttrVT 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 */
39#if __STDC_VERSION__ >= 199901L
40 /* Using a C99 flexible array member avoids false positives under UBSan */
41 void *segments[];
42#else
43 void *segments[1];
44#endif
45};
46
55static xsltAttrVTPtr
58 size_t size = sizeof(xsltAttrVT) + MAX_AVT_SEG * sizeof(void*);
59
61 if (cur == NULL) {
63 "xsltNewAttrVTPtr : malloc failed\n");
64 if (style != NULL) style->errors++;
65 return(NULL);
66 }
67 memset(cur, 0, size);
68
69 cur->nb_seg = 0;
70 cur->max_seg = MAX_AVT_SEG;
71 cur->strstart = 0;
72 cur->next = style->attVTs;
73 /*
74 * Note: this pointer may be changed by a re-alloc within xsltCompileAttr,
75 * so that code may change the stylesheet pointer also!
76 */
77 style->attVTs = (xsltAttrVTPtr) cur;
78
79 return(cur);
80}
81
88static void
90 int i;
91
92 if (avt == NULL) return;
93
94 if (avt->strstart == 1) {
95 for (i = 0;i < avt->nb_seg; i += 2)
96 if (avt->segments[i] != NULL)
97 xmlFree((xmlChar *) avt->segments[i]);
98 for (i = 1;i < avt->nb_seg; i += 2)
99 xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
100 } else {
101 for (i = 0;i < avt->nb_seg; i += 2)
102 xmlXPathFreeCompExpr((xmlXPathCompExprPtr) avt->segments[i]);
103 for (i = 1;i < avt->nb_seg; i += 2)
104 if (avt->segments[i] != NULL)
105 xmlFree((xmlChar *) avt->segments[i]);
106 }
107 if (avt->nsList != NULL)
108 xmlFree(avt->nsList);
109 xmlFree(avt);
110}
111
118void
119xsltFreeAVTList(void *avt) {
121
122 while (cur != NULL) {
123 next = cur->next;
125 cur = next;
126 }
127}
140static xsltAttrVTPtr
142 if (avt->nb_seg >= avt->max_seg) {
143 size_t size = sizeof(xsltAttrVT) +
144 (avt->max_seg + MAX_AVT_SEG) * sizeof(void *);
146 if (tmp == NULL) {
147 xsltFreeAttrVT(avt);
148 return NULL;
149 }
150 avt = tmp;
151 memset(&avt->segments[avt->nb_seg], 0, MAX_AVT_SEG*sizeof(void *));
152 avt->max_seg += MAX_AVT_SEG;
153 }
154 avt->segments[avt->nb_seg++] = val;
155 return avt;
156}
157
167void
169 const xmlChar *str;
170 const xmlChar *cur;
171 xmlChar *ret = NULL;
172 xmlChar *expr = NULL;
173 xsltAttrVTPtr avt;
174 int i = 0, lastavt = 0;
175
176 if ((style == NULL) || (attr == NULL) || (attr->children == NULL))
177 return;
178 if ((attr->children->type != XML_TEXT_NODE) ||
179 (attr->children->next != NULL)) {
181 "Attribute '%s': The content is expected to be a single text "
182 "node when compiling an AVT.\n", attr->name);
183 style->errors++;
184 return;
185 }
186 str = attr->children->content;
187 if ((xmlStrchr(str, '{') == NULL) &&
188 (xmlStrchr(str, '}') == NULL)) return;
189
190#ifdef WITH_XSLT_DEBUG_AVT
192 "Found AVT %s: %s\n", attr->name, str);
193#endif
194 if (attr->psvi != NULL) {
195#ifdef WITH_XSLT_DEBUG_AVT
197 "AVT %s: already compiled\n", attr->name);
198#endif
199 return;
200 }
201 /*
202 * Create a new AVT object.
203 */
204 avt = xsltNewAttrVT(style);
205 if (avt == NULL)
206 return;
207 attr->psvi = avt;
208
209 avt->nsList = xmlGetNsList(attr->doc, attr->parent);
210 if (avt->nsList != NULL) {
211 while (avt->nsList[i] != NULL)
212 i++;
213 }
214 avt->nsNr = i;
215
216 cur = str;
217 while (*cur != 0) {
218 if (*cur == '{') {
219 if (*(cur+1) == '{') { /* escaped '{' */
220 cur++;
221 ret = xmlStrncat(ret, str, cur - str);
222 cur++;
223 str = cur;
224 continue;
225 }
226 if (*(cur+1) == '}') { /* skip empty AVT */
227 ret = xmlStrncat(ret, str, cur - str);
228 cur += 2;
229 str = cur;
230 continue;
231 }
232 if ((ret != NULL) || (cur - str > 0)) {
233 ret = xmlStrncat(ret, str, cur - str);
234 str = cur;
235 if (avt->nb_seg == 0)
236 avt->strstart = 1;
237 if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
238 goto error;
239 ret = NULL;
240 lastavt = 0;
241 }
242
243 cur++;
244 while ((*cur != 0) && (*cur != '}')) {
245 /* Need to check for literal (bug539741) */
246 if ((*cur == '\'') || (*cur == '"')) {
247 char delim = *(cur++);
248 while ((*cur != 0) && (*cur != delim))
249 cur++;
250 if (*cur != 0)
251 cur++; /* skip the ending delimiter */
252 } else
253 cur++;
254 }
255 if (*cur == 0) {
257 "Attribute '%s': The AVT has an unmatched '{'.\n",
258 attr->name);
259 style->errors++;
260 goto error;
261 }
262 str++;
263 expr = xmlStrndup(str, cur - str);
264 if (expr == NULL) {
265 /*
266 * TODO: What needs to be done here?
267 */
269 goto error;
270 } else {
271 xmlXPathCompExprPtr comp;
272
273 comp = xsltXPathCompile(style, expr);
274 if (comp == NULL) {
276 "Attribute '%s': Failed to compile the expression "
277 "'%s' in the AVT.\n", attr->name, expr);
278 style->errors++;
279 goto error;
280 }
281 if (avt->nb_seg == 0)
282 avt->strstart = 0;
283 if (lastavt == 1) {
284 if ((avt = xsltSetAttrVTsegment(avt, NULL)) == NULL)
285 goto error;
286 }
287 if ((avt = xsltSetAttrVTsegment(avt, (void *) comp)) == NULL)
288 goto error;
289 lastavt = 1;
290 xmlFree(expr);
291 expr = NULL;
292 }
293 cur++;
294 str = cur;
295 } else if (*cur == '}') {
296 cur++;
297 if (*cur == '}') { /* escaped '}' */
298 ret = xmlStrncat(ret, str, cur - str);
299 cur++;
300 str = cur;
301 continue;
302 } else {
304 "Attribute '%s': The AVT has an unmatched '}'.\n",
305 attr->name);
306 goto error;
307 }
308 } else
309 cur++;
310 }
311 if ((ret != NULL) || (cur - str > 0)) {
312 ret = xmlStrncat(ret, str, cur - str);
313 str = cur;
314 if (avt->nb_seg == 0)
315 avt->strstart = 1;
316 if ((avt = xsltSetAttrVTsegment(avt, (void *) ret)) == NULL)
317 goto error;
318 ret = NULL;
319 }
320
321error:
322 if (avt == NULL) {
324 "xsltCompileAttr: malloc problem\n");
325 } else {
326 if (attr->psvi != avt) { /* may have changed from realloc */
327 attr->psvi = avt;
328 /*
329 * This is a "hack", but I can't see any clean method of
330 * doing it. If a re-alloc has taken place, then the pointer
331 * for this AVT may have changed. style->attVTs was set by
332 * xsltNewAttrVT, so it needs to be re-set to the new value!
333 */
334 style->attVTs = avt;
335 }
336 }
337 if (ret != NULL)
338 xmlFree(ret);
339 if (expr != NULL)
340 xmlFree(expr);
341}
342
343
355xmlChar *
357 xmlChar *ret = NULL, *tmp;
358 xmlXPathCompExprPtr comp;
360 int i;
361 int str;
362
363 if ((ctxt == NULL) || (avt == NULL) || (node == NULL))
364 return(NULL);
365 str = cur->strstart;
366 for (i = 0;i < cur->nb_seg;i++) {
367 if (str) {
368 ret = xmlStrcat(ret, (const xmlChar *) cur->segments[i]);
369 } else {
370 comp = (xmlXPathCompExprPtr) cur->segments[i];
371 tmp = xsltEvalXPathStringNs(ctxt, comp, cur->nsNr, cur->nsList);
372 if (tmp != NULL) {
373 if (ret != NULL) {
374 ret = xmlStrcat(ret, tmp);
375 xmlFree(tmp);
376 } else {
377 ret = tmp;
378 }
379 }
380 }
381 str = !str;
382 }
383 return(ret);
384}
Arabic default style
Definition: afstyles.h:94
static xsltAttrVTPtr xsltNewAttrVT(xsltStylesheetPtr style)
Definition: attrvt.c:56
xsltAttrVT * xsltAttrVTPtr
Definition: attrvt.c:25
void xsltFreeAVTList(void *avt)
Definition: attrvt.c:119
static xsltAttrVTPtr xsltSetAttrVTsegment(xsltAttrVTPtr avt, void *val)
Definition: attrvt.c:141
static void xsltFreeAttrVT(xsltAttrVTPtr avt)
Definition: attrvt.c:89
void xsltCompileAttr(xsltStylesheetPtr style, xmlAttrPtr attr)
Definition: attrvt.c:168
xmlChar * xsltEvalAVT(xsltTransformContextPtr ctxt, void *avt, xmlNodePtr node)
Definition: attrvt.c:356
#define MAX_AVT_SEG
Definition: attrvt.c:22
struct _xsltAttrVT xsltAttrVT
Definition: attrvt.c:24
#define NULL
Definition: types.h:112
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
XMLPUBVAR xmlMallocFunc xmlMalloc
Definition: globals.h:248
XMLPUBVAR xmlFreeFunc xmlFree
Definition: globals.h:251
XMLPUBVAR xmlReallocFunc xmlRealloc
Definition: globals.h:250
@ XML_TEXT_NODE
Definition: tree.h:162
#define memset(x, y, z)
Definition: compat.h:39
Definition: tree.h:434
Definition: tree.h:489
Definition: tree.h:389
void * segments[1]
Definition: attrvt.c:43
int strstart
Definition: attrvt.c:30
struct _xsltAttrVT * next
Definition: attrvt.c:27
int max_seg
Definition: attrvt.c:29
xmlNsPtr * nsList
Definition: attrvt.c:34
int nsNr
Definition: attrvt.c:35
int nb_seg
Definition: attrvt.c:28
Definition: cookie.c:202
WCHAR * name
Definition: cookie.c:203
Definition: query.h:87
xmlChar * xsltEvalXPathStringNs(xsltTransformContextPtr ctxt, xmlXPathCompExprPtr comp, int nsNr, xmlNsPtr *nsList)
Definition: templates.c:105
Definition: dlist.c:348
int ret
XMLPUBFUN const xmlChar *XMLCALL xmlStrchr(const xmlChar *str, xmlChar val)
Definition: xmlstring.c:325
XMLPUBFUN xmlChar *XMLCALL xmlStrndup(const xmlChar *cur, int len)
Definition: xmlstring.c:42
XMLPUBFUN xmlChar *XMLCALL xmlStrcat(xmlChar *cur, const xmlChar *add)
Definition: xmlstring.c:524
XMLPUBFUN xmlChar *XMLCALL xmlStrncat(xmlChar *cur, const xmlChar *add, int len)
Definition: xmlstring.c:446
unsigned char xmlChar
Definition: xmlstring.h:28
void xsltTransformError(xsltTransformContextPtr ctxt, xsltStylesheetPtr style, xmlNodePtr node, const char *msg,...)
Definition: xsltutils.c:678
xmlXPathCompExprPtr xsltXPathCompile(xsltStylesheetPtr style, const xmlChar *str)
Definition: xsltutils.c:2356
xmlGenericErrorFunc xsltGenericDebug
Definition: xsltutils.c:548
void * xsltGenericDebugContext
Definition: xsltutils.c:549
#define XSLT_TODO
Definition: xsltutils.h:31