Coverage Report

Created: 2025-11-24 06:51

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libxslt/libxslt/preproc.c
Line
Count
Source
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
41.7k
xsltCheckTopLevelElement(xsltStylesheetPtr style, xmlNodePtr inst, int err) {
73
41.7k
    xmlNodePtr parent;
74
41.7k
    if ((style == NULL) || (inst == NULL) || (inst->ns == NULL))
75
0
        return(-1);
76
77
41.7k
    parent = inst->parent;
78
41.7k
    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
41.7k
    if ((parent->ns == NULL) || (parent->type != XML_ELEMENT_NODE) ||
87
39.9k
        ((parent->ns != inst->ns) &&
88
4.25k
   (!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
89
35.9k
  ((!xmlStrEqual(parent->name, BAD_CAST "stylesheet")) &&
90
23.2k
   (!xmlStrEqual(parent->name, BAD_CAST "transform")))) {
91
23.2k
  if (err) {
92
11.4k
      xsltTransformError(NULL, style, inst,
93
11.4k
        "element %s only allowed as child of stylesheet\n",
94
11.4k
             inst->name);
95
11.4k
      style->errors++;
96
11.4k
  }
97
23.2k
  return(0);
98
23.2k
    }
99
18.4k
    return(1);
100
41.7k
}
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
126k
xsltCheckInstructionElement(xsltStylesheetPtr style, xmlNodePtr inst) {
111
126k
    xmlNodePtr parent;
112
126k
    int has_ext;
113
114
126k
    if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
115
126k
        (style->literal_result))
116
788
        return;
117
118
126k
    has_ext = (style->extInfos != NULL);
119
120
126k
    parent = inst->parent;
121
126k
    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
245k
    while ((parent != NULL) && (parent->type != XML_DOCUMENT_NODE)) {
128
243k
        if (((parent->ns == inst->ns) ||
129
99.2k
       ((parent->ns != NULL) &&
130
25.4k
        (xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
131
144k
      ((xmlStrEqual(parent->name, BAD_CAST "template")) ||
132
34.4k
       (xmlStrEqual(parent->name, BAD_CAST "param")) ||
133
34.4k
       (xmlStrEqual(parent->name, BAD_CAST "attribute")) ||
134
118k
       (xmlStrEqual(parent->name, BAD_CAST "variable")))) {
135
118k
      return;
136
118k
  }
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
124k
  if ((has_ext) && (parent->ns != NULL) &&
143
5.82k
      (xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
144
4.91k
      return;
145
146
119k
        parent = parent->parent;
147
119k
    }
148
2.26k
    xsltTransformError(NULL, style, inst,
149
2.26k
      "element %s only allowed within a template, variable or param\n",
150
2.26k
               inst->name);
151
2.26k
    style->errors++;
152
2.26k
}
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
12.5k
                       const xmlChar *allow1, const xmlChar *allow2) {
167
12.5k
    xmlNodePtr parent;
168
169
12.5k
    if ((style == NULL) || (inst == NULL) || (inst->ns == NULL) ||
170
12.5k
        (style->literal_result))
171
237
        return;
172
173
12.2k
    parent = inst->parent;
174
12.2k
    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
12.2k
    if (((parent->ns == inst->ns) ||
181
1.92k
   ((parent->ns != NULL) &&
182
1.44k
    (xmlStrEqual(parent->ns->href, inst->ns->href)))) &&
183
10.7k
  ((xmlStrEqual(parent->name, allow1)) ||
184
9.26k
   (xmlStrEqual(parent->name, allow2)))) {
185
9.26k
  return;
186
9.26k
    }
187
188
3.02k
    if (style->extInfos != NULL) {
189
3.78k
  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
3.39k
      if ((parent->ns != NULL) &&
195
2.76k
    (xmlHashLookup(style->extInfos, parent->ns->href) != NULL))
196
658
    return;
197
198
2.74k
      parent = parent->parent;
199
2.74k
  }
200
1.04k
    }
201
2.36k
    xsltTransformError(NULL, style, inst,
202
2.36k
           "element %s is not allowed within that context\n",
203
2.36k
           inst->name);
204
2.36k
    style->errors++;
205
2.36k
}
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
167k
xsltNewStylePreComp(xsltStylesheetPtr style, xsltStyleType type) {
226
167k
    xsltStylePreCompPtr cur;
227
#ifdef XSLT_REFACTORED
228
    size_t size;
229
#endif
230
231
167k
    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
167k
    cur = (xsltStylePreCompPtr) xmlMalloc(sizeof(xsltStylePreComp));
307
167k
    if (cur == NULL) {
308
3.36k
  xsltTransformError(NULL, style, NULL,
309
3.36k
    "xsltNewStylePreComp : malloc failed\n");
310
3.36k
  style->errors++;
311
3.36k
  return(NULL);
312
3.36k
    }
313
163k
    memset(cur, 0, sizeof(xsltStylePreComp));
314
163k
#endif /* XSLT_REFACTORED */
315
316
    /*
317
    * URGENT TODO: Better to move this to spezialized factory functions.
318
    */
319
163k
    cur->type = type;
320
163k
    switch (cur->type) {
321
6.46k
        case XSLT_FUNC_COPY:
322
6.46k
            cur->func = xsltCopy;break;
323
6.41k
        case XSLT_FUNC_SORT:
324
6.41k
            cur->func = xsltSort;break;
325
11.3k
        case XSLT_FUNC_TEXT:
326
11.3k
            cur->func = xsltText;break;
327
6.91k
        case XSLT_FUNC_ELEMENT:
328
6.91k
            cur->func = xsltElement;break;
329
18.8k
        case XSLT_FUNC_ATTRIBUTE:
330
18.8k
            cur->func = xsltAttribute;break;
331
498
        case XSLT_FUNC_COMMENT:
332
498
            cur->func = xsltComment;break;
333
1.17k
        case XSLT_FUNC_PI:
334
1.17k
            cur->func = xsltProcessingInstruction;
335
1.17k
      break;
336
5.88k
        case XSLT_FUNC_COPYOF:
337
5.88k
            cur->func = xsltCopyOf;break;
338
28.1k
        case XSLT_FUNC_VALUEOF:
339
28.1k
            cur->func = xsltValueOf;break;
340
14.5k
        case XSLT_FUNC_NUMBER:
341
14.5k
            cur->func = xsltNumber;break;
342
787
        case XSLT_FUNC_APPLYIMPORTS:
343
787
            cur->func = xsltApplyImports;break;
344
863
        case XSLT_FUNC_CALLTEMPLATE:
345
863
            cur->func = xsltCallTemplate;break;
346
19.6k
        case XSLT_FUNC_APPLYTEMPLATES:
347
19.6k
            cur->func = xsltApplyTemplates;break;
348
1.33k
        case XSLT_FUNC_CHOOSE:
349
1.33k
            cur->func = xsltChoose;break;
350
2.23k
        case XSLT_FUNC_IF:
351
2.23k
            cur->func = xsltIf;break;
352
3.75k
        case XSLT_FUNC_FOREACH:
353
3.75k
            cur->func = xsltForEach;break;
354
591
        case XSLT_FUNC_DOCUMENT:
355
591
            cur->func = xsltDocumentElem;break;
356
2.77k
  case XSLT_FUNC_WITHPARAM:
357
10.9k
  case XSLT_FUNC_PARAM:
358
32.2k
  case XSLT_FUNC_VARIABLE:
359
34.3k
  case XSLT_FUNC_WHEN:
360
34.3k
      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
163k
    }
368
163k
    cur->next = style->preComps;
369
163k
    style->preComps = (xsltElemPreCompPtr) cur;
370
371
163k
    return(cur);
372
163k
}
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
163k
xsltFreeStylePreComp(xsltStylePreCompPtr comp) {
382
163k
    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
163k
    if (comp->comp != NULL)
498
60.5k
  xmlXPathFreeCompExpr(comp->comp);
499
163k
    if (comp->numdata.countPat != NULL)
500
582
        xsltFreeCompMatchList(comp->numdata.countPat);
501
163k
    if (comp->numdata.fromPat != NULL)
502
1.58k
        xsltFreeCompMatchList(comp->numdata.fromPat);
503
163k
    if (comp->nsList != NULL)
504
163k
  xmlFree(comp->nsList);
505
163k
#endif
506
507
163k
    xmlFree(comp);
508
163k
}
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
610
     xsltTransformFunction function ATTRIBUTE_UNUSED) {
530
#ifdef XSLT_REFACTORED
531
    xsltStyleItemDocumentPtr comp;
532
#else
533
610
    xsltStylePreCompPtr comp;
534
610
#endif
535
610
    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
610
    comp = xsltNewStylePreComp(style, XSLT_FUNC_DOCUMENT);
554
610
#endif
555
556
610
    if (comp == NULL)
557
19
  return (NULL);
558
591
    comp->inst = inst;
559
591
    comp->ver11 = 0;
560
561
591
    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
591
    } 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
591
    } else if (xmlStrEqual(inst->name, (const xmlChar *) "document")) {
592
591
  if (inst->ns != NULL) {
593
591
      if (xmlStrEqual(inst->ns->href, XSLT_NAMESPACE)) {
594
    /*
595
    * Mark the instruction as being of
596
    * XSLT version 1.1 (abandoned).
597
    */
598
591
    comp->ver11 = 1;
599
#ifdef WITH_XSLT_DEBUG_EXTRA
600
    xsltGenericDebug(xsltGenericDebugContext,
601
        "Found xslt11:document construct\n");
602
#endif
603
591
      } 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
591
  }
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
591
  filename = xsltEvalStaticAttrValueTemplate(style, inst,
648
591
      (const xmlChar *)"href", NULL, &comp->has_filename);
649
591
    }
650
591
    if (!comp->has_filename) {
651
238
  goto error;
652
238
    }
653
353
    comp->filename = filename;
654
655
591
error:
656
591
    return ((xsltElemPreCompPtr) comp);
657
353
}
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
6.45k
xsltSortComp(xsltStylesheetPtr style, xmlNodePtr inst) {
674
#ifdef XSLT_REFACTORED
675
    xsltStyleItemSortPtr comp;
676
#else
677
6.45k
    xsltStylePreCompPtr comp;
678
6.45k
#endif
679
6.45k
    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
6.45k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_SORT);
686
6.45k
#endif
687
688
6.45k
    if (comp == NULL)
689
42
  return;
690
6.41k
    inst->psvi = comp;
691
6.41k
    comp->inst = inst;
692
693
6.41k
    comp->stype = xsltEvalStaticAttrValueTemplate(style, inst,
694
6.41k
       (const xmlChar *)"data-type",
695
6.41k
       NULL, &comp->has_stype);
696
6.41k
    if (comp->stype != NULL) {
697
881
  if (xmlStrEqual(comp->stype, (const xmlChar *) "text"))
698
82
      comp->number = 0;
699
799
  else if (xmlStrEqual(comp->stype, (const xmlChar *) "number"))
700
0
      comp->number = 1;
701
799
  else {
702
799
      xsltTransformError(NULL, style, inst,
703
799
     "xsltSortComp: no support for data-type = %s\n", comp->stype);
704
799
      comp->number = 0; /* use default */
705
799
      if (style != NULL) style->warnings++;
706
799
  }
707
881
    }
708
6.41k
    comp->order = xsltEvalStaticAttrValueTemplate(style, inst,
709
6.41k
            (const xmlChar *)"order",
710
6.41k
            NULL, &comp->has_order);
711
6.41k
    if (comp->order != NULL) {
712
206
  if (xmlStrEqual(comp->order, (const xmlChar *) "ascending"))
713
0
      comp->descending = 0;
714
206
  else if (xmlStrEqual(comp->order, (const xmlChar *) "descending"))
715
0
      comp->descending = 1;
716
206
  else {
717
206
      xsltTransformError(NULL, style, inst,
718
206
     "xsltSortComp: invalid value %s for order\n", comp->order);
719
206
      comp->descending = 0; /* use default */
720
206
      if (style != NULL) style->warnings++;
721
206
  }
722
206
    }
723
6.41k
    comp->case_order = xsltEvalStaticAttrValueTemplate(style, inst,
724
6.41k
            (const xmlChar *)"case-order",
725
6.41k
            NULL, &comp->has_use);
726
6.41k
    if (comp->case_order != NULL) {
727
227
  if (xmlStrEqual(comp->case_order, (const xmlChar *) "upper-first"))
728
0
      comp->lower_first = 0;
729
227
  else if (xmlStrEqual(comp->case_order, (const xmlChar *) "lower-first"))
730
0
      comp->lower_first = 1;
731
227
  else {
732
227
      xsltTransformError(NULL, style, inst,
733
227
     "xsltSortComp: invalid value %s for order\n", comp->order);
734
227
      comp->lower_first = 0; /* use default */
735
227
      if (style != NULL) style->warnings++;
736
227
  }
737
227
    }
738
739
6.41k
    comp->lang = xsltEvalStaticAttrValueTemplate(style, inst,
740
6.41k
         (const xmlChar *)"lang",
741
6.41k
         NULL, &comp->has_lang);
742
743
6.41k
    comp->select = xsltGetCNsProp(style, inst,(const xmlChar *)"select", XSLT_NAMESPACE);
744
6.41k
    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
5.42k
  comp->select = xmlDictLookup(style->dict, BAD_CAST ".", 1);
751
5.42k
    }
