Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/xslt/xslt/txStylesheetCompileHandlers.cpp
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/* This Source Code Form is subject to the terms of the Mozilla Public
3
 * License, v. 2.0. If a copy of the MPL was not distributed with this
4
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6
#include "mozilla/ArrayUtils.h"
7
#include "mozilla/FloatingPoint.h"
8
#include "mozilla/Move.h"
9
10
#include "txStylesheetCompiler.h"
11
#include "txStylesheetCompileHandlers.h"
12
#include "nsWhitespaceTokenizer.h"
13
#include "txInstructions.h"
14
#include "nsGkAtoms.h"
15
#include "txCore.h"
16
#include "txStringUtils.h"
17
#include "txStylesheet.h"
18
#include "txToplevelItems.h"
19
#include "txPatternParser.h"
20
#include "txNamespaceMap.h"
21
#include "txURIUtils.h"
22
#include "txXSLTFunctions.h"
23
24
using namespace mozilla;
25
26
txHandlerTable* gTxIgnoreHandler = 0;
27
txHandlerTable* gTxRootHandler = 0;
28
txHandlerTable* gTxEmbedHandler = 0;
29
txHandlerTable* gTxTopHandler = 0;
30
txHandlerTable* gTxTemplateHandler = 0;
31
txHandlerTable* gTxTextHandler = 0;
32
txHandlerTable* gTxApplyTemplatesHandler = 0;
33
txHandlerTable* gTxCallTemplateHandler = 0;
34
txHandlerTable* gTxVariableHandler = 0;
35
txHandlerTable* gTxForEachHandler = 0;
36
txHandlerTable* gTxTopVariableHandler = 0;
37
txHandlerTable* gTxChooseHandler = 0;
38
txHandlerTable* gTxParamHandler = 0;
39
txHandlerTable* gTxImportHandler = 0;
40
txHandlerTable* gTxAttributeSetHandler = 0;
41
txHandlerTable* gTxFallbackHandler = 0;
42
43
static nsresult
44
txFnStartLRE(int32_t aNamespaceID,
45
             nsAtom* aLocalName,
46
             nsAtom* aPrefix,
47
             txStylesheetAttr* aAttributes,
48
             int32_t aAttrCount,
49
             txStylesheetCompilerState& aState);
50
static nsresult
51
txFnEndLRE(txStylesheetCompilerState& aState);
52
53
54
#define TX_RETURN_IF_WHITESPACE(_str, _state)                               \
55
0
    do {                                                                    \
56
0
      if (!_state.mElementContext->mPreserveWhitespace &&                   \
57
0
          XMLUtils::isWhitespace(_str)) {                                   \
58
0
          return NS_OK;                                                     \
59
0
      }                                                                     \
60
0
    } while(0)
61
62
63
static nsresult
64
getStyleAttr(txStylesheetAttr* aAttributes,
65
             int32_t aAttrCount,
66
             int32_t aNamespace,
67
             nsAtom* aName,
68
             bool aRequired,
69
             txStylesheetAttr** aAttr)
70
0
{
71
0
    int32_t i;
72
0
    for (i = 0; i < aAttrCount; ++i) {
73
0
        txStylesheetAttr* attr = aAttributes + i;
74
0
        if (attr->mNamespaceID == aNamespace &&
75
0
            attr->mLocalName == aName) {
76
0
            attr->mLocalName = nullptr;
77
0
            *aAttr = attr;
78
0
79
0
            return NS_OK;
80
0
        }
81
0
    }
82
0
    *aAttr = nullptr;
83
0
84
0
    if (aRequired) {
85
0
        // XXX ErrorReport: missing required attribute
86
0
        return NS_ERROR_XSLT_PARSE_FAILURE;
87
0
    }
88
0
89
0
    return NS_OK;
90
0
}
91
92
static nsresult
93
parseUseAttrSets(txStylesheetAttr* aAttributes,
94
                 int32_t aAttrCount,
95
                 bool aInXSLTNS,
96
                 txStylesheetCompilerState& aState)
97
0
{
98
0
    txStylesheetAttr* attr = nullptr;
99
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount,
100
0
                               aInXSLTNS ? kNameSpaceID_XSLT
101
0
                                         : kNameSpaceID_None,
102
0
                               nsGkAtoms::useAttributeSets, false,
103
0
                               &attr);
104
0
    if (!attr) {
105
0
        return rv;
106
0
    }
107
0
108
0
    nsWhitespaceTokenizer tok(attr->mValue);
109
0
    while (tok.hasMoreTokens()) {
110
0
        txExpandedName name;
111
0
        rv = name.init(tok.nextToken(), aState.mElementContext->mMappings,
112
0
                       false);
113
0
        NS_ENSURE_SUCCESS(rv, rv);
114
0
115
0
        nsAutoPtr<txInstruction> instr(new txInsertAttrSet(name));
116
0
        rv = aState.addInstruction(std::move(instr));
117
0
        NS_ENSURE_SUCCESS(rv, rv);
118
0
    }
119
0
    return NS_OK;
120
0
}
121
122
static nsresult
123
parseExcludeResultPrefixes(txStylesheetAttr* aAttributes,
124
                           int32_t aAttrCount,
125
                           int32_t aNamespaceID)
126
0
{
127
0
    txStylesheetAttr* attr = nullptr;
128
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, aNamespaceID,
129
0
                               nsGkAtoms::excludeResultPrefixes, false,
130
0
                               &attr);
131
0
    if (!attr) {
132
0
        return rv;
133
0
    }
134
0
135
0
    // XXX Needs to be implemented.
136
0
137
0
    return NS_OK;
138
0
}
139
140
static nsresult
141
getQNameAttr(txStylesheetAttr* aAttributes,
142
             int32_t aAttrCount,
143
             nsAtom* aName,
144
             bool aRequired,
145
             txStylesheetCompilerState& aState,
146
             txExpandedName& aExpName)
147
0
{
148
0
    aExpName.reset();
149
0
    txStylesheetAttr* attr = nullptr;
150
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
151
0
                               aName, aRequired, &attr);
152
0
    if (!attr) {
153
0
        return rv;
154
0
    }
155
0
156
0
    rv = aExpName.init(attr->mValue, aState.mElementContext->mMappings,
157
0
                       false);
158
0
    if (!aRequired && NS_FAILED(rv) && aState.fcp()) {
159
0
        aExpName.reset();
160
0
        rv = NS_OK;
161
0
    }
162
0
163
0
    return rv;
164
0
}
165
166
static nsresult
167
getExprAttr(txStylesheetAttr* aAttributes,
168
            int32_t aAttrCount,
169
            nsAtom* aName,
170
            bool aRequired,
171
            txStylesheetCompilerState& aState,
172
            nsAutoPtr<Expr>& aExpr)
173
0
{
174
0
    aExpr = nullptr;
175
0
    txStylesheetAttr* attr = nullptr;
176
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
177
0
                               aName, aRequired, &attr);
178
0
    if (!attr) {
179
0
        return rv;
180
0
    }
181
0
182
0
    rv = txExprParser::createExpr(attr->mValue, &aState,
183
0
                                  getter_Transfers(aExpr));
184
0
    if (NS_FAILED(rv) && aState.ignoreError(rv)) {
185
0
        // use default value in fcp for not required exprs
186
0
        if (aRequired) {
187
0
            aExpr = new txErrorExpr(
188
#ifdef TX_TO_STRING
189
                                    attr->mValue
190
#endif
191
                                    );
192
0
        }
193
0
        else {
194
0
            aExpr = nullptr;
195
0
        }
196
0
        return NS_OK;
197
0
    }
198
0
199
0
    return rv;
200
0
}
201
202
static nsresult
203
getAVTAttr(txStylesheetAttr* aAttributes,
204
           int32_t aAttrCount,
205
           nsAtom* aName,
206
           bool aRequired,
207
           txStylesheetCompilerState& aState,
208
           nsAutoPtr<Expr>& aAVT)
209
0
{
210
0
    aAVT = nullptr;
211
0
    txStylesheetAttr* attr = nullptr;
212
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
213
0
                               aName, aRequired, &attr);
214
0
    if (!attr) {
215
0
        return rv;
216
0
    }
217
0
218
0
    rv = txExprParser::createAVT(attr->mValue, &aState,
219
0
                                 getter_Transfers(aAVT));
220
0
    if (NS_FAILED(rv) && aState.fcp()) {
221
0
        // use default value in fcp for not required exprs
222
0
        if (aRequired) {
223
0
            aAVT = new txErrorExpr(
224
#ifdef TX_TO_STRING
225
                                   attr->mValue
226
#endif
227
                                   );
228
0
        }
229
0
        else {
230
0
            aAVT = nullptr;
231
0
        }
232
0
        return NS_OK;
233
0
    }
234
0
235
0
    return rv;
236
0
}
237
238
static nsresult
239
getPatternAttr(txStylesheetAttr* aAttributes,
240
               int32_t aAttrCount,
241
               nsAtom* aName,
242
               bool aRequired,
243
               txStylesheetCompilerState& aState,
244
               nsAutoPtr<txPattern>& aPattern)
245
0
{
246
0
    aPattern = nullptr;
247
0
    txStylesheetAttr* attr = nullptr;
248
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
249
0
                               aName, aRequired, &attr);
250
0
    if (!attr) {
251
0
        return rv;
252
0
    }
253
0
254
0
    rv = txPatternParser::createPattern(attr->mValue, &aState,
255
0
                                        getter_Transfers(aPattern));
256
0
    if (NS_FAILED(rv) && (aRequired || !aState.ignoreError(rv))) {
257
0
        // XXX ErrorReport: XSLT-Pattern parse failure
258
0
        return rv;
259
0
    }
260
0
261
0
    return NS_OK;
262
0
}
263
264
static nsresult
265
getNumberAttr(txStylesheetAttr* aAttributes,
266
              int32_t aAttrCount,
267
              nsAtom* aName,
268
              bool aRequired,
269
              txStylesheetCompilerState& aState,
270
              double& aNumber)
271
0
{
272
0
    aNumber = UnspecifiedNaN<double>();
273
0
    txStylesheetAttr* attr = nullptr;
274
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
275
0
                               aName, aRequired, &attr);
276
0
    if (!attr) {
277
0
        return rv;
278
0
    }
279
0
280
0
    aNumber = txDouble::toDouble(attr->mValue);
281
0
    if (mozilla::IsNaN(aNumber) && (aRequired || !aState.fcp())) {
282
0
        // XXX ErrorReport: number parse failure
283
0
        return NS_ERROR_XSLT_PARSE_FAILURE;
284
0
    }
285
0
286
0
    return NS_OK;
287
0
}
288
289
static nsresult
290
getAtomAttr(txStylesheetAttr* aAttributes,
291
            int32_t aAttrCount,
292
            nsAtom* aName,
293
            bool aRequired,
294
            txStylesheetCompilerState& aState,
295
            nsAtom** aAtom)
296
0
{
297
0
    *aAtom = nullptr;
298
0
    txStylesheetAttr* attr = nullptr;
299
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
300
0
                               aName, aRequired, &attr);
301
0
    if (!attr) {
302
0
        return rv;
303
0
    }
304
0
305
0
    *aAtom = NS_Atomize(attr->mValue).take();
306
0
    NS_ENSURE_TRUE(*aAtom, NS_ERROR_OUT_OF_MEMORY);
307
0
308
0
    return NS_OK;
309
0
}
310
311
static nsresult
312
getYesNoAttr(txStylesheetAttr* aAttributes,
313
             int32_t aAttrCount,
314
             nsAtom* aName,
315
             bool aRequired,
316
             txStylesheetCompilerState& aState,
317
             txThreeState& aRes)
318
0
{
319
0
    aRes = eNotSet;
320
0
    RefPtr<nsAtom> atom;
321
0
    nsresult rv = getAtomAttr(aAttributes, aAttrCount, aName, aRequired,
322
0
                              aState, getter_AddRefs(atom));
323
0
    if (!atom) {
324
0
        return rv;
325
0
    }
326
0
327
0
    if (atom == nsGkAtoms::yes) {
328
0
        aRes = eTrue;
329
0
    }
330
0
    else if (atom == nsGkAtoms::no) {
331
0
        aRes = eFalse;
332
0
    }
333
0
    else if (aRequired || !aState.fcp()) {
334
0
        // XXX ErrorReport: unknown values
335
0
        return NS_ERROR_XSLT_PARSE_FAILURE;
336
0
    }
337
0
338
0
    return NS_OK;
339
0
}
340
341
static nsresult
342
getCharAttr(txStylesheetAttr* aAttributes,
343
            int32_t aAttrCount,
344
            nsAtom* aName,
345
            bool aRequired,
346
            txStylesheetCompilerState& aState,
347
            char16_t& aChar)
348
0
{
349
0
    // Don't reset aChar since it contains the default value
350
0
    txStylesheetAttr* attr = nullptr;
351
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
352
0
                               aName, aRequired, &attr);
353
0
    if (!attr) {
354
0
        return rv;
355
0
    }
356
0
357
0
    if (attr->mValue.Length() == 1) {
358
0
        aChar = attr->mValue.CharAt(0);
359
0
    }
360
0
    else if (aRequired || !aState.fcp()) {
361
0
        // XXX ErrorReport: not a character
362
0
        return NS_ERROR_XSLT_PARSE_FAILURE;
363
0
    }
364
0
365
0
    return NS_OK;
366
0
}
367
368
369
/**
370
 * Ignore and error handlers
371
 */
372
static nsresult
373
txFnTextIgnore(const nsAString& aStr, txStylesheetCompilerState& aState)
374
0
{
375
0
    return NS_OK;
376
0
}
377
378
static nsresult
379
txFnTextError(const nsAString& aStr, txStylesheetCompilerState& aState)
380
0
{
381
0
    TX_RETURN_IF_WHITESPACE(aStr, aState);
382
0
383
0
    return NS_ERROR_XSLT_PARSE_FAILURE;
384
0
}
385
386
void
387
clearAttributes(txStylesheetAttr* aAttributes,
388
                     int32_t aAttrCount)
389
0
{
390
0
    int32_t i;
391
0
    for (i = 0; i < aAttrCount; ++i) {
392
0
        aAttributes[i].mLocalName = nullptr;
393
0
    }
394
0
}
395
396
static nsresult
397
txFnStartElementIgnore(int32_t aNamespaceID,
398
                       nsAtom* aLocalName,
399
                       nsAtom* aPrefix,
400
                       txStylesheetAttr* aAttributes,
401
                       int32_t aAttrCount,
402
                       txStylesheetCompilerState& aState)
