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