752
6.41k
    comp->comp = xsltXPathCompile(style, comp->select);
753
6.41k
    if (comp->comp == NULL) {
754
305
  xsltTransformError(NULL, style, inst,
755
305
       "xsltSortComp: could not compile select expression '%s'\n",
756
305
                   comp->select);
757
305
  if (style != NULL) style->errors++;
758
305
    }
759
6.41k
    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
6.41k
}
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
6.58k
xsltCopyComp(xsltStylesheetPtr style, xmlNodePtr inst) {
775
#ifdef XSLT_REFACTORED
776
    xsltStyleItemCopyPtr comp;
777
#else
778
6.58k
    xsltStylePreCompPtr comp;
779
6.58k
#endif
780
781
6.58k
    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
6.58k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_COPY);
787
6.58k
#endif
788
789
6.58k
    if (comp == NULL)
790
124
  return;
791
6.46k
    inst->psvi = comp;
792
6.46k
    comp->inst = inst;
793
794
795
6.46k
    comp->use = xsltGetCNsProp(style, inst, (const xmlChar *)"use-attribute-sets",
796
6.46k
            XSLT_NAMESPACE);
797
6.46k
    if (comp->use == NULL)
798
6.11k
  comp->has_use = 0;
799
351
    else
800
351
  comp->has_use = 1;
