Coverage Report

Created: 2023-04-30 15:30

/src/libxslt/libxslt/preproc.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * preproc.c: Preprocessing of style operations
3
 *
4
 * References:
5
 *   http://www.w3.org/TR/1999/REC-xslt-19991116
6
 *
7
 *   Michael Kay "XSLT Programmer's Reference" pp 637-643
8
 *   Writing Multiple Output Files
9
 *
10
 *   XSLT-1.1 Working Draft
11
 *   http://www.w3.org/TR/xslt11#multiple-output
12
 *
13
 * See Copyright for the status of this software.
14
 *
15
 * daniel@veillard.com
16
 */
17
18
#define IN_LIBXSLT
19
#include "libxslt.h"
20
21
#include <string.h>
22
23
#include <libxml/xmlmemory.h>
24
#include <libxml/parser.h>
25
#include <libxml/tree.h>
26
#include <libxml/valid.h>
27
#include <libxml/hash.h>
28
#include <libxml/uri.h>
29
#include <libxml/encoding.h>
30
#include <libxml/xmlerror.h>
31
#include "xslt.h"
32
#include "xsltutils.h"
33
#include "xsltInternals.h"
34
#include "transform.h"
35
#include "templates.h"
36
#include "variables.h"
37
#include "numbersInternals.h"
38
#include "preproc.h"
39
#include "extra.h"
40
#include "imports.h"
41
#include "extensions.h"
42
#include "pattern.h"
43
44
#ifdef WITH_XSLT_DEBUG
45
#define WITH_XSLT_DEBUG_PREPROC
46
#endif
47
48
const xmlChar *xsltExtMarker = (const xmlChar *) "Extension Element";
49
50
/************************************************************************
51
 *                  *
52
 *      Grammar checks          *
53
 *                  *
54
 ************************************************************************/
55
56
#ifdef XSLT_REFACTORED
57
    /*
58
    * Grammar checks are now performed in xslt.c.
59
    */
60
#else
61
/**
62
 * xsltCheckTopLevelElement:
63
 * @style: the XSLT stylesheet
64
 * @inst: the XSLT instruction
65
 * @err: raise an error or not
66
 *
67
 * Check that the instruction is instanciated as a top level element.
68
 *
69
 * Returns -1 in case of error, 0 if failed and 1 in case of success
70
 */