403
0
{
404
0
    if (!aState.fcp()) {
405
0
        clearAttributes(aAttributes, aAttrCount);
406
0
    }
407
0
408
0
    return NS_OK;
409
0
}
410
411
static nsresult
412
txFnEndElementIgnore(txStylesheetCompilerState& aState)
413
0
{
414
0
    return NS_OK;
415
0
}
416
417
static nsresult
418
txFnStartElementSetIgnore(int32_t aNamespaceID,
419
                          nsAtom* aLocalName,
420
                          nsAtom* aPrefix,
421
                          txStylesheetAttr* aAttributes,
422
                          int32_t aAttrCount,
423
                          txStylesheetCompilerState& aState)
424
0
{
425
0
    if (!aState.fcp()) {
426
0
        clearAttributes(aAttributes, aAttrCount);
427
0
    }
428
0
429
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
430
0
}
431
432
static nsresult
433
txFnEndElementSetIgnore(txStylesheetCompilerState& aState)
434
0
{
435
0
    aState.popHandlerTable();
436
0
    return NS_OK;
437
0
}
438
439
static nsresult
440
txFnStartElementError(int32_t aNamespaceID,
441
                      nsAtom* aLocalName,
442
                      nsAtom* aPrefix,
443
                      txStylesheetAttr* aAttributes,
444
                      int32_t aAttrCount,
445
                      txStylesheetCompilerState& aState)
446
0
{
447
0
    return NS_ERROR_XSLT_PARSE_FAILURE;
448
0
}
449
450
static nsresult
451
txFnEndElementError(txStylesheetCompilerState& aState)
452
0
{
453
0
    NS_ERROR("txFnEndElementError shouldn't be called");
454
0
    return NS_ERROR_XSLT_PARSE_FAILURE;
455
0
}
456
457
458
/**
459
 * Root handlers
460
 */
461
static nsresult
462
txFnStartStylesheet(int32_t aNamespaceID,
463
                    nsAtom* aLocalName,
464
                    nsAtom* aPrefix,
465
                    txStylesheetAttr* aAttributes,
466
                    int32_t aAttrCount,
467
                    txStylesheetCompilerState& aState)
468
0
{
469
0
    // extension-element-prefixes is handled in
470
0
    // txStylesheetCompiler::startElementInternal
471
0
472
0
    txStylesheetAttr* attr;
473
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
474
0
                               nsGkAtoms::id, false, &attr);
475
0
    NS_ENSURE_SUCCESS(rv, rv);
476
0
477
0
    rv = parseExcludeResultPrefixes(aAttributes, aAttrCount, kNameSpaceID_None);
478
0
    NS_ENSURE_SUCCESS(rv, rv);
479
0
480
0
    rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
481
0
                      nsGkAtoms::version, true, &attr);
482
0
    NS_ENSURE_SUCCESS(rv, rv);
483
0
484
0
    return aState.pushHandlerTable(gTxImportHandler);
485
0
}
486
487
static nsresult
488
txFnEndStylesheet(txStylesheetCompilerState& aState)
489
0
{
490
0
    aState.popHandlerTable();
491
0
    return NS_OK;
492
0
}
493
494
static nsresult
495
txFnStartElementContinueTopLevel(int32_t aNamespaceID,
496
                                nsAtom* aLocalName,
497
                                nsAtom* aPrefix,
498
                                txStylesheetAttr* aAttributes,
499
                                int32_t aAttrCount,
500
                                txStylesheetCompilerState& aState)
501
0
{
502
0
    aState.mHandlerTable = gTxTopHandler;
503
0
504
0
    return NS_XSLT_GET_NEW_HANDLER;
505
0
}
506
507
static nsresult
508
txFnStartLREStylesheet(int32_t aNamespaceID,
509
                       nsAtom* aLocalName,
510
                       nsAtom* aPrefix,
511
                       txStylesheetAttr* aAttributes,
512
                       int32_t aAttrCount,
513
                       txStylesheetCompilerState& aState)
514
0
{
515
0
    txStylesheetAttr* attr;
516
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_XSLT,
517
0
                               nsGkAtoms::version, true, &attr);
518
0
    NS_ENSURE_SUCCESS(rv, rv);
519
0
520
0
    txExpandedName nullExpr;
521
0
    double prio = UnspecifiedNaN<double>();
522
0
523
0
    nsAutoPtr<txPattern> match(new txRootPattern());
524
0
    nsAutoPtr<txTemplateItem> templ(new txTemplateItem(std::move(match), nullExpr,
525
0
                                                       nullExpr, prio));
526
0
    aState.openInstructionContainer(templ);
527
0
    rv = aState.addToplevelItem(templ);
528
0
    NS_ENSURE_SUCCESS(rv, rv);
529
0
530
0
    templ.forget();
531
0
532
0
    rv = aState.pushHandlerTable(gTxTemplateHandler);
533
0
    NS_ENSURE_SUCCESS(rv, rv);
534
0
535
0
    return txFnStartLRE(aNamespaceID, aLocalName, aPrefix, aAttributes,
536
0
                        aAttrCount, aState);
537
0
}
538
539
static nsresult
540
txFnEndLREStylesheet(txStylesheetCompilerState& aState)
541
0
{
542
0
    nsresult rv = txFnEndLRE(aState);
543
0
    NS_ENSURE_SUCCESS(rv, rv);
544
0
545
0
    aState.popHandlerTable();
546
0
547
0
    nsAutoPtr<txInstruction> instr(new txReturn());
548
0
    rv = aState.addInstruction(std::move(instr));
549
0
    NS_ENSURE_SUCCESS(rv, rv);
550
0
551
0
    aState.closeInstructionContainer();
552
0
553
0
    return NS_OK;
554
0
}
555
556
static nsresult
557
txFnStartEmbed(int32_t aNamespaceID,
558
               nsAtom* aLocalName,
559
               nsAtom* aPrefix,
560
               txStylesheetAttr* aAttributes,
561
               int32_t aAttrCount,
562
               txStylesheetCompilerState& aState)
563
0
{
564
0
    if (!aState.handleEmbeddedSheet()) {
565
0
        return NS_OK;
566
0
    }
567
0
    if (aNamespaceID != kNameSpaceID_XSLT ||
568
0
        (aLocalName != nsGkAtoms::stylesheet &&
569
0
         aLocalName != nsGkAtoms::transform)) {
570
0
        return NS_ERROR_XSLT_PARSE_FAILURE;
571
0
    }
572
0
    return txFnStartStylesheet(aNamespaceID, aLocalName, aPrefix,
573
0
                               aAttributes, aAttrCount, aState);
574
0
}
575
576
static nsresult
577
txFnEndEmbed(txStylesheetCompilerState& aState)
578
0
{
579
0
    if (!aState.handleEmbeddedSheet()) {
580
0
        return NS_OK;
581
0
    }
582
0
    nsresult rv = txFnEndStylesheet(aState);
583
0
    aState.doneEmbedding();
584
0
    return rv;
585
0
}
586
587
588
/**
589
 * Top handlers
590
 */
591
static nsresult
592
txFnStartOtherTop(int32_t aNamespaceID,
593
                  nsAtom* aLocalName,
594
                  nsAtom* aPrefix,
595
                  txStylesheetAttr* aAttributes,
596
                  int32_t aAttrCount,
597
                  txStylesheetCompilerState& aState)
598
0
{
599
0
    if (aNamespaceID == kNameSpaceID_None ||
600
0
        (aNamespaceID == kNameSpaceID_XSLT && !aState.fcp())) {
601
0
        return NS_ERROR_XSLT_PARSE_FAILURE;
602
0
    }
603
0
604
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
605
0
}
606
607
static nsresult
608
txFnEndOtherTop(txStylesheetCompilerState& aState)
609
0
{
610
0
    aState.popHandlerTable();
611
0
    return NS_OK;
612
0
}
613
614
615
// xsl:attribute-set
616
static nsresult
617
txFnStartAttributeSet(int32_t aNamespaceID,
618
                      nsAtom* aLocalName,
619
                      nsAtom* aPrefix,
620
                      txStylesheetAttr* aAttributes,
621
                      int32_t aAttrCount,
622
                      txStylesheetCompilerState& aState)
623
0
{
624
0
    nsresult rv = NS_OK;
625
0
    txExpandedName name;
626
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
627
0
                      aState, name);
628
0
    NS_ENSURE_SUCCESS(rv, rv);
629
0
630
0
    nsAutoPtr<txAttributeSetItem> attrSet(new txAttributeSetItem(name));
631
0
    aState.openInstructionContainer(attrSet);
632
0
633
0
    rv = aState.addToplevelItem(attrSet);
634
0
    NS_ENSURE_SUCCESS(rv, rv);
635
0
636
0
    attrSet.forget();
637
0
638
0
    rv = parseUseAttrSets(aAttributes, aAttrCount, false, aState);
639
0
    NS_ENSURE_SUCCESS(rv, rv);
640
0
641
0
    return aState.pushHandlerTable(gTxAttributeSetHandler);
642
0
}
643
644
static nsresult
645
txFnEndAttributeSet(txStylesheetCompilerState& aState)
646
0
{
647
0
    aState.popHandlerTable();
648
0
649
0
    nsAutoPtr<txInstruction> instr(new txReturn());
650
0
    nsresult rv = aState.addInstruction(std::move(instr));
651
0
    NS_ENSURE_SUCCESS(rv, rv);
652
0
653
0
    aState.closeInstructionContainer();
654
0
655
0
    return NS_OK;
656
0
}
657
658
659
// xsl:decimal-format
660
static nsresult
661
txFnStartDecimalFormat(int32_t aNamespaceID,
662
                       nsAtom* aLocalName,
663
                       nsAtom* aPrefix,
664
                       txStylesheetAttr* aAttributes,
665
                       int32_t aAttrCount,
666
                       txStylesheetCompilerState& aState)
667
0
{
668
0
    nsresult rv = NS_OK;
669
0
    txExpandedName name;
670
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, false,
671
0
                      aState, name);
672
0
    NS_ENSURE_SUCCESS(rv, rv);
673
0
674
0
    nsAutoPtr<txDecimalFormat> format(new txDecimalFormat);
675
0
    rv = getCharAttr(aAttributes, aAttrCount, nsGkAtoms::decimalSeparator,
676
0
                     false, aState, format->mDecimalSeparator);
677
0
    NS_ENSURE_SUCCESS(rv, rv);
678
0
679
0
    rv = getCharAttr(aAttributes, aAttrCount, nsGkAtoms::groupingSeparator,
680
0
                     false, aState, format->mGroupingSeparator);
681
0
    NS_ENSURE_SUCCESS(rv, rv);
682
0
683
0
    txStylesheetAttr* attr = nullptr;
684
0
    rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
685
0
                      nsGkAtoms::infinity, false, &attr);
686
0
    NS_ENSURE_SUCCESS(rv, rv);
687
0
688
0
    if (attr) {
689
0
        format->mInfinity = attr->mValue;
690
0
    }
691
0
692
0
    rv = getCharAttr(aAttributes, aAttrCount, nsGkAtoms::minusSign,
693
0
                     false, aState, format->mMinusSign);
694
0
    NS_ENSURE_SUCCESS(rv, rv);
695
0
696
0
    rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
697
0
                      nsGkAtoms::NaN, false, &attr);
698
0
    NS_ENSURE_SUCCESS(rv, rv);
699
0
700
0
    if (attr) {
701
0
        format->mNaN = attr->mValue;
702
0
    }
703
0
704
0
    rv = getCharAttr(aAttributes, aAttrCount, nsGkAtoms::percent,
705
0
                     false, aState, format->mPercent);
706
0
    NS_ENSURE_SUCCESS(rv, rv);
707
0
708
0
    rv = getCharAttr(aAttributes, aAttrCount, nsGkAtoms::perMille,
709
0
                     false, aState, format->mPerMille);
710
0
    NS_ENSURE_SUCCESS(rv, rv);
711
0
712
0
    rv = getCharAttr(aAttributes, aAttrCount, nsGkAtoms::zeroDigit,
713
0
                     false, aState, format->mZeroDigit);
714
0
    NS_ENSURE_SUCCESS(rv, rv);
715
0
716
0
    rv = getCharAttr(aAttributes, aAttrCount, nsGkAtoms::digit,
717
0
                     false, aState, format->mDigit);
718
0
    NS_ENSURE_SUCCESS(rv, rv);
719
0
720
0
    rv = getCharAttr(aAttributes, aAttrCount, nsGkAtoms::patternSeparator,
721
0
                     false, aState, format->mPatternSeparator);
722
0
    NS_ENSURE_SUCCESS(rv, rv);
723
0
724
0
    rv = aState.mStylesheet->addDecimalFormat(name, std::move(format));
725
0
    NS_ENSURE_SUCCESS(rv, rv);
726
0
727
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
728
0
}
729
730
static nsresult
731
txFnEndDecimalFormat(txStylesheetCompilerState& aState)
732
0
{
733
0
    aState.popHandlerTable();
734
0
735
0
    return NS_OK;
736
0
}
737
738
// xsl:import
739
static nsresult
740
txFnStartImport(int32_t aNamespaceID,
741
                nsAtom* aLocalName,
742
                nsAtom* aPrefix,
743
                txStylesheetAttr* aAttributes,
744
                int32_t aAttrCount,
745
                txStylesheetCompilerState& aState)
746
0
{
747
0
    nsAutoPtr<txImportItem> import(new txImportItem);
748
0
    import->mFrame = new txStylesheet::ImportFrame;
749
0
    nsresult rv = aState.addToplevelItem(import);
750
0
    NS_ENSURE_SUCCESS(rv, rv);
751
0
752
0
    txImportItem* importPtr = import.forget();
753
0
754
0
    txStylesheetAttr* attr = nullptr;
755
0
    rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
756
0
                      nsGkAtoms::href, true, &attr);
757
0
    NS_ENSURE_SUCCESS(rv, rv);
758
0
759
0
    nsAutoString absUri;
760
0
    URIUtils::resolveHref(attr->mValue, aState.mElementContext->mBaseURI,
761
0
                          absUri);
762
0
    rv = aState.loadImportedStylesheet(absUri, importPtr->mFrame);
763
0
    NS_ENSURE_SUCCESS(rv, rv);
764
0
765
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
766
0
}
767
768
static nsresult
769
txFnEndImport(txStylesheetCompilerState& aState)
770
0
{
771
0
    aState.popHandlerTable();
772
0
773
0
    return NS_OK;
774
0
}
775
776
// xsl:include
777
static nsresult
778
txFnStartInclude(int32_t aNamespaceID,
779
                 nsAtom* aLocalName,
780
                 nsAtom* aPrefix,
781
                 txStylesheetAttr* aAttributes,
782
                 int32_t aAttrCount,
783
                 txStylesheetCompilerState& aState)
784
0
{
785
0
    txStylesheetAttr* attr = nullptr;
786
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
787
0
                               nsGkAtoms::href, true, &attr);
788
0
    NS_ENSURE_SUCCESS(rv, rv);
789
0
790
0
    nsAutoString absUri;
791
0
    URIUtils::resolveHref(attr->mValue, aState.mElementContext->mBaseURI,
792
0
                          absUri);