801
6.46k
}
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
11.6k
xsltTextComp(xsltStylesheetPtr style, xmlNodePtr inst) {
818
#ifdef XSLT_REFACTORED
819
    xsltStyleItemTextPtr comp;
820
#else
821
11.6k
    xsltStylePreCompPtr comp;
822
11.6k
#endif
823
11.6k
    const xmlChar *prop;
824
825
11.6k
    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
11.6k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_TEXT);
832
11.6k
#endif
833
11.6k
    if (comp == NULL)
834
267
  return;
835
11.3k
    inst->psvi = comp;
836
11.3k
    comp->inst = inst;
837
11.3k
    comp->noescape = 0;
838
839
11.3k
    prop = xsltGetCNsProp(style, inst,
840
11.3k
      (const xmlChar *)"disable-output-escaping",
841
11.3k
      XSLT_NAMESPACE);
842
11.3k
    if (prop != NULL) {
843
1.10k
  if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
844
185
      comp->noescape = 1;
845
921
  } else if (!xmlStrEqual(prop,
846
921
      (const xmlChar *)"no")){
847
656
      xsltTransformError(NULL, style, inst,
848
656
    "xsl:text: disable-output-escaping allows only yes or no\n");
849
656
      if (style != NULL) style->warnings++;
850
656
  }
851
1.10k
    }
852
11.3k
}
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
6.93k
xsltElementComp(xsltStylesheetPtr style, xmlNodePtr inst) {
864
#ifdef XSLT_REFACTORED
865
    xsltStyleItemElementPtr comp;
866
#else
867
6.93k
    xsltStylePreCompPtr comp;
868
6.93k
#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
6.93k
    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
6.93k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_ELEMENT);
885
6.93k
#endif
886
887
6.93k
    if (comp == NULL)
888
17
  return;
889
6.91k
    inst->psvi = comp;
890
6.91k
    comp->inst = inst;
891
892
    /*
893
    * Attribute "name".
894
    */
895
    /*
896
    * TODO: Precompile the AVT. See bug #344894.
897
    */
898
6.91k
    comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
899
6.91k
  (const xmlChar *)"name", NULL, &comp->has_name);
900
6.91k
    if (! comp->has_name) {
901
1.66k
  xsltTransformError(NULL, style, inst,
902
1.66k
      "xsl:element: The attribute 'name' is missing.\n");
903
1.66k
  style->errors++;
904
1.66k
  goto error;
905
1.66k
    }
906
    /*
907
    * Attribute "namespace".
908
    */
909
    /*
910
    * TODO: Precompile the AVT. See bug #344894.
911
    */
912
5.25k
    comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
913
5.25k
  (const xmlChar *)"namespace", NULL, &comp->has_ns);
914
915
5.25k
    if (comp->name != NULL) {
916
4.73k
  if (xmlValidateQName(comp->name, 0)) {
917
949
      xsltTransformError(NULL, style, inst,
918
949
    "xsl:element: The value '%s' of the attribute 'name' is "
919
949
    "not a valid QName.\n", comp->name);
920
949
      style->errors++;
921
3.78k
  } else {
922
3.78k
      const xmlChar *prefix = NULL, *name;
923
924
3.78k
      name = xsltSplitQName(style->dict, comp->name, &prefix);
925
3.78k
      if (comp->has_ns == 0) {
926
3.55k
    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
3.55k
    ns = xmlSearchNs(inst->doc, inst, prefix);
936
3.55k
    if (ns != NULL) {
937
379
        comp->ns = xmlDictLookup(style->dict, ns->href, -1);
938
379
        comp->has_ns = 1;
939
#ifdef XSLT_REFACTORED
940
        comp->nsPrefix = prefix;
941
        comp->name = name;
942
#else
943
379
                    (void)name; /* Suppress unused variable warning. */
944
379
#endif
945
3.17k
    } else if (prefix != NULL) {
946
438
        xsltTransformError(NULL, style, inst,
947
438
      "xsl:element: The prefixed QName '%s' "
948
438
      "has no namespace binding in scope in the "
949
438
      "stylesheet; this is an error, since the namespace was "
950
438
      "not specified by the instruction itself.\n", comp->name);
951
438
        style->errors++;
952
438
    }
953
3.55k
      }
954
3.78k
      if ((prefix != NULL) &&
955
638
    (!xmlStrncasecmp(prefix, (xmlChar *)"xml", 3)))
956
213
      {
957
    /*
958
    * Mark is to be skipped.
959
    */
960
213
    comp->has_name = 0;
961
213
      }
962
3.78k
  }
963
4.73k
    }
964
    /*
965
    * Attribute "use-attribute-sets",
966
    */
967
5.25k
    comp->use = xsltEvalStaticAttrValueTemplate(style, inst,
968
5.25k
           (const xmlChar *)"use-attribute-sets",
969
5.25k
           NULL, &comp->has_use);
970
971
6.91k
error:
972
6.91k
    return;
973
5.25k
}
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
18.9k
xsltAttributeComp(xsltStylesheetPtr style, xmlNodePtr inst) {
984
#ifdef XSLT_REFACTORED
985
    xsltStyleItemAttributePtr comp;
986
#else
987
18.9k
    xsltStylePreCompPtr comp;
988
18.9k
#endif
989
990
    /*
991
    * <xsl:attribute
992
    *   name = { qname }
993
    *   namespace = { uri-reference }>
994
    *   <!-- Content: template -->
995
    * </xsl:attribute>
996
    */
997
18.9k
    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
18.9k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_ATTRIBUTE);
1005
18.9k
#endif
1006
1007
18.9k
    if (comp == NULL)
1008
82
  return;
1009
18.8k
    inst->psvi = comp;
1010
18.8k
    comp->inst = inst;
1011
1012
    /*
1013
    * Attribute "name".
1014
    */
1015
    /*
1016
    * TODO: Precompile the AVT. See bug #344894.
1017
    */
1018
18.8k
    comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
1019
18.8k
         (const xmlChar *)"name",
1020
18.8k
         NULL, &comp->has_name);
1021
18.8k
    if (! comp->has_name) {
1022
1.34k
  xsltTransformError(NULL, style, inst,
1023
1.34k
      "XSLT-attribute: The attribute 'name' is missing.\n");
1024
1.34k
  style->errors++;
1025
1.34k
  return;
1026
1.34k
    }
1027
    /*
1028
    * Attribute "namespace".
1029
    */
1030
    /*
1031
    * TODO: Precompile the AVT. See bug #344894.
1032
    */
1033
17.5k
    comp->ns = xsltEvalStaticAttrValueTemplate(style, inst,
1034
17.5k
  (const xmlChar *)"namespace",
1035
17.5k
  NULL, &comp->has_ns);