71
static int
72
0
xsltCheckTopLevelElement(xsltStylesheetPtr style, xmlNodePtr inst, int err) {
73
0
    xmlNodePtr parent;
74
0
    if ((style == NULL) || (inst == NULL) || (inst->ns == NULL))
75
0
        return(-1);
76
77
0
    parent = inst->parent;
78
0
    if (parent == NULL) {
79
0
        if (err) {
80
0
      xsltTransformError(NULL, style, inst,
81
0
        "internal problem: element has no parent\n");
82
0
      style->errors++;
83
0
  }
84
0
  return(0);
85
0
    }
86
0
    if ((parent->ns == NULL) || (parent->type != XML_ELEMENT_NODE) ||
87
0
        ((parent->ns != inst->ns) &&
88
0
   (!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
89
0
  ((!xmlStrEqual(parent->name, BAD_CAST "stylesheet")) &&
90
0
   (!xmlStrEqual(parent->name, BAD_CAST "transform")))) {
91
0
  if (err) {
92
0
      xsltTransformError(NULL, style, inst,
93
0
        "element %s only allowed as child of stylesheet\n",
94
0
             inst->name);
95
0
      style->errors++;
96
0
  }
97
0
  return(0);
98
0
    }
99
0
    return(1);
100
0
}
101
102
/**
103
 * xsltCheckInstructionElement:
104
 * @style: the XSLT stylesheet
105
 * @inst: the XSLT instruction
106
 *
107
 * Check that the instruction is instanciated as an instruction element.
108
 */
109
static void
110
0
xsltCheckInstructionElement(xsltStylesheetPtr style, xmlNodePtr inst) {
111
0
    xmlNodePtr parent;
112
0
    int has_ext;
113
114
0
    if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
115
0
        (style->literal_result))
116
0
        return;
117
118
0
    has_ext = (style->extInfos != NULL);
119
120
0
    parent = inst->parent;
121
0
    if (parent == NULL) {
122
0
  xsltTransformError(NULL, style, inst,
123
0
    "internal problem: element has no parent\n");
124
0
  style->errors++;
125
0
  return;
126
0
    }
127
0
    while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
128
0
        if (((parent->ns == inst->ns) ||
129
0
       ((parent->ns != NULL) &&
130
0
        (xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
131
0
      ((xmlStrEqual(parent->name, BAD_CAST "template")) ||
132
0
       (xmlStrEqual(parent->name, BAD_CAST "param")) ||
133
0
       (xmlStrEqual(parent->name, BAD_CAST "attribute")) ||
134
0
       (xmlStrEqual(parent->name, BAD_CAST "variable")))) {
135
0
      return;
136
0
  }
137
138
  /*
139
   * if we are within an extension element all bets are off
140
   * about the semantic there e.g. xsl:param within func:function
141
   */
142
0
  if ((has_ext) && (parent->ns != NULL) &&
143
0
      (xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
144
0
      return;
145
146
0
        parent = parent->parent;
147
0
    }
148
0
    xsltTransformError(NULL, style, inst,
149
0
      "element %s only allowed within a template, variable or param\n",
150
0
               inst->name);
151
0
    style->errors++;
152
0
}
153
154
/**
155
 * xsltCheckParentElement:
156
 * @style: the XSLT stylesheet
157
 * @inst: the XSLT instruction
158
 * @allow1: allowed parent1
159
 * @allow2: allowed parent2
160
 *
161
 * Check that the instruction is instanciated as the childre of one of the
162
 * possible parents.
163
 */
164
static void
165
xsltCheckParentElement(xsltStylesheetPtr style, xmlNodePtr inst,
166
0
                       const xmlChar *allow1, const xmlChar *allow2) {
167
0
    xmlNodePtr parent;
168
169
0
    if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
170
0
        (style->literal_result))
171
0
        return;
172
173
0
    parent = inst->parent;
174
0
    if (parent == NULL) {
175
0
  xsltTransformError(NULL, style, inst,
176
0
    "internal problem: element has no parent\n");
177
0
  style->errors++;
178
0
  return;
179
0
    }
180
0
    if (((parent->ns == inst->ns) ||
181
0
   ((parent->ns != NULL) &&
182
0
    (xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
183
0
  ((xmlStrEqual(parent->name, allow1)) ||
184
0
   (xmlStrEqual(parent->name, allow2)))) {
185
0
  return;
186
0
    }
187
188
0
    if (style->extInfos != NULL) {
189
0
  while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
190
      /*
191
       * if we are within an extension element all bets are off
192
       * about the semantic there e.g. xsl:param within func:function
193
       */
194
0
      if ((parent->ns != NULL) &&
195
0
    (xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
196
0
    return;
197
198
0
      parent = parent->parent;
199
0
  }
200
0
    }
201
0
    xsltTransformError(NULL, style, inst,
202
0
           "element %s is not allowed within that context\n",
203
0
           inst->name);
204
0
    style->errors++;
205
0
}
206
#endif
207
208
/************************************************************************
209
 *                  *
210
 *      handling of precomputed data      *
211
 *                  *
212
 ************************************************************************/
213
214
/**
215
 * xsltNewStylePreComp:
216
 * @style:  the XSLT stylesheet
217
 * @type:  the construct type
218
 *
219
 * Create a new XSLT Style precomputed block
220
 *
221
 * Returns the newly allocated specialized structure
222
 *         or NULL in case of error
223
 */
224
static xsltStylePreCompPtr
225
0
xsltNewStylePreComp(xsltStylesheetPtr style, xsltStyleType type) {
226
0
    xsltStylePreCompPtr cur;
227
#ifdef XSLT_REFACTORED
228
    size_t size;
229
#endif
230
231
0
    if (style == NULL)
232
0
        return(NULL);
233
234
#ifdef XSLT_REFACTORED
235
    /*
236
    * URGENT TODO: Use specialized factory functions in order
237
    *   to avoid this ugliness.
238
    */
239
    switch (type) {
240
        case XSLT_FUNC_COPY:
241
            size = sizeof(xsltStyleItemCopy); break;
242
        case XSLT_FUNC_SORT:
243
            size = sizeof(xsltStyleItemSort); break;
244
        case XSLT_FUNC_TEXT:
245
            size = sizeof(xsltStyleItemText); break;
246
        case XSLT_FUNC_ELEMENT:
247
            size = sizeof(xsltStyleItemElement); break;
248
        case XSLT_FUNC_ATTRIBUTE:
249
            size = sizeof(xsltStyleItemAttribute); break;
250
        case XSLT_FUNC_COMMENT:
251
            size = sizeof(xsltStyleItemComment); break;
252
        case XSLT_FUNC_PI:
253
            size = sizeof(xsltStyleItemPI); break;
254
        case XSLT_FUNC_COPYOF:
255
            size = sizeof(xsltStyleItemCopyOf); break;
256
        case XSLT_FUNC_VALUEOF:
257
            size = sizeof(xsltStyleItemValueOf); break;;
258
        case XSLT_FUNC_NUMBER:
259
            size = sizeof(xsltStyleItemNumber); break;
260
        case XSLT_FUNC_APPLYIMPORTS:
261
            size = sizeof(xsltStyleItemApplyImports); break;
262
        case XSLT_FUNC_CALLTEMPLATE:
263
            size = sizeof(xsltStyleItemCallTemplate); break;
264
        case XSLT_FUNC_APPLYTEMPLATES:
265
            size = sizeof(xsltStyleItemApplyTemplates); break;
266
        case XSLT_FUNC_CHOOSE:
267
            size = sizeof(xsltStyleItemChoose); break;
268
        case XSLT_FUNC_IF:
269
            size = sizeof(xsltStyleItemIf); break;
270
        case XSLT_FUNC_FOREACH:
271
            size = sizeof(xsltStyleItemForEach); break;
272
        case XSLT_FUNC_DOCUMENT:
273
            size = sizeof(xsltStyleItemDocument); break;
274
  case XSLT_FUNC_WITHPARAM:
275
      size = sizeof(xsltStyleItemWithParam); break;
276
  case XSLT_FUNC_PARAM:
277
      size = sizeof(xsltStyleItemParam); break;
278
  case XSLT_FUNC_VARIABLE:
279
      size = sizeof(xsltStyleItemVariable); break;
280
  case XSLT_FUNC_WHEN:
281
      size = sizeof(xsltStyleItemWhen); break;
282
  case XSLT_FUNC_OTHERWISE:
283
      size = sizeof(xsltStyleItemOtherwise); break;
284
  default:
285
      xsltTransformError(NULL, style, NULL,
286
        "xsltNewStylePreComp : invalid type %d\n", type);
287
      style->errors++;
288
      return(NULL);
289
    }
290
    /*
291
    * Create the structure.
292
    */
293
    cur = (xsltStylePreCompPtr) xmlMalloc(size);
294
    if (cur == NULL) {
295
  xsltTransformError(NULL, style, NULL,
296
    "xsltNewStylePreComp : malloc failed\n");
297
  style->errors++;
298
  return(NULL);
299
    }
300
    memset(cur, 0, size);
301
302
#else /* XSLT_REFACTORED */
303
    /*
304
    * Old behaviour.
305
    */
306
0
    cur = (xsltStylePreCompPtr) xmlMalloc(sizeof(xsltStylePreComp));
307
0
    if (cur == NULL) {
308
0
  xsltTransformError(NULL, style, NULL,
309
0
    "xsltNewStylePreComp : malloc failed\n");
310
0
  style->errors++;
311
0
  return(NULL);
312
0
    }
313
0
    memset(cur, 0, sizeof(xsltStylePreComp));
314
0
#endif /* XSLT_REFACTORED */
315
316
    /*
317
    * URGENT TODO: Better to move this to spezialized factory functions.
318
    */
319
0
    cur->type = type;
320
0
    switch (cur->type) {
321
0
        case XSLT_FUNC_COPY:
322
0
            cur->func = xsltCopy;break;
323
0
        case XSLT_FUNC_SORT:
324
0
            cur->func = xsltSort;break;
325
0
        case XSLT_FUNC_TEXT:
326
0
            cur->func = xsltText;break;
327
0
        case XSLT_FUNC_ELEMENT:
328
0
            cur->func = xsltElement;break;
329
0
        case XSLT_FUNC_ATTRIBUTE:
330
0
            cur->func = xsltAttribute;break;
331
0
        case XSLT_FUNC_COMMENT:
332
0
            cur->func = xsltComment;break;
333
0
        case XSLT_FUNC_PI:
334
0
            cur->func = xsltProcessingInstruction;
335
0
      break;
336
0
        case XSLT_FUNC_COPYOF:
337
0
            cur->func = xsltCopyOf;break;
338
0
        case XSLT_FUNC_VALUEOF:
339
0
            cur->func = xsltValueOf;break;
340
0
        case XSLT_FUNC_NUMBER:
341
0
            cur->func = xsltNumber;break;
342
0
        case XSLT_FUNC_APPLYIMPORTS:
343
0
            cur->func = xsltApplyImports;break;
344
0
        case XSLT_FUNC_CALLTEMPLATE:
345
0
            cur->func = xsltCallTemplate;break;
346
0
        case XSLT_FUNC_APPLYTEMPLATES:
347
0
            cur->func = xsltApplyTemplates;break;
348
0
        case XSLT_FUNC_CHOOSE:
349
0
            cur->func = xsltChoose;break;
350
0
        case XSLT_FUNC_IF:
351
0
            cur->func = xsltIf;break;
352
0
        case XSLT_FUNC_FOREACH:
353
0
            cur->func = xsltForEach;break;
354
0
        case XSLT_FUNC_DOCUMENT:
355
0
            cur->func = xsltDocumentElem;break;
356
0
  case XSLT_FUNC_WITHPARAM:
357
0
  case XSLT_FUNC_PARAM:
358
0
  case XSLT_FUNC_VARIABLE:
359
0
  case XSLT_FUNC_WHEN:
360
0
      break;
361
0
  default:
362
0
  if (cur->func == NULL) {
363
0
      xsltTransformError(NULL, style, NULL,
364
0
        "xsltNewStylePreComp : no function for type %d\n", type);
365
0
      style->errors++;
366
0
  }
367
0
    }
368
0
    cur->next = style->preComps;
369
0
    style->preComps = (xsltElemPreCompPtr) cur;
370
371
0
    return(cur);
372
0
}
373
374
/**
375
 * xsltFreeStylePreComp:
376
 * @comp:  an XSLT Style precomputed block
377
 *
378
 * Free up the memory allocated by @comp
379
 */
380
static void
381
0
xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
382
0
    if (comp == NULL)
383
0
  return;
384
#ifdef XSLT_REFACTORED
385
    /*
386
    * URGENT TODO: Implement destructors.
387
    */
388
    switch (comp->type) {
389
  case XSLT_FUNC_LITERAL_RESULT_ELEMENT:
390
      break;
391
  case XSLT_FUNC_COPY:
392
            break;
393
        case XSLT_FUNC_SORT: {
394
    xsltStyleItemSortPtr item = (xsltStyleItemSortPtr) comp;
395
    if (item->comp != NULL)
396
        xmlXPathFreeCompExpr(item->comp);
397
      }
398
            break;
399
        case XSLT_FUNC_TEXT:
400
            break;
401
        case XSLT_FUNC_ELEMENT:
402
            break;
403
        case XSLT_FUNC_ATTRIBUTE:
404
            break;
405
        case XSLT_FUNC_COMMENT:
406
            break;
407
        case XSLT_FUNC_PI:
408
      break;
409
        case XSLT_FUNC_COPYOF: {
410
    xsltStyleItemCopyOfPtr item = (xsltStyleItemCopyOfPtr) comp;
411
    if (item->comp != NULL)
412
        xmlXPathFreeCompExpr(item->comp);
413
      }
414
            break;
415
        case XSLT_FUNC_VALUEOF: {
416
    xsltStyleItemValueOfPtr item = (xsltStyleItemValueOfPtr) comp;
417
    if (item->comp != NULL)
418
        xmlXPathFreeCompExpr(item->comp);
419
      }
420
            break;
421
        case XSLT_FUNC_NUMBER: {
422
                xsltStyleItemNumberPtr item = (xsltStyleItemNumberPtr) comp;
423
                if (item->numdata.countPat != NULL)
424
                    xsltFreeCompMatchList(item->numdata.countPat);
425
                if (item->numdata.fromPat != NULL)
426
                    xsltFreeCompMatchList(item->numdata.fromPat);
427
            }
428
            break;
429
        case XSLT_FUNC_APPLYIMPORTS:
430
            break;
431
        case XSLT_FUNC_CALLTEMPLATE:
432
            break;
433
        case XSLT_FUNC_APPLYTEMPLATES: {
434
    xsltStyleItemApplyTemplatesPtr item =
435
        (xsltStyleItemApplyTemplatesPtr) comp;
436
    if (item->comp != NULL)
437
        xmlXPathFreeCompExpr(item->comp);
438
      }
439
            break;
440
        case XSLT_FUNC_CHOOSE:
441
            break;
442
        case XSLT_FUNC_IF: {
443
    xsltStyleItemIfPtr item = (xsltStyleItemIfPtr) comp;
444
    if (item->comp != NULL)
445
        xmlXPathFreeCompExpr(item->comp);
446
      }
447
            break;
448
        case XSLT_FUNC_FOREACH: {
449
    xsltStyleItemForEachPtr item =
450
        (xsltStyleItemForEachPtr) comp;
451
    if (item->comp != NULL)
452
        xmlXPathFreeCompExpr(item->comp);
453
      }
454
            break;
455
        case XSLT_FUNC_DOCUMENT:
456
            break;
457
  case XSLT_FUNC_WITHPARAM: {
458
    xsltStyleItemWithParamPtr item =
459
        (xsltStyleItemWithParamPtr) comp;
460
    if (item->comp != NULL)
461
        xmlXPathFreeCompExpr(item->comp);
462
      }
463
      break;
464
  case XSLT_FUNC_PARAM: {
465
    xsltStyleItemParamPtr item =
466
        (xsltStyleItemParamPtr) comp;
467
    if (item->comp != NULL)
468
        xmlXPathFreeCompExpr(item->comp);
469
      }
470
      break;
471
  case XSLT_FUNC_VARIABLE: {
472
    xsltStyleItemVariablePtr item =
473
        (xsltStyleItemVariablePtr) comp;
474
    if (item->comp != NULL)
475
        xmlXPathFreeCompExpr(item->comp);
476
      }
477
      break;
478
  case XSLT_FUNC_WHEN: {
479
    xsltStyleItemWhenPtr item =
480
        (xsltStyleItemWhenPtr) comp;
481
    if (item->comp != NULL)
482
        xmlXPathFreeCompExpr(item->comp);
483
      }
484
      break;
485
  case XSLT_FUNC_OTHERWISE:
486
  case XSLT_FUNC_FALLBACK:
487
  case XSLT_FUNC_MESSAGE:
488
  case XSLT_FUNC_INCLUDE:
489
  case XSLT_FUNC_ATTRSET:
490
491
      break;
492
  default:
493
      /* TODO: Raise error. */
494
      break;
495
    }
496
#else
497
0
    if (comp->comp != NULL)
498
0
  xmlXPathFreeCompExpr(comp->comp);
499
0
    if (comp->numdata.countPat != NULL)
500
0
        xsltFreeCompMatchList(comp->numdata.countPat);
501
0
    if (comp->numdata.fromPat != NULL)
502
0
        xsltFreeCompMatchList(comp->numdata.fromPat);
503
0
    if (comp->nsList != NULL)
504
0
  xmlFree(comp->nsList);
505
0
#endif
506
507
0
    xmlFree(comp);
508
0
}
509
510
511
/************************************************************************
512
 *                  *
513
 *        XSLT-1.1 extensions         *
514
 *                  *
515
 ************************************************************************/
516
517
/**
518
 * xsltDocumentComp:
519
 * @style:  the XSLT stylesheet
520
 * @inst:  the instruction in the stylesheet
521
 * @function:  unused
522
 *
523
 * Pre process an XSLT-1.1 document element
524
 *
525
 * Returns a precompiled data structure for the element
526
 */
527
xsltElemPreCompPtr
528
xsltDocumentComp(xsltStylesheetPtr style, xmlNodePtr inst,
529
0
     xsltTransformFunction function ATTRIBUTE_UNUSED) {
530
#ifdef XSLT_REFACTORED
531
    xsltStyleItemDocumentPtr comp;
532
#else
533
0
    xsltStylePreCompPtr comp;
534
0
#endif
535
0
    const xmlChar *filename = NULL;
536
537
    /*
538
    * As of 2006-03-30, this function is currently defined in Libxslt
539
    * to be used for:
540
    * (in libxslt/extra.c)
541
    * "output" in XSLT_SAXON_NAMESPACE
542
    * "write" XSLT_XALAN_NAMESPACE
543
    * "document" XSLT_XT_NAMESPACE
544
    * "document" XSLT_NAMESPACE (from the abandoned old working
545
    *                            draft of XSLT 1.1)
546
    * (in libexslt/common.c)
547
    * "document" in EXSLT_COMMON_NAMESPACE
548
    */
549
#ifdef XSLT_REFACTORED
550
    comp = (xsltStyleItemDocumentPtr)
551
  xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
552
#else
553
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
554
0
#endif
555
556
0
    if (comp == NULL)
557
0
  return (NULL);
558
0
    comp->inst = inst;
559
0
    comp->ver11 = 0;
560
561
0
    if (xmlStrEqual(inst->name, (const xmlChar *) "output")) {
562
#ifdef WITH_XSLT_DEBUG_EXTRA
563
  xsltGenericDebug(xsltGenericDebugContext,
564
      "Found saxon:output extension\n");
565
#endif
566
  /*
567
  * The element "output" is in the namespace XSLT_SAXON_NAMESPACE
568
  *   (http://icl.com/saxon)
569
  * The @file is in no namespace; it is an AVT.
570
  *   (http://www.computerwizards.com/saxon/doc/extensions.html#saxon:output)
571
  *
572
  * TODO: Do we need not to check the namespace here?
573
  */
574
0
  filename = xsltEvalStaticAttrValueTemplate(style, inst,
575
0
       (const xmlChar *)"file",
576
0
       NULL, &comp->has_filename);
577
0
    } else if (xmlStrEqual(inst->name, (const xmlChar *) "write")) {
578
#ifdef WITH_XSLT_DEBUG_EXTRA
579
  xsltGenericDebug(xsltGenericDebugContext,
580
      "Found xalan:write extension\n");
581
#endif
582
  /* the filename need to be interpreted */
583
  /*
584
  * TODO: Is "filename need to be interpreted" meant to be a todo?
585
  *   Where will be the filename of xalan:write be processed?
586
  *
587
  * TODO: Do we need not to check the namespace here?
588
  *   The extension ns is "http://xml.apache.org/xalan/redirect".
589
  *   See http://xml.apache.org/xalan-j/extensionslib.html.
590
  */
591
0
    } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
592
0
  if (inst->ns != NULL) {
593
0
      if (xmlStrEqual(inst->ns->href, XSLT_NAMESPACE)) {
594
    /*
595
    * Mark the instruction as being of
596
    * XSLT version 1.1 (abandoned).
597
    */
598
0
    comp->ver11 = 1;
599
#ifdef WITH_XSLT_DEBUG_EXTRA
600
    xsltGenericDebug(xsltGenericDebugContext,
601
        "Found xslt11:document construct\n");
602
#endif
603
0
      } else {
604
0
    if (xmlStrEqual(inst->ns->href,
605
0
        (const xmlChar *)"http://exslt.org/common")) {
606
        /* EXSLT. */
607
#ifdef WITH_XSLT_DEBUG_EXTRA
608
        xsltGenericDebug(xsltGenericDebugContext,
609
      "Found exslt:document extension\n");
610
#endif
611
0
    } else if (xmlStrEqual(inst->ns->href, XSLT_XT_NAMESPACE)) {
612
        /* James Clark's XT. */
613
#ifdef WITH_XSLT_DEBUG_EXTRA
614
        xsltGenericDebug(xsltGenericDebugContext,
615
      "Found xt:document extension\n");
616
#endif
617
0
    }
618
0
      }
619
0
  }
620
  /*
621
  * The element "document" is used in conjunction with the
622
  * following namespaces:
623
  *
624
  * 1) XSLT_NAMESPACE (http://www.w3.org/1999/XSL/Transform version 1.1)
625
  *    <!ELEMENT xsl:document %template;>
626
  *    <!ATTLIST xsl:document
627
  *       href %avt; #REQUIRED
628
  *    @href is an AVT
629
  *    IMPORTANT: xsl:document was in the abandoned XSLT 1.1 draft,
630
  *    it was removed and isn't available in XSLT 1.1 anymore.
631
  *    In XSLT 2.0 it was renamed to xsl:result-document.
632
  *
633
  *   All other attributes are identical to the attributes
634
  *   on xsl:output
635
  *
636
  * 2) EXSLT_COMMON_NAMESPACE (http://exslt.org/common)
637
  *    <exsl:document
638
  *       href = { uri-reference }
639
  *    TODO: is @href is an AVT?
640
  *
641
  * 3) XSLT_XT_NAMESPACE (http://www.jclark.com/xt)
642
  *     Example: <xt:document method="xml" href="myFile.xml">
643
  *    TODO: is @href is an AVT?
644
  *
645
  * In all cases @href is in no namespace.
646
  */
647
0
  filename = xsltEvalStaticAttrValueTemplate(style, inst,
648
0
      (const xmlChar *)"href", NULL, &comp->has_filename);
649
0
    }
650
0
    if (!comp->has_filename) {
651
0
  goto error;
652
0
    }
653
0
    comp->filename = filename;
654
655
0
error:
656
0
    return ((xsltElemPreCompPtr) comp);
657
0
}
658
659
/************************************************************************
660
 *                  *
661
 *    Most of the XSLT-1.0 transformations      *
662
 *                  *
663
 ************************************************************************/
664
665
/**
666
 * xsltSortComp:
667
 * @style:  the XSLT stylesheet
668
 * @inst:  the xslt sort node
669
 *
670
 * Process the xslt sort node on the source node
671
 */
672
static void
673
0
xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
674
#ifdef XSLT_REFACTORED
675
    xsltStyleItemSortPtr comp;
676
#else
677
0
    xsltStylePreCompPtr comp;
678
0
#endif
679
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
680
0
  return;
681
682
#ifdef XSLT_REFACTORED
683
    comp = (xsltStyleItemSortPtr) xsltNewStylePreComp(style, XSLT_FUNC_SORT);
684
#else
685
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT);
686
0
#endif
687
688
0
    if (comp == NULL)
689
0
  return;
690
0
    inst->psvi = comp;
691
0
    comp->inst = inst;
692
693
0
    comp->stype = xsltEvalStaticAttrValueTemplate(style, inst,
694
0
       (const xmlChar *)"data-type",
695
0
       NULL, &comp->has_stype);
696
0
    if (comp->stype != NULL) {
697
0
  if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
698
0
      comp->number = 0;
699
0
  else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
700
0
      comp->number = 1;
701
0
  else {
702
0
      xsltTransformError(NULL, style, inst,
703
0
     "xsltSortComp: no support for data-type = %s\n", comp->stype);
704
0
      comp->number = 0; /* use default */
705
0
      if (style != NULL) style->warnings++;
706
0
  }
707
0
    }
708
0
    comp->order = xsltEvalStaticAttrValueTemplate(style, inst,
709
0
            (const xmlChar *)"order",
710
0
            NULL, &comp->has_order);
711
0
    if (comp->order != NULL) {
712
0
  if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
713
0
      comp->descending = 0;
714
0
  else if (xmlStrEqual(comp->order, (const xmlChar *) "descending"))
715
0
      comp->descending = 1;
716
0
  else {
717
0
      xsltTransformError(NULL, style, inst,
718
0
     "xsltSortComp: invalid value %s for order\n", comp->order);
719
0
      comp->descending = 0; /* use default */
720
0
      if (style != NULL) style->warnings++;
721
0
  }
722
0
    }
723
0
    comp->case_order = xsltEvalStaticAttrValueTemplate(style, inst,
724
0
            (const xmlChar *)"case-order",
725
0
            NULL, &comp->has_use);
726
0
    if (comp->case_order != NULL) {
727
0
  if (xmlStrEqual(comp->case_order, (const xmlChar *) "upper-first"))
728
0
      comp->lower_first = 0;
729
0
  else if (xmlStrEqual(comp->case_order, (const xmlChar *) "lower-first"))
730
0
      comp->lower_first = 1;
731
0
  else {
732
0
      xsltTransformError(NULL, style, inst,
733
0
     "xsltSortComp: invalid value %s for order\n", comp->order);
734
0
      comp->lower_first = 0; /* use default */
735
0
      if (style != NULL) style->warnings++;
736
0
  }
737
0
    }
738
739
0
    comp->lang = xsltEvalStaticAttrValueTemplate(style, inst,
740
0
         (const xmlChar *)"lang",
741
0
         NULL, &comp->has_lang);
742
743
0
    comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE);
744
0
    if (comp->select == NULL) {
745
  /*
746
   * The default value of the select attribute is ., which will
747
   * cause the string-value of the current node to be used as
748
   * the sort key.
749
   */
750
0
  comp->select = xmlDictLookup(style->dict, BAD_CAST ".", 1);
751
0
    }
752
0
    comp->comp = xsltXPathCompile(style, comp->select);
753
0
    if (comp->comp == NULL) {
754
0
  xsltTransformError(NULL, style, inst,
755
0
       "xsltSortComp: could not compile select expression '%s'\n",
756
0
                   comp->select);
757
0
  if (style != NULL) style->errors++;
758
0
    }
759
0
    if (inst->children != NULL) {
760
0
  xsltTransformError(NULL, style, inst,
761
0
  "xsl:sort : is not empty\n");
762
0
  if (style != NULL) style->errors++;
763
0
    }
764
0
}
765
766
/**
767
 * xsltCopyComp:
768
 * @style:  the XSLT stylesheet
769
 * @inst:  the xslt copy node
770
 *
771
 * Process the xslt copy node on the source node
772
 */
773
static void
774
0
xsltCopyComp(xsltStylesheetPtr style, xmlNodePtr inst) {
775
#ifdef XSLT_REFACTORED
776
    xsltStyleItemCopyPtr comp;
777
#else
778
0
    xsltStylePreCompPtr comp;
779
0
#endif
780
781
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
782
0
  return;
783
#ifdef XSLT_REFACTORED
784
    comp = (xsltStyleItemCopyPtr) xsltNewStylePreComp(style, XSLT_FUNC_COPY);
785
#else
786
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_COPY);
787
0
#endif
788
789
0
    if (comp == NULL)
790
0
  return;
791
0
    inst->psvi = comp;
792
0
    comp->inst = inst;
793
794
795
0
    comp->use = xsltGetCNsProp(style, inst, (const xmlChar *)"use-attribute-sets",
796
0
            XSLT_NAMESPACE);
797
0
    if (comp->use == NULL)
798
0
  comp->has_use = 0;
799
0
    else
800
0
  comp->has_use = 1;
801
0
}
802
803
#ifdef XSLT_REFACTORED
804
    /* Enable if ever needed for xsl:text. */
805
#else
806
/**
807
 * xsltTextComp:
808
 * @style: an XSLT compiled stylesheet
809
 * @inst:  the xslt text node
810
 *
811
 * TODO: This function is obsolete, since xsl:text won't
812
 *  be compiled, but removed from the tree.
813
 *
814
 * Process the xslt text node on the source node
815
 */
816
static void
817
0
xsltTextComp(xsltStylesheetPtr style, xmlNodePtr inst) {
818
#ifdef XSLT_REFACTORED
819
    xsltStyleItemTextPtr comp;
820
#else
821
0
    xsltStylePreCompPtr comp;
822
0
#endif
823
0
    const xmlChar *prop;
824
825
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
826
0
  return;
827
828
#ifdef XSLT_REFACTORED
829
    comp = (xsltStyleItemTextPtr) xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
830
#else
831
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
832
0
#endif
833
0
    if (comp == NULL)
834
0
  return;
835
0
    inst->psvi = comp;
836
0
    comp->inst = inst;
837
0
    comp->noescape = 0;
838
839
0
    prop = xsltGetCNsProp(style, inst,
840
0
      (const xmlChar *)"disable-output-escaping",
841
0
      XSLT_NAMESPACE);
842
0
    if (prop != NULL) {
843
0
  if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
844
0
      comp->noescape = 1;
845
0
  } else if (!xmlStrEqual(prop,
846
0
      (const xmlChar *)"no")){
847
0
      xsltTransformError(NULL, style, inst,
848
0
    "xsl:text: disable-output-escaping allows only yes or no\n");
849
0
      if (style != NULL) style->warnings++;
850
0
  }
851
0
    }
852
0
}
853
#endif /* else of XSLT_REFACTORED */
854
855
/**
856
 * xsltElementComp:
857
 * @style: an XSLT compiled stylesheet
858
 * @inst:  the xslt element node
859
 *
860
 * Process the xslt element node on the source node
861
 */
862
static void
863
0
xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
864
#ifdef XSLT_REFACTORED
865
    xsltStyleItemElementPtr comp;
866
#else
867
0
    xsltStylePreCompPtr comp;
868
0
#endif
869
870
    /*
871
    * <xsl:element
872
    *   name = { qname }
873
    *   namespace = { uri-reference }
874
    *   use-attribute-sets = qnames>
875
    *   <!-- Content: template -->
876
    * </xsl:element>
877
    */
878
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
879
0
  return;
880
881
#ifdef XSLT_REFACTORED
882
    comp = (xsltStyleItemElementPtr) xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
883
#else
884
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
885
0
#endif
886
887
0
    if (comp == NULL)
888
0
  return;
889
0
    inst->psvi = comp;
890
0
    comp->inst = inst;
891
892
    /*
893
    * Attribute "name".
894
    */
895
    /*
896
    * TODO: Precompile the AVT. See bug #344894.
897
    */
898
0
    comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
899
0
  (const xmlChar *)"name", NULL, &comp->has_name);