793
0
    rv = aState.loadIncludedStylesheet(absUri);
794
0
    NS_ENSURE_SUCCESS(rv, rv);
795
0
796
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
797
0
}
798
799
static nsresult
800
txFnEndInclude(txStylesheetCompilerState& aState)
801
0
{
802
0
    aState.popHandlerTable();
803
0
804
0
    return NS_OK;
805
0
}
806
807
// xsl:key
808
static nsresult
809
txFnStartKey(int32_t aNamespaceID,
810
             nsAtom* aLocalName,
811
             nsAtom* aPrefix,
812
             txStylesheetAttr* aAttributes,
813
             int32_t aAttrCount,
814
             txStylesheetCompilerState& aState)
815
0
{
816
0
    nsresult rv = NS_OK;
817
0
    txExpandedName name;
818
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
819
0
                      aState, name);
820
0
    NS_ENSURE_SUCCESS(rv, rv);
821
0
822
0
    aState.mDisAllowed = txIParseContext::KEY_FUNCTION;
823
0
824
0
    nsAutoPtr<txPattern> match;
825
0
    rv = getPatternAttr(aAttributes, aAttrCount, nsGkAtoms::match, true,
826
0
                        aState, match);
827
0
    NS_ENSURE_SUCCESS(rv, rv);
828
0
829
0
    nsAutoPtr<Expr> use;
830
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::use, true,
831
0
                     aState, use);
832
0
    NS_ENSURE_SUCCESS(rv, rv);
833
0
834
0
    aState.mDisAllowed = 0;
835
0
836
0
    rv = aState.mStylesheet->addKey(name, std::move(match), std::move(use));
837
0
    NS_ENSURE_SUCCESS(rv, rv);
838
0
839
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
840
0
}
841
842
static nsresult
843
txFnEndKey(txStylesheetCompilerState& aState)
844
0
{
845
0
    aState.popHandlerTable();
846
0
847
0
    return NS_OK;
848
0
}
849
850
// xsl:namespace-alias
851
static nsresult
852
txFnStartNamespaceAlias(int32_t aNamespaceID,
853
             nsAtom* aLocalName,
854
             nsAtom* aPrefix,
855
             txStylesheetAttr* aAttributes,
856
             int32_t aAttrCount,
857
             txStylesheetCompilerState& aState)
858
0
{
859
0
    txStylesheetAttr* attr = nullptr;
860
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
861
0
                               nsGkAtoms::stylesheetPrefix, true, &attr);
862
0
    NS_ENSURE_SUCCESS(rv, rv);
863
0
864
0
    rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
865
0
                      nsGkAtoms::resultPrefix, true, &attr);
866
0
    NS_ENSURE_SUCCESS(rv, rv);
867
0
868
0
    // XXX Needs to be implemented.
869
0
870
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
871
0
}
872
873
static nsresult
874
txFnEndNamespaceAlias(txStylesheetCompilerState& aState)
875
0
{
876
0
    aState.popHandlerTable();
877
0
878
0
    return NS_OK;
879
0
}
880
881
// xsl:output
882
static nsresult
883
txFnStartOutput(int32_t aNamespaceID,
884
                nsAtom* aLocalName,
885
                nsAtom* aPrefix,
886
                txStylesheetAttr* aAttributes,
887
                int32_t aAttrCount,
888
                txStylesheetCompilerState& aState)
889
0
{
890
0
    nsresult rv = NS_OK;
891
0
892
0
    nsAutoPtr<txOutputItem> item(new txOutputItem);
893
0
894
0
    txExpandedName methodExpName;
895
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::method, false,
896
0
                      aState, methodExpName);
897
0
    NS_ENSURE_SUCCESS(rv, rv);
898
0
899
0
    if (!methodExpName.isNull()) {
900
0
        if (methodExpName.mNamespaceID != kNameSpaceID_None) {
901
0
            // The spec doesn't say what to do here so we'll just ignore the
902
0
            // value. We could possibly warn.
903
0
        }
904
0
        else if (methodExpName.mLocalName == nsGkAtoms::html) {
905
0
            item->mFormat.mMethod = eHTMLOutput;
906
0
        }
907
0
        else if (methodExpName.mLocalName == nsGkAtoms::text) {
908
0
            item->mFormat.mMethod = eTextOutput;
909
0
        }
910
0
        else if (methodExpName.mLocalName == nsGkAtoms::xml) {
911
0
            item->mFormat.mMethod = eXMLOutput;
912
0
        }
913
0
        else {
914
0
            return NS_ERROR_XSLT_PARSE_FAILURE;
915
0
        }
916
0
    }
917
0
918
0
    txStylesheetAttr* attr = nullptr;
919
0
    getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
920
0
                 nsGkAtoms::version, false, &attr);
921
0
    if (attr) {
922
0
        item->mFormat.mVersion = attr->mValue;
923
0
    }
924
0
925
0
    getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
926
0
                 nsGkAtoms::encoding, false, &attr);
927
0
    if (attr) {
928
0
        item->mFormat.mEncoding = attr->mValue;
929
0
    }
930
0
931
0
    rv = getYesNoAttr(aAttributes, aAttrCount,
932
0
                      nsGkAtoms::omitXmlDeclaration, false, aState,
933
0
                      item->mFormat.mOmitXMLDeclaration);
934
0
    NS_ENSURE_SUCCESS(rv, rv);
935
0
936
0
    rv = getYesNoAttr(aAttributes, aAttrCount,
937
0
                      nsGkAtoms::standalone, false, aState,
938
0
                      item->mFormat.mStandalone);
939
0
    NS_ENSURE_SUCCESS(rv, rv);
940
0
941
0
    getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
942
0
                 nsGkAtoms::doctypePublic, false, &attr);
943
0
    if (attr) {
944
0
        item->mFormat.mPublicId = attr->mValue;
945
0
    }
946
0
947
0
    getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
948
0
                 nsGkAtoms::doctypeSystem, false, &attr);
949
0
    if (attr) {
950
0
        item->mFormat.mSystemId = attr->mValue;
951
0
    }
952
0
953
0
    getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
954
0
                 nsGkAtoms::cdataSectionElements, false, &attr);
955
0
    if (attr) {
956
0
        nsWhitespaceTokenizer tokens(attr->mValue);
957
0
        while (tokens.hasMoreTokens()) {
958
0
            nsAutoPtr<txExpandedName> qname(new txExpandedName());
959
0
            rv = qname->init(tokens.nextToken(),
960
0
                             aState.mElementContext->mMappings, false);
961
0
            NS_ENSURE_SUCCESS(rv, rv);
962
0
963
0
            rv = item->mFormat.mCDATASectionElements.add(qname);
964
0
            NS_ENSURE_SUCCESS(rv, rv);
965
0
            qname.forget();
966
0
        }
967
0
    }
968
0
969
0
    rv = getYesNoAttr(aAttributes, aAttrCount,
970
0
                      nsGkAtoms::indent, false, aState,
971
0
                      item->mFormat.mIndent);
972
0
    NS_ENSURE_SUCCESS(rv, rv);
973
0
974
0
    getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
975
0
                 nsGkAtoms::mediaType, false, &attr);
976
0
    if (attr) {
977
0
        item->mFormat.mMediaType = attr->mValue;
978
0
    }
979
0
980
0
    rv = aState.addToplevelItem(item);
981
0
    NS_ENSURE_SUCCESS(rv, rv);
982
0
983
0
    item.forget();
984
0
985
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
986
0
}
987
988
static nsresult
989
txFnEndOutput(txStylesheetCompilerState& aState)
990
0
{
991
0
    aState.popHandlerTable();
992
0
993
0
    return NS_OK;
994
0
}
995
996
// xsl:strip-space/xsl:preserve-space
997
static nsresult
998
txFnStartStripSpace(int32_t aNamespaceID,
999
                    nsAtom* aLocalName,
1000
                    nsAtom* aPrefix,
1001
                    txStylesheetAttr* aAttributes,
1002
                    int32_t aAttrCount,
1003
                    txStylesheetCompilerState& aState)
1004
0
{
1005
0
    txStylesheetAttr* attr = nullptr;
1006
0
    nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
1007
0
                               nsGkAtoms::elements, true, &attr);
1008
0
    NS_ENSURE_SUCCESS(rv, rv);
1009
0
1010
0
    bool strip = aLocalName == nsGkAtoms::stripSpace;
1011
0
1012
0
    nsAutoPtr<txStripSpaceItem> stripItem(new txStripSpaceItem);
1013
0
    nsWhitespaceTokenizer tokenizer(attr->mValue);
1014
0
    while (tokenizer.hasMoreTokens()) {
1015
0
        const nsAString& name = tokenizer.nextToken();
1016
0
        int32_t ns = kNameSpaceID_None;
1017
0
        RefPtr<nsAtom> prefix, localName;
1018
0
        rv = XMLUtils::splitQName(name, getter_AddRefs(prefix),
1019
0
                                  getter_AddRefs(localName));
1020
0
        if (NS_FAILED(rv)) {
1021
0
            // check for "*" or "prefix:*"
1022
0
            uint32_t length = name.Length();
1023
0
            const char16_t* c;
1024
0
            name.BeginReading(c);
1025
0
            if (length == 2 || c[length-1] != '*') {
1026
0
                // these can't work
1027
0
                return NS_ERROR_XSLT_PARSE_FAILURE;
1028
0
            }
1029
0
            if (length > 1) {
1030
0
                // Check for a valid prefix, that is, the returned prefix
1031
0
                // should be empty and the real prefix is returned in
1032
0
                // localName.
1033
0
                if (c[length-2] != ':') {
1034
0
                    return NS_ERROR_XSLT_PARSE_FAILURE;
1035
0
                }
1036
0
                rv = XMLUtils::splitQName(StringHead(name, length - 2),
1037
0
                                          getter_AddRefs(prefix),
1038
0
                                          getter_AddRefs(localName));
1039
0
                if (NS_FAILED(rv) || prefix) {
1040
0
                    // bad chars or two ':'
1041
0
                    return NS_ERROR_XSLT_PARSE_FAILURE;
1042
0
                }
1043
0
                prefix = localName;
1044
0
            }
1045
0
            localName = nsGkAtoms::_asterisk;
1046
0
        }
1047
0
        if (prefix) {
1048
0
            ns = aState.mElementContext->mMappings->lookupNamespace(prefix);
1049
0
            NS_ENSURE_TRUE(ns != kNameSpaceID_Unknown, NS_ERROR_FAILURE);
1050
0
        }
1051
0
        nsAutoPtr<txStripSpaceTest> sst(new txStripSpaceTest(prefix, localName,
1052
0
                                                             ns, strip));
1053
0
        rv = stripItem->addStripSpaceTest(sst);
1054
0
        NS_ENSURE_SUCCESS(rv, rv);
1055
0
1056
0
        sst.forget();
1057
0
    }
1058
0
1059
0
    rv = aState.addToplevelItem(stripItem);
1060
0
    NS_ENSURE_SUCCESS(rv, rv);
1061
0
1062
0
    stripItem.forget();
1063
0
1064
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
1065
0
}
1066
1067
static nsresult
1068
txFnEndStripSpace(txStylesheetCompilerState& aState)
1069
0
{
1070
0
    aState.popHandlerTable();
1071
0
1072
0
    return NS_OK;
1073
0
}
1074
1075
// xsl:template
1076
static nsresult
1077
txFnStartTemplate(int32_t aNamespaceID,
1078
                  nsAtom* aLocalName,
1079
                  nsAtom* aPrefix,
1080
                  txStylesheetAttr* aAttributes,
1081
                  int32_t aAttrCount,
1082
                  txStylesheetCompilerState& aState)
1083
0
{
1084
0
    nsresult rv = NS_OK;
1085
0
    txExpandedName name;
1086
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, false,
1087
0
                      aState, name);
1088
0
    NS_ENSURE_SUCCESS(rv, rv);
1089
0
1090
0
    txExpandedName mode;
1091
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::mode, false,
1092
0
                      aState, mode);
1093
0
    NS_ENSURE_SUCCESS(rv, rv);
1094
0
1095
0
    double prio = UnspecifiedNaN<double>();
1096
0
    rv = getNumberAttr(aAttributes, aAttrCount, nsGkAtoms::priority,
1097
0
                       false, aState, prio);
1098
0
    NS_ENSURE_SUCCESS(rv, rv);
1099
0
1100
0
    nsAutoPtr<txPattern> match;
1101
0
    rv = getPatternAttr(aAttributes, aAttrCount, nsGkAtoms::match,
1102
0
                        name.isNull(), aState, match);
1103
0
    NS_ENSURE_SUCCESS(rv, rv);
1104
0
1105
0
    nsAutoPtr<txTemplateItem> templ(new txTemplateItem(std::move(match), name, mode,
1106
0
                                                       prio));
1107
0
    aState.openInstructionContainer(templ);
1108
0
    rv = aState.addToplevelItem(templ);
1109
0
    NS_ENSURE_SUCCESS(rv, rv);
1110
0
1111
0
    templ.forget();
1112
0
1113
0
    return aState.pushHandlerTable(gTxParamHandler);
1114
0
}
1115
1116
static nsresult
1117
txFnEndTemplate(txStylesheetCompilerState& aState)
1118
0
{
1119
0
    aState.popHandlerTable();
1120
0
1121
0
    nsAutoPtr<txInstruction> instr(new txReturn());
1122
0
    nsresult rv = aState.addInstruction(std::move(instr));
1123
0
    NS_ENSURE_SUCCESS(rv, rv);
1124
0
1125
0
    aState.closeInstructionContainer();
1126
0
1127
0
    return NS_OK;
1128
0
}
1129
1130
// xsl:variable, xsl:param
1131
static nsresult
1132
txFnStartTopVariable(int32_t aNamespaceID,
1133
                     nsAtom* aLocalName,
1134
                     nsAtom* aPrefix,
1135
                     txStylesheetAttr* aAttributes,
1136
                     int32_t aAttrCount,
1137
                     txStylesheetCompilerState& aState)
1138
0
{
1139
0
    nsresult rv = NS_OK;
1140
0
    txExpandedName name;
1141
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
1142
0
                      aState, name);
1143
0
    NS_ENSURE_SUCCESS(rv, rv);
1144
0
1145
0
    nsAutoPtr<Expr> select;
1146
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, false,
1147
0
                     aState, select);
1148
0
    NS_ENSURE_SUCCESS(rv, rv);
1149
0
1150
0
    nsAutoPtr<txVariableItem> var(
1151
0
        new txVariableItem(name, std::move(select),
1152
0
                           aLocalName == nsGkAtoms::param));
1153
0
    aState.openInstructionContainer(var);
1154
0
    rv = aState.pushPtr(var, aState.eVariableItem);
1155
0
    NS_ENSURE_SUCCESS(rv, rv);