1036
1037
17.5k
    if (comp->name != NULL) {
1038
16.8k
  if (xmlValidateQName(comp->name, 0)) {
1039
834
      xsltTransformError(NULL, style, inst,
1040
834
    "xsl:attribute: The value '%s' of the attribute 'name' is "
1041
834
    "not a valid QName.\n", comp->name);
1042
834
      style->errors++;
1043
16.0k
        } else if (xmlStrEqual(comp->name, BAD_CAST "xmlns")) {
1044
262
      xsltTransformError(NULL, style, inst,
1045
262
                "xsl:attribute: The attribute name 'xmlns' is not allowed.\n");
1046
262
      style->errors++;
1047
15.7k
  } else {
1048
15.7k
      const xmlChar *prefix = NULL, *name;
1049
1050
15.7k
      name = xsltSplitQName(style->dict, comp->name, &prefix);
1051
15.7k
      if (prefix != NULL) {
1052
1.82k
    if (comp->has_ns == 0) {
1053
683
        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
683
        ns = xmlSearchNs(inst->doc, inst, prefix);
1063
683
        if (ns != NULL) {
1064
425
      comp->ns = xmlDictLookup(style->dict, ns->href, -1);
1065
425
      comp->has_ns = 1;
1066
#ifdef XSLT_REFACTORED
1067
      comp->nsPrefix = prefix;
1068
      comp->name = name;
1069
#else
1070
425
                        (void)name; /* Suppress unused variable warning. */
1071
425
#endif
1072
425
        } else {
1073
258
      xsltTransformError(NULL, style, inst,
1074
258
          "xsl:attribute: The prefixed QName '%s' "
1075
258
          "has no namespace binding in scope in the "
1076
258
          "stylesheet; this is an error, since the "
1077
258
          "namespace was not specified by the instruction "
1078
258
          "itself.\n", comp->name);
1079
258
      style->errors++;
1080
258
        }
1081
683
    }
1082
1.82k
      }
1083
15.7k
  }
1084
16.8k
    }
1085
17.5k
}
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
540
xsltCommentComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1096
#ifdef XSLT_REFACTORED
1097
    xsltStyleItemCommentPtr comp;
1098
#else
1099
540
    xsltStylePreCompPtr comp;
1100
540
#endif
1101
1102
540
    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
540
    comp = xsltNewStylePreComp(style, XSLT_FUNC_COMMENT);
1109
540
#endif
1110
1111
540
    if (comp == NULL)
1112
42
  return;
1113
498
    inst->psvi = comp;
1114
498
    comp->inst = inst;
1115
498
}
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
1.21k
xsltProcessingInstructionComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1126
#ifdef XSLT_REFACTORED
1127
    xsltStyleItemPIPtr comp;
1128
#else
1129
1.21k
    xsltStylePreCompPtr comp;
1130
1.21k
#endif
1131
1132
1.21k
    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
1.21k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_PI);
1139
1.21k
#endif
1140
1141
1.21k
    if (comp == NULL)
1142
41
  return;
1143
1.17k
    inst->psvi = comp;
1144
1.17k
    comp->inst = inst;
1145
1146
1.17k
    comp->name = xsltEvalStaticAttrValueTemplate(style, inst,
1147
1.17k
         (const xmlChar *)"name",
1148
1.17k
         XSLT_NAMESPACE, &comp->has_name);
1149
1.17k
}
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
6.00k
xsltCopyOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1160
#ifdef XSLT_REFACTORED
1161
    xsltStyleItemCopyOfPtr comp;
1162
#else
1163
6.00k
    xsltStylePreCompPtr comp;
1164
6.00k
#endif
1165
1166
6.00k
    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
6.00k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_COPYOF);
1173
6.00k
#endif
1174
1175
6.00k
    if (comp == NULL)
1176
116
  return;
1177
5.88k
    inst->psvi = comp;
1178
5.88k
    comp->inst = inst;
1179
1180
5.88k
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1181
5.88k
                          XSLT_NAMESPACE);
1182
5.88k
    if (comp->select == NULL) {
1183
1.64k
  xsltTransformError(NULL, style, inst,
1184
1.64k
       "xsl:copy-of : select is missing\n");
1185
1.64k
  if (style != NULL) style->errors++;
1186
1.64k
  return;
1187
1.64k
    }
1188
4.24k
    comp->comp = xsltXPathCompile(style, comp->select);
1189
4.24k
    if (comp->comp == NULL) {
1190
768
  xsltTransformError(NULL, style, inst,
1191
768
       "xsl:copy-of : could not compile select expression '%s'\n",
1192
768
                   comp->select);
1193
768
  if (style != NULL) style->errors++;
1194
768
    }
1195
4.24k
}
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
28.9k
xsltValueOfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1206
#ifdef XSLT_REFACTORED
1207
    xsltStyleItemValueOfPtr comp;
1208
#else
1209
28.9k
    xsltStylePreCompPtr comp;
1210
28.9k
#endif
1211
28.9k
    const xmlChar *prop;
1212
1213
28.9k
    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
28.9k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_VALUEOF);
1220
28.9k
#endif
1221
1222
28.9k
    if (comp == NULL)
1223
756
  return;
1224
28.1k
    inst->psvi = comp;
1225
28.1k
    comp->inst = inst;
1226
1227
28.1k
    prop = xsltGetCNsProp(style, inst,
1228
28.1k
      (const xmlChar *)"disable-output-escaping",
1229
28.1k
      XSLT_NAMESPACE);
1230
28.1k
    if (prop != NULL) {
1231
548
  if (xmlStrEqual(prop, (const xmlChar *)"yes")) {
1232
284
      comp->noescape = 1;
1233
284
  } else if (!xmlStrEqual(prop,
1234
264
        (const xmlChar *)"no")){
1235
264
      xsltTransformError(NULL, style, inst,
1236
264
"xsl:value-of : disable-output-escaping allows only yes or no\n");
1237
264
      if (style != NULL) style->warnings++;
1238
264
  }
1239
548
    }
1240
28.1k
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1241
28.1k
                          XSLT_NAMESPACE);
1242
28.1k
    if (comp->select == NULL) {
1243
309
  xsltTransformError(NULL, style, inst,
1244
309
       "xsl:value-of : select is missing\n");
1245
309
  if (style != NULL) style->errors++;
1246
309
  return;
1247
309
    }
1248
27.8k
    comp->comp = xsltXPathCompile(style, comp->select);
1249
27.8k
    if (comp->comp == NULL) {
1250
869
  xsltTransformError(NULL, style, inst,
1251
869
       "xsl:value-of : could not compile select expression '%s'\n",
1252
869
                   comp->select);
1253
869
  if (style != NULL) style->errors++;
1254
869
    }
1255
27.8k
}
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
52.8k
{
1264
52.8k
    const xmlChar *prop;
1265
1266
52.8k
    if (nsName)
1267
52.8k
  *nsName = NULL;
1268
52.8k
    if (localName)
1269
52.8k
  *localName = NULL;
1270
52.8k
    if (hasProp)
1271
33.1k
  *hasProp = 0;
1272
1273
52.8k
    prop = xsltGetCNsProp(style, inst, propName, XSLT_NAMESPACE);
1274
52.8k
    if (prop == NULL) {
1275
22.8k
  if (mandatory) {
1276
3.52k
      xsltTransformError(NULL, style, inst,
1277
3.52k
    "The attribute '%s' is missing.\n", propName);
1278
3.52k
      style->errors++;
1279
3.52k
      return;
1280
3.52k
  }
1281
29.9k
    } else {
1282
29.9k
        const xmlChar *URI;
1283
1284
29.9k
  if (xmlValidateQName(prop, 0)) {
1285
1.79k
      xsltTransformError(NULL, style, inst,
1286
1.79k
    "The value '%s' of the attribute "
1287
1.79k
    "'%s' is not a valid QName.\n", prop, propName);
1288
1.79k
      style->errors++;
1289
1.79k
      return;
1290
28.1k
  } else {
1291
      /*
1292
      * @prop will be in the string dict afterwards, @URI not.
1293
      */
1294
28.1k
      URI = xsltGetQNameURI2(style, inst, &prop);
1295
28.1k
      if (prop == NULL) {
1296
1.10k
    style->errors++;
1297
27.0k
      } else {
1298
27.0k
    if (localName)
1299
27.0k
        *localName = prop;
1300
27.0k
    if (hasProp)
1301
26.7k
        *hasProp = 1;
1302
27.0k
    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
1.73k
        if (nsName)
1309
1.73k
      *nsName = xmlDictLookup(style->dict, URI, -1);
1310
        /* comp->has_ns = 1; */
1311
1.73k
    }
1312
27.0k
      }
1313
28.1k
  }
1314
29.9k
    }