900
0
    if (! comp->has_name) {
901
0
  xsltTransformError(NULL, style, inst,
902
0
      "xsl:element: The attribute 'name' is missing.\n");
903
0
  style->errors++;
904
0
  goto error;
905
0
    }
906
    /*
907
    * Attribute "namespace".
908
    */
909
    /*
910
    * TODO: Precompile the AVT. See bug #344894.
911
    */
912
0
    comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
913
0
  (const xmlChar *)"namespace", NULL, &comp->has_ns);
914
915
0
    if (comp->name != NULL) {
916
0
  if (xmlValidateQName(comp->name, 0)) {
917
0
      xsltTransformError(NULL, style, inst,
918
0
    "xsl:element: The value '%s' of the attribute 'name' is "
919
0
    "not a valid QName.\n", comp->name);
920
0
      style->errors++;
921
0
  } else {
922
0
      const xmlChar *prefix = NULL, *name;
923
924
0
      name = xsltSplitQName(style->dict, comp->name, &prefix);
925
0
      if (comp->has_ns == 0) {
926
0
    xmlNsPtr ns;
927
928
    /*
929
    * SPEC XSLT 1.0:
930
    *  "If the namespace attribute is not present, then the QName is
931
    *  expanded into an expanded-name using the namespace declarations
932
    *  in effect for the xsl:element element, including any default
933
    *  namespace declaration.
934
    */
935
0
    ns = xmlSearchNs(inst->doc, inst, prefix);
936
0
    if (ns != NULL) {
937
0
        comp->ns = xmlDictLookup(style->dict, ns->href, -1);
938
0
        comp->has_ns = 1;
939
#ifdef XSLT_REFACTORED
940
        comp->nsPrefix = prefix;
941
        comp->name = name;
942
#else
943
0
                    (void)name; /* Suppress unused variable warning. */
944
0
#endif
945
0
    } else if (prefix != NULL) {
946
0
        xsltTransformError(NULL, style, inst,
947
0
      "xsl:element: The prefixed QName '%s' "
948
0
      "has no namespace binding in scope in the "
949
0
      "stylesheet; this is an error, since the namespace was "
950
0
      "not specified by the instruction itself.\n", comp->name);
951
0
        style->errors++;
952
0
    }
953
0
      }
954
0
      if ((prefix != NULL) &&
955
0
    (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)))
956
0
      {
957
    /*
958
    * Mark is to be skipped.
959
    */
960
0
    comp->has_name = 0;
961
0
      }
962
0
  }