1156
0
1157
0
    if (var->mValue) {
1158
0
        // XXX should be gTxErrorHandler?
1159
0
        rv = aState.pushHandlerTable(gTxIgnoreHandler);
1160
0
        NS_ENSURE_SUCCESS(rv, rv);
1161
0
    }
1162
0
    else {
1163
0
        rv = aState.pushHandlerTable(gTxTopVariableHandler);
1164
0
        NS_ENSURE_SUCCESS(rv, rv);
1165
0
    }
1166
0
1167
0
    rv = aState.addToplevelItem(var);
1168
0
    NS_ENSURE_SUCCESS(rv, rv);
1169
0
1170
0
    var.forget();
1171
0
1172
0
    return NS_OK;
1173
0
}
1174
1175
static nsresult
1176
txFnEndTopVariable(txStylesheetCompilerState& aState)
1177
0
{
1178
0
    txHandlerTable* prev = aState.mHandlerTable;
1179
0
    aState.popHandlerTable();
1180
0
    txVariableItem* var =
1181
0
        static_cast<txVariableItem*>(aState.popPtr(aState.eVariableItem));
1182
0
1183
0
    if (prev == gTxTopVariableHandler) {
1184
0
        // No children were found.
1185
0
        NS_ASSERTION(!var->mValue,
1186
0
                     "There shouldn't be a select-expression here");
1187
0
        var->mValue = new txLiteralExpr(EmptyString());
1188
0
    }
1189
0
    else if (!var->mValue) {
1190
0
        // If we don't have a select-expression there mush be children.
1191
0
        nsAutoPtr<txInstruction> instr(new txReturn());
1192
0
        nsresult rv = aState.addInstruction(std::move(instr));
1193
0
        NS_ENSURE_SUCCESS(rv, rv);
1194
0
    }
1195
0
1196
0
    aState.closeInstructionContainer();
1197
0
1198
0
    return NS_OK;
1199
0
}
1200
1201
static nsresult
1202
txFnStartElementStartTopVar(int32_t aNamespaceID,
1203
                            nsAtom* aLocalName,
1204
                            nsAtom* aPrefix,
1205
                            txStylesheetAttr* aAttributes,
1206
                            int32_t aAttrCount,
1207
                            txStylesheetCompilerState& aState)
1208
0
{
1209
0
    aState.mHandlerTable = gTxTemplateHandler;
1210
0
1211
0
    return NS_XSLT_GET_NEW_HANDLER;
1212
0
}
1213
1214
static nsresult
1215
txFnTextStartTopVar(const nsAString& aStr, txStylesheetCompilerState& aState)
1216
0
{
1217
0
    TX_RETURN_IF_WHITESPACE(aStr, aState);
1218
0
1219
0
    aState.mHandlerTable = gTxTemplateHandler;
1220
0
1221
0
    return NS_XSLT_GET_NEW_HANDLER;
1222
0
}
1223
1224
/**
1225
 * Template Handlers
1226
 */
1227
1228
/*
1229
  LRE
1230
1231
  txStartLREElement
1232
  txInsertAttrSet        one for each qname in xsl:use-attribute-sets
1233
  txLREAttribute         one for each attribute
1234
  [children]
1235
  txEndElement
1236
*/
1237
static nsresult
1238
txFnStartLRE(int32_t aNamespaceID,
1239
             nsAtom* aLocalName,
1240
             nsAtom* aPrefix,
1241
             txStylesheetAttr* aAttributes,
1242
             int32_t aAttrCount,
1243
             txStylesheetCompilerState& aState)
1244
0
{
1245
0
    nsresult rv = NS_OK;
1246
0
1247
0
    nsAutoPtr<txInstruction> instr(new txStartLREElement(aNamespaceID,
1248
0
                                                         aLocalName, aPrefix));
1249
0
    rv = aState.addInstruction(std::move(instr));
1250
0
    NS_ENSURE_SUCCESS(rv, rv);
1251
0
1252
0
    rv = parseExcludeResultPrefixes(aAttributes, aAttrCount, kNameSpaceID_XSLT);
1253
0
    NS_ENSURE_SUCCESS(rv, rv);
1254
0
1255
0
    rv = parseUseAttrSets(aAttributes, aAttrCount, true, aState);
1256
0
    NS_ENSURE_SUCCESS(rv, rv);
1257
0
1258
0
    txStylesheetAttr* attr = nullptr;
1259
0
    int32_t i;
1260
0
    for (i = 0; i < aAttrCount; ++i) {
1261
0
        attr = aAttributes + i;
1262
0
1263
0
        if (attr->mNamespaceID == kNameSpaceID_XSLT) {
1264
0
            if (attr->mLocalName == nsGkAtoms::version) {
1265
0
                attr->mLocalName = nullptr;
1266
0
            }
1267
0
1268
0
            continue;
1269
0
        }
1270
0
1271
0
        nsAutoPtr<Expr> avt;
1272
0
        rv = txExprParser::createAVT(attr->mValue, &aState,
1273
0
                                     getter_Transfers(avt));
1274
0
        NS_ENSURE_SUCCESS(rv, rv);
1275
0
1276
0
        instr = new txLREAttribute(attr->mNamespaceID, attr->mLocalName,
1277
0
                                   attr->mPrefix, std::move(avt));
1278
0
        rv = aState.addInstruction(std::move(instr));
1279
0
        NS_ENSURE_SUCCESS(rv, rv);
1280
0
    }
1281
0
1282
0
    return NS_OK;
1283
0
}
1284
1285
static nsresult
1286
txFnEndLRE(txStylesheetCompilerState& aState)
1287
0
{
1288
0
    nsAutoPtr<txInstruction> instr(new txEndElement);
1289
0
    nsresult rv = aState.addInstruction(std::move(instr));
1290
0
    NS_ENSURE_SUCCESS(rv, rv);
1291
0
1292
0
    return NS_OK;
1293
0
}
1294
1295
/*
1296
  "LRE text"
1297
1298
  txText
1299
*/
1300
static nsresult
1301
txFnText(const nsAString& aStr, txStylesheetCompilerState& aState)
1302
0
{
1303
0
    TX_RETURN_IF_WHITESPACE(aStr, aState);
1304
0
1305
0
    nsAutoPtr<txInstruction> instr(new txText(aStr, false));
1306
0
    nsresult rv = aState.addInstruction(std::move(instr));
1307
0
    NS_ENSURE_SUCCESS(rv, rv);
1308
0
1309
0
    return NS_OK;
1310
0
}
1311
1312
/*
1313
  xsl:apply-imports
1314
1315
  txApplyImportsStart
1316
  txApplyImportsEnd
1317
*/
1318
static nsresult
1319
txFnStartApplyImports(int32_t aNamespaceID,
1320
                      nsAtom* aLocalName,
1321
                      nsAtom* aPrefix,
1322
                      txStylesheetAttr* aAttributes,
1323
                      int32_t aAttrCount,
1324
                      txStylesheetCompilerState& aState)
1325
0
{
1326
0
    nsresult rv = NS_OK;
1327
0
1328
0
    nsAutoPtr<txInstruction> instr(new txApplyImportsStart);
1329
0
    rv = aState.addInstruction(std::move(instr));
1330
0
    NS_ENSURE_SUCCESS(rv, rv);
1331
0
1332
0
    instr = new txApplyImportsEnd;
1333
0
    rv = aState.addInstruction(std::move(instr));
1334
0
    NS_ENSURE_SUCCESS(rv, rv);
1335
0
1336
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
1337
0
}
1338
1339
static nsresult
1340
txFnEndApplyImports(txStylesheetCompilerState& aState)
1341
0
{
1342
0
    aState.popHandlerTable();
1343
0
1344
0
    return NS_OK;
1345
0
}
1346
1347
/*
1348
  xsl:apply-templates
1349
1350
  txPushParams
1351
  [params]
1352
  txPushNewContext    -+   (holds <xsl:sort>s)
1353
  txApplyTemplate <-+  |
1354
  txLoopNodeSet    -+  |
1355
  txPopParams        <-+
1356
*/
1357
static nsresult
1358
txFnStartApplyTemplates(int32_t aNamespaceID,
1359
                        nsAtom* aLocalName,
1360
                        nsAtom* aPrefix,
1361
                        txStylesheetAttr* aAttributes,
1362
                        int32_t aAttrCount,
1363
                        txStylesheetCompilerState& aState)
1364
0
{
1365
0
    nsresult rv = NS_OK;
1366
0
1367
0
    nsAutoPtr<txInstruction> instr(new txPushParams);
1368
0
    rv = aState.addInstruction(std::move(instr));
1369
0
    NS_ENSURE_SUCCESS(rv, rv);
1370
0
1371
0
    txExpandedName mode;
1372
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::mode, false,
1373
0
                      aState, mode);
1374
0
    NS_ENSURE_SUCCESS(rv, rv);
1375
0
1376
0
    instr = new txApplyTemplates(mode);
1377
0
    rv = aState.pushObject(instr);
1378
0
    NS_ENSURE_SUCCESS(rv, rv);
1379
0
1380
0
    instr.forget();
1381
0
1382
0
    nsAutoPtr<Expr> select;
1383
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, false,
1384
0
                     aState, select);
1385
0
    NS_ENSURE_SUCCESS(rv, rv);
1386
0
1387
0
    if (!select) {
1388
0
        nsAutoPtr<txNodeTest> nt(
1389
0
            new txNodeTypeTest(txNodeTypeTest::NODE_TYPE));
1390
0
        select = new LocationStep(nt, LocationStep::CHILD_AXIS);
1391
0
        nt.forget();
1392
0
    }
1393
0
1394
0
    nsAutoPtr<txPushNewContext> pushcontext( new txPushNewContext(std::move(select)));
1395
0
    rv = aState.pushSorter(pushcontext);
1396
0
    NS_ENSURE_SUCCESS(rv, rv);
1397
0
1398
0
    rv = aState.pushObject(pushcontext);
1399
0
    NS_ENSURE_SUCCESS(rv, rv);
1400
0
1401
0
    pushcontext.forget();
1402
0
1403
0
    return aState.pushHandlerTable(gTxApplyTemplatesHandler);
1404
0
}
1405
1406
static nsresult
1407
txFnEndApplyTemplates(txStylesheetCompilerState& aState)
1408
0
{
1409
0
    aState.popHandlerTable();
1410
0
1411
0
    txPushNewContext* pushcontext =
1412
0
        static_cast<txPushNewContext*>(aState.popObject());
1413
0
    nsAutoPtr<txInstruction> instr(pushcontext); // txPushNewContext
1414
0
    nsresult rv = aState.addInstruction(std::move(instr));
1415
0
    NS_ENSURE_SUCCESS(rv, rv);
1416
0
1417
0
    aState.popSorter();
1418
0
1419
0
    instr = static_cast<txInstruction*>(aState.popObject()); // txApplyTemplates
1420
0
    nsAutoPtr<txLoopNodeSet> loop(new txLoopNodeSet(instr));
1421
0
    rv = aState.addInstruction(std::move(instr));
1422
0
    NS_ENSURE_SUCCESS(rv, rv);
1423
0
1424
0
    instr = loop.forget();
1425
0
    rv = aState.addInstruction(std::move(instr));
1426
0
    NS_ENSURE_SUCCESS(rv, rv);
1427
0
1428
0
    instr = new txPopParams;
1429
0
    pushcontext->mBailTarget = instr;
1430
0
    rv = aState.addInstruction(std::move(instr));
1431
0
    NS_ENSURE_SUCCESS(rv, rv);
1432
0
1433
0
    return NS_OK;
1434
0
}
1435
1436
/*
1437
  xsl:attribute
1438
1439
  txPushStringHandler
1440
  [children]
1441
  txAttribute
1442
*/
1443
static nsresult
1444
txFnStartAttribute(int32_t aNamespaceID,
1445
                   nsAtom* aLocalName,
1446
                   nsAtom* aPrefix,
1447
                   txStylesheetAttr* aAttributes,
1448
                   int32_t aAttrCount,
1449
                   txStylesheetCompilerState& aState)
1450
0
{
1451
0
    nsresult rv = NS_OK;
1452
0
1453
0
    nsAutoPtr<txInstruction> instr(new txPushStringHandler(true));
1454
0
    rv = aState.addInstruction(std::move(instr));
1455
0
    NS_ENSURE_SUCCESS(rv, rv);
1456
0
1457
0
    nsAutoPtr<Expr> name;
1458
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
1459
0
                    aState, name);
1460
0
    NS_ENSURE_SUCCESS(rv, rv);
1461
0
1462
0
    nsAutoPtr<Expr> nspace;
1463
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::_namespace, false,
1464
0
                    aState, nspace);
1465
0
    NS_ENSURE_SUCCESS(rv, rv);
1466
0
1467
0
    instr = new txAttribute(std::move(name), std::move(nspace),
1468
0
                            aState.mElementContext->mMappings);
1469
0
    rv = aState.pushObject(instr);
1470
0
    NS_ENSURE_SUCCESS(rv, rv);
1471
0
1472
0
    instr.forget();
1473
0
1474
0
    // We need to push the template-handler since the current might be
1475
0
    // the attributeset-handler
1476
0
    return aState.pushHandlerTable(gTxTemplateHandler);
1477
0
}
1478
1479
static nsresult
1480
txFnEndAttribute(txStylesheetCompilerState& aState)
1481
0
{
1482
0
    aState.popHandlerTable();
1483
0
    nsAutoPtr<txInstruction> instr(static_cast<txInstruction*>
1484
0
                                              (aState.popObject()));
1485
0
    nsresult rv = aState.addInstruction(std::move(instr));
1486
0
    NS_ENSURE_SUCCESS(rv, rv);
1487
0
1488
0
    return NS_OK;
1489
0
}
1490
1491
/*
1492
  xsl:call-template
1493
1494
  txPushParams
1495
  [params]
1496
  txCallTemplate
1497
  txPopParams
1498
*/
1499
static nsresult
1500
txFnStartCallTemplate(int32_t aNamespaceID,
1501
                      nsAtom* aLocalName,
1502
                      nsAtom* aPrefix,
1503
                      txStylesheetAttr* aAttributes,
1504
                      int32_t aAttrCount,
1505
                      txStylesheetCompilerState& aState)
1506
0
{
1507
0
    nsresult rv = NS_OK;
1508
0
1509
0
    nsAutoPtr<txInstruction> instr(new txPushParams);
1510
0
    rv = aState.addInstruction(std::move(instr));
1511
0
    NS_ENSURE_SUCCESS(rv, rv);
1512
0
1513
0
    txExpandedName name;
1514
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
1515
0
                      aState, name);
1516
0
    NS_ENSURE_SUCCESS(rv, rv);
1517
0
1518
0
    instr = new txCallTemplate(name);
1519
0
    rv = aState.pushObject(instr);
1520
0
    NS_ENSURE_SUCCESS(rv, rv);
1521
0
1522
0
    instr.forget();
1523
0
1524
0
    return aState.pushHandlerTable(gTxCallTemplateHandler);