1315
47.4k
    return;
1316
52.8k
}
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
2.79k
xsltWithParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1333
#ifdef XSLT_REFACTORED
1334
    xsltStyleItemWithParamPtr comp;
1335
#else
1336
2.79k
    xsltStylePreCompPtr comp;
1337
2.79k
#endif
1338
1339
2.79k
    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
2.79k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_WITHPARAM);
1346
2.79k
#endif
1347
1348
2.79k
    if (comp == NULL)
1349
13
  return;
1350
2.77k
    inst->psvi = comp;
1351
2.77k
    comp->inst = inst;
1352
1353
    /*
1354
    * Attribute "name".
1355
    */
1356
2.77k
    xsltGetQNameProperty(style, inst, BAD_CAST "name",
1357
2.77k
  1, &(comp->has_name), &(comp->ns), &(comp->name));
1358
2.77k
    if (comp->ns)
1359
253
  comp->has_ns = 1;
1360
    /*
1361
    * Attribute "select".
1362
    */
1363
2.77k
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1364
2.77k
                          XSLT_NAMESPACE);
1365
2.77k
    if (comp->select != NULL) {
1366
1.43k
  comp->comp = xsltXPathCompile(style, comp->select);
1367
1.43k
  if (comp->comp == NULL) {
1368
1.01k
      xsltTransformError(NULL, style, inst,
1369
1.01k
     "XSLT-with-param: Failed to compile select "
1370
1.01k
     "expression '%s'\n", comp->select);
1371
1.01k
      style->errors++;
1372
1.01k
  }
1373
1.43k
  if (inst->children != NULL) {
1374
82
      xsltTransformError(NULL, style, inst,
1375
82
    "XSLT-with-param: The content should be empty since "
1376
82
    "the attribute select is present.\n");
1377
82
      style->warnings++;
1378
82
  }
1379
1.43k
    }
1380
2.77k
}
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
14.6k
xsltNumberComp(xsltStylesheetPtr style, xmlNodePtr cur) {
1391
#ifdef XSLT_REFACTORED
1392
    xsltStyleItemNumberPtr comp;
1393
#else
1394
14.6k
    xsltStylePreCompPtr comp;
1395
14.6k
#endif
1396
14.6k
    const xmlChar *prop;
1397
1398
14.6k
    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
14.6k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_NUMBER);
1405
14.6k
#endif
1406
1407
14.6k
    if (comp == NULL)
1408
123
  return;
1409
14.5k
    cur->psvi = comp;
1410
1411
14.5k
    comp->numdata.doc = cur->doc;
1412
14.5k
    comp->numdata.node = cur;
1413
14.5k
    comp->numdata.value = xsltGetCNsProp(style, cur, (const xmlChar *)"value",
1414
14.5k
                                  XSLT_NAMESPACE);
1415
1416
14.5k
    prop = xsltEvalStaticAttrValueTemplate(style, cur,
1417
14.5k
       (const xmlChar *)"format",
1418
14.5k
       XSLT_NAMESPACE, &comp->numdata.has_format);
1419
14.5k
    if (comp->numdata.has_format == 0) {
1420
13.2k
  comp->numdata.format = xmlDictLookup(style->dict, BAD_CAST "" , 0);
1421
13.2k
    } else {
1422
1.27k
  comp->numdata.format = prop;
1423
1.27k
    }
1424
1425
14.5k
    comp->numdata.count = xsltGetCNsProp(style, cur, (const xmlChar *)"count",
1426
14.5k
                                         XSLT_NAMESPACE);
1427
14.5k
    comp->numdata.from = xsltGetCNsProp(style, cur, (const xmlChar *)"from",
1428
14.5k
                                        XSLT_NAMESPACE);
1429
1430
14.5k
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"count", XSLT_NAMESPACE);
1431
14.5k
    if (prop != NULL) {
1432
595
  comp->numdata.countPat = xsltCompilePattern(prop, cur->doc, cur, style,
1433
595
                                                    NULL);
1434
595
    }
1435
1436
14.5k
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"from", XSLT_NAMESPACE);
1437
14.5k
    if (prop != NULL) {
1438
1.58k
  comp->numdata.fromPat = xsltCompilePattern(prop, cur->doc, cur, style,
1439
1.58k
                                                   NULL);
1440
1.58k
    }
1441
1442
14.5k
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"level", XSLT_NAMESPACE);
1443
14.5k
    if (prop != NULL) {
1444
2.03k
  if (xmlStrEqual(prop, BAD_CAST("single")) ||
1445
2.03k
      xmlStrEqual(prop, BAD_CAST("multiple")) ||
1446
1.67k
      xmlStrEqual(prop, BAD_CAST("any"))) {
1447
1.67k
      comp->numdata.level = prop;
1448
1.67k
  } else {
1449
362
      xsltTransformError(NULL, style, cur,
1450
362
       "xsl:number : invalid value %s for level\n", prop);
1451
362
      if (style != NULL) style->warnings++;
1452
362
  }
1453
2.03k
    }
1454
1455
14.5k
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"lang", XSLT_NAMESPACE);
1456
14.5k
    if (prop != NULL) {
1457
311
      xsltTransformError(NULL, style, cur,
1458
311
     "xsl:number : lang attribute not implemented\n");
1459
311
  XSLT_TODO; /* xsl:number lang attribute */
1460
311
    }
1461
1462
14.5k
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"letter-value", XSLT_NAMESPACE);
1463
14.5k
    if (prop != NULL) {
1464
582
  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
582
  } 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
582
  } else {
1475
582
      xsltTransformError(NULL, style, cur,
1476
582
         "xsl:number : invalid value %s for letter-value\n", prop);
1477
582
      if (style != NULL) style->warnings++;
1478
582
  }
1479
582
    }
1480
1481
14.5k
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-separator",
1482
14.5k
                  XSLT_NAMESPACE);
1483
14.5k
    if (prop != NULL) {
1484
8.21k
        comp->numdata.groupingCharacterLen = xmlStrlen(prop);
1485
8.21k
  comp->numdata.groupingCharacter =
1486
8.21k
      xsltGetUTF8Char(prop, &(comp->numdata.groupingCharacterLen));
1487
8.21k
        if (comp->numdata.groupingCharacter < 0)
1488
226
            comp->numdata.groupingCharacter = 0;
1489
8.21k
    }
1490
1491
14.5k
    prop = xsltGetCNsProp(style, cur, (const xmlChar *)"grouping-size", XSLT_NAMESPACE);
1492
14.5k
    if (prop != NULL) {
1493
3.27k
  sscanf((char *)prop, "%d", &comp->numdata.digitsPerGroup);
1494
11.2k
    } else {
1495
11.2k
  comp->numdata.groupingCharacter = 0;
1496
11.2k
    }
1497
1498
    /* Set default values */
1499
14.5k
    if (comp->numdata.value == NULL) {
1500
10.0k
  if (comp->numdata.level == NULL) {
1501
9.18k
      comp->numdata.level = xmlDictLookup(style->dict,
1502
9.18k
                                          BAD_CAST"single", 6);
1503
9.18k
  }
1504
10.0k
    }