963
0
    }
964
    /*
965
    * Attribute "use-attribute-sets",
966
    */
967
0
    comp->use = xsltEvalStaticAttrValueTemplate(style, inst,
968
0
           (const xmlChar *)"use-attribute-sets",
969
0
           NULL, &comp->has_use);
970
971
0
error:
972
0
    return;
973
0
}
974
975
/**
976
 * xsltAttributeComp:
977
 * @style: an XSLT compiled stylesheet
978
 * @inst:  the xslt attribute node
979
 *
980
 * Process the xslt attribute node on the source node
981
 */
982
static void
983
0
xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
984
#ifdef XSLT_REFACTORED
985
    xsltStyleItemAttributePtr comp;
986
#else
987
0
    xsltStylePreCompPtr comp;
988
0
#endif
989
990
    /*
991
    * <xsl:attribute
992
    *   name = { qname }
993
    *   namespace = { uri-reference }>
994
    *   <!-- Content: template -->
995
    * </xsl:attribute>
996
    */
997
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
998
0
  return;
999
1000
#ifdef XSLT_REFACTORED
1001
    comp = (xsltStyleItemAttributePtr) xsltNewStylePreComp(style,
1002
  XSLT_FUNC_ATTRIBUTE);
1003
#else
1004
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE);
1005
0
#endif
1006
1007
0
    if (comp == NULL)
1008
0
  return;
1009
0
    inst->psvi = comp;
1010
0
    comp->inst = inst;
1011
1012
    /*
1013
    * Attribute "name".
1014
    */
1015
    /*
1016
    * TODO: Precompile the AVT. See bug #344894.
1017
    */
1018
0
    comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
1019
0
         (const xmlChar *)"name",
1020
0
         NULL, &comp->has_name);
1021
0
    if (! comp->has_name) {
1022
0
  xsltTransformError(NULL, style, inst,
1023
0
      "XSLT-attribute: The attribute 'name' is missing.\n");
1024
0
  style->errors++;
1025
0
  return;
1026
0
    }
1027
    /*
1028
    * Attribute "namespace".
1029
    */
1030
    /*
1031
    * TODO: Precompile the AVT. See bug #344894.
1032
    */
1033
0
    comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
1034
0
  (const xmlChar *)"namespace",
1035
0
  NULL, &comp->has_ns);
1036
1037
0
    if (comp->name != NULL) {
1038
0
  if (xmlValidateQName(comp->name, 0)) {
1039
0
      xsltTransformError(NULL, style, inst,
1040
0
    "xsl:attribute: The value '%s' of the attribute 'name' is "
1041
0
    "not a valid QName.\n", comp->name);
1042
0
      style->errors++;
1043
0
        } else if (xmlStrEqual(comp->name, BAD_CAST "xmlns")) {
1044
0
      xsltTransformError(NULL, style, inst,
1045
0
                "xsl:attribute: The attribute name 'xmlns' is not allowed.\n");
1046
0
      style->errors++;
1047
0
  } else {
1048
0
      const xmlChar *prefix = NULL, *name;
1049
1050
0
      name = xsltSplitQName(style->dict, comp->name, &prefix);
1051
0
      if (prefix != NULL) {
1052
0
    if (comp->has_ns == 0) {
1053
0
        xmlNsPtr ns;
1054
1055
        /*
1056
        * SPEC XSLT 1.0:
1057
        *  "If the namespace attribute is not present, then the
1058
        *  QName is expanded into an expanded-name using the
1059
        *  namespace declarations in effect for the xsl:element
1060
        *  element, including any default namespace declaration.
1061
        */
1062
0
        ns = xmlSearchNs(inst->doc, inst, prefix);
1063
0
        if (ns != NULL) {
1064
0
      comp->ns = xmlDictLookup(style->dict, ns->href, -1);
1065
0
      comp->has_ns = 1;
1066
#ifdef XSLT_REFACTORED
1067
      comp->nsPrefix = prefix;
1068
      comp->name = name;
1069
#else
1070
0
                        (void)name; /* Suppress unused variable warning. */
1071
0
#endif
1072
0
        } else {
1073
0
      xsltTransformError(NULL, style, inst,
1074
0
          "xsl:attribute: The prefixed QName '%s' "
1075
0
          "has no namespace binding in scope in the "
1076
0
          "stylesheet; this is an error, since the "
1077
0
          "namespace was not specified by the instruction "
1078
0
          "itself.\n", comp->name);
1079
0
      style->errors++;
1080
0
        }
1081
0
    }
1082
0
      }
1083
0
  }
1084
0
    }
1085
0
}
1086
1087
/**
1088
 * xsltCommentComp:
1089
 * @style: an XSLT compiled stylesheet
1090
 * @inst:  the xslt comment node
1091
 *
1092
 * Process the xslt comment node on the source node
1093
 */
1094
static void
1095
0
xsltCommentComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1096
#ifdef XSLT_REFACTORED
1097
    xsltStyleItemCommentPtr comp;
1098
#else
1099
0
    xsltStylePreCompPtr comp;
1100
0
#endif
1101
1102
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1103
0
  return;
1104
1105
#ifdef XSLT_REFACTORED
1106
    comp = (xsltStyleItemCommentPtr) xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
1107
#else
1108
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
1109
0
#endif
1110
1111
0
    if (comp == NULL)
1112
0
  return;
1113
0
    inst->psvi = comp;
1114
0
    comp->inst = inst;
1115
0
}
1116
1117
/**
1118
 * xsltProcessingInstructionComp:
1119
 * @style: an XSLT compiled stylesheet
1120
 * @inst:  the xslt processing-instruction node
1121
 *
1122
 * Process the xslt processing-instruction node on the source node
1123
 */
1124
static void
1125
0
xsltProcessingInstructionComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1126
#ifdef XSLT_REFACTORED
1127
    xsltStyleItemPIPtr comp;
1128
#else
1129
0
    xsltStylePreCompPtr comp;
1130
0
#endif
1131
1132
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1133
0
  return;
1134
1135
#ifdef XSLT_REFACTORED
1136
    comp = (xsltStyleItemPIPtr) xsltNewStylePreComp(style, XSLT_FUNC_PI);
1137
#else
1138
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_PI);
1139
0
#endif
1140
1141
0
    if (comp == NULL)
1142
0
  return;
1143
0
    inst->psvi = comp;
1144
0
    comp->inst = inst;
1145
1146
0
    comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
1147
0
         (const xmlChar *)"name",
1148
0
         XSLT_NAMESPACE, &comp->has_name);
1149
0
}
1150
1151
/**
1152
 * xsltCopyOfComp:
1153
 * @style: an XSLT compiled stylesheet
1154
 * @inst:  the xslt copy-of node
1155
 *
1156
 * Process the xslt copy-of node on the source node
1157
 */
1158
static void
1159
0
xsltCopyOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1160
#ifdef XSLT_REFACTORED
1161
    xsltStyleItemCopyOfPtr comp;
1162
#else
1163
0
    xsltStylePreCompPtr comp;
1164
0
#endif
1165
1166
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1167
0
  return;
1168
1169
#ifdef XSLT_REFACTORED
1170
    comp = (xsltStyleItemCopyOfPtr) xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
1171
#else
1172
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
1173
0
#endif
1174
1175
0
    if (comp == NULL)
1176
0
  return;
1177
0
    inst->psvi = comp;
1178
0
    comp->inst = inst;
1179
1180
0
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1181
0
                          XSLT_NAMESPACE);
1182
0
    if (comp->select == NULL) {
1183
0
  xsltTransformError(NULL, style, inst,
1184
0
       "xsl:copy-of : select is missing\n");
1185
0
  if (style != NULL) style->errors++;
1186
0
  return;
1187
0
    }
1188
0
    comp->comp = xsltXPathCompile(style, comp->select);
1189
0
    if (comp->comp == NULL) {
1190
0
  xsltTransformError(NULL, style, inst,
1191
0
       "xsl:copy-of : could not compile select expression '%s'\n",
1192
0
                   comp->select);
1193
0
  if (style != NULL) style->errors++;
1194
0
    }
1195
0
}
1196
1197
/**
1198
 * xsltValueOfComp:
1199
 * @style: an XSLT compiled stylesheet
1200
 * @inst:  the xslt value-of node
1201
 *
1202
 * Process the xslt value-of node on the source node
1203
 */
1204
static void
1205
0
xsltValueOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1206
#ifdef XSLT_REFACTORED
1207
    xsltStyleItemValueOfPtr comp;
1208
#else
1209
0
    xsltStylePreCompPtr comp;
1210
0
#endif
1211
0
    const xmlChar *prop;
1212
1213
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1214
0
  return;
1215
1216
#ifdef XSLT_REFACTORED
1217
    comp = (xsltStyleItemValueOfPtr) xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
1218
#else
1219
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
1220
0
#endif
1221
1222
0
    if (comp == NULL)
1223
0
  return;
1224
0
    inst->psvi = comp;
1225
0
    comp->inst = inst;
1226
1227
0
    prop = xsltGetCNsProp(style, inst,
1228
0
      (const xmlChar *)"disable-output-escaping",
1229
0
      XSLT_NAMESPACE);
