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