1505
1506
14.5k
}
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
826
xsltApplyImportsComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1517
#ifdef XSLT_REFACTORED
1518
    xsltStyleItemApplyImportsPtr comp;
1519
#else
1520
826
    xsltStylePreCompPtr comp;
1521
826
#endif
1522
1523
826
    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
826
    comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYIMPORTS);
1530
826
#endif
1531
1532
826
    if (comp == NULL)
1533
39
  return;
1534
787
    inst->psvi = comp;
1535
787
    comp->inst = inst;
1536
787
}
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
1.07k
xsltCallTemplateComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1547
#ifdef XSLT_REFACTORED
1548
    xsltStyleItemCallTemplatePtr comp;
1549
#else
1550
1.07k
    xsltStylePreCompPtr comp;
1551
1.07k
#endif
1552
1553
1.07k
    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
1.07k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_CALLTEMPLATE);
1561
1.07k
#endif
1562
1563
1.07k
    if (comp == NULL)
1564
210
  return;
1565
863
    inst->psvi = comp;
1566
863
    comp->inst = inst;
1567
1568
    /*
1569
     * Attribute "name".
1570
     */
1571
863
    xsltGetQNameProperty(style, inst, BAD_CAST "name",
1572
863
  1, &(comp->has_name), &(comp->ns), &(comp->name));
1573
863
    if (comp->ns)
1574
226
  comp->has_ns = 1;
1575
863
}
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
19.7k
xsltApplyTemplatesComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1586
#ifdef XSLT_REFACTORED
1587
    xsltStyleItemApplyTemplatesPtr comp;
1588
#else
1589
19.7k
    xsltStylePreCompPtr comp;
1590
19.7k
#endif
1591
1592
19.7k
    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
19.7k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_APPLYTEMPLATES);
1600
19.7k
#endif
1601
1602
19.7k
    if (comp == NULL)
1603
84
  return;
1604
19.6k
    inst->psvi = comp;
1605
19.6k
    comp->inst = inst;
1606
1607
    /*
1608
     * Attribute "mode".
1609
     */
1610
19.6k
    xsltGetQNameProperty(style, inst, BAD_CAST "mode",
1611
19.6k
  0, NULL, &(comp->modeURI), &(comp->mode));
1612
    /*
1613
    * Attribute "select".
1614
    */
1615
19.6k
    comp->select = xsltGetCNsProp(style, inst, BAD_CAST "select",
1616
19.6k
  XSLT_NAMESPACE);
1617
19.6k
    if (comp->select != NULL) {
1618
10.1k
  comp->comp = xsltXPathCompile(style, comp->select);
1619
10.1k
  if (comp->comp == NULL) {
1620
2.35k
      xsltTransformError(NULL, style, inst,
1621
2.35k
    "XSLT-apply-templates: could not compile select "
1622
2.35k
    "expression '%s'\n", comp->select);
1623
2.35k
       style->errors++;
1624
2.35k
  }
1625
10.1k
    }
1626
    /* TODO: handle (or skip) the xsl:sort and xsl:with-param */
1627
19.6k
}
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
1.37k
xsltChooseComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1638
#ifdef XSLT_REFACTORED
1639
    xsltStyleItemChoosePtr comp;
1640
#else
1641
1.37k
    xsltStylePreCompPtr comp;
1642
1.37k
#endif
1643
1644
1.37k
    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
1.37k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_CHOOSE);
1652
1.37k
#endif
1653
1654
1.37k
    if (comp == NULL)
1655
32
  return;
1656
1.33k
    inst->psvi = comp;
1657
1.33k
    comp->inst = inst;
1658
1.33k
}
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
2.27k
xsltIfComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1669
#ifdef XSLT_REFACTORED
1670
    xsltStyleItemIfPtr comp;
1671
#else
1672
2.27k
    xsltStylePreCompPtr comp;
1673
2.27k
#endif
1674
1675
2.27k
    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
2.27k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_IF);
1683
2.27k
#endif
1684
1685
2.27k
    if (comp == NULL)
1686
40
  return;
1687
2.23k
    inst->psvi = comp;
1688
2.23k
    comp->inst = inst;
1689
1690
2.23k
    comp->test = xsltGetCNsProp(style, inst, (const xmlChar *)"test", XSLT_NAMESPACE);
1691
2.23k
    if (comp->test == NULL) {
1692
427
  xsltTransformError(NULL, style, inst,
1693
427
       "xsl:if : test is not defined\n");
1694
427
  if (style != NULL) style->errors++;
1695
427
  return;
1696
427
    }
1697
1.81k
    comp->comp = xsltXPathCompile(style, comp->test);
1698
1.81k
    if (comp->comp == NULL) {
1699
633
  xsltTransformError(NULL, style, inst,
1700
633
       "xsl:if : could not compile test expression '%s'\n",
1701
633
                   comp->test);
1702
633
  if (style != NULL) style->errors++;
1703
633
    }
1704
1.81k
}
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
2.10k
xsltWhenComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1715
#ifdef XSLT_REFACTORED
1716
    xsltStyleItemWhenPtr comp;
1717
#else
1718
2.10k
    xsltStylePreCompPtr comp;
1719
2.10k
#endif
1720
1721
2.10k
    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
2.10k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_WHEN);
1729
2.10k
#endif
1730
1731
2.10k
    if (comp == NULL)
1732
40
  return;
1733
2.06k
    inst->psvi = comp;
1734
2.06k
    comp->inst = inst;
1735
1736
2.06k
    comp->test = xsltGetCNsProp(style, inst, (const xmlChar *)"test", XSLT_NAMESPACE);
1737
2.06k
    if (comp->test == NULL) {
1738
733
  xsltTransformError(NULL, style, inst,
1739
733
       "xsl:when : test is not defined\n");
1740
733
  if (style != NULL) style->errors++;
1741
733
  return;
1742
733
    }
1743
1.33k
    comp->comp = xsltXPathCompile(style, comp->test);
1744
1.33k
    if (comp->comp == NULL) {
1745
512
  xsltTransformError(NULL, style, inst,
1746
512
       "xsl:when : could not compile test expression '%s'\n",
1747
512
                   comp->test);
1748
512
  if (style != NULL) style->errors++;
1749
512
    }
1750
1.33k
}
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
4.23k
xsltForEachComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1761
#ifdef XSLT_REFACTORED
1762
    xsltStyleItemForEachPtr comp;
1763
#else
1764
4.23k
    xsltStylePreCompPtr comp;
1765
4.23k
#endif
1766
1767
4.23k
    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
4.23k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_FOREACH);
1775
4.23k
#endif
1776
1777
4.23k
    if (comp == NULL)
1778
479
  return;
1779
3.75k
    inst->psvi = comp;
1780
3.75k
    comp->inst = inst;
1781
1782
3.75k
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1783
3.75k
                          XSLT_NAMESPACE);
1784
3.75k
    if (comp->select == NULL) {
1785
479
  xsltTransformError(NULL, style, inst,
1786
479
    "xsl:for-each : select is missing\n");
1787
479
  if (style != NULL) style->errors++;
1788
3.27k
    } else {
1789
3.27k
  comp->comp = xsltXPathCompile(style, comp->select);
1790
3.27k
  if (comp->comp == NULL) {
1791
272
      xsltTransformError(NULL, style, inst,
1792
272
     "xsl:for-each : could not compile select expression '%s'\n",
1793
272
           comp->select);
1794
272
      if (style != NULL) style->errors++;
1795
272
  }
1796
3.27k
    }
1797
    /* TODO: handle and skip the xsl:sort */