1230
0
    if (prop != NULL) {
1231
0
  if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
1232
0
      comp->noescape = 1;
1233
0
  } else if (!xmlStrEqual(prop,
1234
0
        (const xmlChar *)"no")){
1235
0
      xsltTransformError(NULL, style, inst,
1236
0
"xsl:value-of : disable-output-escaping allows only yes or no\n");
1237
0
      if (style != NULL) style->warnings++;
1238
0
  }
1239
0
    }
1240
0
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1241
0
                          XSLT_NAMESPACE);
1242
0
    if (comp->select == NULL) {
1243
0
  xsltTransformError(NULL, style, inst,
1244
0
       "xsl:value-of : select is missing\n");
1245
0
  if (style != NULL) style->errors++;
1246
0
  return;
1247
0
    }
1248
0
    comp->comp = xsltXPathCompile(style, comp->select);
1249
0
    if (comp->comp == NULL) {
1250
0
  xsltTransformError(NULL, style, inst,
1251
0
       "xsl:value-of : could not compile select expression '%s'\n",
1252
0
                   comp->select);
1253
0
  if (style != NULL) style->errors++;
1254
0
    }
1255
0
}
1256
1257
static void
1258
xsltGetQNameProperty(xsltStylesheetPtr style, xmlNodePtr inst,
1259
         const xmlChar *propName,
1260
         int mandatory,
1261
         int *hasProp, const xmlChar **nsName,
1262
         const xmlChar** localName)
1263
0
{
1264
0
    const xmlChar *prop;
1265
1266
0
    if (nsName)
1267
0
  *nsName = NULL;
1268
0
    if (localName)
1269
0
  *localName = NULL;
1270
0
    if (hasProp)
1271
0
  *hasProp = 0;
1272
1273
0
    prop = xsltGetCNsProp(style, inst, propName, XSLT_NAMESPACE);
1274
0
    if (prop == NULL) {
1275
0
  if (mandatory) {
1276
0
      xsltTransformError(NULL, style, inst,
1277
0
    "The attribute '%s' is missing.\n", propName);
1278
0
      style->errors++;
1279
0
      return;
1280
0
  }
1281
0
    } else {
1282
0
        const xmlChar *URI;
1283
1284
0
  if (xmlValidateQName(prop, 0)) {
1285
0
      xsltTransformError(NULL, style, inst,
1286
0
    "The value '%s' of the attribute "
1287
0
    "'%s' is not a valid QName.\n", prop, propName);
1288
0
      style->errors++;
1289
0
      return;
1290
0
  } else {
1291
      /*
1292
      * @prop will be in the string dict afterwards, @URI not.
1293
      */
1294
0
      URI = xsltGetQNameURI2(style, inst, &prop);
1295
0
      if (prop == NULL) {
1296
0
    style->errors++;
1297
0
      } else {
1298
0
    if (localName)
1299
0
        *localName = prop;
1300
0
    if (hasProp)
1301
0
        *hasProp = 1;
1302
0
    if (URI != NULL) {
1303
        /*
1304
        * Fixes bug #308441: Put the ns-name in the dict
1305
        * in order to pointer compare names during XPath's
1306
        * variable lookup.
1307
        */
1308
0
        if (nsName)
1309
0
      *nsName = xmlDictLookup(style->dict, URI, -1);
1310
        /* comp->has_ns = 1; */
1311
0
    }
1312
0
      }
1313
0
  }
1314
0
    }
1315
0
    return;
1316
0
}
1317
1318
/**
1319
 * xsltWithParamComp:
1320
 * @style: an XSLT compiled stylesheet
1321
 * @inst:  the xslt with-param node
1322
 *
1323
 * Process the xslt with-param node on the source node
1324
 * Allowed parents: xsl:call-template, xsl:apply-templates.
1325
 * <xsl:with-param
1326
 *  name = qname
1327
 *  select = expression>
1328
 *  <!-- Content: template -->
1329
 * </xsl:with-param>
1330
 */
1331
static void
1332
0
xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1333
#ifdef XSLT_REFACTORED
1334
    xsltStyleItemWithParamPtr comp;
1335
#else
1336
0
    xsltStylePreCompPtr comp;
1337
0
#endif
1338
1339
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1340
0
  return;
1341
1342
#ifdef XSLT_REFACTORED
1343
    comp = (xsltStyleItemWithParamPtr) xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
1344
#else
1345
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
1346
0
#endif
1347
1348
0
    if (comp == NULL)
1349
0
  return;
1350
0
    inst->psvi = comp;
1351
0
    comp->inst = inst;
1352
1353
    /*
1354
    * Attribute "name".
1355
    */
1356
0
    xsltGetQNameProperty(style, inst, BAD_CAST "name",
1357
0
  1, &(comp->has_name), &(comp->ns), &(comp->name));
1358
0
    if (comp->ns)
1359
0
  comp->has_ns = 1;
1360
    /*
1361
    * Attribute "select".
1362
    */
1363
0
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1364
0
                          XSLT_NAMESPACE);
1365
0
    if (comp->select != NULL) {
1366
0
  comp->comp = xsltXPathCompile(style, comp->select);
1367
0
  if (comp->comp == NULL) {
1368
0
      xsltTransformError(NULL, style, inst,
1369
0
     "XSLT-with-param: Failed to compile select "
1370
0
     "expression '%s'\n", comp->select);
1371
0
      style->errors++;
1372
0
  }
1373
0
  if (inst->children != NULL) {
1374
0
      xsltTransformError(NULL, style, inst,
1375
0
    "XSLT-with-param: The content should be empty since "
1376
0
    "the attribute select is present.\n");
1377
0
      style->warnings++;
1378
0
  }
1379
0
    }
1380
0
}
1381
1382
/**
1383
 * xsltNumberComp:
1384
 * @style: an XSLT compiled stylesheet
1385
 * @cur:   the xslt number node
1386
 *
1387
 * Process the xslt number node on the source node
1388
 */
1389
static void
1390
0
xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
1391
#ifdef XSLT_REFACTORED
1392
    xsltStyleItemNumberPtr comp;
1393
#else
1394
0
    xsltStylePreCompPtr comp;
1395
0
#endif
1396
0
    const xmlChar *prop;
1397
1398
0
    if ((style == NULL) || (cur == NULL) || (cur->type != XML_ELEMENT_NODE))
1399
0
  return;
1400
1401
#ifdef XSLT_REFACTORED
1402
    comp = (xsltStyleItemNumberPtr) xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
1403
#else
1404
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
1405
0
#endif
1406
1407
0
    if (comp == NULL)
1408
0
  return;
1409
0
    cur->psvi = comp;
1410
1411
0
    comp->numdata.doc = cur->doc;
1412
0
    comp->numdata.node = cur;
1413
0
    comp->numdata.value = xsltGetCNsProp(style, cur, (const xmlChar *)"value",
1414
0
                                  XSLT_NAMESPACE);
1415
1416
0
    prop = xsltEvalStaticAttrValueTemplate(style, cur,
1417
0
       (const xmlChar *)"format",
1418
0
       XSLT_NAMESPACE, &comp->numdata.has_format);
1419
0
    if (comp->numdata.has_format == 0) {
1420
0
  comp->numdata.format = xmlDictLookup(style->dict, BAD_CAST "" , 0);
1421
0
    } else {
1422
0
  comp->numdata.format = prop;
1423
0
    }
1424
1425
0
    comp->numdata.count = xsltGetCNsProp(style, cur, (const xmlChar *)"count",
1426
0
                                         XSLT_NAMESPACE);
1427
0
    comp->numdata.from = xsltGetCNsProp(style, cur, (const xmlChar *)"from",
1428
0
                                        XSLT_NAMESPACE);
1429
1430
0
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"count", XSLT_NAMESPACE);
1431
0
    if (prop != NULL) {
1432
0
  comp->numdata.countPat = xsltCompilePattern(prop, cur->doc, cur, style,
1433
0
                                                    NULL);
1434
0
    }
1435
1436
0
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"from", XSLT_NAMESPACE);
1437
0
    if (prop != NULL) {
1438
0
  comp->numdata.fromPat = xsltCompilePattern(prop, cur->doc, cur, style,
1439
0
                                                   NULL);
1440
0
    }
1441
1442
0
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"level", XSLT_NAMESPACE);
1443
0
    if (prop != NULL) {
1444
0
  if (xmlStrEqual(prop, BAD_CAST("single")) ||
1445
0
      xmlStrEqual(prop, BAD_CAST("multiple")) ||
1446
0
      xmlStrEqual(prop, BAD_CAST("any"))) {
1447
0
      comp->numdata.level = prop;
1448
0
  } else {
1449
0
      xsltTransformError(NULL, style, cur,
1450
0
       "xsl:number : invalid value %s for level\n", prop);
1451
0
      if (style != NULL) style->warnings++;
1452
0
  }
1453
0
    }
1454
1455
0
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"lang", XSLT_NAMESPACE);
1456
0
    if (prop != NULL) {
1457
0
      xsltTransformError(NULL, style, cur,
1458
0
     "xsl:number : lang attribute not implemented\n");
1459
0
  XSLT_TODO; /* xsl:number lang attribute */
1460
0
    }
1461
1462
0
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"letter-value", XSLT_NAMESPACE);
1463
0
    if (prop != NULL) {
1464
0
  if (xmlStrEqual(prop, BAD_CAST("alphabetic"))) {
1465
0
      xsltTransformError(NULL, style, cur,
1466
0
     "xsl:number : letter-value 'alphabetic' not implemented\n");
1467
0
      if (style != NULL) style->warnings++;
1468
0
      XSLT_TODO; /* xsl:number letter-value attribute alphabetic */
1469
0
  } else if (xmlStrEqual(prop, BAD_CAST("traditional"))) {
1470
0
      xsltTransformError(NULL, style, cur,
1471
0
     "xsl:number : letter-value 'traditional' not implemented\n");
1472
0
      if (style != NULL) style->warnings++;
1473
0
      XSLT_TODO; /* xsl:number letter-value attribute traditional */
1474
0
  } else {
1475
0
      xsltTransformError(NULL, style, cur,
1476
0
         "xsl:number : invalid value %s for letter-value\n", prop);
1477
0
      if (style != NULL) style->warnings++;
1478
0
  }
1479
0
    }
1480
1481
0
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-separator",
1482
0
                  XSLT_NAMESPACE);
1483
0
    if (prop != NULL) {
1484
0
        comp->numdata.groupingCharacterLen = xmlStrlen(prop);
1485
0
  comp->numdata.groupingCharacter =
1486
0
      xsltGetUTF8Char(prop, &(comp->numdata.groupingCharacterLen));
1487
0
        if (comp->numdata.groupingCharacter < 0)
1488
0
            comp->numdata.groupingCharacter = 0;
1489
0
    }
1490
1491
0
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-size", XSLT_NAMESPACE);
1492
0
    if (prop != NULL) {
1493
0
  sscanf((char *)prop, "%d", &comp->numdata.digitsPerGroup);
1494
0
    } else {
1495
0
  comp->numdata.groupingCharacter = 0;
1496
0
    }
1497
1498
    /* Set default values */
1499
0
    if (comp->numdata.value == NULL) {
1500
0
  if (comp->numdata.level == NULL) {
1501
0
      comp->numdata.level = xmlDictLookup(style->dict,
1502
0
                                          BAD_CAST"single", 6);
1503
0
  }
1504
0
    }
1505
1506
0
}
1507
1508
/**
1509
 * xsltApplyImportsComp:
1510
 * @style: an XSLT compiled stylesheet
1511
 * @inst:  the xslt apply-imports node
1512
 *
1513
 * Process the xslt apply-imports node on the source node
1514
 */