1525
0
}
1526
1527
static nsresult
1528
txFnEndCallTemplate(txStylesheetCompilerState& aState)
1529
0
{
1530
0
    aState.popHandlerTable();
1531
0
1532
0
    // txCallTemplate
1533
0
    nsAutoPtr<txInstruction> instr(static_cast<txInstruction*>(aState.popObject()));
1534
0
    nsresult rv = aState.addInstruction(std::move(instr));
1535
0
    NS_ENSURE_SUCCESS(rv, rv);
1536
0
1537
0
    instr = new txPopParams;
1538
0
    rv = aState.addInstruction(std::move(instr));
1539
0
    NS_ENSURE_SUCCESS(rv, rv);
1540
0
1541
0
    return NS_OK;
1542
0
}
1543
1544
/*
1545
  xsl:choose
1546
1547
  txCondotionalGoto      --+        \
1548
  [children]               |         | one for each xsl:when
1549
  txGoTo           --+     |        /
1550
                     |     |
1551
  txCondotionalGoto  |   <-+  --+
1552
  [children]         |          |
1553
  txGoTo           --+          |
1554
                     |          |
1555
  [children]         |        <-+      for the xsl:otherwise, if there is one
1556
                   <-+
1557
*/
1558
static nsresult
1559
txFnStartChoose(int32_t aNamespaceID,
1560
                 nsAtom* aLocalName,
1561
                 nsAtom* aPrefix,
1562
                 txStylesheetAttr* aAttributes,
1563
                 int32_t aAttrCount,
1564
                 txStylesheetCompilerState& aState)
1565
0
{
1566
0
    nsresult rv = aState.pushChooseGotoList();
1567
0
    NS_ENSURE_SUCCESS(rv, rv);
1568
0
1569
0
    return aState.pushHandlerTable(gTxChooseHandler);
1570
0
}
1571
1572
static nsresult
1573
txFnEndChoose(txStylesheetCompilerState& aState)
1574
0
{
1575
0
    nsresult rv = NS_OK;
1576
0
    aState.popHandlerTable();
1577
0
    txListIterator iter(aState.mChooseGotoList);
1578
0
    txGoTo* gotoinstr;
1579
0
    while ((gotoinstr = static_cast<txGoTo*>(iter.next()))) {
1580
0
        rv = aState.addGotoTarget(&gotoinstr->mTarget);
1581
0
        NS_ENSURE_SUCCESS(rv, rv);
1582
0
    }
1583
0
1584
0
    aState.popChooseGotoList();
1585
0
1586
0
    return NS_OK;
1587
0
}
1588
1589
/*
1590
  xsl:comment
1591
1592
  txPushStringHandler
1593
  [children]
1594
  txComment
1595
*/
1596
static nsresult
1597
txFnStartComment(int32_t aNamespaceID,
1598
                 nsAtom* aLocalName,
1599
                 nsAtom* aPrefix,
1600
                 txStylesheetAttr* aAttributes,
1601
                 int32_t aAttrCount,
1602
                 txStylesheetCompilerState& aState)
1603
0
{
1604
0
    nsAutoPtr<txInstruction> instr(new txPushStringHandler(true));
1605
0
    nsresult rv = aState.addInstruction(std::move(instr));
1606
0
    NS_ENSURE_SUCCESS(rv, rv);
1607
0
1608
0
    return NS_OK;
1609
0
}
1610
1611
static nsresult
1612
txFnEndComment(txStylesheetCompilerState& aState)
1613
0
{
1614
0
    nsAutoPtr<txInstruction> instr(new txComment);
1615
0
    nsresult rv = aState.addInstruction(std::move(instr));
1616
0
    NS_ENSURE_SUCCESS(rv, rv);
1617
0
1618
0
    return NS_OK;
1619
0
}
1620
1621
/*
1622
  xsl:copy
1623
1624
  txCopy          -+
1625
  txInsertAttrSet  |     one for each qname in use-attribute-sets
1626
  [children]       |
1627
  txEndElement     |
1628
                 <-+
1629
*/
1630
static nsresult
1631
txFnStartCopy(int32_t aNamespaceID,
1632
              nsAtom* aLocalName,
1633
              nsAtom* aPrefix,
1634
              txStylesheetAttr* aAttributes,
1635
              int32_t aAttrCount,
1636
              txStylesheetCompilerState& aState)
1637
0
{
1638
0
    nsAutoPtr<txCopy> copy(new txCopy);
1639
0
    nsresult rv = aState.pushPtr(copy, aState.eCopy);
1640
0
    NS_ENSURE_SUCCESS(rv, rv);
1641
0
1642
0
    nsAutoPtr<txInstruction> instr(copy.forget());
1643
0
    rv = aState.addInstruction(std::move(instr));
1644
0
    NS_ENSURE_SUCCESS(rv, rv);
1645
0
1646
0
    rv = parseUseAttrSets(aAttributes, aAttrCount, false, aState);
1647
0
    NS_ENSURE_SUCCESS(rv, rv);
1648
0
1649
0
    return NS_OK;
1650
0
}
1651
1652
static nsresult
1653
txFnEndCopy(txStylesheetCompilerState& aState)
1654
0
{
1655
0
    nsAutoPtr<txInstruction> instr(new txEndElement);
1656
0
    nsresult rv = aState.addInstruction(std::move(instr));
1657
0
    NS_ENSURE_SUCCESS(rv, rv);
1658
0
1659
0
    txCopy* copy = static_cast<txCopy*>(aState.popPtr(aState.eCopy));
1660
0
    rv = aState.addGotoTarget(&copy->mBailTarget);
1661
0
    NS_ENSURE_SUCCESS(rv, rv);
1662
0
1663
0
    return NS_OK;
1664
0
}
1665
1666
/*
1667
  xsl:copy-of
1668
1669
  txCopyOf
1670
*/
1671
static nsresult
1672
txFnStartCopyOf(int32_t aNamespaceID,
1673
                nsAtom* aLocalName,
1674
                nsAtom* aPrefix,
1675
                txStylesheetAttr* aAttributes,
1676
                int32_t aAttrCount,
1677
                txStylesheetCompilerState& aState)
1678
0
{
1679
0
    nsresult rv = NS_OK;
1680
0
1681
0
    nsAutoPtr<Expr> select;
1682
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, true,
1683
0
                    aState, select);
1684
0
    NS_ENSURE_SUCCESS(rv, rv);
1685
0
1686
0
    nsAutoPtr<txInstruction> instr(new txCopyOf(std::move(select)));
1687
0
    rv = aState.addInstruction(std::move(instr));
1688
0
    NS_ENSURE_SUCCESS(rv, rv);
1689
0
1690
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
1691
0
}
1692
1693
static nsresult
1694
txFnEndCopyOf(txStylesheetCompilerState& aState)
1695
0
{
1696
0
    aState.popHandlerTable();
1697
0
    return NS_OK;
1698
0
}
1699
1700
/*
1701
  xsl:element
1702
1703
  txStartElement
1704
  txInsertAttrSet        one for each qname in use-attribute-sets
1705
  [children]
1706
  txEndElement
1707
*/
1708
static nsresult
1709
txFnStartElement(int32_t aNamespaceID,
1710
                 nsAtom* aLocalName,
1711
                 nsAtom* aPrefix,
1712
                 txStylesheetAttr* aAttributes,
1713
                 int32_t aAttrCount,
1714
                 txStylesheetCompilerState& aState)
1715
0
{
1716
0
    nsresult rv = NS_OK;
1717
0
1718
0
    nsAutoPtr<Expr> name;
1719
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
1720
0
                    aState, name);
1721
0
    NS_ENSURE_SUCCESS(rv, rv);
1722
0
1723
0
    nsAutoPtr<Expr> nspace;
1724
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::_namespace, false,
1725
0
                    aState, nspace);
1726
0
    NS_ENSURE_SUCCESS(rv, rv);
1727
0
1728
0
    nsAutoPtr<txInstruction> instr(
1729
0
        new txStartElement(std::move(name), std::move(nspace),
1730
0
                           aState.mElementContext->mMappings));
1731
0
    rv = aState.addInstruction(std::move(instr));
1732
0
    NS_ENSURE_SUCCESS(rv, rv);
1733
0
1734
0
    rv = parseUseAttrSets(aAttributes, aAttrCount, false, aState);
1735
0
    NS_ENSURE_SUCCESS(rv, rv);
1736
0
1737
0
    return NS_OK;
1738
0
}
1739
1740
static nsresult
1741
txFnEndElement(txStylesheetCompilerState& aState)
1742
0
{
1743
0
    nsAutoPtr<txInstruction> instr(new txEndElement);
1744
0
    nsresult rv = aState.addInstruction(std::move(instr));
1745
0
    NS_ENSURE_SUCCESS(rv, rv);
1746
0
1747
0
    return NS_OK;
1748
0
}
1749
1750
/*
1751
    xsl:fallback
1752
1753
    [children]
1754
*/
1755
static nsresult
1756
txFnStartFallback(int32_t aNamespaceID,
1757
                  nsAtom* aLocalName,
1758
                  nsAtom* aPrefix,
1759
                  txStylesheetAttr* aAttributes,
1760
                  int32_t aAttrCount,
1761
                  txStylesheetCompilerState& aState)
1762
0
{
1763
0
    aState.mSearchingForFallback = false;
1764
0
1765
0
    return aState.pushHandlerTable(gTxTemplateHandler);
1766
0
}
1767
1768
static nsresult
1769
txFnEndFallback(txStylesheetCompilerState& aState)
1770
0
{
1771
0
    aState.popHandlerTable();
1772
0
1773
0
    NS_ASSERTION(!aState.mSearchingForFallback,
1774
0
                 "bad nesting of unknown-instruction and fallback handlers");
1775
0
    return NS_OK;
1776
0
}
1777
1778
/*
1779
  xsl:for-each
1780
1781
  txPushNewContext            -+    (holds <xsl:sort>s)
1782
  txPushNullTemplateRule  <-+  |
1783
  [children]                |  |
1784
  txLoopNodeSet            -+  |
1785
                             <-+
1786
*/
1787
static nsresult
1788
txFnStartForEach(int32_t aNamespaceID,
1789
                 nsAtom* aLocalName,
1790
                 nsAtom* aPrefix,
1791
                 txStylesheetAttr* aAttributes,
1792
                 int32_t aAttrCount,
1793
                 txStylesheetCompilerState& aState)
1794
0
{
1795
0
    nsresult rv = NS_OK;
1796
0
1797
0
    nsAutoPtr<Expr> select;
1798
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, true,
1799
0
                     aState, select);
1800
0
    NS_ENSURE_SUCCESS(rv, rv);
1801
0
1802
0
    nsAutoPtr<txPushNewContext> pushcontext(new txPushNewContext(std::move(select)));
1803
0
    rv = aState.pushPtr(pushcontext, aState.ePushNewContext);
1804
0
    NS_ENSURE_SUCCESS(rv, rv);
1805
0
1806
0
    rv = aState.pushSorter(pushcontext);
1807
0
    NS_ENSURE_SUCCESS(rv, rv);
1808
0
1809
0
    nsAutoPtr<txInstruction> instr(pushcontext.forget());
1810
0
    rv = aState.addInstruction(std::move(instr));
1811
0
    NS_ENSURE_SUCCESS(rv, rv);
1812
0
1813
0
    instr = new txPushNullTemplateRule;
1814
0
    rv = aState.pushPtr(instr, aState.ePushNullTemplateRule);
1815
0
    NS_ENSURE_SUCCESS(rv, rv);
1816
0
1817
0
    rv = aState.addInstruction(std::move(instr));
1818
0
    NS_ENSURE_SUCCESS(rv, rv);
1819
0
1820
0
    return aState.pushHandlerTable(gTxForEachHandler);
1821
0
}
1822
1823
static nsresult
1824
txFnEndForEach(txStylesheetCompilerState& aState)
1825
0
{
1826
0
    aState.popHandlerTable();
1827
0
1828
0
    // This is a txPushNullTemplateRule
1829
0
    txInstruction* pnullrule =
1830
0
        static_cast<txInstruction*>(aState.popPtr(aState.ePushNullTemplateRule));
1831
0
1832
0
    nsAutoPtr<txInstruction> instr(new txLoopNodeSet(pnullrule));
1833
0
    nsresult rv = aState.addInstruction(std::move(instr));
1834
0
    NS_ENSURE_SUCCESS(rv, rv);
1835
0
1836
0
    aState.popSorter();
1837
0
    txPushNewContext* pushcontext =
1838
0
        static_cast<txPushNewContext*>(aState.popPtr(aState.ePushNewContext));
1839
0
    aState.addGotoTarget(&pushcontext->mBailTarget);
1840
0
1841
0
    return NS_OK;
1842
0
}
1843
1844
static nsresult
1845
txFnStartElementContinueTemplate(int32_t aNamespaceID,
1846
                                nsAtom* aLocalName,
1847
                                nsAtom* aPrefix,
1848
                                txStylesheetAttr* aAttributes,
1849
                                int32_t aAttrCount,
1850
                                txStylesheetCompilerState& aState)
1851
0
{
1852
0
    aState.mHandlerTable = gTxTemplateHandler;
1853
0
1854
0
    return NS_XSLT_GET_NEW_HANDLER;
1855
0
}
1856
1857
static nsresult
1858
txFnTextContinueTemplate(const nsAString& aStr,
1859
                        txStylesheetCompilerState& aState)
1860
0
{
1861
0
    TX_RETURN_IF_WHITESPACE(aStr, aState);
1862
0
1863
0
    aState.mHandlerTable = gTxTemplateHandler;
1864
0
1865
0
    return NS_XSLT_GET_NEW_HANDLER;
1866
0
}
1867
1868
/*
1869
  xsl:if
1870
1871
  txConditionalGoto  -+
1872
  [children]          |
1873
                    <-+
1874
*/
1875
static nsresult
1876
txFnStartIf(int32_t aNamespaceID,
1877
            nsAtom* aLocalName,
1878
            nsAtom* aPrefix,
1879
            txStylesheetAttr* aAttributes,
1880
            int32_t aAttrCount,
1881
            txStylesheetCompilerState& aState)
1882
0
{
1883
0
    nsresult rv = NS_OK;
1884
0
1885
0
    nsAutoPtr<Expr> test;
1886
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::test, true,
1887
0
                     aState, test);
1888
0
    NS_ENSURE_SUCCESS(rv, rv);
1889
0
1890
0
    nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(std::move(test),
1891
0
                                                                nullptr));
1892
0
    rv = aState.pushPtr(condGoto, aState.eConditionalGoto);
1893
0
    NS_ENSURE_SUCCESS(rv, rv);
1894
0
1895
0
    nsAutoPtr<txInstruction> instr(condGoto.forget());
1896
0
    rv = aState.addInstruction(std::move(instr));
1897
0
    NS_ENSURE_SUCCESS(rv, rv);