1798
3.75k
}
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
21.8k
xsltVariableComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1809
#ifdef XSLT_REFACTORED
1810
    xsltStyleItemVariablePtr comp;
1811
#else
1812
21.8k
    xsltStylePreCompPtr comp;
1813
21.8k
#endif
1814
1815
21.8k
    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
21.8k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_VARIABLE);
1823
21.8k
#endif
1824
1825
21.8k
    if (comp == NULL)
1826
537
  return;
1827
1828
21.3k
    inst->psvi = comp;
1829
21.3k
    comp->inst = inst;
1830
    /*
1831
     * The full template resolution can be done statically
1832
     */
1833
1834
    /*
1835
    * Attribute "name".
1836
    */
1837
21.3k
    xsltGetQNameProperty(style, inst, BAD_CAST "name",
1838
21.3k
  1, &(comp->has_name), &(comp->ns), &(comp->name));
1839
21.3k
    if (comp->ns)
1840
258
  comp->has_ns = 1;
1841
    /*
1842
    * Attribute "select".
1843
    */
1844
21.3k
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1845
21.3k
                          XSLT_NAMESPACE);
1846
21.3k
    if (comp->select != NULL) {
1847
10.0k
#ifndef XSLT_REFACTORED
1848
10.0k
        xmlNodePtr cur;
1849
10.0k
#endif
1850
10.0k
  comp->comp = xsltXPathCompile(style, comp->select);
1851
10.0k
  if (comp->comp == NULL) {
1852
1.11k
      xsltTransformError(NULL, style, inst,
1853
1.11k
    "XSLT-variable: Failed to compile the XPath expression '%s'.\n",
1854
1.11k
    comp->select);
1855
1.11k
      style->errors++;
1856
1.11k
  }
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
12.1k
        for (cur = inst->children; cur != NULL; cur = cur->next) {
1866
2.06k
            if (cur->type != XML_COMMENT_NODE &&
1867
1.77k
                (cur->type != XML_TEXT_NODE || !xsltIsBlank(cur->content)))
1868
1.47k
            {
1869
1.47k
                xsltTransformError(NULL, style, inst,
1870
1.47k
                    "XSLT-variable: There must be no child nodes, since the "
1871
1.47k
                    "attribute 'select' was specified.\n");
1872
1.47k
                style->errors++;
1873
1.47k
            }
1874
2.06k
        }
1875
10.0k
#endif
1876
10.0k
    }
1877
21.3k
}
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
8.38k
xsltParamComp(xsltStylesheetPtr style, xmlNodePtr inst) {
1888
#ifdef XSLT_REFACTORED
1889
    xsltStyleItemParamPtr comp;
1890
#else
1891
8.38k
    xsltStylePreCompPtr comp;
1892
8.38k
#endif
1893
1894
8.38k
    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
8.38k
    comp = xsltNewStylePreComp(style, XSLT_FUNC_PARAM);
1902
8.38k
#endif
1903
1904
8.38k
    if (comp == NULL)
1905
258
  return;
1906
8.12k
    inst->psvi = comp;
1907
8.12k
    comp->inst = inst;
1908
1909
    /*
1910
     * Attribute "name".
1911
     */
1912
8.12k
    xsltGetQNameProperty(style, inst, BAD_CAST "name",
1913
8.12k
  1, &(comp->has_name), &(comp->ns), &(comp->name));
1914
8.12k
    if (comp->ns)
1915
897
  comp->has_ns = 1;
1916
    /*
1917
    * Attribute "select".
1918
    */
1919
8.12k
    comp->select = xsltGetCNsProp(style, inst, (const xmlChar *)"select",
1920
8.12k
                          XSLT_NAMESPACE);
1921
8.12k
    if (comp->select != NULL) {
1922
2.39k
  comp->comp = xsltXPathCompile(style, comp->select);
1923
2.39k
  if (comp->comp == NULL) {
1924
580
      xsltTransformError(NULL, style, inst,
1925
580
    "XSLT-param: could not compile select expression '%s'.\n",
1926
580
    comp->select);
1927
580
      style->errors++;
1928
580
  }
1929
2.39k
  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
2.39k
    }
1936
8.12k
}
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
424k
xsltFreeStylePreComps(xsltStylesheetPtr style) {
1952
424k
    xsltElemPreCompPtr cur, next;
1953
1954
424k
    if (style == NULL)
1955
0
  return;
1956
1957
424k
    cur = style->preComps;
1958
596k
    while (cur != NULL) {
1959
172k
  next = cur->next;
1960
172k
  if (cur->type == XSLT_FUNC_EXTENSION)
1961
8.32k
      cur->free(cur);
1962
163k
  else
1963
163k
      xsltFreeStylePreComp((xsltStylePreCompPtr) cur);
1964
172k
  cur = next;
1965
172k
    }
1966
424k
}
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
206k
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
206k
    if ((inst == NULL) || (inst->type != XML_ELEMENT_NODE) ||
2202
206k
        (inst->psvi != NULL))
2203
0
  return;