1515
static void
1516
0
xsltApplyImportsComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1517
#ifdef XSLT_REFACTORED
1518
    xsltStyleItemApplyImportsPtr comp;
1519
#else
1520
0
    xsltStylePreCompPtr comp;
1521
0
#endif
1522
1523
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1524
0
  return;
1525
1526
#ifdef XSLT_REFACTORED
1527
    comp = (xsltStyleItemApplyImportsPtr) xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
1528
#else
1529
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
1530
0
#endif
1531
1532
0
    if (comp == NULL)
1533
0
  return;
1534
0
    inst->psvi = comp;
1535
0
    comp->inst = inst;
1536
0
}
1537
1538
/**
1539
 * xsltCallTemplateComp:
1540
 * @style: an XSLT compiled stylesheet
1541
 * @inst:  the xslt call-template node
1542
 *
1543
 * Process the xslt call-template node on the source node
1544
 */
1545
static void
1546
0
xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1547
#ifdef XSLT_REFACTORED
1548
    xsltStyleItemCallTemplatePtr comp;
1549
#else
1550
0
    xsltStylePreCompPtr comp;
1551
0
#endif
1552
1553
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1554
0
  return;
1555
1556
#ifdef XSLT_REFACTORED
1557
    comp = (xsltStyleItemCallTemplatePtr)
1558
  xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
1559
#else
1560
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
1561
0
#endif
1562
1563
0
    if (comp == NULL)
1564
0
  return;
1565
0
    inst->psvi = comp;
1566
0
    comp->inst = inst;
1567
1568
    /*
1569
     * Attribute "name".
1570
     */
1571
0
    xsltGetQNameProperty(style, inst, BAD_CAST "name",
1572
0
  1, &(comp->has_name), &(comp->ns), &(comp->name));
1573
0
    if (comp->ns)
1574
0
  comp->has_ns = 1;
1575
0
}
1576
1577
/**
1578
 * xsltApplyTemplatesComp:
1579
 * @style: an XSLT compiled stylesheet
1580
 * @inst:  the apply-templates node
1581
 *
1582
 * Process the apply-templates node on the source node
1583
 */
1584
static void
1585
0
xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1586
#ifdef XSLT_REFACTORED
1587
    xsltStyleItemApplyTemplatesPtr comp;
1588
#else
1589
0
    xsltStylePreCompPtr comp;
1590
0
#endif
1591
1592
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1593
0
  return;
1594
1595
#ifdef XSLT_REFACTORED
1596
    comp = (xsltStyleItemApplyTemplatesPtr)
1597
  xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
1598
#else
1599
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
1600
0
#endif
1601
1602
0
    if (comp == NULL)
1603
0
  return;
1604
0
    inst->psvi = comp;
1605
0
    comp->inst = inst;
1606
1607
    /*
1608
     * Attribute "mode".
1609
     */
1610
0
    xsltGetQNameProperty(style, inst, BAD_CAST "mode",
1611
0
  0, NULL, &(comp->modeURI), &(comp->mode));
1612
    /*
1613
    * Attribute "select".
1614
    */
1615
0
    comp->select = xsltGetCNsProp(style, inst, BAD_CAST "select",
1616
0
  XSLT_NAMESPACE);
1617
0
    if (comp->select != NULL) {
1618
0
  comp->comp = xsltXPathCompile(style, comp->select);
1619
0
  if (comp->comp == NULL) {
1620
0
      xsltTransformError(NULL, style, inst,
1621
0
    "XSLT-apply-templates: could not compile select "
1622
0
    "expression '%s'\n", comp->select);
1623
0
       style->errors++;
1624
0
  }
1625
0
    }
1626
    /* TODO: handle (or skip) the xsl:sort and xsl:with-param */
1627
0
}
1628
1629
/**
1630
 * xsltChooseComp:
1631
 * @style: an XSLT compiled stylesheet
1632
 * @inst:  the xslt choose node
1633
 *
1634
 * Process the xslt choose node on the source node
1635
 */
1636
static void
1637
0
xsltChooseComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1638
#ifdef XSLT_REFACTORED
1639
    xsltStyleItemChoosePtr comp;
1640
#else
1641
0
    xsltStylePreCompPtr comp;
1642
0
#endif
1643
1644
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1645
0
  return;
1646
1647
#ifdef XSLT_REFACTORED
1648
    comp = (xsltStyleItemChoosePtr)
1649
  xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
1650
#else
1651
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
1652
0
#endif
1653
1654
0
    if (comp == NULL)
1655
0
  return;
1656
0
    inst->psvi = comp;
1657
0
    comp->inst = inst;
1658
0
}
1659
1660
/**
1661
 * xsltIfComp:
1662
 * @style: an XSLT compiled stylesheet
1663
 * @inst:  the xslt if node
1664
 *
1665
 * Process the xslt if node on the source node
1666
 */
1667
static void
1668
0
xsltIfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1669
#ifdef XSLT_REFACTORED
1670
    xsltStyleItemIfPtr comp;
1671
#else
1672
0
    xsltStylePreCompPtr comp;
1673
0
#endif
1674
1675
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1676
0
  return;
1677
1678
#ifdef XSLT_REFACTORED
1679
    comp = (xsltStyleItemIfPtr)
1680
  xsltNewStylePreComp(style, XSLT_FUNC_IF);
1681
#else
1682
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_IF);
1683
0
#endif
1684
1685
0
    if (comp == NULL)
1686
0
  return;
1687
0
    inst->psvi = comp;
1688
0
    comp->inst = inst;
1689
1690
0
    comp->test = xsltGetCNsProp(style, inst, (const xmlChar *)"test", XSLT_NAMESPACE);
1691
0
    if (comp->test == NULL) {
1692
0
  xsltTransformError(NULL, style, inst,
1693
0
       "xsl:if : test is not defined\n");
1694
0
  if (style != NULL) style->errors++;
1695
0
  return;
1696
0
    }
1697
0
    comp->comp = xsltXPathCompile(style, comp->test);
1698
0
    if (comp->comp == NULL) {
1699
0
  xsltTransformError(NULL, style, inst,
1700
0
       "xsl:if : could not compile test expression '%s'\n",
1701
0
                   comp->test);
1702
0
  if (style != NULL) style->errors++;
1703
0
    }
1704
0
}
1705
1706
/**
1707
 * xsltWhenComp:
1708
 * @style: an XSLT compiled stylesheet
1709
 * @inst:  the xslt if node
1710
 *
1711
 * Process the xslt if node on the source node
1712
 */
1713
static void
1714
0
xsltWhenComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1715
#ifdef XSLT_REFACTORED
1716
    xsltStyleItemWhenPtr comp;
1717
#else
1718
0
    xsltStylePreCompPtr comp;
1719
0
#endif
1720
1721
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1722
0
  return;
1723
1724
#ifdef XSLT_REFACTORED
1725
    comp = (xsltStyleItemWhenPtr)
1726
  xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
1727
#else
1728
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
1729
0
#endif
1730
1731
0
    if (comp == NULL)
1732
0
  return;
1733
0
    inst->psvi = comp;
1734
0
    comp->inst = inst;
1735
1736
0
    comp->test = xsltGetCNsProp(style, inst, (const xmlChar *)"test", XSLT_NAMESPACE);
1737
0
    if (comp->test == NULL) {
1738
0
  xsltTransformError(NULL, style, inst,
1739
0
       "xsl:when : test is not defined\n");
1740
0
  if (style != NULL) style->errors++;
1741
0
  return;
1742
0
    }
1743
0
    comp->comp = xsltXPathCompile(style, comp->test);
1744
0
    if (comp->comp == NULL) {
1745
0
  xsltTransformError(NULL, style, inst,
1746
0
       "xsl:when : could not compile test expression '%s'\n",
1747
0
                   comp->test);
1748
0
  if (style != NULL) style->errors++;
1749
0
    }
1750
0
}
1751
1752
/**
1753
 * xsltForEachComp:
1754
 * @style: an XSLT compiled stylesheet
1755
 * @inst:  the xslt for-each node
1756
 *
1757
 * Process the xslt for-each node on the source node
1758
 */
1759
static void
1760
0
xsltForEachComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1761
#ifdef XSLT_REFACTORED
1762
    xsltStyleItemForEachPtr comp;
1763
#else
1764
0
    xsltStylePreCompPtr comp;
1765
0
#endif
1766
1767
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1768
0
  return;
1769
1770
#ifdef XSLT_REFACTORED
1771
    comp = (xsltStyleItemForEachPtr)
1772
  xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
1773
#else
1774
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
1775
0
#endif
1776
1777
0
    if (comp == NULL)
1778
0
  return;
1779
0
    inst->psvi = comp;
1780
0
    comp->inst = inst;
1781
1782
0
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1783
0
                          XSLT_NAMESPACE);
1784
0
    if (comp->select == NULL) {
1785
0
  xsltTransformError(NULL, style, inst,
1786
0
    "xsl:for-each : select is missing\n");
1787
0
  if (style != NULL) style->errors++;
1788
0
    } else {
1789
0
  comp->comp = xsltXPathCompile(style, comp->select);
1790
0
  if (comp->comp == NULL) {
1791
0
      xsltTransformError(NULL, style, inst,
1792
0
     "xsl:for-each : could not compile select expression '%s'\n",
1793
0
           comp->select);
1794
0
      if (style != NULL) style->errors++;
1795
0
  }
1796
0
    }
1797
    /* TODO: handle and skip the xsl:sort */
1798
0
}
1799
1800
/**
1801
 * xsltVariableComp:
1802
 * @style: an XSLT compiled stylesheet
1803
 * @inst:  the xslt variable node
1804
 *
1805
 * Process the xslt variable node on the source node
1806
 */
1807
static void
1808
0
xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1809
#ifdef XSLT_REFACTORED
1810
    xsltStyleItemVariablePtr comp;
1811
#else
1812
0
    xsltStylePreCompPtr comp;
1813
0
#endif
1814
1815
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1816
0
  return;
1817
1818
#ifdef XSLT_REFACTORED
1819
    comp = (xsltStyleItemVariablePtr)
1820
  xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
1821
#else
1822
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
1823
0
#endif
1824
1825
0
    if (comp == NULL)
1826
0
  return;
1827
1828
0
    inst->psvi = comp;
1829
0
    comp->inst = inst;
1830
    /*
1831
     * The full template resolution can be done statically
1832
     */
1833
1834
    /*
1835
    * Attribute "name".
1836
    */
1837
0
    xsltGetQNameProperty(style, inst, BAD_CAST "name",
1838
0
  1, &(comp->has_name), &(comp->ns), &(comp->name));
1839
0
    if (comp->ns)
1840
0
  comp->has_ns = 1;
1841
    /*
1842
    * Attribute "select".
1843
    */
1844
0
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1845
0
                          XSLT_NAMESPACE);