1898
0
1899
0
    return NS_OK;
1900
0
}
1901
1902
static nsresult
1903
txFnEndIf(txStylesheetCompilerState& aState)
1904
0
{
1905
0
    txConditionalGoto* condGoto =
1906
0
        static_cast<txConditionalGoto*>(aState.popPtr(aState.eConditionalGoto));
1907
0
    return aState.addGotoTarget(&condGoto->mTarget);
1908
0
}
1909
1910
/*
1911
  xsl:message
1912
1913
  txPushStringHandler
1914
  [children]
1915
  txMessage
1916
*/
1917
static nsresult
1918
txFnStartMessage(int32_t aNamespaceID,
1919
                 nsAtom* aLocalName,
1920
                 nsAtom* aPrefix,
1921
                 txStylesheetAttr* aAttributes,
1922
                 int32_t aAttrCount,
1923
                 txStylesheetCompilerState& aState)
1924
0
{
1925
0
    nsAutoPtr<txInstruction> instr(new txPushStringHandler(false));
1926
0
    nsresult rv = aState.addInstruction(std::move(instr));
1927
0
    NS_ENSURE_SUCCESS(rv, rv);
1928
0
1929
0
    txThreeState term;
1930
0
    rv = getYesNoAttr(aAttributes, aAttrCount, nsGkAtoms::terminate,
1931
0
                      false, aState, term);
1932
0
    NS_ENSURE_SUCCESS(rv, rv);
1933
0
1934
0
    instr = new txMessage(term == eTrue);
1935
0
    rv = aState.pushObject(instr);
1936
0
    NS_ENSURE_SUCCESS(rv, rv);
1937
0
1938
0
    instr.forget();
1939
0
1940
0
    return NS_OK;
1941
0
}
1942
1943
static nsresult
1944
txFnEndMessage(txStylesheetCompilerState& aState)
1945
0
{
1946
0
    nsAutoPtr<txInstruction> instr(static_cast<txInstruction*>(aState.popObject()));
1947
0
    nsresult rv = aState.addInstruction(std::move(instr));
1948
0
    NS_ENSURE_SUCCESS(rv, rv);
1949
0
1950
0
    return NS_OK;
1951
0
}
1952
1953
/*
1954
  xsl:number
1955
1956
  txNumber
1957
*/
1958
static nsresult
1959
txFnStartNumber(int32_t aNamespaceID,
1960
                nsAtom* aLocalName,
1961
                nsAtom* aPrefix,
1962
                txStylesheetAttr* aAttributes,
1963
                int32_t aAttrCount,
1964
                txStylesheetCompilerState& aState)
1965
0
{
1966
0
    nsresult rv = NS_OK;
1967
0
1968
0
    RefPtr<nsAtom> levelAtom;
1969
0
    rv = getAtomAttr(aAttributes, aAttrCount, nsGkAtoms::level, false,
1970
0
                     aState, getter_AddRefs(levelAtom));
1971
0
    NS_ENSURE_SUCCESS(rv, rv);
1972
0
1973
0
    txXSLTNumber::LevelType level = txXSLTNumber::eLevelSingle;
1974
0
    if (levelAtom == nsGkAtoms::multiple) {
1975
0
        level = txXSLTNumber::eLevelMultiple;
1976
0
    }
1977
0
    else if (levelAtom == nsGkAtoms::any) {
1978
0
        level = txXSLTNumber::eLevelAny;
1979
0
    }
1980
0
    else if (levelAtom && levelAtom != nsGkAtoms::single && !aState.fcp()) {
1981
0
        return NS_ERROR_XSLT_PARSE_FAILURE;
1982
0
    }
1983
0
1984
0
    nsAutoPtr<txPattern> count;
1985
0
    rv = getPatternAttr(aAttributes, aAttrCount, nsGkAtoms::count, false,
1986
0
                        aState, count);
1987
0
    NS_ENSURE_SUCCESS(rv, rv);
1988
0
1989
0
    nsAutoPtr<txPattern> from;
1990
0
    rv = getPatternAttr(aAttributes, aAttrCount, nsGkAtoms::from, false,
1991
0
                        aState, from);
1992
0
    NS_ENSURE_SUCCESS(rv, rv);
1993
0
1994
0
    nsAutoPtr<Expr> value;
1995
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::value, false,
1996
0
                     aState, value);
1997
0
    NS_ENSURE_SUCCESS(rv, rv);
1998
0
1999
0
    nsAutoPtr<Expr> format;
2000
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::format, false,
2001
0
                    aState, format);
2002
0
    NS_ENSURE_SUCCESS(rv, rv);
2003
0
2004
0
    nsAutoPtr<Expr> lang;
2005
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::lang, false,
2006
0
                      aState, lang);
2007
0
    NS_ENSURE_SUCCESS(rv, rv);
2008
0
2009
0
    nsAutoPtr<Expr> letterValue;
2010
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::letterValue, false,
2011
0
                    aState, letterValue);
2012
0
    NS_ENSURE_SUCCESS(rv, rv);
2013
0
2014
0
    nsAutoPtr<Expr> groupingSeparator;
2015
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::groupingSeparator,
2016
0
                    false, aState, groupingSeparator);
2017
0
    NS_ENSURE_SUCCESS(rv, rv);
2018
0
2019
0
    nsAutoPtr<Expr> groupingSize;
2020
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::groupingSize,
2021
0
                    false, aState, groupingSize);
2022
0
    NS_ENSURE_SUCCESS(rv, rv);
2023
0
2024
0
    nsAutoPtr<txInstruction> instr(new txNumber(level, std::move(count), std::move(from),
2025
0
                                                std::move(value), std::move(format),
2026
0
                                                std::move(groupingSeparator),
2027
0
                                                std::move(groupingSize)));
2028
0
    rv = aState.addInstruction(std::move(instr));
2029
0
    NS_ENSURE_SUCCESS(rv, rv);
2030
0
2031
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
2032
0
}
2033
2034
static nsresult
2035
txFnEndNumber(txStylesheetCompilerState& aState)
2036
0
{
2037
0
    aState.popHandlerTable();
2038
0
2039
0
    return NS_OK;
2040
0
}
2041
2042
/*
2043
    xsl:otherwise
2044
2045
    (see xsl:choose)
2046
*/
2047
static nsresult
2048
txFnStartOtherwise(int32_t aNamespaceID,
2049
                   nsAtom* aLocalName,
2050
                   nsAtom* aPrefix,
2051
                   txStylesheetAttr* aAttributes,
2052
                   int32_t aAttrCount,
2053
                   txStylesheetCompilerState& aState)
2054
0
{
2055
0
    return aState.pushHandlerTable(gTxTemplateHandler);
2056
0
}
2057
2058
static nsresult
2059
txFnEndOtherwise(txStylesheetCompilerState& aState)
2060
0
{
2061
0
    aState.popHandlerTable();
2062
0
    aState.mHandlerTable = gTxIgnoreHandler; // XXX should be gTxErrorHandler
2063
0
2064
0
    return NS_OK;
2065
0
}
2066
2067
/*
2068
    xsl:param
2069
2070
    txCheckParam    --+
2071
    txPushRTFHandler  |  --- (for RTF-parameters)
2072
    [children]        |  /
2073
    txSetVariable     |
2074
                    <-+
2075
*/
2076
static nsresult
2077
txFnStartParam(int32_t aNamespaceID,
2078
               nsAtom* aLocalName,
2079
               nsAtom* aPrefix,
2080
               txStylesheetAttr* aAttributes,
2081
               int32_t aAttrCount,
2082
               txStylesheetCompilerState& aState)
2083
0
{
2084
0
    nsresult rv = NS_OK;
2085
0
2086
0
    txExpandedName name;
2087
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
2088
0
                      aState, name);
2089
0
    NS_ENSURE_SUCCESS(rv, rv);
2090
0
2091
0
    nsAutoPtr<txCheckParam> checkParam(new txCheckParam(name));
2092
0
    NS_ENSURE_SUCCESS(rv, rv);
2093
0
2094
0
    rv = aState.pushPtr(checkParam, aState.eCheckParam);
2095
0
    NS_ENSURE_SUCCESS(rv, rv);
2096
0
2097
0
    nsAutoPtr<txInstruction> instr(checkParam.forget());
2098
0
    rv = aState.addInstruction(std::move(instr));
2099
0
    NS_ENSURE_SUCCESS(rv, rv);
2100
0
2101
0
    nsAutoPtr<Expr> select;
2102
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, false,
2103
0
                     aState, select);
2104
0
    NS_ENSURE_SUCCESS(rv, rv);
2105
0
2106
0
    nsAutoPtr<txSetVariable> var(new txSetVariable(name, std::move(select)));
2107
0
    if (var->mValue) {
2108
0
        // XXX should be gTxErrorHandler?
2109
0
        rv = aState.pushHandlerTable(gTxIgnoreHandler);
2110
0
        NS_ENSURE_SUCCESS(rv, rv);
2111
0
    }
2112
0
    else {
2113
0
        rv = aState.pushHandlerTable(gTxVariableHandler);
2114
0
        NS_ENSURE_SUCCESS(rv, rv);
2115
0
    }
2116
0
2117
0
    rv = aState.pushObject(var);
2118
0
    NS_ENSURE_SUCCESS(rv, rv);
2119
0
2120
0
    var.forget();
2121
0
2122
0
    return NS_OK;
2123
0
}
2124
2125
static nsresult
2126
txFnEndParam(txStylesheetCompilerState& aState)
2127
0
{
2128
0
    nsAutoPtr<txSetVariable> var(static_cast<txSetVariable*>
2129
0
                                            (aState.popObject()));
2130
0
    txHandlerTable* prev = aState.mHandlerTable;
2131
0
    aState.popHandlerTable();
2132
0
2133
0
    if (prev == gTxVariableHandler) {
2134
0
        // No children were found.
2135
0
        NS_ASSERTION(!var->mValue,
2136
0
                     "There shouldn't be a select-expression here");
2137
0
        var->mValue = new txLiteralExpr(EmptyString());
2138
0
    }
2139
0
2140
0
    nsresult rv = aState.addVariable(var->mName);
2141
0
    NS_ENSURE_SUCCESS(rv, rv);
2142
0
2143
0
    nsAutoPtr<txInstruction> instr(var.forget());
2144
0
    rv = aState.addInstruction(std::move(instr));
2145
0
    NS_ENSURE_SUCCESS(rv, rv);
2146
0
2147
0
    txCheckParam* checkParam =
2148
0
        static_cast<txCheckParam*>(aState.popPtr(aState.eCheckParam));
2149
0
    aState.addGotoTarget(&checkParam->mBailTarget);
2150
0
2151
0
    return NS_OK;
2152
0
}
2153
2154
/*
2155
  xsl:processing-instruction
2156
2157
  txPushStringHandler
2158
  [children]
2159
  txProcessingInstruction
2160
*/
2161
static nsresult
2162
txFnStartPI(int32_t aNamespaceID,
2163
            nsAtom* aLocalName,
2164
            nsAtom* aPrefix,
2165
            txStylesheetAttr* aAttributes,
2166
            int32_t aAttrCount,
2167
            txStylesheetCompilerState& aState)
2168
0
{
2169
0
    nsAutoPtr<txInstruction> instr(new txPushStringHandler(true));
2170
0
    nsresult rv = aState.addInstruction(std::move(instr));
2171
0
    NS_ENSURE_SUCCESS(rv, rv);
2172
0
2173
0
    nsAutoPtr<Expr> name;
2174
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
2175
0
                    aState, name);
2176
0
    NS_ENSURE_SUCCESS(rv, rv);
2177
0
2178
0
    instr = new txProcessingInstruction(std::move(name));
2179
0
    rv = aState.pushObject(instr);
2180
0
    NS_ENSURE_SUCCESS(rv, rv);
2181
0
2182
0
    instr.forget();
2183
0
2184
0
    return NS_OK;
2185
0
}
2186
2187
static nsresult
2188
txFnEndPI(txStylesheetCompilerState& aState)
2189
0
{
2190
0
    nsAutoPtr<txInstruction> instr(static_cast<txInstruction*>
2191
0
                                              (aState.popObject()));
2192
0
    nsresult rv = aState.addInstruction(std::move(instr));
2193
0
    NS_ENSURE_SUCCESS(rv, rv);
2194
0
2195
0
    return NS_OK;
2196
0
}
2197
2198
/*
2199
    xsl:sort
2200
2201
    (no instructions)
2202
*/
2203
static nsresult
2204
txFnStartSort(int32_t aNamespaceID,
2205
              nsAtom* aLocalName,
2206
              nsAtom* aPrefix,
2207
              txStylesheetAttr* aAttributes,
2208
              int32_t aAttrCount,
2209
              txStylesheetCompilerState& aState)
2210
0
{
2211
0
    nsresult rv = NS_OK;
2212
0
2213
0
    nsAutoPtr<Expr> select;
2214
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, false,
2215
0
                     aState, select);
2216
0
    NS_ENSURE_SUCCESS(rv, rv);
2217
0
2218
0
    if (!select) {
2219
0
        nsAutoPtr<txNodeTest> nt(
2220
0
              new txNodeTypeTest(txNodeTypeTest::NODE_TYPE));
2221
0
2222
0
        select = new LocationStep(nt, LocationStep::SELF_AXIS);
2223
0
2224
0
        nt.forget();
2225
0
    }
2226
0
2227
0
    nsAutoPtr<Expr> lang;
2228
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::lang, false,
2229
0
                    aState, lang);
2230
0
    NS_ENSURE_SUCCESS(rv, rv);
2231
0
2232
0
    nsAutoPtr<Expr> dataType;
2233
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::dataType, false,
2234
0
                    aState, dataType);
2235
0
    NS_ENSURE_SUCCESS(rv, rv);
2236
0
2237
0
    nsAutoPtr<Expr> order;
2238
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::order, false,
2239
0
                    aState, order);
2240
0
    NS_ENSURE_SUCCESS(rv, rv);
2241
0
2242
0
    nsAutoPtr<Expr> caseOrder;
2243
0
    rv = getAVTAttr(aAttributes, aAttrCount, nsGkAtoms::caseOrder, false,
2244
0
                    aState, caseOrder);
2245
0
    NS_ENSURE_SUCCESS(rv, rv);
2246
0
2247
0
    rv = aState.mSorter->addSort(std::move(select), std::move(lang), std::move(dataType),
2248
0
                                 std::move(order), std::move(caseOrder));
2249
0
    NS_ENSURE_SUCCESS(rv, rv);
2250
0
2251
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
2252
0
}
2253
2254
static nsresult
2255
txFnEndSort(txStylesheetCompilerState& aState)
2256
0
{
2257
0
    aState.popHandlerTable();
2258
0
2259
0
    return NS_OK;
2260
0
}
2261
2262
/*
2263
  xsl:text
2264
2265
  [children]     (only txText)
2266
*/
2267
static nsresult
2268
txFnStartText(int32_t aNamespaceID,
2269
              nsAtom* aLocalName,
2270
              nsAtom* aPrefix,
2271
              txStylesheetAttr* aAttributes,
2272
              int32_t aAttrCount,
2273
              txStylesheetCompilerState& aState)