2204
2205
206k
    if (IS_XSLT_ELEM(inst)) {
2206
197k
  xsltStylePreCompPtr cur;
2207
2208
197k
  if (IS_XSLT_NAME(inst, "apply-templates")) {
2209
19.7k
      xsltCheckInstructionElement(style, inst);
2210
19.7k
      xsltApplyTemplatesComp(style, inst);
2211
177k
  } else if (IS_XSLT_NAME(inst, "with-param")) {
2212
2.79k
      xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
2213
2.79k
                             BAD_CAST "call-template");
2214
2.79k
      xsltWithParamComp(style, inst);
2215
174k
  } else if (IS_XSLT_NAME(inst, "value-of")) {
2216
28.9k
      xsltCheckInstructionElement(style, inst);
2217
28.9k
      xsltValueOfComp(style, inst);
2218
145k
  } else if (IS_XSLT_NAME(inst, "copy")) {
2219
6.58k
      xsltCheckInstructionElement(style, inst);
2220
6.58k
      xsltCopyComp(style, inst);
2221
139k
  } else if (IS_XSLT_NAME(inst, "copy-of")) {
2222
6.00k
      xsltCheckInstructionElement(style, inst);
2223
6.00k
      xsltCopyOfComp(style, inst);
2224
133k
  } else if (IS_XSLT_NAME(inst, "if")) {
2225
2.27k
      xsltCheckInstructionElement(style, inst);
2226
2.27k
      xsltIfComp(style, inst);
2227
130k
  } else if (IS_XSLT_NAME(inst, "when")) {
2228
2.10k
      xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
2229
2.10k
      xsltWhenComp(style, inst);
2230
128k
  } else if (IS_XSLT_NAME(inst, "choose")) {
2231
1.37k
      xsltCheckInstructionElement(style, inst);
2232
1.37k
      xsltChooseComp(style, inst);
2233
127k
  } else if (IS_XSLT_NAME(inst, "for-each")) {
2234
4.23k
      xsltCheckInstructionElement(style, inst);
2235
4.23k
      xsltForEachComp(style, inst);
2236
123k
  } else if (IS_XSLT_NAME(inst, "apply-imports")) {
2237
826
      xsltCheckInstructionElement(style, inst);
2238
826
      xsltApplyImportsComp(style, inst);
2239
122k
  } else if (IS_XSLT_NAME(inst, "attribute")) {
2240
18.9k
      xmlNodePtr parent = inst->parent;
2241
2242
18.9k
      if ((parent == NULL) ||
2243
18.9k
          (parent->type != XML_ELEMENT_NODE) || (parent->ns == NULL) ||
2244
16.9k
    ((parent->ns != inst->ns) &&
2245
2.69k
     (!xmlStrEqual(parent->ns->href, inst->ns->href))) ||
2246
14.4k
    (!xmlStrEqual(parent->name, BAD_CAST "attribute-set"))) {
2247
5.69k
    xsltCheckInstructionElement(style, inst);
2248
5.69k
      }
2249
18.9k
      xsltAttributeComp(style, inst);
2250
103k
  } else if (IS_XSLT_NAME(inst, "element")) {
2251
6.93k
      xsltCheckInstructionElement(style, inst);
2252
6.93k
      xsltElementComp(style, inst);
2253
96.4k
  } else if (IS_XSLT_NAME(inst, "text")) {
2254
11.6k
      xsltCheckInstructionElement(style, inst);
2255
11.6k
      xsltTextComp(style, inst);
2256
84.8k
  } else if (IS_XSLT_NAME(inst, "sort")) {
2257
6.45k
      xsltCheckParentElement(style, inst, BAD_CAST "apply-templates",
2258
6.45k
                             BAD_CAST "for-each");
2259
6.45k
      xsltSortComp(style, inst);
2260
78.3k
  } else if (IS_XSLT_NAME(inst, "comment")) {
2261
540
      xsltCheckInstructionElement(style, inst);
2262
540
      xsltCommentComp(style, inst);
2263
77.8k
  } else if (IS_XSLT_NAME(inst, "number")) {
2264
14.6k
      xsltCheckInstructionElement(style, inst);
2265
14.6k
      xsltNumberComp(style, inst);
2266
63.1k
  } else if (IS_XSLT_NAME(inst, "processing-instruction")) {
2267
1.21k
      xsltCheckInstructionElement(style, inst);
2268
1.21k
      xsltProcessingInstructionComp(style, inst);
2269
61.9k
  } else if (IS_XSLT_NAME(inst, "call-template")) {
2270
1.07k
      xsltCheckInstructionElement(style, inst);
2271
1.07k
      xsltCallTemplateComp(style, inst);
2272
60.8k
  } else if (IS_XSLT_NAME(inst, "param")) {
2273
8.38k
      if (xsltCheckTopLevelElement(style, inst, 0) == 0)
2274
4.35k
          xsltCheckInstructionElement(style, inst);
2275
8.38k
      xsltParamComp(style, inst);
2276
52.5k
  } else if (IS_XSLT_NAME(inst, "variable")) {
2277
21.8k
      if (xsltCheckTopLevelElement(style, inst, 0) == 0)
2278
7.47k
          xsltCheckInstructionElement(style, inst);
2279
21.8k
      xsltVariableComp(style, inst);
2280
30.6k
  } else if (IS_XSLT_NAME(inst, "otherwise")) {
2281
1.16k
      xsltCheckParentElement(style, inst, BAD_CAST "choose", NULL);
2282
1.16k
      xsltCheckInstructionElement(style, inst);
2283
1.16k
      return;
2284
29.4k
  } else if (IS_XSLT_NAME(inst, "template")) {
2285
3.49k
      xsltCheckTopLevelElement(style, inst, 1);
2286
3.49k
      return;
2287
25.9k
  } else if (IS_XSLT_NAME(inst, "output")) {
2288
988
      xsltCheckTopLevelElement(style, inst, 1);
2289
988
      return;
2290
24.9k
  } else if (IS_XSLT_NAME(inst, "preserve-space")) {
2291
204
      xsltCheckTopLevelElement(style, inst, 1);
2292
204
      return;
2293
24.7k
  } else if (IS_XSLT_NAME(inst, "strip-space")) {
2294
823
      xsltCheckTopLevelElement(style, inst, 1);
2295
823
      return;
2296
23.9k
  } else if ((IS_XSLT_NAME(inst, "stylesheet")) ||
2297
23.7k
             (IS_XSLT_NAME(inst, "transform"))) {
2298
1.00k
      xmlNodePtr parent = inst->parent;
2299
2300
1.00k
      if ((parent == NULL) || (parent->type != XML_DOCUMENT_NODE)) {
2301
1.00k
    xsltTransformError(NULL, style, inst,
2302
1.00k
        "element %s only allowed only as root element\n",
2303
1.00k
           inst->name);
2304
1.00k
    style->errors++;
2305
1.00k
      }
2306
1.00k
      return;
2307
22.9k
  } else if (IS_XSLT_NAME(inst, "key")) {
2308
1.26k
      xsltCheckTopLevelElement(style, inst, 1);
2309
1.26k
      return;
2310
21.6k
  } else if (IS_XSLT_NAME(inst, "message")) {
2311
285
      xsltCheckInstructionElement(style, inst);
2312
285
      return;
2313
21.3k
  } else if (IS_XSLT_NAME(inst, "attribute-set")) {
2314
296
      xsltCheckTopLevelElement(style, inst, 1);
2315
296
      return;
2316
21.0k
  } else if (IS_XSLT_NAME(inst, "namespace-alias")) {
2317
379
      xsltCheckTopLevelElement(style, inst, 1);
2318
379
      return;
2319
20.6k
  } else if (IS_XSLT_NAME(inst, "include")) {
2320
364
      xsltCheckTopLevelElement(style, inst, 1);
2321
364
      return;
2322
20.3k
  } else if (IS_XSLT_NAME(inst, "import")) {
2323
3.45k
      xsltCheckTopLevelElement(style, inst, 1);
2324
3.45k
      return;
2325
16.8k
  } else if (IS_XSLT_NAME(inst, "decimal-format")) {
2326
203
      xsltCheckTopLevelElement(style, inst, 1);
2327
203
      return;
2328
16.6k
  } else if (IS_XSLT_NAME(inst, "fallback")) {
2329
1.30k
      xsltCheckInstructionElement(style, inst);
2330
1.30k
      return;
2331
15.3k
  } else if (IS_XSLT_NAME(inst, "document")) {
2332
610
      xsltCheckInstructionElement(style, inst);
2333
610
      inst->psvi = (void *) xsltDocumentComp(style, inst,
2334
610
        xsltDocumentElem);
2335
14.7k
  } else if ((style == NULL) || (style->forwards_compatible == 0)) {
2336
11.5k
      xsltTransformError(NULL, style, inst,
2337
11.5k
     "xsltStylePreCompute: unknown xsl:%s\n", inst->name);
2338
11.5k
      if (style != NULL) style->warnings++;
2339
11.5k
  }
2340
2341
181k
  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
181k
  if (cur != NULL) {
2347
163k
      int i = 0;
2348
2349
163k
      cur->nsList = xmlGetNsList(inst->doc, inst);
2350
163k
            if (cur->nsList != NULL) {
2351
832k
    while (cur->nsList[i] != NULL)
2352
669k
        i++;
2353
163k
      }
2354
163k
      cur->nsNr = i;
2355
163k
  }
2356
181k
    } else {
2357
9.36k
  inst->psvi =
2358
9.36k
      (void *) xsltPreComputeExtModuleElement(style, inst);
2359
2360
  /*
2361
   * Unknown element, maybe registered at the context
2362
   * level. Mark it for later recognition.
2363
   */
2364
9.36k
  if (inst->psvi == NULL)
2365
1.03k
      inst->psvi = (void *) xsltExtMarker;
2366
9.36k
    }
2367
206k
}
2368
#endif /* XSLT_REFACTORED */