1846
0
    if (comp->select != NULL) {
1847
0
#ifndef XSLT_REFACTORED
1848
0
        xmlNodePtr cur;
1849
0
#endif
1850
0
  comp->comp = xsltXPathCompile(style, comp->select);
1851
0
  if (comp->comp == NULL) {
1852
0
      xsltTransformError(NULL, style, inst,
1853
0
    "XSLT-variable: Failed to compile the XPath expression '%s'.\n",
1854
0
    comp->select);
1855
0
      style->errors++;
1856
0
  }
1857
#ifdef XSLT_REFACTORED
1858
  if (inst->children != NULL) {
1859
      xsltTransformError(NULL, style, inst,
1860
    "XSLT-variable: There must be no child nodes, since the "
1861
    "attribute 'select' was specified.\n");
1862
      style->errors++;
1863
  }
1864
#else
1865
0
        for (cur = inst->children; cur != NULL; cur = cur->next) {
1866
0
            if (cur->type != XML_COMMENT_NODE &&
1867
0
                (cur->type != XML_TEXT_NODE || !xsltIsBlank(cur->content)))
1868
0
            {
1869
0
                xsltTransformError(NULL, style, inst,
1870
0
                    "XSLT-variable: There must be no child nodes, since the "
1871
0
                    "attribute 'select' was specified.\n");
1872
0
                style->errors++;
1873
0
            }
1874
0
        }
1875
0
#endif
1876
0
    }
1877
0
}
1878
1879
/**
1880
 * xsltParamComp:
1881
 * @style: an XSLT compiled stylesheet
1882
 * @inst:  the xslt param node
1883
 *
1884
 * Process the xslt param node on the source node
1885
 */
1886
static void
1887
0
xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1888
#ifdef XSLT_REFACTORED
1889
    xsltStyleItemParamPtr comp;
1890
#else
1891
0
    xsltStylePreCompPtr comp;
1892
0
#endif
1893
1894
0
    if ((style == NULL) || (inst == NULL) || (inst->type != XML_ELEMENT_NODE))
1895
0
  return;
1896
1897
#ifdef XSLT_REFACTORED
1898
    comp = (xsltStyleItemParamPtr)
1899
  xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
1900
#else
1901
0
    comp = xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
1902
0
#endif
1903
1904
0
    if (comp == NULL)
1905
0
  return;
1906
0
    inst->psvi = comp;
1907
0
    comp->inst = inst;
1908
1909
    /*
1910
     * Attribute "name".
1911
     */
1912
0
    xsltGetQNameProperty(style, inst, BAD_CAST "name",
1913
0
  1, &(comp->has_name), &(comp->ns), &(comp->name));
1914
0
    if (comp->ns)
1915
0
  comp->has_ns = 1;
1916
    /*
1917
    * Attribute "select".
1918
    */
1919
0
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1920
0
                          XSLT_NAMESPACE);
1921
0
    if (comp->select != NULL) {
1922
0
  comp->comp = xsltXPathCompile(style, comp->select);
1923
0
  if (comp->comp == NULL) {
1924
0
      xsltTransformError(NULL, style, inst,
1925
0
    "XSLT-param: could not compile select expression '%s'.\n",
1926
0
    comp->select);
1927
0
      style->errors++;
1928
0
  }
1929
0
  if (inst->children != NULL) {
1930
0
      xsltTransformError(NULL, style, inst,
1931
0
    "XSLT-param: The content should be empty since the "
1932
0
    "attribute 'select' is present.\n");
1933
0
      style->warnings++;
1934
0
  }
1935
0
    }
1936
0
}
1937
1938
/************************************************************************
1939
 *                  *
1940
 *        Generic interface         *
1941
 *                  *
1942
 ************************************************************************/
1943
1944
/**
1945
 * xsltFreeStylePreComps:
1946
 * @style:  an XSLT transformation context
1947
 *
1948
 * Free up the memory allocated by all precomputed blocks
1949
 */
1950
void
1951
0
xsltFreeStylePreComps(xsltStylesheetPtr style) {
1952
0
    xsltElemPreCompPtr cur, next;
1953
1954
0
    if (style == NULL)
1955
0
  return;
1956
1957
0
    cur = style->preComps;
1958
0
    while (cur != NULL) {
1959
0
  next = cur->next;
1960
0
  if (cur->type == XSLT_FUNC_EXTENSION)
1961
0
      cur->free(cur);
1962
0
  else
1963
0
      xsltFreeStylePreComp((xsltStylePreCompPtr) cur);
1964
0
  cur = next;
1965
0
    }
1966
0
}
1967
1968
#ifdef XSLT_REFACTORED
1969
1970
/**
1971
 * xsltStylePreCompute:
1972
 * @style:  the XSLT stylesheet
1973
 * @node:  the element in the XSLT namespace
1974
 *
1975
 * Precompute an XSLT element.
1976
 * This expects the type of the element to be already
1977
 * set in style->compCtxt->inode->type;
1978
 */
1979
void
1980
xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr node) {
1981
    /*
1982
    * The xsltXSLTElemMarker marker was set beforehand by
1983
    *  the parsing mechanism for all elements in the XSLT namespace.
1984
    */
1985
    if (style == NULL) {
1986
  if ((node != NULL) && (node->type == XML_ELEMENT_NODE))
1987
      node->psvi = NULL;
1988
  return;
1989
    }
1990
    if (node == NULL)
1991
  return;
1992
    if (! IS_XSLT_ELEM_FAST(node))
1993
  return;
1994
1995
    node->psvi = NULL;
1996
    if (XSLT_CCTXT(style)->inode->type != 0) {
1997
  switch (XSLT_CCTXT(style)->inode->type) {
1998
      case XSLT_FUNC_APPLYTEMPLATES:
1999
    xsltApplyTemplatesComp(style, node);
2000
    break;
2001
      case XSLT_FUNC_WITHPARAM:
2002
    xsltWithParamComp(style, node);
2003
    break;
2004
      case XSLT_FUNC_VALUEOF:
2005
    xsltValueOfComp(style, node);
2006
    break;
2007
      case XSLT_FUNC_COPY:
2008
    xsltCopyComp(style, node);
2009
    break;
2010
      case XSLT_FUNC_COPYOF:
2011
    xsltCopyOfComp(style, node);
2012
    break;
2013
      case XSLT_FUNC_IF:
2014
    xsltIfComp(style, node);
2015
    break;
2016
      case XSLT_FUNC_CHOOSE:
2017
    xsltChooseComp(style, node);
2018
    break;
2019
      case XSLT_FUNC_WHEN:
2020
    xsltWhenComp(style, node);
2021
    break;
2022
      case XSLT_FUNC_OTHERWISE:
2023
    /* NOP yet */
2024
    return;
2025
      case XSLT_FUNC_FOREACH:
2026
    xsltForEachComp(style, node);
2027
    break;
2028
      case XSLT_FUNC_APPLYIMPORTS:
2029
    xsltApplyImportsComp(style, node);
2030
    break;
2031
      case XSLT_FUNC_ATTRIBUTE:
2032
    xsltAttributeComp(style, node);
2033
    break;
2034
      case XSLT_FUNC_ELEMENT:
2035
    xsltElementComp(style, node);
2036
    break;
2037
      case XSLT_FUNC_SORT:
2038
    xsltSortComp(style, node);
2039
    break;
2040
      case XSLT_FUNC_COMMENT:
2041
    xsltCommentComp(style, node);
2042
    break;
2043
      case XSLT_FUNC_NUMBER:
2044
    xsltNumberComp(style, node);
2045
    break;
2046
      case XSLT_FUNC_PI:
2047
    xsltProcessingInstructionComp(style, node);
2048
    break;
2049
      case XSLT_FUNC_CALLTEMPLATE:
2050
    xsltCallTemplateComp(style, node);
2051
    break;
2052
      case XSLT_FUNC_PARAM:
2053
    xsltParamComp(style, node);
2054
    break;
2055
      case XSLT_FUNC_VARIABLE:
2056
    xsltVariableComp(style, node);
2057
    break;
2058
      case XSLT_FUNC_FALLBACK:
2059
    /* NOP yet */
2060
    return;
2061
      case XSLT_FUNC_DOCUMENT:
2062
    /* The extra one */
2063
    node->psvi = (void *) xsltDocumentComp(style, node,
2064
        xsltDocumentElem);
2065
    break;
2066
      case XSLT_FUNC_MESSAGE:
2067
    /* NOP yet */
2068
    return;
2069
      default:
2070
    /*
2071
    * NOTE that xsl:text, xsl:template, xsl:stylesheet,
2072
    *  xsl:transform, xsl:import, xsl:include are not expected
2073
    *  to be handed over to this function.
2074
    */
2075
    xsltTransformError(NULL, style, node,
2076
        "Internal error: (xsltStylePreCompute) cannot handle "
2077
        "the XSLT element '%s'.\n", node->name);
2078
    style->errors++;
2079
    return;
2080
  }
2081
    } else {
2082
  /*
2083
  * Fallback to string comparison.
2084
  */
2085
  if (IS_XSLT_NAME(node, "apply-templates")) {
2086
      xsltApplyTemplatesComp(style, node);
2087
  } else if (IS_XSLT_NAME(node, "with-param")) {
2088
      xsltWithParamComp(style, node);
2089
  } else if (IS_XSLT_NAME(node, "value-of")) {
2090
      xsltValueOfComp(style, node);
2091
  } else if (IS_XSLT_NAME(node, "copy")) {
2092
      xsltCopyComp(style, node);
2093
  } else if (IS_XSLT_NAME(node, "copy-of")) {
2094
      xsltCopyOfComp(style, node);
2095
  } else if (IS_XSLT_NAME(node, "if")) {
2096
      xsltIfComp(style, node);
2097
  } else if (IS_XSLT_NAME(node, "choose")) {
2098
      xsltChooseComp(style, node);
2099
  } else if (IS_XSLT_NAME(node, "when")) {
2100
      xsltWhenComp(style, node);
2101
  } else if (IS_XSLT_NAME(node, "otherwise")) {
2102
      /* NOP yet */
2103
      return;
2104
  } else if (IS_XSLT_NAME(node, "for-each")) {
2105
      xsltForEachComp(style, node);
2106
  } else if (IS_XSLT_NAME(node, "apply-imports")) {
2107
      xsltApplyImportsComp(style, node);
2108
  } else if (IS_XSLT_NAME(node, "attribute")) {
2109
      xsltAttributeComp(style, node);
2110
  } else if (IS_XSLT_NAME(node, "element")) {
2111
      xsltElementComp(style, node);
2112
  } else if (IS_XSLT_NAME(node, "sort")) {
2113
      xsltSortComp(style, node);
2114
  } else if (IS_XSLT_NAME(node, "comment")) {
2115
      xsltCommentComp(style, node);
2116
  } else if (IS_XSLT_NAME(node, "number")) {
2117
      xsltNumberComp(style, node);
2118
  } else if (IS_XSLT_NAME(node, "processing-instruction")) {
2119
      xsltProcessingInstructionComp(style, node);
2120
  } else if (IS_XSLT_NAME(node, "call-template")) {
2121
      xsltCallTemplateComp(style, node);
2122
  } else if (IS_XSLT_NAME(node, "param")) {
2123
      xsltParamComp(style, node);
2124
  } else if (IS_XSLT_NAME(node, "variable")) {
2125
      xsltVariableComp(style, node);
2126
  } else if (IS_XSLT_NAME(node, "fallback")) {
2127
      /* NOP yet */
2128
      return;
2129
  } else if (IS_XSLT_NAME(node, "document")) {
2130
      /* The extra one */
2131
      node->psvi = (void *) xsltDocumentComp(style, node,
2132
    xsltDocumentElem);
2133
  } else if (IS_XSLT_NAME(node, "output")) {
2134
      /* Top-level */
2135
      return;
2136
  } else if (IS_XSLT_NAME(node, "preserve-space")) {
2137
      /* Top-level */
2138
      return;
2139
  } else if (IS_XSLT_NAME(node, "strip-space")) {
2140
      /* Top-level */
2141
      return;
2142
  } else if (IS_XSLT_NAME(node, "key")) {
2143
      /* Top-level */
2144
      return;
2145
  } else if (IS_XSLT_NAME(node, "message")) {
2146
      return;
2147
  } else if (IS_XSLT_NAME(node, "attribute-set")) {
2148
      /* Top-level */
2149
      return;
2150
  } else if (IS_XSLT_NAME(node, "namespace-alias")) {
2151
      /* Top-level */
2152
      return;
2153
  } else if (IS_XSLT_NAME(node, "decimal-format")) {
2154
      /* Top-level */
2155
      return;
2156
  } else if (IS_XSLT_NAME(node, "include")) {
2157
      /* Top-level */
2158
  } else {
2159
      /*
2160
      * NOTE that xsl:text, xsl:template, xsl:stylesheet,
2161
      *  xsl:transform, xsl:import, xsl:include are not expected
2162
      *  to be handed over to this function.
2163
      */
2164
      xsltTransformError(NULL, style, node,
2165
    "Internal error: (xsltStylePreCompute) cannot handle "
2166
    "the XSLT element '%s'.\n", node->name);
2167
    style->errors++;
2168
      return;
2169
  }
2170
    }
2171
    /*
2172
    * Assign the current list of in-scope namespaces to the
2173
    * item. This is needed for XPath expressions.
2174
    */
2175
    if (node->psvi != NULL) {
2176
  ((xsltStylePreCompPtr) node->psvi)->inScopeNs =
2177
      XSLT_CCTXT(style)->inode->inScopeNs;
2178
    }
2179
}
2180
2181
#else
2182
2183
/**
2184
 * xsltStylePreCompute:
2185
 * @style:  the XSLT stylesheet
2186
 * @inst:  the instruction in the stylesheet
2187
 *
2188
 * Precompute an XSLT stylesheet element
2189
 */