2274
0
{
2275
0
    NS_ASSERTION(!aState.mDOE, "nested d-o-e elements should not happen");
2276
0
2277
0
    nsresult rv = NS_OK;
2278
0
    txThreeState doe;
2279
0
    rv = getYesNoAttr(aAttributes, aAttrCount,
2280
0
                      nsGkAtoms::disableOutputEscaping, false, aState,
2281
0
                      doe);
2282
0
    NS_ENSURE_SUCCESS(rv, rv);
2283
0
2284
0
    aState.mDOE = doe == eTrue;
2285
0
2286
0
    return aState.pushHandlerTable(gTxTextHandler);
2287
0
}
2288
2289
static nsresult
2290
txFnEndText(txStylesheetCompilerState& aState)
2291
0
{
2292
0
    aState.mDOE = false;
2293
0
    aState.popHandlerTable();
2294
0
    return NS_OK;
2295
0
}
2296
2297
static nsresult
2298
txFnTextText(const nsAString& aStr, txStylesheetCompilerState& aState)
2299
0
{
2300
0
    nsAutoPtr<txInstruction> instr(new txText(aStr, aState.mDOE));
2301
0
    nsresult rv = aState.addInstruction(std::move(instr));
2302
0
    NS_ENSURE_SUCCESS(rv, rv);
2303
0
2304
0
    return NS_OK;
2305
0
}
2306
2307
/*
2308
  xsl:value-of
2309
2310
  txValueOf
2311
*/
2312
static nsresult
2313
txFnStartValueOf(int32_t aNamespaceID,
2314
                 nsAtom* aLocalName,
2315
                 nsAtom* aPrefix,
2316
                 txStylesheetAttr* aAttributes,
2317
                 int32_t aAttrCount,
2318
                 txStylesheetCompilerState& aState)
2319
0
{
2320
0
    nsresult rv = NS_OK;
2321
0
2322
0
    txThreeState doe;
2323
0
    rv = getYesNoAttr(aAttributes, aAttrCount,
2324
0
                     nsGkAtoms::disableOutputEscaping, false, aState,
2325
0
                     doe);
2326
0
    NS_ENSURE_SUCCESS(rv, rv);
2327
0
2328
0
    nsAutoPtr<Expr> select;
2329
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, true,
2330
0
                     aState, select);
2331
0
    NS_ENSURE_SUCCESS(rv, rv);
2332
0
2333
0
    nsAutoPtr<txInstruction> instr(new txValueOf(std::move(select), doe == eTrue));
2334
0
    rv = aState.addInstruction(std::move(instr));
2335
0
    NS_ENSURE_SUCCESS(rv, rv);
2336
0
2337
0
    return aState.pushHandlerTable(gTxIgnoreHandler);
2338
0
}
2339
2340
static nsresult
2341
txFnEndValueOf(txStylesheetCompilerState& aState)
2342
0
{
2343
0
    aState.popHandlerTable();
2344
0
    return NS_OK;
2345
0
}
2346
2347
/*
2348
    xsl:variable
2349
2350
    txPushRTFHandler     --- (for RTF-parameters)
2351
    [children]           /
2352
    txSetVariable
2353
*/
2354
static nsresult
2355
txFnStartVariable(int32_t aNamespaceID,
2356
                  nsAtom* aLocalName,
2357
                  nsAtom* aPrefix,
2358
                  txStylesheetAttr* aAttributes,
2359
                  int32_t aAttrCount,
2360
                  txStylesheetCompilerState& aState)
2361
0
{
2362
0
    nsresult rv = NS_OK;
2363
0
2364
0
    txExpandedName name;
2365
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
2366
0
                      aState, name);
2367
0
    NS_ENSURE_SUCCESS(rv, rv);
2368
0
2369
0
    nsAutoPtr<Expr> select;
2370
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, false,
2371
0
                     aState, select);
2372
0
    NS_ENSURE_SUCCESS(rv, rv);
2373
0
2374
0
    nsAutoPtr<txSetVariable> var(new txSetVariable(name, std::move(select)));
2375
0
    if (var->mValue) {
2376
0
        // XXX should be gTxErrorHandler?
2377
0
        rv = aState.pushHandlerTable(gTxIgnoreHandler);
2378
0
        NS_ENSURE_SUCCESS(rv, rv);
2379
0
    }
2380
0
    else {
2381
0
        rv = aState.pushHandlerTable(gTxVariableHandler);
2382
0
        NS_ENSURE_SUCCESS(rv, rv);
2383
0
    }
2384
0
2385
0
    rv = aState.pushObject(var);
2386
0
    NS_ENSURE_SUCCESS(rv, rv);
2387
0
2388
0
    var.forget();
2389
0
2390
0
    return NS_OK;
2391
0
}
2392
2393
static nsresult
2394
txFnEndVariable(txStylesheetCompilerState& aState)
2395
0
{
2396
0
    nsAutoPtr<txSetVariable> var(static_cast<txSetVariable*>
2397
0
                                            (aState.popObject()));
2398
0
2399
0
    txHandlerTable* prev = aState.mHandlerTable;
2400
0
    aState.popHandlerTable();
2401
0
2402
0
    if (prev == gTxVariableHandler) {
2403
0
        // No children were found.
2404
0
        NS_ASSERTION(!var->mValue,
2405
0
                     "There shouldn't be a select-expression here");
2406
0
        var->mValue = new txLiteralExpr(EmptyString());
2407
0
    }
2408
0
2409
0
    nsresult rv = aState.addVariable(var->mName);
2410
0
    NS_ENSURE_SUCCESS(rv, rv);
2411
0
2412
0
    nsAutoPtr<txInstruction> instr(var.forget());
2413
0
    rv = aState.addInstruction(std::move(instr));
2414
0
    NS_ENSURE_SUCCESS(rv, rv);
2415
0
2416
0
    return NS_OK;
2417
0
}
2418
2419
static nsresult
2420
txFnStartElementStartRTF(int32_t aNamespaceID,
2421
                         nsAtom* aLocalName,
2422
                         nsAtom* aPrefix,
2423
                         txStylesheetAttr* aAttributes,
2424
                         int32_t aAttrCount,
2425
                         txStylesheetCompilerState& aState)
2426
0
{
2427
0
    nsAutoPtr<txInstruction> instr(new txPushRTFHandler);
2428
0
    nsresult rv = aState.addInstruction(std::move(instr));
2429
0
    NS_ENSURE_SUCCESS(rv, rv);
2430
0
2431
0
    aState.mHandlerTable = gTxTemplateHandler;
2432
0
2433
0
    return NS_XSLT_GET_NEW_HANDLER;
2434
0
}
2435
2436
static nsresult
2437
txFnTextStartRTF(const nsAString& aStr, txStylesheetCompilerState& aState)
2438
0
{
2439
0
    TX_RETURN_IF_WHITESPACE(aStr, aState);
2440
0
2441
0
    nsAutoPtr<txInstruction> instr(new txPushRTFHandler);
2442
0
    nsresult rv = aState.addInstruction(std::move(instr));
2443
0
    NS_ENSURE_SUCCESS(rv, rv);
2444
0
2445
0
    aState.mHandlerTable = gTxTemplateHandler;
2446
0
2447
0
    return NS_XSLT_GET_NEW_HANDLER;
2448
0
}
2449
2450
/*
2451
    xsl:when
2452
2453
    (see xsl:choose)
2454
*/
2455
static nsresult
2456
txFnStartWhen(int32_t aNamespaceID,
2457
              nsAtom* aLocalName,
2458
              nsAtom* aPrefix,
2459
              txStylesheetAttr* aAttributes,
2460
              int32_t aAttrCount,
2461
              txStylesheetCompilerState& aState)
2462
0
{
2463
0
    nsresult rv = NS_OK;
2464
0
2465
0
    nsAutoPtr<Expr> test;
2466
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::test, true,
2467
0
                     aState, test);
2468
0
    NS_ENSURE_SUCCESS(rv, rv);
2469
0
2470
0
    nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(std::move(test),
2471
0
                                                                nullptr));
2472
0
    rv = aState.pushPtr(condGoto, aState.eConditionalGoto);
2473
0
    NS_ENSURE_SUCCESS(rv, rv);
2474
0
2475
0
    nsAutoPtr<txInstruction> instr(condGoto.forget());
2476
0
    rv = aState.addInstruction(std::move(instr));
2477
0
    NS_ENSURE_SUCCESS(rv, rv);
2478
0
2479
0
    return aState.pushHandlerTable(gTxTemplateHandler);
2480
0
}
2481
2482
static nsresult
2483
txFnEndWhen(txStylesheetCompilerState& aState)
2484
0
{
2485
0
    aState.popHandlerTable();
2486
0
    nsAutoPtr<txGoTo> gotoinstr(new txGoTo(nullptr));
2487
0
    nsresult rv = aState.mChooseGotoList->add(gotoinstr);
2488
0
    NS_ENSURE_SUCCESS(rv, rv);
2489
0
2490
0
    nsAutoPtr<txInstruction> instr(gotoinstr.forget());
2491
0
    rv = aState.addInstruction(std::move(instr));
2492
0
    NS_ENSURE_SUCCESS(rv, rv);
2493
0
2494
0
    txConditionalGoto* condGoto =
2495
0
        static_cast<txConditionalGoto*>(aState.popPtr(aState.eConditionalGoto));
2496
0
    rv = aState.addGotoTarget(&condGoto->mTarget);
2497
0
    NS_ENSURE_SUCCESS(rv, rv);
2498
0
2499
0
    return NS_OK;
2500
0
}
2501
2502
/*
2503
    xsl:with-param
2504
2505
    txPushRTFHandler   -- for RTF-parameters
2506
    [children]         /
2507
    txSetParam
2508
*/
2509
static nsresult
2510
txFnStartWithParam(int32_t aNamespaceID,
2511
                   nsAtom* aLocalName,
2512
                   nsAtom* aPrefix,
2513
                   txStylesheetAttr* aAttributes,
2514
                   int32_t aAttrCount,
2515
                   txStylesheetCompilerState& aState)
2516
0
{
2517
0
    nsresult rv = NS_OK;
2518
0
2519
0
    txExpandedName name;
2520
0
    rv = getQNameAttr(aAttributes, aAttrCount, nsGkAtoms::name, true,
2521
0
                      aState, name);
2522
0
    NS_ENSURE_SUCCESS(rv, rv);
2523
0
2524
0
    nsAutoPtr<Expr> select;
2525
0
    rv = getExprAttr(aAttributes, aAttrCount, nsGkAtoms::select, false,
2526
0
                     aState, select);
2527
0
    NS_ENSURE_SUCCESS(rv, rv);
2528
0
2529
0
    nsAutoPtr<txSetParam> var(new txSetParam(name, std::move(select)));
2530
0
    if (var->mValue) {
2531
0
        // XXX should be gTxErrorHandler?
2532
0
        rv = aState.pushHandlerTable(gTxIgnoreHandler);
2533
0
        NS_ENSURE_SUCCESS(rv, rv);
2534
0
    }
2535
0
    else {
2536
0
        rv = aState.pushHandlerTable(gTxVariableHandler);
2537
0
        NS_ENSURE_SUCCESS(rv, rv);
2538
0
    }
2539
0
2540
0
    rv = aState.pushObject(var);
2541
0
    NS_ENSURE_SUCCESS(rv, rv);
2542
0
2543
0
    var.forget();
2544
0
2545
0
    return NS_OK;
2546
0
}
2547
2548
static nsresult
2549
txFnEndWithParam(txStylesheetCompilerState& aState)
2550
0
{
2551
0
    nsAutoPtr<txSetParam> var(static_cast<txSetParam*>(aState.popObject()));
2552
0
    txHandlerTable* prev = aState.mHandlerTable;
2553
0
    aState.popHandlerTable();
2554
0
2555
0
    if (prev == gTxVariableHandler) {
2556
0
        // No children were found.
2557
0
        NS_ASSERTION(!var->mValue,
2558
0
                     "There shouldn't be a select-expression here");
2559
0
        var->mValue = new txLiteralExpr(EmptyString());
2560
0
    }
2561
0
2562
0
    nsAutoPtr<txInstruction> instr(var.forget());
2563
0
    nsresult rv = aState.addInstruction(std::move(instr));
2564
0
    NS_ENSURE_SUCCESS(rv, rv);
2565
0
2566
0
    return NS_OK;
2567
0
}
2568
2569
/*
2570
    Unknown instruction
2571
2572
    [fallbacks]           if one or more xsl:fallbacks are found
2573
    or
2574
    txErrorInstruction    otherwise
2575
*/
2576
static nsresult
2577
txFnStartUnknownInstruction(int32_t aNamespaceID,
2578
                            nsAtom* aLocalName,
2579
                            nsAtom* aPrefix,
2580
                            txStylesheetAttr* aAttributes,
2581
                            int32_t aAttrCount,
2582
                            txStylesheetCompilerState& aState)
2583
0
{
2584
0
    NS_ASSERTION(!aState.mSearchingForFallback,
2585
0
                 "bad nesting of unknown-instruction and fallback handlers");
2586
0
2587
0
    if (aNamespaceID == kNameSpaceID_XSLT && !aState.fcp()) {
2588
0
        return NS_ERROR_XSLT_PARSE_FAILURE;
2589
0
    }
2590
0
2591
0
    aState.mSearchingForFallback = true;
2592
0
2593
0
    return aState.pushHandlerTable(gTxFallbackHandler);
2594
0
}
2595
2596
static nsresult
2597
txFnEndUnknownInstruction(txStylesheetCompilerState& aState)
2598
0
{
2599
0
    aState.popHandlerTable();
2600
0
2601
0
    if (aState.mSearchingForFallback) {
2602
0
        nsAutoPtr<txInstruction> instr(new txErrorInstruction());
2603
0
        nsresult rv = aState.addInstruction(std::move(instr));
2604
0
        NS_ENSURE_SUCCESS(rv, rv);
2605
0
    }
2606
0
2607
0
    aState.mSearchingForFallback = false;
2608
0
2609
0
    return NS_OK;
2610
0
}
2611
2612
/**
2613
 * Table Datas
2614
 */
2615
2616
struct txHandlerTableData {
2617
    txElementHandler mOtherHandler;
2618
    txElementHandler mLREHandler;
2619
    HandleTextFn mTextHandler;
2620
};
2621
2622
const txHandlerTableData gTxIgnoreTableData = {
2623
  // Other
2624
  { 0, 0, txFnStartElementIgnore, txFnEndElementIgnore },
2625
  // LRE
2626
  { 0, 0, txFnStartElementIgnore, txFnEndElementIgnore },
2627
  // Text
2628
  txFnTextIgnore
2629
};
2630
2631
const txElementHandler gTxRootElementHandlers[] = {
2632
  { kNameSpaceID_XSLT, "stylesheet", txFnStartStylesheet, txFnEndStylesheet },
2633
  { kNameSpaceID_XSLT, "transform", txFnStartStylesheet, txFnEndStylesheet }
2634
};
2635
2636
const txHandlerTableData gTxRootTableData = {
2637
  // Other
2638
  { 0, 0, txFnStartElementError, txFnEndElementError },
2639
  // LRE
2640
  { 0, 0, txFnStartLREStylesheet, txFnEndLREStylesheet },
2641
  // Text
2642
  txFnTextError
2643
};
2644
2645
const txHandlerTableData gTxEmbedTableData = {
2646
  // Other
2647
  { 0, 0, txFnStartEmbed, txFnEndEmbed },
2648
  // LRE
2649
  { 0, 0, txFnStartEmbed, txFnEndEmbed },
2650
  // Text
2651
  txFnTextIgnore
2652
};
2653
2654
const txElementHandler gTxTopElementHandlers[] = {
2655
  { kNameSpaceID_XSLT, "attribute-set", txFnStartAttributeSet, txFnEndAttributeSet },
2656
  { kNameSpaceID_XSLT, "decimal-format", txFnStartDecimalFormat, txFnEndDecimalFormat },
2657
  { kNameSpaceID_XSLT, "include", txFnStartInclude, txFnEndInclude },
2658
  { kNameSpaceID_XSLT, "key", txFnStartKey, txFnEndKey },
2659
  { kNameSpaceID_XSLT, "namespace-alias", txFnStartNamespaceAlias,
2660
    txFnEndNamespaceAlias },
2661
  { kNameSpaceID_XSLT, "output", txFnStartOutput, txFnEndOutput },
2662
  { kNameSpaceID_XSLT, "param", txFnStartTopVariable, txFnEndTopVariable },
2663
  { kNameSpaceID_XSLT, "preserve-space", txFnStartStripSpace, txFnEndStripSpace },
2664
  { kNameSpaceID_XSLT, "strip-space", txFnStartStripSpace, txFnEndStripSpace },
2665
  { kNameSpaceID_XSLT, "template", txFnStartTemplate, txFnEndTemplate },
2666
  { kNameSpaceID_XSLT, "variable", txFnStartTopVariable, txFnEndTopVariable }
2667
};
2668
2669
const txHandlerTableData gTxTopTableData = {
2670
  // Other
2671
  { 0, 0, txFnStartOtherTop, txFnEndOtherTop },
2672
  // LRE
2673
  { 0, 0, txFnStartOtherTop, txFnEndOtherTop },
2674
  // Text
2675
  txFnTextIgnore
2676
};
2677
2678
const txElementHandler gTxTemplateElementHandlers[] = {
2679
  { kNameSpaceID_XSLT, "apply-imports", txFnStartApplyImports, txFnEndApplyImports },
2680
  { kNameSpaceID_XSLT, "apply-templates", txFnStartApplyTemplates, txFnEndApplyTemplates },
2681
  { kNameSpaceID_XSLT, "attribute", txFnStartAttribute, txFnEndAttribute },
2682
  { kNameSpaceID_XSLT, "call-template", txFnStartCallTemplate, txFnEndCallTemplate },
2683
  { kNameSpaceID_XSLT, "choose", txFnStartChoose, txFnEndChoose },
2684
  { kNameSpaceID_XSLT, "comment", txFnStartComment, txFnEndComment },
2685
  { kNameSpaceID_XSLT, "copy", txFnStartCopy, txFnEndCopy },
2686
  { kNameSpaceID_XSLT, "copy-of", txFnStartCopyOf, txFnEndCopyOf },
2687
  { kNameSpaceID_XSLT, "element", txFnStartElement, txFnEndElement },
2688
  { kNameSpaceID_XSLT, "fallback", txFnStartElementSetIgnore, txFnEndElementSetIgnore },
2689
  { kNameSpaceID_XSLT, "for-each", txFnStartForEach, txFnEndForEach },
2690
  { kNameSpaceID_XSLT, "if", txFnStartIf, txFnEndIf },
2691
  { kNameSpaceID_XSLT, "message", txFnStartMessage, txFnEndMessage },
2692
  { kNameSpaceID_XSLT, "number", txFnStartNumber, txFnEndNumber },
2693
  { kNameSpaceID_XSLT, "processing-instruction", txFnStartPI, txFnEndPI },
2694
  { kNameSpaceID_XSLT, "text", txFnStartText, txFnEndText },
2695
  { kNameSpaceID_XSLT, "value-of", txFnStartValueOf, txFnEndValueOf },
2696
  { kNameSpaceID_XSLT, "variable", txFnStartVariable, txFnEndVariable }
2697
};
2698
2699
const txHandlerTableData gTxTemplateTableData = {
2700
  // Other
2701
  { 0, 0, txFnStartUnknownInstruction, txFnEndUnknownInstruction },
2702
  // LRE
2703
  { 0, 0, txFnStartLRE, txFnEndLRE },
2704
  // Text
2705
  txFnText
2706
};
2707
2708
const txHandlerTableData gTxTextTableData = {
2709
  // Other
2710
  { 0, 0, txFnStartElementError, txFnEndElementError },
2711
  // LRE
2712
  { 0, 0, txFnStartElementError, txFnEndElementError },
2713
  // Text
2714
  txFnTextText
2715
};
2716
2717
const txElementHandler gTxApplyTemplatesElementHandlers[] = {
2718
  { kNameSpaceID_XSLT, "sort", txFnStartSort, txFnEndSort },
2719
  { kNameSpaceID_XSLT, "with-param", txFnStartWithParam, txFnEndWithParam }
2720
};
2721
2722
const txHandlerTableData gTxApplyTemplatesTableData = {
2723
  // Other
2724
  { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore }, // should this be error?
2725
  // LRE
2726
  { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore },
2727
  // Text
2728
  txFnTextIgnore
2729
};
2730
2731
const txElementHandler gTxCallTemplateElementHandlers[] = {
2732
  { kNameSpaceID_XSLT, "with-param", txFnStartWithParam, txFnEndWithParam }
2733
};
2734
2735
const txHandlerTableData gTxCallTemplateTableData = {
2736
  // Other
2737
  { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore }, // should this be error?
2738
  // LRE
2739
  { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore },
2740
  // Text
2741
  txFnTextIgnore
2742
};
2743
2744
const txHandlerTableData gTxVariableTableData = {
2745
  // Other
2746
  { 0, 0, txFnStartElementStartRTF, 0 },
2747
  // LRE
2748
  { 0, 0, txFnStartElementStartRTF, 0 },
2749
  // Text
2750
  txFnTextStartRTF
2751
};
2752
2753
const txElementHandler gTxForEachElementHandlers[] = {
2754
  { kNameSpaceID_XSLT, "sort", txFnStartSort, txFnEndSort }
2755
};
2756
2757
const txHandlerTableData gTxForEachTableData = {
2758
  // Other
2759
  { 0, 0, txFnStartElementContinueTemplate, 0 },
2760
  // LRE
2761
  { 0, 0, txFnStartElementContinueTemplate, 0 },
2762
  // Text
2763
  txFnTextContinueTemplate
2764
};
2765
2766
const txHandlerTableData gTxTopVariableTableData = {
2767
  // Other
2768
  { 0, 0, txFnStartElementStartTopVar, 0 },
2769
  // LRE
2770
  { 0, 0, txFnStartElementStartTopVar, 0 },
2771
  // Text
2772
  txFnTextStartTopVar
2773
};
2774
2775
const txElementHandler gTxChooseElementHandlers[] = {
2776
  { kNameSpaceID_XSLT, "otherwise", txFnStartOtherwise, txFnEndOtherwise },
2777
  { kNameSpaceID_XSLT, "when", txFnStartWhen, txFnEndWhen }
2778
};
2779
2780
const txHandlerTableData gTxChooseTableData = {
2781
  // Other
2782
  { 0, 0, txFnStartElementError, 0 },
2783
  // LRE
2784
  { 0, 0, txFnStartElementError, 0 },
2785
  // Text
2786
  txFnTextError
2787
};
2788
2789
const txElementHandler gTxParamElementHandlers[] = {
2790
  { kNameSpaceID_XSLT, "param", txFnStartParam, txFnEndParam }
2791
};
2792
2793
const txHandlerTableData gTxParamTableData = {
2794
  // Other
2795
  { 0, 0, txFnStartElementContinueTemplate, 0 },
2796
  // LRE
2797
  { 0, 0, txFnStartElementContinueTemplate, 0 },
2798
  // Text
2799
  txFnTextContinueTemplate
2800
};
2801
2802
const txElementHandler gTxImportElementHandlers[] = {
2803
  { kNameSpaceID_XSLT, "import", txFnStartImport, txFnEndImport }
2804
};
2805
2806
const txHandlerTableData gTxImportTableData = {
2807
  // Other
2808
  { 0, 0, txFnStartElementContinueTopLevel, 0 },
2809
  // LRE
2810
  { 0, 0, txFnStartOtherTop, txFnEndOtherTop }, // XXX what should we do here?
2811
  // Text
2812
  txFnTextIgnore  // XXX what should we do here?
2813
};
2814
2815
const txElementHandler gTxAttributeSetElementHandlers[] = {
2816
  { kNameSpaceID_XSLT, "attribute", txFnStartAttribute, txFnEndAttribute }
2817
};
2818
2819
const txHandlerTableData gTxAttributeSetTableData = {
2820
  // Other
2821
  { 0, 0, txFnStartElementError, 0 },
2822
  // LRE
2823
  { 0, 0, txFnStartElementError, 0 },
2824
  // Text
2825
  txFnTextError
2826
};
2827
2828
const txElementHandler gTxFallbackElementHandlers[] = {
2829
  { kNameSpaceID_XSLT, "fallback", txFnStartFallback, txFnEndFallback }
2830
};
2831
2832
const txHandlerTableData gTxFallbackTableData = {
2833
  // Other
2834
  { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore },
2835
  // LRE
2836
  { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore },
2837
  // Text
2838
  txFnTextIgnore
2839
};
2840
2841
2842
2843
/**
2844
 * txHandlerTable
2845
 */
2846
txHandlerTable::txHandlerTable(const HandleTextFn aTextHandler,
2847
                               const txElementHandler* aLREHandler,
2848
                               const txElementHandler* aOtherHandler)
2849
  : mTextHandler(aTextHandler),
2850
    mLREHandler(aLREHandler),
2851
    mOtherHandler(aOtherHandler)
2852
48
{
2853
48
}
2854
2855
nsresult
2856
txHandlerTable::init(const txElementHandler* aHandlers, uint32_t aCount)
2857
33
{
2858
33
    nsresult rv = NS_OK;
2859
33
2860
33
    uint32_t i;
2861
156
    for (i = 0; i < aCount; ++i) {
2862
123
        RefPtr<nsAtom> nameAtom = NS_Atomize(aHandlers->mLocalName);
2863
123
        txExpandedName name(aHandlers->mNamespaceID, nameAtom);
2864
123
        rv = mHandlers.add(name, aHandlers);
2865
123
        NS_ENSURE_SUCCESS(rv, rv);
2866
123
2867
123
        ++aHandlers;
2868
123
    }
2869
33
    return NS_OK;
2870
33
}
2871
2872
const txElementHandler*
2873
txHandlerTable::find(int32_t aNamespaceID, nsAtom* aLocalName)
2874
0
{
2875
0
    txExpandedName name(aNamespaceID, aLocalName);
2876
0
    const txElementHandler* handler = mHandlers.get(name);
2877
0
    if (!handler) {
2878
0
        handler = mOtherHandler;
2879
0
    }
2880
0
    return handler;
2881
0
}
2882
2883
#define INIT_HANDLER(_name)                                          \
2884
48
    gTx##_name##Handler =                                            \
2885
45
        new txHandlerTable(gTx##_name##TableData.mTextHandler,       \
2886
45
                           &gTx##_name##TableData.mLREHandler,       \
2887
45
                           &gTx##_name##TableData.mOtherHandler);    \
2888
48
    if (!gTx##_name##Handler)                                        \
2889
45
        return false
2890
2891
#define INIT_HANDLER_WITH_ELEMENT_HANDLERS(_name)                    \
2892
33
    INIT_HANDLER(_name);                                             \
2893
30
                                                                     \
2894
33
    rv = gTx##_name##Handler->init(gTx##_name##ElementHandlers,      \
2895
33
                                   ArrayLength(gTx##_name##ElementHandlers)); \
2896
33
    if (NS_FAILED(rv))                                               \
2897
33
        return false
2898
2899
#define SHUTDOWN_HANDLER(_name)                                      \
2900
0
    delete gTx##_name##Handler;                                      \
2901
0
    gTx##_name##Handler = nullptr
2902
2903
// static
2904
bool
2905
txHandlerTable::init()
2906
3
{
2907
3
    nsresult rv = NS_OK;
2908
3
2909
3
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(Root);
2910
3
    INIT_HANDLER(Embed);
2911
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(Top);
2912
6
    INIT_HANDLER(Ignore);
2913
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(Template);
2914
6
    INIT_HANDLER(Text);
2915
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(ApplyTemplates);
2916
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(CallTemplate);
2917
6
    INIT_HANDLER(Variable);
2918
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(ForEach);
2919
6
    INIT_HANDLER(TopVariable);
2920
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(Choose);
2921
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(Param);
2922
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(Import);
2923
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(AttributeSet);
2924
6
    INIT_HANDLER_WITH_ELEMENT_HANDLERS(Fallback);
2925
6
2926
6
    return true;
2927
6
}
2928
2929
// static
2930
void
2931
txHandlerTable::shutdown()
2932
0
{
2933
0
    SHUTDOWN_HANDLER(Root);
2934
0
    SHUTDOWN_HANDLER(Embed);
2935
0
    SHUTDOWN_HANDLER(Top);
2936
0
    SHUTDOWN_HANDLER(Ignore);
2937
0
    SHUTDOWN_HANDLER(Template);
2938
0
    SHUTDOWN_HANDLER(Text);
2939
0
    SHUTDOWN_HANDLER(ApplyTemplates);
2940
0
    SHUTDOWN_HANDLER(CallTemplate);
2941
0
    SHUTDOWN_HANDLER(Variable);
2942
0
    SHUTDOWN_HANDLER(ForEach);
2943
0
    SHUTDOWN_HANDLER(TopVariable);
2944
0
    SHUTDOWN_HANDLER(Choose);
2945
0
    SHUTDOWN_HANDLER(Param);
2946
0
    SHUTDOWN_HANDLER(Import);
2947
0
    SHUTDOWN_HANDLER(AttributeSet);
2948
0
    SHUTDOWN_HANDLER(Fallback);
2949
0
}