2190
void
2191
0
xsltStylePreCompute(xsltStylesheetPtr style, xmlNodePtr inst) {
2192
    /*
2193
    * URGENT TODO: Normally inst->psvi Should never be reserved here,
2194
    *   BUT: since if we include the same stylesheet from
2195
    *   multiple imports, then the stylesheet will be parsed
2196
    *   again. We simply must not try to compute the stylesheet again.
2197
    * TODO: Get to the point where we don't need to query the
2198
    *   namespace- and local-name of the node, but can evaluate this
2199
    *   using cctxt->style->inode->category;
2200
    */
2201
0
    if ((inst == NULL) || (inst->type != XML_ELEMENT_NODE) ||
2202
0
        (inst->psvi != NULL))
2203
0
  return;
2204
2205
0
    if (IS_XSLT_ELEM(inst)) {
2206
0
  xsltStylePreCompPtr cur;
2207
2208
0
  if (IS_XSLT_NAME(inst, "apply-templates")) {
2209
0
      xsltCheckInstructionElement(style, inst);
2210
0
      xsltApplyTemplatesComp(style, inst);
2211
0
  } else if (IS_XSLT_NAME(inst, "with-param")) {
2212
0
      xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
2213
0
                             BAD_CAST "call-template");
2214
0
      xsltWithParamComp(style, inst);
2215
0
  } else if (IS_XSLT_NAME(inst, "value-of")) {
2216
0
      xsltCheckInstructionElement(style, inst);
2217
0
      xsltValueOfComp(style, inst);
2218
0
  } else if (IS_XSLT_NAME(inst, "copy")) {
2219
0
      xsltCheckInstructionElement(style, inst);
2220
0
      xsltCopyComp(style, inst);
2221
0
  } else if (IS_XSLT_NAME(inst, "copy-of")) {
2222
0
      xsltCheckInstructionElement(style, inst);
2223
0
      xsltCopyOfComp(style, inst);
2224
0
  } else if (IS_XSLT_NAME(inst, "if")) {
2225
0
      xsltCheckInstructionElement(style, inst);
2226
0
      xsltIfComp(style, inst);
2227
0
  } else if (IS_XSLT_NAME(inst, "when")) {
2228
0
      xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
2229
0
      xsltWhenComp(style, inst);
2230
0
  } else if (IS_XSLT_NAME(inst, "choose")) {
2231
0
      xsltCheckInstructionElement(style, inst);
2232
0
      xsltChooseComp(style, inst);
2233
0
  } else if (IS_XSLT_NAME(inst, "for-each")) {
2234
0
      xsltCheckInstructionElement(style, inst);
2235
0
      xsltForEachComp(style, inst);
2236
0
  } else if (IS_XSLT_NAME(inst, "apply-imports")) {
2237
0
      xsltCheckInstructionElement(style, inst);
2238
0
      xsltApplyImportsComp(style, inst);
2239
0
  } else if (IS_XSLT_NAME(inst, "attribute")) {
2240
0
      xmlNodePtr parent = inst->parent;
2241
2242
0
      if ((parent == NULL) ||
2243
0
          (parent->type != XML_ELEMENT_NODE) || (parent->ns == NULL) ||
2244
0
    ((parent->ns != inst->ns) &&
2245
0
     (!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
2246
0
    (!xmlStrEqual(parent->name, BAD_CAST "attribute-set"))) {
2247
0
    xsltCheckInstructionElement(style, inst);
2248
0
      }
2249
0
      xsltAttributeComp(style, inst);
2250
0
  } else if (IS_XSLT_NAME(inst, "element")) {
2251
0
      xsltCheckInstructionElement(style, inst);
2252
0
      xsltElementComp(style, inst);
2253
0
  } else if (IS_XSLT_NAME(inst, "text")) {
2254
0
      xsltCheckInstructionElement(style, inst);
2255
0
      xsltTextComp(style, inst);
2256
0
  } else if (IS_XSLT_NAME(inst, "sort")) {
2257
0
      xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
2258
0
                             BAD_CAST "for-each");
2259
0
      xsltSortComp(style, inst);
2260
0
  } else if (IS_XSLT_NAME(inst, "comment")) {
2261
0
      xsltCheckInstructionElement(style, inst);
2262
0
      xsltCommentComp(style, inst);
2263
0
  } else if (IS_XSLT_NAME(inst, "number")) {
2264
0
      xsltCheckInstructionElement(style, inst);
2265
0
      xsltNumberComp(style, inst);
2266
0
  } else if (IS_XSLT_NAME(inst, "processing-instruction")) {
2267
0
      xsltCheckInstructionElement(style, inst);
2268
0
      xsltProcessingInstructionComp(style, inst);
2269
0
  } else if (IS_XSLT_NAME(inst, "call-template")) {
2270
0
      xsltCheckInstructionElement(style, inst);
2271
0
      xsltCallTemplateComp(style, inst);
2272
0
  } else if (IS_XSLT_NAME(inst, "param")) {
2273
0
      if (xsltCheckTopLevelElement(style, inst, 0) == 0)
2274
0
          xsltCheckInstructionElement(style, inst);
2275
0
      xsltParamComp(style, inst);
2276
0
  } else if (IS_XSLT_NAME(inst, "variable")) {
2277
0
      if (xsltCheckTopLevelElement(style, inst, 0) == 0)
2278
0
          xsltCheckInstructionElement(style, inst);
2279
0
      xsltVariableComp(style, inst);
2280
0
  } else if (IS_XSLT_NAME(inst, "otherwise")) {
2281
0
      xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
2282
0
      xsltCheckInstructionElement(style, inst);
2283
0
      return;
2284
0
  } else if (IS_XSLT_NAME(inst, "template")) {
2285
0
      xsltCheckTopLevelElement(style, inst, 1);
2286
0
      return;
2287
0
  } else if (IS_XSLT_NAME(inst, "output")) {
2288
0
      xsltCheckTopLevelElement(style, inst, 1);
2289
0
      return;
2290
0
  } else if (IS_XSLT_NAME(inst, "preserve-space")) {
2291
0
      xsltCheckTopLevelElement(style, inst, 1);
2292
0
      return;
2293
0
  } else if (IS_XSLT_NAME(inst, "strip-space")) {
2294
0
      xsltCheckTopLevelElement(style, inst, 1);
2295
0
      return;
2296
0
  } else if ((IS_XSLT_NAME(inst, "stylesheet")) ||
2297
0
             (IS_XSLT_NAME(inst, "transform"))) {
2298
0
      xmlNodePtr parent = inst->parent;
2299
2300
0
      if ((parent == NULL) || (parent->type != XML_DOCUMENT_NODE)) {
2301
0
    xsltTransformError(NULL, style, inst,
2302
0
        "element %s only allowed only as root element\n",
2303
0
           inst->name);
2304
0
    style->errors++;
2305
0
      }
2306
0
      return;
2307
0
  } else if (IS_XSLT_NAME(inst, "key")) {
2308
0
      xsltCheckTopLevelElement(style, inst, 1);
2309
0
      return;
2310
0
  } else if (IS_XSLT_NAME(inst, "message")) {
2311
0
      xsltCheckInstructionElement(style, inst);
2312
0
      return;
2313
0
  } else if (IS_XSLT_NAME(inst, "attribute-set")) {
2314
0
      xsltCheckTopLevelElement(style, inst, 1);
2315
0
      return;
2316
0
  } else if (IS_XSLT_NAME(inst, "namespace-alias")) {
2317
0
      xsltCheckTopLevelElement(style, inst, 1);
2318
0
      return;
2319
0
  } else if (IS_XSLT_NAME(inst, "include")) {
2320
0
      xsltCheckTopLevelElement(style, inst, 1);
2321
0
      return;
2322
0
  } else if (IS_XSLT_NAME(inst, "import")) {
2323
0
      xsltCheckTopLevelElement(style, inst, 1);
2324
0
      return;
2325
0
  } else if (IS_XSLT_NAME(inst, "decimal-format")) {
2326
0
      xsltCheckTopLevelElement(style, inst, 1);
2327
0
      return;
2328
0
  } else if (IS_XSLT_NAME(inst, "fallback")) {
2329
0
      xsltCheckInstructionElement(style, inst);
2330
0
      return;
2331
0
  } else if (IS_XSLT_NAME(inst, "document")) {
2332
0
      xsltCheckInstructionElement(style, inst);
2333
0
      inst->psvi = (void *) xsltDocumentComp(style, inst,
2334
0
        xsltDocumentElem);
2335
0
  } else if ((style == NULL) || (style->forwards_compatible == 0)) {
2336
0
      xsltTransformError(NULL, style, inst,
2337
0
     "xsltStylePreCompute: unknown xsl:%s\n", inst->name);
2338
0
      if (style != NULL) style->warnings++;
2339
0
  }
2340
2341
0
  cur = (xsltStylePreCompPtr) inst->psvi;
2342
  /*
2343
  * A ns-list is build for every XSLT item in the
2344
  * node-tree. This is needed for XPath expressions.
2345
  */
2346
0
  if (cur != NULL) {
2347
0
      int i = 0;
2348
2349
0
      cur->nsList = xmlGetNsList(inst->doc, inst);
2350
0
            if (cur->nsList != NULL) {
2351
0
    while (cur->nsList[i] != NULL)
2352
0
        i++;
2353
0
      }
2354
0
      cur->nsNr = i;
2355
0
  }
2356
0
    } else {
2357
0
  inst->psvi =
2358
0
      (void *) xsltPreComputeExtModuleElement(style, inst);
2359
2360
  /*
2361
   * Unknown element, maybe registered at the context
2362
   * level. Mark it for later recognition.
2363
   */
2364
0
  if (inst->psvi == NULL)
2365
0
      inst->psvi = (void *) xsltExtMarker;
2366
0
    }
2367
0
}
2368
#endif /* XSLT_REFACTORED */