Back to index

lightning-sunbird  0.9+nobinonly
txStylesheetCompileHandlers.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is TransforMiiX XSLT processor code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Jonas Sicking.
00019  * Portions created by the Initial Developer are Copyright (C) 2002
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Jonas Sicking <jonas@sicking.cc>
00024  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either the GNU General Public License Version 2 or later (the "GPL"), or
00027  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "txStylesheetCompiler.h"
00040 #include "txStylesheetCompileHandlers.h"
00041 #include "txTokenizer.h"
00042 #include "txInstructions.h"
00043 #include "txAtoms.h"
00044 #include "txCore.h"
00045 #include "txStringUtils.h"
00046 #include "txStylesheet.h"
00047 #include "txToplevelItems.h"
00048 #include "txPatternParser.h"
00049 #include "txNamespaceMap.h"
00050 #include "txURIUtils.h"
00051 #include "XSLTFunctions.h"
00052 
00053 txHandlerTable* gTxIgnoreHandler = 0;
00054 txHandlerTable* gTxRootHandler = 0;
00055 txHandlerTable* gTxEmbedHandler = 0;
00056 txHandlerTable* gTxTopHandler = 0;
00057 txHandlerTable* gTxTemplateHandler = 0;
00058 txHandlerTable* gTxTextHandler = 0;
00059 txHandlerTable* gTxApplyTemplatesHandler = 0;
00060 txHandlerTable* gTxCallTemplateHandler = 0;
00061 txHandlerTable* gTxVariableHandler = 0;
00062 txHandlerTable* gTxForEachHandler = 0;
00063 txHandlerTable* gTxTopVariableHandler = 0;
00064 txHandlerTable* gTxChooseHandler = 0;
00065 txHandlerTable* gTxParamHandler = 0;
00066 txHandlerTable* gTxImportHandler = 0;
00067 txHandlerTable* gTxAttributeSetHandler = 0;
00068 txHandlerTable* gTxFallbackHandler = 0;
00069 
00070 nsresult
00071 txFnStartLRE(PRInt32 aNamespaceID,
00072              nsIAtom* aLocalName,
00073              nsIAtom* aPrefix,
00074              txStylesheetAttr* aAttributes,
00075              PRInt32 aAttrCount,
00076              txStylesheetCompilerState& aState);
00077 nsresult
00078 txFnEndLRE(txStylesheetCompilerState& aState);
00079 
00080 
00081 #define TX_RETURN_IF_WHITESPACE(_str, _state)                               \
00082     do {                                                                    \
00083       if (!_state.mElementContext->mPreserveWhitespace &&                   \
00084           XMLUtils::isWhitespace(PromiseFlatString(_str))) {                \
00085           return NS_OK;                                                     \
00086       }                                                                     \
00087     } while(0)
00088 
00089 
00090 nsresult
00091 getStyleAttr(txStylesheetAttr* aAttributes,
00092              PRInt32 aAttrCount,
00093              PRInt32 aNamespace,
00094              nsIAtom* aName,
00095              PRBool aRequired,
00096              txStylesheetAttr** aAttr)
00097 {
00098     PRInt32 i;
00099     for (i = 0; i < aAttrCount; ++i) {
00100         txStylesheetAttr* attr = aAttributes + i;
00101         if (attr->mNamespaceID == aNamespace &&
00102             attr->mLocalName == aName) {
00103             *aAttr = attr;
00104 
00105             return NS_OK;
00106         }
00107     }
00108     *aAttr = nsnull;
00109     
00110     if (aRequired) {
00111         // XXX ErrorReport: missing required attribute
00112         return NS_ERROR_XSLT_PARSE_FAILURE;
00113     }
00114     
00115     return NS_OK;
00116 }
00117 
00118 nsresult
00119 parseUseAttrSets(txStylesheetAttr* aAttributes,
00120                  PRInt32 aAttrCount,
00121                  PRBool aInXSLTNS,
00122                  txStylesheetCompilerState& aState)
00123 {
00124     txStylesheetAttr* attr = nsnull;
00125     nsresult rv = getStyleAttr(aAttributes, aAttrCount,
00126                                aInXSLTNS ? kNameSpaceID_XSLT
00127                                          : kNameSpaceID_None,
00128                                txXSLTAtoms::useAttributeSets, PR_FALSE,
00129                                &attr);
00130     if (!attr) {
00131         return rv;
00132     }
00133 
00134     txTokenizer tok(attr->mValue);
00135     while (tok.hasMoreTokens()) {
00136         txExpandedName name;
00137         rv = name.init(tok.nextToken(), aState.mElementContext->mMappings,
00138                        PR_FALSE);
00139         NS_ENSURE_SUCCESS(rv, rv);
00140 
00141         nsAutoPtr<txInstruction> instr(new txInsertAttrSet(name));
00142         NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
00143 
00144         rv = aState.addInstruction(instr);
00145         NS_ENSURE_SUCCESS(rv, rv);
00146     }
00147     return NS_OK;
00148 }
00149 
00150 nsresult
00151 getQNameAttr(txStylesheetAttr* aAttributes,
00152              PRInt32 aAttrCount,
00153              nsIAtom* aName,
00154              PRBool aRequired,
00155              txStylesheetCompilerState& aState,
00156              txExpandedName& aExpName)
00157 {
00158     aExpName.reset();
00159     txStylesheetAttr* attr = nsnull;
00160     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00161                                aName, aRequired, &attr);
00162     if (!attr) {
00163         return rv;
00164     }
00165 
00166     rv = aExpName.init(attr->mValue, aState.mElementContext->mMappings,
00167                        PR_FALSE);
00168     if (!aRequired && NS_FAILED(rv) && aState.fcp()) {
00169         aExpName.reset();
00170         rv = NS_OK;
00171     }
00172 
00173     return rv;
00174 }
00175 
00176 nsresult
00177 getExprAttr(txStylesheetAttr* aAttributes,
00178             PRInt32 aAttrCount,
00179             nsIAtom* aName,
00180             PRBool aRequired,
00181             txStylesheetCompilerState& aState,
00182             nsAutoPtr<Expr>& aExpr)
00183 {
00184     aExpr = nsnull;
00185     txStylesheetAttr* attr = nsnull;
00186     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00187                                aName, aRequired, &attr);
00188     if (!attr) {
00189         return rv;
00190     }
00191 
00192     rv = txExprParser::createExpr(attr->mValue, &aState,
00193                                   getter_Transfers(aExpr));
00194     if (NS_FAILED(rv) && aState.fcp()) {
00195         // use default value in fcp for not required exprs
00196         if (aRequired) {
00197             aExpr = new txErrorExpr(
00198 #ifdef TX_TO_STRING
00199                                     attr->mValue
00200 #endif
00201                                     );
00202             NS_ENSURE_TRUE(aExpr, NS_ERROR_OUT_OF_MEMORY);
00203         }
00204         else {
00205             aExpr = nsnull;
00206         }
00207         return NS_OK;
00208     }
00209 
00210     return rv;
00211 }
00212 
00213 nsresult
00214 getAVTAttr(txStylesheetAttr* aAttributes,
00215            PRInt32 aAttrCount,
00216            nsIAtom* aName,
00217            PRBool aRequired,
00218            txStylesheetCompilerState& aState,
00219            nsAutoPtr<Expr>& aAVT)
00220 {
00221     aAVT = nsnull;
00222     txStylesheetAttr* attr = nsnull;
00223     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00224                                aName, aRequired, &attr);
00225     if (!attr) {
00226         return rv;
00227     }
00228 
00229     aAVT = txExprParser::createAttributeValueTemplate(attr->mValue, &aState);
00230     if (!aAVT) {
00231         if (!aState.fcp()) {
00232             // XXX ErrorReport: XPath parse failure
00233             return NS_ERROR_XPATH_PARSE_FAILURE;
00234         }
00235 
00236         if (aRequired) {
00237             aAVT = new txErrorExpr(
00238 #ifdef TX_TO_STRING
00239                                    attr->mValue
00240 #endif
00241                                    );
00242             NS_ENSURE_TRUE(aAVT, NS_ERROR_OUT_OF_MEMORY);
00243         }
00244     }
00245 
00246     return NS_OK;
00247 }
00248 
00249 nsresult
00250 getPatternAttr(txStylesheetAttr* aAttributes,
00251                PRInt32 aAttrCount,
00252                nsIAtom* aName,
00253                PRBool aRequired,
00254                txStylesheetCompilerState& aState,
00255                nsAutoPtr<txPattern>& aPattern)
00256 {
00257     aPattern = nsnull;
00258     txStylesheetAttr* attr = nsnull;
00259     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00260                                aName, aRequired, &attr);
00261     if (!attr) {
00262         return rv;
00263     }
00264 
00265     aPattern = txPatternParser::createPattern(attr->mValue, &aState);
00266     if (!aPattern && (aRequired || !aState.fcp())) {
00267         // XXX ErrorReport: XSLT-Pattern parse failure
00268         return NS_ERROR_XPATH_PARSE_FAILURE;
00269     }
00270 
00271     return NS_OK;
00272 }
00273 
00274 nsresult
00275 getNumberAttr(txStylesheetAttr* aAttributes,
00276               PRInt32 aAttrCount,
00277               nsIAtom* aName,
00278               PRBool aRequired,
00279               txStylesheetCompilerState& aState,
00280               double& aNumber)
00281 {
00282     aNumber = Double::NaN;
00283     txStylesheetAttr* attr = nsnull;
00284     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00285                                aName, aRequired, &attr);
00286     if (!attr) {
00287         return rv;
00288     }
00289 
00290     aNumber = Double::toDouble(attr->mValue);
00291     if (Double::isNaN(aNumber) && (aRequired || !aState.fcp())) {
00292         // XXX ErrorReport: number parse failure
00293         return NS_ERROR_XSLT_PARSE_FAILURE;
00294     }
00295 
00296     return NS_OK;
00297 }
00298 
00299 nsresult
00300 getAtomAttr(txStylesheetAttr* aAttributes,
00301             PRInt32 aAttrCount,
00302             nsIAtom* aName,
00303             PRBool aRequired,
00304             txStylesheetCompilerState& aState,
00305             nsIAtom** aAtom)
00306 {
00307     *aAtom = nsnull;
00308     txStylesheetAttr* attr = nsnull;
00309     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00310                                aName, aRequired, &attr);
00311     if (!attr) {
00312         return rv;
00313     }
00314 
00315     *aAtom = NS_NewAtom(attr->mValue);
00316     NS_ENSURE_TRUE(*aAtom, NS_ERROR_OUT_OF_MEMORY);
00317 
00318     return NS_OK;
00319 }
00320 
00321 nsresult
00322 getYesNoAttr(txStylesheetAttr* aAttributes,
00323              PRInt32 aAttrCount,
00324              nsIAtom* aName,
00325              PRBool aRequired,
00326              txStylesheetCompilerState& aState,
00327              txThreeState& aRes)
00328 {
00329     aRes = eNotSet;
00330     nsCOMPtr<nsIAtom> atom;
00331     nsresult rv = getAtomAttr(aAttributes, aAttrCount, aName, aRequired,
00332                               aState, getter_AddRefs(atom));
00333     if (!atom) {
00334         return rv;
00335     }
00336 
00337     if (atom == txXSLTAtoms::yes) {
00338         aRes = eTrue;
00339     }
00340     else if (atom == txXSLTAtoms::no) {
00341         aRes = eFalse;
00342     }
00343     else if (aRequired || !aState.fcp()) {
00344         // XXX ErrorReport: unknown values
00345         return NS_ERROR_XSLT_PARSE_FAILURE;
00346     }
00347 
00348     return NS_OK;
00349 }
00350 
00351 nsresult
00352 getCharAttr(txStylesheetAttr* aAttributes,
00353             PRInt32 aAttrCount,
00354             nsIAtom* aName,
00355             PRBool aRequired,
00356             txStylesheetCompilerState& aState,
00357             PRUnichar& aChar)
00358 {
00359     // Don't reset aChar since it contains the default value
00360     txStylesheetAttr* attr = nsnull;
00361     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00362                                aName, aRequired, &attr);
00363     if (!attr) {
00364         return rv;
00365     }
00366 
00367     if (attr->mValue.Length() == 1) {
00368         aChar = attr->mValue.CharAt(0);
00369     }
00370     else if (aRequired || !aState.fcp()) {
00371         // XXX ErrorReport: not a character
00372         return NS_ERROR_XSLT_PARSE_FAILURE;
00373     }
00374 
00375     return NS_OK;
00376 }
00377 
00378 
00382 nsresult
00383 txFnTextIgnore(const nsAString& aStr, txStylesheetCompilerState& aState)
00384 {
00385     return NS_OK;
00386 }
00387 
00388 nsresult
00389 txFnTextError(const nsAString& aStr, txStylesheetCompilerState& aState)
00390 {
00391     TX_RETURN_IF_WHITESPACE(aStr, aState);
00392 
00393     return NS_ERROR_XSLT_PARSE_FAILURE;
00394 }
00395 
00396 nsresult
00397 txFnStartElementIgnore(PRInt32 aNamespaceID,
00398                        nsIAtom* aLocalName,
00399                        nsIAtom* aPrefix,
00400                        txStylesheetAttr* aAttributes,
00401                        PRInt32 aAttrCount,
00402                        txStylesheetCompilerState& aState)
00403 {
00404     return NS_OK;
00405 }
00406 
00407 nsresult
00408 txFnEndElementIgnore(txStylesheetCompilerState& aState)
00409 {
00410     return NS_OK;
00411 }
00412 
00413 nsresult
00414 txFnStartElementSetIgnore(PRInt32 aNamespaceID,
00415                           nsIAtom* aLocalName,
00416                           nsIAtom* aPrefix,
00417                           txStylesheetAttr* aAttributes,
00418                           PRInt32 aAttrCount,
00419                           txStylesheetCompilerState& aState)
00420 {
00421     return aState.pushHandlerTable(gTxIgnoreHandler);
00422 }
00423 
00424 nsresult
00425 txFnEndElementSetIgnore(txStylesheetCompilerState& aState)
00426 {
00427     aState.popHandlerTable();
00428     return NS_OK;
00429 }
00430 
00431 nsresult
00432 txFnStartElementError(PRInt32 aNamespaceID,
00433                       nsIAtom* aLocalName,
00434                       nsIAtom* aPrefix,
00435                       txStylesheetAttr* aAttributes,
00436                       PRInt32 aAttrCount,
00437                       txStylesheetCompilerState& aState)
00438 {
00439     return NS_ERROR_XSLT_PARSE_FAILURE;
00440 }
00441 
00442 nsresult
00443 txFnEndElementError(txStylesheetCompilerState& aState)
00444 {
00445     NS_ERROR("txFnEndElementError shouldn't be called"); 
00446     return NS_ERROR_XSLT_PARSE_FAILURE;
00447 }
00448 
00449 
00453 nsresult
00454 txFnStartStylesheet(PRInt32 aNamespaceID,
00455                     nsIAtom* aLocalName,
00456                     nsIAtom* aPrefix,
00457                     txStylesheetAttr* aAttributes,
00458                     PRInt32 aAttrCount,
00459                     txStylesheetCompilerState& aState)
00460 {
00461     txStylesheetAttr* attr;
00462     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00463                                txXSLTAtoms::version, PR_TRUE, &attr);
00464     NS_ENSURE_SUCCESS(rv, rv);
00465 
00466     return aState.pushHandlerTable(gTxImportHandler);
00467 }
00468 
00469 nsresult
00470 txFnEndStylesheet(txStylesheetCompilerState& aState)
00471 {
00472     aState.popHandlerTable();
00473     return NS_OK;
00474 }
00475 
00476 nsresult
00477 txFnStartElementContinueTopLevel(PRInt32 aNamespaceID,
00478                                 nsIAtom* aLocalName,
00479                                 nsIAtom* aPrefix,
00480                                 txStylesheetAttr* aAttributes,
00481                                 PRInt32 aAttrCount,
00482                                 txStylesheetCompilerState& aState)
00483 {
00484     aState.mHandlerTable = gTxTopHandler;
00485 
00486     return NS_XSLT_GET_NEW_HANDLER;
00487 }
00488 
00489 nsresult
00490 txFnStartLREStylesheet(PRInt32 aNamespaceID,
00491                        nsIAtom* aLocalName,
00492                        nsIAtom* aPrefix,
00493                        txStylesheetAttr* aAttributes,
00494                        PRInt32 aAttrCount,
00495                        txStylesheetCompilerState& aState)
00496 {
00497     txStylesheetAttr* attr;
00498     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_XSLT,
00499                                txXSLTAtoms::version, PR_TRUE, &attr);
00500     NS_ENSURE_SUCCESS(rv, rv);
00501 
00502     txExpandedName nullExpr;
00503     double prio = Double::NaN;
00504 
00505     nsAutoPtr<txPattern> match(new txRootPattern());
00506     NS_ENSURE_TRUE(match, NS_ERROR_OUT_OF_MEMORY);
00507 
00508     nsAutoPtr<txTemplateItem> templ(new txTemplateItem(match, nullExpr,
00509                                                        nullExpr, prio));
00510     NS_ENSURE_TRUE(templ, NS_ERROR_OUT_OF_MEMORY);
00511 
00512     aState.openInstructionContainer(templ);
00513     rv = aState.addToplevelItem(templ);
00514     NS_ENSURE_SUCCESS(rv, rv);
00515 
00516     templ.forget();
00517 
00518     rv = aState.pushHandlerTable(gTxTemplateHandler);
00519     NS_ENSURE_SUCCESS(rv, rv);
00520     
00521     return txFnStartLRE(aNamespaceID, aLocalName, aPrefix, aAttributes,
00522                         aAttrCount, aState);
00523 }
00524 
00525 nsresult
00526 txFnEndLREStylesheet(txStylesheetCompilerState& aState)
00527 {
00528     nsresult rv = txFnEndLRE(aState);
00529     NS_ENSURE_SUCCESS(rv, rv);
00530 
00531     aState.popHandlerTable();
00532 
00533     nsAutoPtr<txInstruction> instr(new txReturn());
00534     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
00535 
00536     rv = aState.addInstruction(instr);
00537     NS_ENSURE_SUCCESS(rv, rv);
00538 
00539     aState.closeInstructionContainer();
00540 
00541     return NS_OK;
00542 }
00543 
00544 nsresult
00545 txFnStartEmbed(PRInt32 aNamespaceID,
00546                nsIAtom* aLocalName,
00547                nsIAtom* aPrefix,
00548                txStylesheetAttr* aAttributes,
00549                PRInt32 aAttrCount,
00550                txStylesheetCompilerState& aState)
00551 {
00552     if (!aState.handleEmbeddedSheet()) {
00553         return NS_OK;
00554     }
00555     if (aNamespaceID != kNameSpaceID_XSLT ||
00556         (aLocalName != txXSLTAtoms::stylesheet &&
00557          aLocalName != txXSLTAtoms::transform)) {
00558         return NS_ERROR_XSLT_PARSE_FAILURE;
00559     }
00560     return txFnStartStylesheet(aNamespaceID, aLocalName, aPrefix,
00561                                aAttributes, aAttrCount, aState);
00562 }
00563 
00564 nsresult
00565 txFnEndEmbed(txStylesheetCompilerState& aState)
00566 {
00567     if (!aState.handleEmbeddedSheet()) {
00568         return NS_OK;
00569     }
00570     nsresult rv = txFnEndStylesheet(aState);
00571     aState.doneEmbedding();
00572     return rv;
00573 }
00574 
00575 
00579 nsresult
00580 txFnStartOtherTop(PRInt32 aNamespaceID,
00581                   nsIAtom* aLocalName,
00582                   nsIAtom* aPrefix,
00583                   txStylesheetAttr* aAttributes,
00584                   PRInt32 aAttrCount,
00585                   txStylesheetCompilerState& aState)
00586 {
00587     if (aNamespaceID == kNameSpaceID_None) {
00588         return NS_ERROR_XSLT_PARSE_FAILURE;
00589     }
00590     
00591     return aState.pushHandlerTable(gTxIgnoreHandler);
00592 }
00593 
00594 nsresult
00595 txFnEndOtherTop(txStylesheetCompilerState& aState)
00596 {
00597     aState.popHandlerTable();
00598     return NS_OK;
00599 }
00600 
00601 
00602 // xsl:attribute-set
00603 nsresult
00604 txFnStartAttributeSet(PRInt32 aNamespaceID,
00605                       nsIAtom* aLocalName,
00606                       nsIAtom* aPrefix,
00607                       txStylesheetAttr* aAttributes,
00608                       PRInt32 aAttrCount,
00609                       txStylesheetCompilerState& aState)
00610 {
00611     nsresult rv = NS_OK;
00612     txExpandedName name;
00613     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
00614                       aState, name);
00615     NS_ENSURE_SUCCESS(rv, rv);
00616 
00617     nsAutoPtr<txAttributeSetItem> attrSet(new txAttributeSetItem(name));
00618     NS_ENSURE_TRUE(attrSet, NS_ERROR_OUT_OF_MEMORY);
00619 
00620     aState.openInstructionContainer(attrSet);
00621 
00622     rv = aState.addToplevelItem(attrSet);
00623     NS_ENSURE_SUCCESS(rv, rv);
00624 
00625     attrSet.forget();
00626 
00627     rv = parseUseAttrSets(aAttributes, aAttrCount, PR_FALSE, aState);
00628     NS_ENSURE_SUCCESS(rv, rv);
00629 
00630     return aState.pushHandlerTable(gTxAttributeSetHandler);
00631 }
00632 
00633 nsresult
00634 txFnEndAttributeSet(txStylesheetCompilerState& aState)
00635 {
00636     aState.popHandlerTable();
00637 
00638     nsAutoPtr<txInstruction> instr(new txReturn());
00639     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
00640 
00641     nsresult rv = aState.addInstruction(instr);
00642     NS_ENSURE_SUCCESS(rv, rv);
00643 
00644     aState.closeInstructionContainer();
00645 
00646     return NS_OK;
00647 }
00648 
00649 
00650 // xsl:decimal-format
00651 nsresult
00652 txFnStartDecimalFormat(PRInt32 aNamespaceID,
00653                        nsIAtom* aLocalName,
00654                        nsIAtom* aPrefix,
00655                        txStylesheetAttr* aAttributes,
00656                        PRInt32 aAttrCount,
00657                        txStylesheetCompilerState& aState)
00658 {
00659     nsresult rv = NS_OK;
00660     txExpandedName name;
00661     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_FALSE,
00662                       aState, name);
00663     NS_ENSURE_SUCCESS(rv, rv);
00664 
00665     nsAutoPtr<txDecimalFormat> format(new txDecimalFormat);
00666     NS_ENSURE_TRUE(format, NS_ERROR_OUT_OF_MEMORY);
00667 
00668     rv = getCharAttr(aAttributes, aAttrCount, txXSLTAtoms::decimalSeparator,
00669                      PR_FALSE, aState, format->mDecimalSeparator);
00670     NS_ENSURE_SUCCESS(rv, rv);
00671 
00672     rv = getCharAttr(aAttributes, aAttrCount, txXSLTAtoms::groupingSeparator,
00673                      PR_FALSE, aState, format->mGroupingSeparator);
00674     NS_ENSURE_SUCCESS(rv, rv);
00675 
00676     txStylesheetAttr* attr = nsnull;
00677     rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00678                       txXSLTAtoms::infinity, PR_FALSE, &attr);
00679     NS_ENSURE_SUCCESS(rv, rv);
00680 
00681     if (attr) {
00682         format->mInfinity = attr->mValue;
00683     }
00684 
00685     rv = getCharAttr(aAttributes, aAttrCount, txXSLTAtoms::minusSign,
00686                      PR_FALSE, aState, format->mMinusSign);
00687     NS_ENSURE_SUCCESS(rv, rv);
00688 
00689     rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00690                       txXSLTAtoms::NaN, PR_FALSE, &attr);
00691     NS_ENSURE_SUCCESS(rv, rv);
00692 
00693     if (attr) {
00694         format->mNaN = attr->mValue;
00695     }
00696 
00697     rv = getCharAttr(aAttributes, aAttrCount, txXSLTAtoms::percent,
00698                      PR_FALSE, aState, format->mPercent);
00699     NS_ENSURE_SUCCESS(rv, rv);
00700 
00701     rv = getCharAttr(aAttributes, aAttrCount, txXSLTAtoms::perMille,
00702                      PR_FALSE, aState, format->mPerMille);
00703     NS_ENSURE_SUCCESS(rv, rv);
00704 
00705     rv = getCharAttr(aAttributes, aAttrCount, txXSLTAtoms::zeroDigit,
00706                      PR_FALSE, aState, format->mZeroDigit);
00707     NS_ENSURE_SUCCESS(rv, rv);
00708 
00709     rv = getCharAttr(aAttributes, aAttrCount, txXSLTAtoms::digit,
00710                      PR_FALSE, aState, format->mDigit);
00711     NS_ENSURE_SUCCESS(rv, rv);
00712 
00713     rv = getCharAttr(aAttributes, aAttrCount, txXSLTAtoms::patternSeparator,
00714                      PR_FALSE, aState, format->mPatternSeparator);
00715     NS_ENSURE_SUCCESS(rv, rv);
00716 
00717     rv = aState.mStylesheet->addDecimalFormat(name, format);
00718     NS_ENSURE_SUCCESS(rv, rv);
00719     
00720     return aState.pushHandlerTable(gTxIgnoreHandler);
00721 }
00722 
00723 nsresult
00724 txFnEndDecimalFormat(txStylesheetCompilerState& aState)
00725 {
00726     aState.popHandlerTable();
00727 
00728     return NS_OK;
00729 }
00730 
00731 // xsl:import
00732 nsresult
00733 txFnStartImport(PRInt32 aNamespaceID,
00734                 nsIAtom* aLocalName,
00735                 nsIAtom* aPrefix,
00736                 txStylesheetAttr* aAttributes,
00737                 PRInt32 aAttrCount,
00738                 txStylesheetCompilerState& aState)
00739 {
00740     nsAutoPtr<txImportItem> import(new txImportItem);
00741     NS_ENSURE_TRUE(import, NS_ERROR_OUT_OF_MEMORY);
00742     
00743     import->mFrame = new txStylesheet::ImportFrame;
00744     NS_ENSURE_TRUE(import->mFrame, NS_ERROR_OUT_OF_MEMORY);
00745 
00746     nsresult rv = aState.addToplevelItem(import);
00747     NS_ENSURE_SUCCESS(rv, rv);
00748     
00749     txImportItem* importPtr = import.forget();
00750     
00751     txStylesheetAttr* attr = nsnull;
00752     rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00753                       txXSLTAtoms::href, PR_TRUE, &attr);
00754     NS_ENSURE_SUCCESS(rv, rv);
00755 
00756     nsAutoString absUri;
00757     URIUtils::resolveHref(attr->mValue, aState.mElementContext->mBaseURI,
00758                           absUri);
00759     rv = aState.loadImportedStylesheet(absUri, importPtr->mFrame);
00760     NS_ENSURE_SUCCESS(rv, rv);
00761 
00762     return aState.pushHandlerTable(gTxIgnoreHandler);
00763 }
00764 
00765 nsresult
00766 txFnEndImport(txStylesheetCompilerState& aState)
00767 {
00768     aState.popHandlerTable();
00769 
00770     return NS_OK;
00771 }
00772 
00773 // xsl:include
00774 nsresult
00775 txFnStartInclude(PRInt32 aNamespaceID,
00776                  nsIAtom* aLocalName,
00777                  nsIAtom* aPrefix,
00778                  txStylesheetAttr* aAttributes,
00779                  PRInt32 aAttrCount,
00780                  txStylesheetCompilerState& aState)
00781 {
00782     txStylesheetAttr* attr = nsnull;
00783     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00784                                txXSLTAtoms::href, PR_TRUE, &attr);
00785     NS_ENSURE_SUCCESS(rv, rv);
00786 
00787     nsAutoString absUri;
00788     URIUtils::resolveHref(attr->mValue, aState.mElementContext->mBaseURI,
00789                           absUri);
00790     rv = aState.loadIncludedStylesheet(absUri);
00791     NS_ENSURE_SUCCESS(rv, rv);
00792 
00793     return aState.pushHandlerTable(gTxIgnoreHandler);
00794 }
00795 
00796 nsresult
00797 txFnEndInclude(txStylesheetCompilerState& aState)
00798 {
00799     aState.popHandlerTable();
00800 
00801     return NS_OK;
00802 }
00803 
00804 // xsl:key
00805 nsresult
00806 txFnStartKey(PRInt32 aNamespaceID,
00807              nsIAtom* aLocalName,
00808              nsIAtom* aPrefix,
00809              txStylesheetAttr* aAttributes,
00810              PRInt32 aAttrCount,
00811              txStylesheetCompilerState& aState)
00812 {
00813     nsresult rv = NS_OK;
00814     txExpandedName name;
00815     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
00816                       aState, name);
00817     NS_ENSURE_SUCCESS(rv, rv);
00818 
00819     nsAutoPtr<txPattern> match;
00820     rv = getPatternAttr(aAttributes, aAttrCount, txXSLTAtoms::match, PR_TRUE,
00821                         aState, match);
00822     NS_ENSURE_SUCCESS(rv, rv);
00823 
00824     nsAutoPtr<Expr> use;
00825     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::use, PR_TRUE,
00826                      aState, use);
00827     NS_ENSURE_SUCCESS(rv, rv);
00828 
00829     rv = aState.mStylesheet->addKey(name, match, use);
00830     NS_ENSURE_SUCCESS(rv, rv);
00831     
00832     return aState.pushHandlerTable(gTxIgnoreHandler);
00833 }
00834 
00835 nsresult
00836 txFnEndKey(txStylesheetCompilerState& aState)
00837 {
00838     aState.popHandlerTable();
00839 
00840     return NS_OK;
00841 }
00842 
00843 // xsl:output
00844 nsresult
00845 txFnStartOutput(PRInt32 aNamespaceID,
00846                 nsIAtom* aLocalName,
00847                 nsIAtom* aPrefix,
00848                 txStylesheetAttr* aAttributes,
00849                 PRInt32 aAttrCount,
00850                 txStylesheetCompilerState& aState)
00851 {
00852     nsresult rv = NS_OK;
00853 
00854     nsAutoPtr<txOutputItem> item(new txOutputItem);
00855     NS_ENSURE_TRUE(item, NS_ERROR_OUT_OF_MEMORY);
00856 
00857     txExpandedName methodExpName;
00858     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::method, PR_FALSE,
00859                       aState, methodExpName);
00860     NS_ENSURE_SUCCESS(rv, rv);
00861 
00862     if (!methodExpName.isNull()) {
00863         if (methodExpName.mNamespaceID != kNameSpaceID_None) {
00864             // The spec doesn't say what to do here so we'll just ignore the
00865             // value. We could possibly warn.
00866         }
00867         else if (methodExpName.mLocalName == txXSLTAtoms::html) {
00868             item->mFormat.mMethod = eHTMLOutput;
00869         }
00870         else if (methodExpName.mLocalName == txXSLTAtoms::text) {
00871             item->mFormat.mMethod = eTextOutput;
00872         }
00873         else if (methodExpName.mLocalName == txXSLTAtoms::xml) {
00874             item->mFormat.mMethod = eXMLOutput;
00875         }
00876         else {
00877             return NS_ERROR_XSLT_PARSE_FAILURE;
00878         }
00879     }
00880 
00881     txStylesheetAttr* attr = nsnull;
00882     getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00883                  txXSLTAtoms::version, PR_FALSE, &attr);
00884     if (attr) {
00885         item->mFormat.mVersion = attr->mValue;
00886     }
00887 
00888     getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00889                  txXSLTAtoms::encoding, PR_FALSE, &attr);
00890     if (attr) {
00891         item->mFormat.mEncoding = attr->mValue;
00892     }
00893 
00894     rv = getYesNoAttr(aAttributes, aAttrCount,
00895                       txXSLTAtoms::omitXmlDeclaration, PR_FALSE, aState,
00896                       item->mFormat.mOmitXMLDeclaration);
00897     NS_ENSURE_SUCCESS(rv, rv);
00898 
00899     rv = getYesNoAttr(aAttributes, aAttrCount,
00900                       txXSLTAtoms::standalone, PR_FALSE, aState,
00901                       item->mFormat.mStandalone);
00902     NS_ENSURE_SUCCESS(rv, rv);
00903 
00904     getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00905                  txXSLTAtoms::doctypePublic, PR_FALSE, &attr);
00906     if (attr) {
00907         item->mFormat.mPublicId = attr->mValue;
00908     }
00909 
00910     getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00911                  txXSLTAtoms::doctypeSystem, PR_FALSE, &attr);
00912     if (attr) {
00913         item->mFormat.mSystemId = attr->mValue;
00914     }
00915 
00916     getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00917                  txXSLTAtoms::cdataSectionElements, PR_FALSE, &attr);
00918     if (attr) {
00919         txTokenizer tokens(attr->mValue);
00920         while (tokens.hasMoreTokens()) {
00921             txExpandedName* qname = new txExpandedName();
00922             NS_ENSURE_TRUE(qname, NS_ERROR_OUT_OF_MEMORY);
00923 
00924             rv = qname->init(tokens.nextToken(),
00925                              aState.mElementContext->mMappings, PR_FALSE);
00926             NS_ENSURE_SUCCESS(rv, rv);
00927 
00928             rv = item->mFormat.mCDATASectionElements.add(qname);
00929             NS_ENSURE_SUCCESS(rv, rv);
00930         }
00931     }
00932 
00933     rv = getYesNoAttr(aAttributes, aAttrCount,
00934                       txXSLTAtoms::indent, PR_FALSE, aState,
00935                       item->mFormat.mIndent);
00936     NS_ENSURE_SUCCESS(rv, rv);
00937 
00938     getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00939                  txXSLTAtoms::mediaType, PR_FALSE, &attr);
00940     if (attr) {
00941         item->mFormat.mMediaType = attr->mValue;
00942     }
00943 
00944     rv = aState.addToplevelItem(item);
00945     NS_ENSURE_SUCCESS(rv, rv);
00946     
00947     item.forget();
00948 
00949     return aState.pushHandlerTable(gTxIgnoreHandler);
00950 }
00951 
00952 nsresult
00953 txFnEndOutput(txStylesheetCompilerState& aState)
00954 {
00955     aState.popHandlerTable();
00956 
00957     return NS_OK;
00958 }
00959 
00960 // xsl:strip-space/xsl:preserve-space
00961 nsresult
00962 txFnStartStripSpace(PRInt32 aNamespaceID,
00963                     nsIAtom* aLocalName,
00964                     nsIAtom* aPrefix,
00965                     txStylesheetAttr* aAttributes,
00966                     PRInt32 aAttrCount,
00967                     txStylesheetCompilerState& aState)
00968 {
00969     txStylesheetAttr* attr = nsnull;
00970     nsresult rv = getStyleAttr(aAttributes, aAttrCount, kNameSpaceID_None,
00971                                txXSLTAtoms::elements, PR_TRUE, &attr);
00972     NS_ENSURE_SUCCESS(rv, rv);
00973 
00974     PRBool strip = aLocalName == txXSLTAtoms::stripSpace;
00975 
00976     nsAutoPtr<txStripSpaceItem> stripItem(new txStripSpaceItem);
00977     NS_ENSURE_TRUE(stripItem, NS_ERROR_OUT_OF_MEMORY);
00978 
00979     txTokenizer tokenizer(attr->mValue);
00980     while (tokenizer.hasMoreTokens()) {
00981         const nsASingleFragmentString& name = tokenizer.nextToken();
00982         PRInt32 ns = kNameSpaceID_None;
00983         nsCOMPtr<nsIAtom> prefix, localName;
00984         rv = XMLUtils::splitQName(name, getter_AddRefs(prefix),
00985                                   getter_AddRefs(localName));
00986         if (NS_FAILED(rv)) {
00987             // check for "*" or "prefix:*"
00988             PRUint32 length = name.Length();
00989             const PRUnichar* c;
00990             name.BeginReading(c);
00991             if (length == 2 || c[length-1] != '*') {
00992                 // these can't work
00993                 return NS_ERROR_XSLT_PARSE_FAILURE;
00994             }
00995             if (length > 1) {
00996                 // Check for a valid prefix, that is, the returned prefix
00997                 // should be empty and the real prefix is returned in
00998                 // localName.
00999                 if (c[length-2] != ':') {
01000                     return NS_ERROR_XSLT_PARSE_FAILURE;
01001                 }
01002                 rv = XMLUtils::splitQName(Substring(name, 0, length-2), 
01003                                           getter_AddRefs(prefix),
01004                                           getter_AddRefs(localName));
01005                 if (NS_FAILED(rv) || prefix) {
01006                     // bad chars or two ':'
01007                     return NS_ERROR_XSLT_PARSE_FAILURE;
01008                 }
01009                 prefix = localName;
01010             }
01011             localName = txXPathAtoms::_asterix;
01012         }
01013         if (prefix) {
01014             ns = aState.mElementContext->mMappings->lookupNamespace(prefix);
01015             NS_ENSURE_TRUE(ns != kNameSpaceID_Unknown, NS_ERROR_FAILURE);
01016         }
01017         nsAutoPtr<txStripSpaceTest> sst(new txStripSpaceTest(prefix, localName,
01018                                                              ns, strip));
01019         NS_ENSURE_TRUE(sst, NS_ERROR_OUT_OF_MEMORY);
01020 
01021         rv = stripItem->addStripSpaceTest(sst);
01022         NS_ENSURE_SUCCESS(rv, rv);
01023         
01024         sst.forget();
01025     }
01026 
01027     rv = aState.addToplevelItem(stripItem);
01028     NS_ENSURE_SUCCESS(rv, rv);
01029 
01030     stripItem.forget();
01031 
01032     return aState.pushHandlerTable(gTxIgnoreHandler);
01033 }
01034 
01035 nsresult
01036 txFnEndStripSpace(txStylesheetCompilerState& aState)
01037 {
01038     aState.popHandlerTable();
01039 
01040     return NS_OK;
01041 }
01042 
01043 // xsl:template
01044 nsresult
01045 txFnStartTemplate(PRInt32 aNamespaceID,
01046                   nsIAtom* aLocalName,
01047                   nsIAtom* aPrefix,
01048                   txStylesheetAttr* aAttributes,
01049                   PRInt32 aAttrCount,
01050                   txStylesheetCompilerState& aState)
01051 {
01052     nsresult rv = NS_OK;
01053     txExpandedName name;
01054     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_FALSE,
01055                       aState, name);
01056     NS_ENSURE_SUCCESS(rv, rv);
01057 
01058     txExpandedName mode;
01059     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::mode, PR_FALSE,
01060                       aState, mode);
01061     NS_ENSURE_SUCCESS(rv, rv);
01062 
01063     double prio = Double::NaN;
01064     rv = getNumberAttr(aAttributes, aAttrCount, txXSLTAtoms::priority,
01065                        PR_FALSE, aState, prio);
01066     NS_ENSURE_SUCCESS(rv, rv);
01067 
01068     nsAutoPtr<txPattern> match;
01069     rv = getPatternAttr(aAttributes, aAttrCount, txXSLTAtoms::match,
01070                         name.isNull(), aState, match);
01071     NS_ENSURE_SUCCESS(rv, rv);
01072 
01073     nsAutoPtr<txTemplateItem> templ(new txTemplateItem(match, name, mode, prio));
01074     NS_ENSURE_TRUE(templ, NS_ERROR_OUT_OF_MEMORY);
01075 
01076     aState.openInstructionContainer(templ);
01077     rv = aState.addToplevelItem(templ);
01078     NS_ENSURE_SUCCESS(rv, rv);
01079     
01080     templ.forget();
01081 
01082     return aState.pushHandlerTable(gTxParamHandler);
01083 }
01084 
01085 nsresult
01086 txFnEndTemplate(txStylesheetCompilerState& aState)
01087 {
01088     aState.popHandlerTable();
01089 
01090     nsAutoPtr<txInstruction> instr(new txReturn());
01091     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01092 
01093     nsresult rv = aState.addInstruction(instr);
01094     NS_ENSURE_SUCCESS(rv, rv);
01095 
01096     aState.closeInstructionContainer();
01097 
01098     return NS_OK;
01099 }
01100 
01101 // xsl:variable, xsl:param
01102 nsresult
01103 txFnStartTopVariable(PRInt32 aNamespaceID,
01104                      nsIAtom* aLocalName,
01105                      nsIAtom* aPrefix,
01106                      txStylesheetAttr* aAttributes,
01107                      PRInt32 aAttrCount,
01108                      txStylesheetCompilerState& aState)
01109 {
01110     nsresult rv = NS_OK;
01111     txExpandedName name;
01112     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
01113                       aState, name);
01114     NS_ENSURE_SUCCESS(rv, rv);
01115 
01116     nsAutoPtr<Expr> select;
01117     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_FALSE,
01118                      aState, select);
01119     NS_ENSURE_SUCCESS(rv, rv);
01120 
01121     nsAutoPtr<txVariableItem> var(
01122         new txVariableItem(name, select, aLocalName == txXSLTAtoms::param));
01123     NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
01124 
01125     aState.openInstructionContainer(var);
01126     rv = aState.pushPtr(var);
01127     NS_ENSURE_SUCCESS(rv, rv);
01128 
01129     if (var->mValue) {
01130         // XXX should be gTxErrorHandler?
01131         rv = aState.pushHandlerTable(gTxIgnoreHandler);
01132         NS_ENSURE_SUCCESS(rv, rv);
01133     }
01134     else {
01135         rv = aState.pushHandlerTable(gTxTopVariableHandler);
01136         NS_ENSURE_SUCCESS(rv, rv);
01137     }
01138 
01139     rv = aState.addToplevelItem(var);
01140     NS_ENSURE_SUCCESS(rv, rv);
01141     
01142     var.forget();
01143 
01144     return NS_OK;
01145 }
01146 
01147 nsresult
01148 txFnEndTopVariable(txStylesheetCompilerState& aState)
01149 {
01150     txHandlerTable* prev = aState.mHandlerTable;
01151     aState.popHandlerTable();
01152     txVariableItem* var = NS_STATIC_CAST(txVariableItem*, aState.popPtr());
01153 
01154     if (prev == gTxTopVariableHandler) {
01155         // No children were found.
01156         NS_ASSERTION(!var->mValue,
01157                      "There shouldn't be a select-expression here");
01158         var->mValue = new txLiteralExpr(EmptyString());
01159         NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY);
01160     }
01161     else if (!var->mValue) {
01162         // If we don't have a select-expression there mush be children.
01163         nsAutoPtr<txInstruction> instr(new txReturn());
01164         NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01165 
01166         nsresult rv = aState.addInstruction(instr);
01167         NS_ENSURE_SUCCESS(rv, rv);
01168     }
01169 
01170     aState.closeInstructionContainer();
01171 
01172     return NS_OK;
01173 }
01174 
01175 nsresult
01176 txFnStartElementStartTopVar(PRInt32 aNamespaceID,
01177                             nsIAtom* aLocalName,
01178                             nsIAtom* aPrefix,
01179                             txStylesheetAttr* aAttributes,
01180                             PRInt32 aAttrCount,
01181                             txStylesheetCompilerState& aState)
01182 {
01183     aState.mHandlerTable = gTxTemplateHandler;
01184 
01185     return NS_XSLT_GET_NEW_HANDLER;
01186 }
01187 
01188 nsresult
01189 txFnTextStartTopVar(const nsAString& aStr, txStylesheetCompilerState& aState)
01190 {
01191     TX_RETURN_IF_WHITESPACE(aStr, aState);
01192 
01193     aState.mHandlerTable = gTxTemplateHandler;
01194 
01195     return NS_XSLT_GET_NEW_HANDLER;
01196 }
01197 
01202 /*
01203   LRE
01204 
01205   txStartLREElement
01206   txInsertAttrSet        one for each qname in xsl:use-attribute-sets
01207   txLREAttribute         one for each attribute
01208   [children]
01209   txEndElement
01210 */
01211 nsresult
01212 txFnStartLRE(PRInt32 aNamespaceID,
01213              nsIAtom* aLocalName,
01214              nsIAtom* aPrefix,
01215              txStylesheetAttr* aAttributes,
01216              PRInt32 aAttrCount,
01217              txStylesheetCompilerState& aState)
01218 {
01219     nsresult rv = NS_OK;
01220 
01221     nsAutoPtr<txInstruction> instr(new txStartLREElement(aNamespaceID,
01222                                                          aLocalName, aPrefix));
01223     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01224 
01225     rv = aState.addInstruction(instr);
01226     NS_ENSURE_SUCCESS(rv, rv);
01227     
01228     rv = parseUseAttrSets(aAttributes, aAttrCount, PR_TRUE, aState);
01229     NS_ENSURE_SUCCESS(rv, rv);
01230 
01231     txStylesheetAttr* attr = nsnull;
01232     PRInt32 i;
01233     for (i = 0; i < aAttrCount; ++i) {
01234         attr = aAttributes + i;
01235         
01236         if (attr->mNamespaceID == kNameSpaceID_XSLT) {
01237             continue;
01238         }
01239         
01240         nsAutoPtr<Expr> avt(
01241               txExprParser::createAttributeValueTemplate(attr->mValue, &aState));
01242         NS_ENSURE_TRUE(avt, NS_ERROR_XPATH_PARSE_FAILURE);
01243 
01244         instr = new txLREAttribute(attr->mNamespaceID, attr->mLocalName,
01245                                    attr->mPrefix, avt);
01246         NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01247         
01248         rv = aState.addInstruction(instr);
01249         NS_ENSURE_SUCCESS(rv, rv);
01250     }
01251 
01252     return NS_OK;
01253 }
01254 
01255 nsresult
01256 txFnEndLRE(txStylesheetCompilerState& aState)
01257 {
01258     nsAutoPtr<txInstruction> instr(new txEndElement);
01259     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01260 
01261     nsresult rv = aState.addInstruction(instr);
01262     NS_ENSURE_SUCCESS(rv, rv);
01263 
01264     return NS_OK;
01265 }
01266 
01267 /*
01268   "LRE text"
01269 
01270   txText
01271 */
01272 nsresult
01273 txFnText(const nsAString& aStr, txStylesheetCompilerState& aState)
01274 {
01275     TX_RETURN_IF_WHITESPACE(aStr, aState);
01276 
01277     nsAutoPtr<txInstruction> instr(new txText(aStr, MB_FALSE));
01278     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01279 
01280     nsresult rv = aState.addInstruction(instr);
01281     NS_ENSURE_SUCCESS(rv, rv);
01282 
01283     return NS_OK;
01284 }
01285 
01286 /*
01287   xsl:apply-imports
01288 
01289   txApplyImportsStart
01290   txApplyImportsEnd
01291 */
01292 nsresult
01293 txFnStartApplyImports(PRInt32 aNamespaceID,
01294                       nsIAtom* aLocalName,
01295                       nsIAtom* aPrefix,
01296                       txStylesheetAttr* aAttributes,
01297                       PRInt32 aAttrCount,
01298                       txStylesheetCompilerState& aState)
01299 {
01300     nsresult rv = NS_OK;
01301 
01302     nsAutoPtr<txInstruction> instr(new txApplyImportsStart);
01303     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01304 
01305     rv = aState.addInstruction(instr);
01306     NS_ENSURE_SUCCESS(rv, rv);
01307 
01308     instr = new txApplyImportsEnd;
01309     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01310 
01311     rv = aState.addInstruction(instr);
01312     NS_ENSURE_SUCCESS(rv, rv);
01313 
01314     return aState.pushHandlerTable(gTxIgnoreHandler);
01315 }
01316 
01317 nsresult
01318 txFnEndApplyImports(txStylesheetCompilerState& aState)
01319 {
01320     aState.popHandlerTable();
01321 
01322     return NS_OK;
01323 }
01324 
01325 /*
01326   xsl:apply-templates
01327 
01328   txPushParams
01329   [params]
01330   txPushNewContext    -+   (holds <xsl:sort>s)
01331   txApplyTemplate <-+  |
01332   txLoopNodeSet    -+  |
01333   txPopParams        <-+
01334 */
01335 nsresult
01336 txFnStartApplyTemplates(PRInt32 aNamespaceID,
01337                         nsIAtom* aLocalName,
01338                         nsIAtom* aPrefix,
01339                         txStylesheetAttr* aAttributes,
01340                         PRInt32 aAttrCount,
01341                         txStylesheetCompilerState& aState)
01342 {
01343     nsresult rv = NS_OK;
01344 
01345     nsAutoPtr<txInstruction> instr(new txPushParams);
01346     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01347 
01348     rv = aState.addInstruction(instr);
01349     NS_ENSURE_SUCCESS(rv, rv);
01350 
01351     txExpandedName mode;
01352     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::mode, PR_FALSE,
01353                       aState, mode);
01354     NS_ENSURE_SUCCESS(rv, rv);
01355 
01356     instr = new txApplyTemplates(mode);
01357     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01358 
01359     rv = aState.pushObject(instr);
01360     NS_ENSURE_SUCCESS(rv, rv);
01361 
01362     instr.forget();
01363 
01364     nsAutoPtr<Expr> select;
01365     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_FALSE,
01366                      aState, select);
01367     NS_ENSURE_SUCCESS(rv, rv);
01368 
01369     if (!select) {
01370         nsAutoPtr<txNodeTest> nt(
01371             new txNodeTypeTest(txNodeTypeTest::NODE_TYPE));
01372         NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);
01373 
01374         select = new LocationStep(nt, LocationStep::CHILD_AXIS);
01375         NS_ENSURE_TRUE(select, NS_ERROR_OUT_OF_MEMORY);
01376     }
01377 
01378     nsAutoPtr<txPushNewContext> pushcontext(new txPushNewContext(select));
01379     NS_ENSURE_TRUE(pushcontext, NS_ERROR_OUT_OF_MEMORY);
01380 
01381     rv = aState.pushSorter(pushcontext);
01382     NS_ENSURE_SUCCESS(rv, rv);
01383 
01384     rv = aState.pushObject(pushcontext);
01385     NS_ENSURE_SUCCESS(rv, rv);
01386     
01387     pushcontext.forget();
01388 
01389     return aState.pushHandlerTable(gTxApplyTemplatesHandler);
01390 }
01391 
01392 nsresult
01393 txFnEndApplyTemplates(txStylesheetCompilerState& aState)
01394 {
01395     aState.popHandlerTable();
01396 
01397     txPushNewContext* pushcontext =
01398         NS_STATIC_CAST(txPushNewContext*, aState.popObject());
01399     nsAutoPtr<txInstruction> instr(pushcontext); // txPushNewContext
01400     nsresult rv = aState.addInstruction(instr);
01401     NS_ENSURE_SUCCESS(rv, rv);
01402 
01403     aState.popSorter();
01404 
01405     instr = NS_STATIC_CAST(txInstruction*, aState.popObject()); // txApplyTemplates
01406     nsAutoPtr<txLoopNodeSet> loop(new txLoopNodeSet(instr));
01407     NS_ENSURE_TRUE(loop, NS_ERROR_OUT_OF_MEMORY);
01408 
01409     rv = aState.addInstruction(instr);
01410     NS_ENSURE_SUCCESS(rv, rv);
01411 
01412     instr = loop.forget();
01413     rv = aState.addInstruction(instr);
01414     NS_ENSURE_SUCCESS(rv, rv);
01415 
01416     instr = new txPopParams;
01417     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01418     
01419     pushcontext->mBailTarget = instr;
01420     rv = aState.addInstruction(instr);
01421     NS_ENSURE_SUCCESS(rv, rv);
01422 
01423     return NS_OK;
01424 }
01425 
01426 /*
01427   xsl:attribute
01428 
01429   txPushStringHandler
01430   [children]
01431   txAttribute
01432 */
01433 nsresult
01434 txFnStartAttribute(PRInt32 aNamespaceID,
01435                    nsIAtom* aLocalName,
01436                    nsIAtom* aPrefix,
01437                    txStylesheetAttr* aAttributes,
01438                    PRInt32 aAttrCount,
01439                    txStylesheetCompilerState& aState)
01440 {
01441     nsresult rv = NS_OK;
01442 
01443     nsAutoPtr<txInstruction> instr(new txPushStringHandler(PR_TRUE));
01444     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01445 
01446     rv = aState.addInstruction(instr);
01447     NS_ENSURE_SUCCESS(rv, rv);
01448 
01449     nsAutoPtr<Expr> name;
01450     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
01451                     aState, name);
01452     NS_ENSURE_SUCCESS(rv, rv);
01453 
01454     nsAutoPtr<Expr> nspace;
01455     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::_namespace, PR_FALSE,
01456                     aState, nspace);
01457     NS_ENSURE_SUCCESS(rv, rv);
01458 
01459     instr = new txAttribute(name, nspace, aState.mElementContext->mMappings);
01460     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01461 
01462     rv = aState.pushObject(instr);
01463     NS_ENSURE_SUCCESS(rv, rv);
01464 
01465     instr.forget();
01466 
01467     // We need to push the template-handler since the current might be
01468     // the attributeset-handler
01469     return aState.pushHandlerTable(gTxTemplateHandler);
01470 }
01471 
01472 nsresult
01473 txFnEndAttribute(txStylesheetCompilerState& aState)
01474 {
01475     aState.popHandlerTable();
01476     nsAutoPtr<txInstruction> instr(NS_STATIC_CAST(txInstruction*,
01477                                                   aState.popObject()));
01478     nsresult rv = aState.addInstruction(instr);
01479     NS_ENSURE_SUCCESS(rv, rv);
01480 
01481     return NS_OK;
01482 }
01483 
01484 /*
01485   xsl:call-template
01486 
01487   txPushParams
01488   [params]
01489   txCallTemplate
01490   txPopParams
01491 */
01492 nsresult
01493 txFnStartCallTemplate(PRInt32 aNamespaceID,
01494                       nsIAtom* aLocalName,
01495                       nsIAtom* aPrefix,
01496                       txStylesheetAttr* aAttributes,
01497                       PRInt32 aAttrCount,
01498                       txStylesheetCompilerState& aState)
01499 {
01500     nsresult rv = NS_OK;
01501 
01502     nsAutoPtr<txInstruction> instr(new txPushParams);
01503     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01504 
01505     rv = aState.addInstruction(instr);
01506     NS_ENSURE_SUCCESS(rv, rv);
01507 
01508     txExpandedName name;
01509     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
01510                       aState, name);
01511     NS_ENSURE_SUCCESS(rv, rv);
01512 
01513     instr = new txCallTemplate(name);
01514     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01515 
01516     rv = aState.pushObject(instr);
01517     NS_ENSURE_SUCCESS(rv, rv);
01518     
01519     instr.forget();
01520 
01521     return aState.pushHandlerTable(gTxCallTemplateHandler);
01522 }
01523 
01524 nsresult
01525 txFnEndCallTemplate(txStylesheetCompilerState& aState)
01526 {
01527     aState.popHandlerTable();
01528 
01529     // txCallTemplate
01530     nsAutoPtr<txInstruction> instr(NS_STATIC_CAST(txInstruction*, 
01531                                                   aState.popObject()));
01532     nsresult rv = aState.addInstruction(instr);
01533     NS_ENSURE_SUCCESS(rv, rv);
01534 
01535     instr = new txPopParams;
01536     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01537 
01538     rv = aState.addInstruction(instr);
01539     NS_ENSURE_SUCCESS(rv, rv);
01540 
01541     return NS_OK;
01542 }
01543 
01544 /*
01545   xsl:choose
01546 
01547   txCondotionalGoto      --+        \
01548   [children]               |         | one for each xsl:when
01549   txGoTo           --+     |        /
01550                      |     |
01551   txCondotionalGoto  |   <-+  --+
01552   [children]         |          |
01553   txGoTo           --+          |
01554                      |          |
01555   [children]         |        <-+      for the xsl:otherwise, if there is one
01556                    <-+
01557 */
01558 nsresult
01559 txFnStartChoose(PRInt32 aNamespaceID,
01560                  nsIAtom* aLocalName,
01561                  nsIAtom* aPrefix,
01562                  txStylesheetAttr* aAttributes,
01563                  PRInt32 aAttrCount,
01564                  txStylesheetCompilerState& aState)
01565 {
01566     nsresult rv = aState.pushChooseGotoList();
01567     NS_ENSURE_SUCCESS(rv, rv);
01568     
01569     return aState.pushHandlerTable(gTxChooseHandler);
01570 }
01571 
01572 nsresult
01573 txFnEndChoose(txStylesheetCompilerState& aState)
01574 {
01575     nsresult rv = NS_OK;
01576     aState.popHandlerTable();
01577     txListIterator iter(aState.mChooseGotoList);
01578     txGoTo* gotoinstr;
01579     while ((gotoinstr = NS_STATIC_CAST(txGoTo*, iter.next()))) {
01580         rv = aState.addGotoTarget(&gotoinstr->mTarget);
01581         NS_ENSURE_SUCCESS(rv, rv);
01582     }
01583 
01584     aState.popChooseGotoList();
01585 
01586     return NS_OK;
01587 }
01588 
01589 /*
01590   xsl:comment
01591 
01592   txPushStringHandler
01593   [children]
01594   txComment
01595 */
01596 nsresult
01597 txFnStartComment(PRInt32 aNamespaceID,
01598                  nsIAtom* aLocalName,
01599                  nsIAtom* aPrefix,
01600                  txStylesheetAttr* aAttributes,
01601                  PRInt32 aAttrCount,
01602                  txStylesheetCompilerState& aState)
01603 {
01604     nsAutoPtr<txInstruction> instr(new txPushStringHandler(PR_TRUE));
01605     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01606 
01607     nsresult rv = aState.addInstruction(instr);
01608     NS_ENSURE_SUCCESS(rv, rv);
01609 
01610     return NS_OK;
01611 }
01612 
01613 nsresult
01614 txFnEndComment(txStylesheetCompilerState& aState)
01615 {
01616     nsAutoPtr<txInstruction> instr(new txComment);
01617     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01618 
01619     nsresult rv = aState.addInstruction(instr);
01620     NS_ENSURE_SUCCESS(rv, rv);
01621 
01622     return NS_OK;
01623 }
01624 
01625 /*
01626   xsl:copy
01627 
01628   txCopy          -+
01629   txInsertAttrSet  |     one for each qname in use-attribute-sets
01630   [children]       |
01631   txEndElement     |
01632                  <-+
01633 */
01634 nsresult
01635 txFnStartCopy(PRInt32 aNamespaceID,
01636               nsIAtom* aLocalName,
01637               nsIAtom* aPrefix,
01638               txStylesheetAttr* aAttributes,
01639               PRInt32 aAttrCount,
01640               txStylesheetCompilerState& aState)
01641 {
01642     nsAutoPtr<txCopy> copy(new txCopy);
01643     NS_ENSURE_TRUE(copy, NS_ERROR_OUT_OF_MEMORY);
01644 
01645     nsresult rv = aState.pushPtr(copy);
01646     NS_ENSURE_SUCCESS(rv, rv);
01647 
01648     nsAutoPtr<txInstruction> instr(copy.forget());
01649     rv = aState.addInstruction(instr);
01650     NS_ENSURE_SUCCESS(rv, rv);
01651 
01652     rv = parseUseAttrSets(aAttributes, aAttrCount, PR_FALSE, aState);
01653     NS_ENSURE_SUCCESS(rv, rv);
01654 
01655     return NS_OK;
01656 }
01657 
01658 nsresult
01659 txFnEndCopy(txStylesheetCompilerState& aState)
01660 {
01661     nsAutoPtr<txInstruction> instr(new txEndElement);
01662     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01663 
01664     nsresult rv = aState.addInstruction(instr);
01665     NS_ENSURE_SUCCESS(rv, rv);
01666 
01667     txCopy* copy = NS_STATIC_CAST(txCopy*, aState.popPtr());
01668     rv = aState.addGotoTarget(&copy->mBailTarget);
01669     NS_ENSURE_SUCCESS(rv, rv);
01670 
01671     return NS_OK;
01672 }
01673 
01674 /*
01675   xsl:copy-of
01676 
01677   txCopyOf
01678 */
01679 nsresult
01680 txFnStartCopyOf(PRInt32 aNamespaceID,
01681                 nsIAtom* aLocalName,
01682                 nsIAtom* aPrefix,
01683                 txStylesheetAttr* aAttributes,
01684                 PRInt32 aAttrCount,
01685                 txStylesheetCompilerState& aState)
01686 {
01687     nsresult rv = NS_OK;
01688 
01689     nsAutoPtr<Expr> select;
01690     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_TRUE,
01691                     aState, select);
01692     NS_ENSURE_SUCCESS(rv, rv);
01693 
01694     nsAutoPtr<txInstruction> instr(new txCopyOf(select));
01695     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01696     
01697     rv = aState.addInstruction(instr);
01698     NS_ENSURE_SUCCESS(rv, rv);
01699 
01700     return aState.pushHandlerTable(gTxIgnoreHandler);
01701 }
01702 
01703 nsresult
01704 txFnEndCopyOf(txStylesheetCompilerState& aState)
01705 {
01706     aState.popHandlerTable();
01707     return NS_OK;
01708 }
01709 
01710 /*
01711   xsl:element
01712 
01713   txStartElement
01714   txInsertAttrSet        one for each qname in use-attribute-sets
01715   [children]
01716   txEndElement
01717 */
01718 nsresult
01719 txFnStartElement(PRInt32 aNamespaceID,
01720                  nsIAtom* aLocalName,
01721                  nsIAtom* aPrefix,
01722                  txStylesheetAttr* aAttributes,
01723                  PRInt32 aAttrCount,
01724                  txStylesheetCompilerState& aState)
01725 {
01726     nsresult rv = NS_OK;
01727 
01728     nsAutoPtr<Expr> name;
01729     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
01730                     aState, name);
01731     NS_ENSURE_SUCCESS(rv, rv);
01732 
01733     nsAutoPtr<Expr> nspace;
01734     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::_namespace, PR_FALSE,
01735                     aState, nspace);
01736     NS_ENSURE_SUCCESS(rv, rv);
01737 
01738     nsAutoPtr<txInstruction> instr(
01739         new txStartElement(name, nspace, aState.mElementContext->mMappings));
01740     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01741 
01742     rv = aState.addInstruction(instr);
01743     NS_ENSURE_SUCCESS(rv, rv);
01744 
01745     rv = parseUseAttrSets(aAttributes, aAttrCount, PR_FALSE, aState);
01746     NS_ENSURE_SUCCESS(rv, rv);
01747 
01748     return NS_OK;
01749 }
01750 
01751 nsresult
01752 txFnEndElement(txStylesheetCompilerState& aState)
01753 {
01754     nsAutoPtr<txInstruction> instr(new txEndElement);
01755     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01756 
01757     nsresult rv = aState.addInstruction(instr);
01758     NS_ENSURE_SUCCESS(rv, rv);
01759 
01760     return NS_OK;
01761 }
01762 
01763 /*
01764     xsl:fallback
01765 
01766     [children]
01767 */
01768 nsresult
01769 txFnStartFallback(PRInt32 aNamespaceID,
01770                   nsIAtom* aLocalName,
01771                   nsIAtom* aPrefix,
01772                   txStylesheetAttr* aAttributes,
01773                   PRInt32 aAttrCount,
01774                   txStylesheetCompilerState& aState)
01775 {
01776     aState.mSearchingForFallback = PR_FALSE;
01777 
01778     return aState.pushHandlerTable(gTxTemplateHandler);
01779 }
01780 
01781 nsresult
01782 txFnEndFallback(txStylesheetCompilerState& aState)
01783 {
01784     aState.popHandlerTable();
01785 
01786     NS_ASSERTION(!aState.mSearchingForFallback,
01787                  "bad nesting of unknown-instruction and fallback handlers");
01788     return NS_OK;
01789 }
01790 
01791 /*
01792   xsl:for-each
01793 
01794   txPushNewContext            -+    (holds <xsl:sort>s)
01795   txPushNullTemplateRule  <-+  |
01796   [children]                |  |
01797   txLoopNodeSet            -+  |
01798                              <-+
01799 */
01800 nsresult
01801 txFnStartForEach(PRInt32 aNamespaceID,
01802                  nsIAtom* aLocalName,
01803                  nsIAtom* aPrefix,
01804                  txStylesheetAttr* aAttributes,
01805                  PRInt32 aAttrCount,
01806                  txStylesheetCompilerState& aState)
01807 {
01808     nsresult rv = NS_OK;
01809 
01810     nsAutoPtr<Expr> select;
01811     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_TRUE,
01812                      aState, select);
01813     NS_ENSURE_SUCCESS(rv, rv);
01814 
01815     nsAutoPtr<txPushNewContext> pushcontext(new txPushNewContext(select));
01816     NS_ENSURE_TRUE(pushcontext, NS_ERROR_OUT_OF_MEMORY);
01817 
01818     rv = aState.pushPtr(pushcontext);
01819     NS_ENSURE_SUCCESS(rv, rv);
01820 
01821     rv = aState.pushSorter(pushcontext);
01822     NS_ENSURE_SUCCESS(rv, rv);
01823 
01824     nsAutoPtr<txInstruction> instr(pushcontext.forget());
01825     rv = aState.addInstruction(instr);
01826     NS_ENSURE_SUCCESS(rv, rv);
01827     
01828     instr = new txPushNullTemplateRule;
01829     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01830 
01831     rv = aState.pushPtr(instr);
01832     NS_ENSURE_SUCCESS(rv, rv);
01833 
01834     rv = aState.addInstruction(instr);
01835     NS_ENSURE_SUCCESS(rv, rv);
01836 
01837     return aState.pushHandlerTable(gTxForEachHandler);
01838 }
01839 
01840 nsresult
01841 txFnEndForEach(txStylesheetCompilerState& aState)
01842 {
01843     aState.popHandlerTable();
01844 
01845     // This is a txPushNullTemplateRule
01846     txInstruction* pnullrule =
01847         NS_STATIC_CAST(txInstruction*, aState.popPtr());
01848 
01849     nsAutoPtr<txInstruction> instr(new txLoopNodeSet(pnullrule));
01850     nsresult rv = aState.addInstruction(instr);
01851     NS_ENSURE_SUCCESS(rv, rv);
01852 
01853     aState.popSorter();
01854     txPushNewContext* pushcontext =
01855         NS_STATIC_CAST(txPushNewContext*, aState.popPtr());
01856     aState.addGotoTarget(&pushcontext->mBailTarget);
01857 
01858     return NS_OK;
01859 }
01860 
01861 nsresult
01862 txFnStartElementContinueTemplate(PRInt32 aNamespaceID,
01863                                 nsIAtom* aLocalName,
01864                                 nsIAtom* aPrefix,
01865                                 txStylesheetAttr* aAttributes,
01866                                 PRInt32 aAttrCount,
01867                                 txStylesheetCompilerState& aState)
01868 {
01869     aState.mHandlerTable = gTxTemplateHandler;
01870 
01871     return NS_XSLT_GET_NEW_HANDLER;
01872 }
01873 
01874 nsresult
01875 txFnTextContinueTemplate(const nsAString& aStr,
01876                         txStylesheetCompilerState& aState)
01877 {
01878     TX_RETURN_IF_WHITESPACE(aStr, aState);
01879 
01880     aState.mHandlerTable = gTxTemplateHandler;
01881 
01882     return NS_XSLT_GET_NEW_HANDLER;
01883 }
01884 
01885 /*
01886   xsl:if
01887 
01888   txConditionalGoto  -+
01889   [children]          |
01890                     <-+
01891 */
01892 nsresult
01893 txFnStartIf(PRInt32 aNamespaceID,
01894             nsIAtom* aLocalName,
01895             nsIAtom* aPrefix,
01896             txStylesheetAttr* aAttributes,
01897             PRInt32 aAttrCount,
01898             txStylesheetCompilerState& aState)
01899 {
01900     nsresult rv = NS_OK;
01901 
01902     nsAutoPtr<Expr> test;
01903     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::test, PR_TRUE,
01904                      aState, test);
01905     NS_ENSURE_SUCCESS(rv, rv);
01906 
01907     nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(test, nsnull));
01908     NS_ENSURE_TRUE(condGoto, NS_ERROR_OUT_OF_MEMORY);
01909 
01910     rv = aState.pushPtr(condGoto);
01911     NS_ENSURE_SUCCESS(rv, rv);
01912 
01913     nsAutoPtr<txInstruction> instr(condGoto.forget());
01914     rv = aState.addInstruction(instr);
01915     NS_ENSURE_SUCCESS(rv, rv);
01916 
01917     return NS_OK;
01918 }
01919 
01920 nsresult
01921 txFnEndIf(txStylesheetCompilerState& aState)
01922 {
01923     txConditionalGoto* condGoto =
01924         NS_STATIC_CAST(txConditionalGoto*, aState.popPtr());
01925     return aState.addGotoTarget(&condGoto->mTarget);
01926 }
01927 
01928 /*
01929   xsl:message
01930 
01931   txPushStringHandler
01932   [children]
01933   txMessage
01934 */
01935 nsresult
01936 txFnStartMessage(PRInt32 aNamespaceID,
01937                  nsIAtom* aLocalName,
01938                  nsIAtom* aPrefix,
01939                  txStylesheetAttr* aAttributes,
01940                  PRInt32 aAttrCount,
01941                  txStylesheetCompilerState& aState)
01942 {
01943     nsAutoPtr<txInstruction> instr(new txPushStringHandler(PR_FALSE));
01944     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01945 
01946     nsresult rv = aState.addInstruction(instr);
01947     NS_ENSURE_SUCCESS(rv, rv);
01948 
01949     txThreeState term;
01950     rv = getYesNoAttr(aAttributes, aAttrCount, txXSLTAtoms::terminate,
01951                       PR_FALSE, aState, term);
01952     NS_ENSURE_SUCCESS(rv, rv);
01953 
01954     instr = new txMessage(term == eTrue);
01955     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
01956 
01957     rv = aState.pushObject(instr);
01958     NS_ENSURE_SUCCESS(rv, rv);
01959 
01960     instr.forget();
01961 
01962     return NS_OK;
01963 }
01964 
01965 nsresult
01966 txFnEndMessage(txStylesheetCompilerState& aState)
01967 {
01968     nsAutoPtr<txInstruction> instr(NS_STATIC_CAST(txInstruction*, 
01969                                                   aState.popObject()));
01970     nsresult rv = aState.addInstruction(instr);
01971     NS_ENSURE_SUCCESS(rv, rv);
01972 
01973     return NS_OK;
01974 }
01975 
01976 /*
01977   xsl:number
01978 
01979   txNumber
01980 */
01981 nsresult
01982 txFnStartNumber(PRInt32 aNamespaceID,
01983                 nsIAtom* aLocalName,
01984                 nsIAtom* aPrefix,
01985                 txStylesheetAttr* aAttributes,
01986                 PRInt32 aAttrCount,
01987                 txStylesheetCompilerState& aState)
01988 {
01989     nsresult rv = NS_OK;
01990 
01991     nsCOMPtr<nsIAtom> levelAtom;
01992     rv = getAtomAttr(aAttributes, aAttrCount, txXSLTAtoms::level, PR_FALSE,
01993                      aState, getter_AddRefs(levelAtom));
01994     NS_ENSURE_SUCCESS(rv, rv);
01995     
01996     txXSLTNumber::LevelType level = txXSLTNumber::eLevelSingle;
01997     if (levelAtom == txXSLTAtoms::multiple) {
01998         level = txXSLTNumber::eLevelMultiple;
01999     }
02000     else if (levelAtom == txXSLTAtoms::any) {
02001         level = txXSLTNumber::eLevelAny;
02002     }
02003     else if (levelAtom && levelAtom != txXSLTAtoms::single && !aState.fcp()) {
02004         return NS_ERROR_XSLT_PARSE_FAILURE;
02005     }
02006     
02007     nsAutoPtr<txPattern> count;
02008     rv = getPatternAttr(aAttributes, aAttrCount, txXSLTAtoms::count, PR_FALSE,
02009                         aState, count);
02010     NS_ENSURE_SUCCESS(rv, rv);
02011     
02012     nsAutoPtr<txPattern> from;
02013     rv = getPatternAttr(aAttributes, aAttrCount, txXSLTAtoms::from, PR_FALSE,
02014                         aState, from);
02015     NS_ENSURE_SUCCESS(rv, rv);
02016 
02017     nsAutoPtr<Expr> value;
02018     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::value, PR_FALSE,
02019                      aState, value);
02020     NS_ENSURE_SUCCESS(rv, rv);
02021 
02022     nsAutoPtr<Expr> format;
02023     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::format, PR_FALSE,
02024                     aState, format);
02025     NS_ENSURE_SUCCESS(rv, rv);
02026     
02027     nsAutoPtr<Expr> groupingSeparator;
02028     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::groupingSeparator,
02029                     PR_FALSE, aState, groupingSeparator);
02030     NS_ENSURE_SUCCESS(rv, rv);
02031     
02032     nsAutoPtr<Expr> groupingSize;
02033     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::groupingSize,
02034                     PR_FALSE, aState, groupingSize);
02035     NS_ENSURE_SUCCESS(rv, rv);
02036     
02037     nsAutoPtr<txInstruction> instr(new txNumber(level, count, from, value,
02038                                                 format,groupingSeparator,
02039                                                 groupingSize));
02040     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
02041     
02042     rv = aState.addInstruction(instr);
02043     NS_ENSURE_SUCCESS(rv, rv);
02044 
02045     return aState.pushHandlerTable(gTxIgnoreHandler);
02046 }
02047 
02048 nsresult
02049 txFnEndNumber(txStylesheetCompilerState& aState)
02050 {
02051     aState.popHandlerTable();
02052 
02053     return NS_OK;
02054 }
02055 
02056 /*
02057     xsl:otherwise
02058     
02059     (see xsl:choose)
02060 */
02061 nsresult
02062 txFnStartOtherwise(PRInt32 aNamespaceID,
02063                    nsIAtom* aLocalName,
02064                    nsIAtom* aPrefix,
02065                    txStylesheetAttr* aAttributes,
02066                    PRInt32 aAttrCount,
02067                    txStylesheetCompilerState& aState)
02068 {
02069     return aState.pushHandlerTable(gTxTemplateHandler);
02070 }
02071 
02072 nsresult
02073 txFnEndOtherwise(txStylesheetCompilerState& aState)
02074 {
02075     aState.popHandlerTable();
02076     aState.mHandlerTable = gTxIgnoreHandler; // XXX should be gTxErrorHandler
02077 
02078     return NS_OK;
02079 }
02080 
02081 /*
02082     xsl:param
02083     
02084     txCheckParam    --+
02085     txPushRTFHandler  |  --- (for RTF-parameters)
02086     [children]        |  /
02087     txSetVariable     |
02088                     <-+
02089 */
02090 nsresult
02091 txFnStartParam(PRInt32 aNamespaceID,
02092                nsIAtom* aLocalName,
02093                nsIAtom* aPrefix,
02094                txStylesheetAttr* aAttributes,
02095                PRInt32 aAttrCount,
02096                txStylesheetCompilerState& aState)
02097 {
02098     nsresult rv = NS_OK;
02099 
02100     txExpandedName name;
02101     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
02102                       aState, name);
02103     NS_ENSURE_SUCCESS(rv, rv);
02104 
02105     nsAutoPtr<txCheckParam> checkParam(new txCheckParam(name));
02106     NS_ENSURE_SUCCESS(rv, rv);
02107     
02108     rv = aState.pushPtr(checkParam);
02109     NS_ENSURE_SUCCESS(rv, rv);
02110 
02111     nsAutoPtr<txInstruction> instr(checkParam.forget());
02112     rv = aState.addInstruction(instr);
02113     NS_ENSURE_SUCCESS(rv, rv);
02114 
02115     nsAutoPtr<Expr> select;
02116     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_FALSE,
02117                      aState, select);
02118     NS_ENSURE_SUCCESS(rv, rv);
02119 
02120     nsAutoPtr<txSetVariable> var(new txSetVariable(name, select));
02121     NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
02122 
02123     if (var->mValue) {
02124         // XXX should be gTxErrorHandler?
02125         rv = aState.pushHandlerTable(gTxIgnoreHandler);
02126         NS_ENSURE_SUCCESS(rv, rv);
02127     }
02128     else {
02129         rv = aState.pushHandlerTable(gTxVariableHandler);
02130         NS_ENSURE_SUCCESS(rv, rv);
02131     }
02132 
02133     rv = aState.pushObject(var);
02134     NS_ENSURE_SUCCESS(rv, rv);
02135     
02136     var.forget();
02137 
02138     return NS_OK;
02139 }
02140 
02141 nsresult
02142 txFnEndParam(txStylesheetCompilerState& aState)
02143 {
02144     nsAutoPtr<txSetVariable> var(NS_STATIC_CAST(txSetVariable*,
02145                                                 aState.popObject()));
02146     txHandlerTable* prev = aState.mHandlerTable;
02147     aState.popHandlerTable();
02148 
02149     if (prev == gTxVariableHandler) {
02150         // No children were found.
02151         NS_ASSERTION(!var->mValue,
02152                      "There shouldn't be a select-expression here");
02153         var->mValue = new txLiteralExpr(EmptyString());
02154         NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY);
02155     }
02156 
02157     nsresult rv = aState.addVariable(var->mName);
02158     NS_ENSURE_SUCCESS(rv, rv);
02159 
02160     nsAutoPtr<txInstruction> instr(var.forget());
02161     rv = aState.addInstruction(instr);
02162     NS_ENSURE_SUCCESS(rv, rv);
02163 
02164     txCheckParam* checkParam = NS_STATIC_CAST(txCheckParam*, aState.popPtr());
02165     aState.addGotoTarget(&checkParam->mBailTarget);
02166 
02167     return NS_OK;
02168 }
02169 
02170 /*
02171   xsl:processing-instruction
02172 
02173   txPushStringHandler
02174   [children]
02175   txProcessingInstruction
02176 */
02177 nsresult
02178 txFnStartPI(PRInt32 aNamespaceID,
02179             nsIAtom* aLocalName,
02180             nsIAtom* aPrefix,
02181             txStylesheetAttr* aAttributes,
02182             PRInt32 aAttrCount,
02183             txStylesheetCompilerState& aState)
02184 {
02185     nsAutoPtr<txInstruction> instr(new txPushStringHandler(PR_TRUE));
02186     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
02187 
02188     nsresult rv = aState.addInstruction(instr);
02189     NS_ENSURE_SUCCESS(rv, rv);
02190 
02191     nsAutoPtr<Expr> name;
02192     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
02193                     aState, name);
02194     NS_ENSURE_SUCCESS(rv, rv);
02195 
02196     instr = new txProcessingInstruction(name);
02197     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
02198 
02199     rv = aState.pushObject(instr);
02200     NS_ENSURE_SUCCESS(rv, rv);
02201 
02202     instr.forget();
02203 
02204     return NS_OK;
02205 }
02206 
02207 nsresult
02208 txFnEndPI(txStylesheetCompilerState& aState)
02209 {
02210     nsAutoPtr<txInstruction> instr(NS_STATIC_CAST(txInstruction*,
02211                                                   aState.popObject()));
02212     nsresult rv = aState.addInstruction(instr);
02213     NS_ENSURE_SUCCESS(rv, rv);
02214 
02215     return NS_OK;
02216 }
02217 
02218 /*
02219     xsl:sort
02220     
02221     (no instructions)
02222 */
02223 nsresult
02224 txFnStartSort(PRInt32 aNamespaceID,
02225               nsIAtom* aLocalName,
02226               nsIAtom* aPrefix,
02227               txStylesheetAttr* aAttributes,
02228               PRInt32 aAttrCount,
02229               txStylesheetCompilerState& aState)
02230 {
02231     nsresult rv = NS_OK;
02232 
02233     nsAutoPtr<Expr> select;
02234     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_FALSE,
02235                      aState, select);
02236     NS_ENSURE_SUCCESS(rv, rv);
02237 
02238     if (!select) {
02239         nsAutoPtr<txNodeTest> nt(
02240               new txNodeTypeTest(txNodeTypeTest::NODE_TYPE));
02241         NS_ENSURE_TRUE(nt, NS_ERROR_OUT_OF_MEMORY);
02242 
02243         select = new LocationStep(nt, LocationStep::SELF_AXIS);
02244         NS_ENSURE_TRUE(select, NS_ERROR_OUT_OF_MEMORY);
02245     }
02246 
02247     nsAutoPtr<Expr> lang;
02248     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::lang, PR_FALSE,
02249                     aState, lang);
02250     NS_ENSURE_SUCCESS(rv, rv);
02251 
02252     nsAutoPtr<Expr> dataType;
02253     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::dataType, PR_FALSE,
02254                     aState, dataType);
02255     NS_ENSURE_SUCCESS(rv, rv);
02256 
02257     nsAutoPtr<Expr> order;
02258     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::order, PR_FALSE,
02259                     aState, order);
02260     NS_ENSURE_SUCCESS(rv, rv);
02261 
02262     nsAutoPtr<Expr> caseOrder;
02263     rv = getAVTAttr(aAttributes, aAttrCount, txXSLTAtoms::caseOrder, PR_FALSE,
02264                     aState, caseOrder);
02265     NS_ENSURE_SUCCESS(rv, rv);
02266 
02267     rv = aState.mSorter->addSort(select, lang, dataType, order, caseOrder);
02268     NS_ENSURE_SUCCESS(rv, rv);
02269 
02270     return aState.pushHandlerTable(gTxIgnoreHandler);
02271 }
02272 
02273 nsresult
02274 txFnEndSort(txStylesheetCompilerState& aState)
02275 {
02276     aState.popHandlerTable();
02277 
02278     return NS_OK;
02279 }
02280 
02281 /*
02282   xsl:text
02283 
02284   [children]     (only txText)
02285 */
02286 nsresult
02287 txFnStartText(PRInt32 aNamespaceID,
02288               nsIAtom* aLocalName,
02289               nsIAtom* aPrefix,
02290               txStylesheetAttr* aAttributes,
02291               PRInt32 aAttrCount,
02292               txStylesheetCompilerState& aState)
02293 {
02294     NS_ASSERTION(!aState.mDOE, "nested d-o-e elements should not happen");
02295 
02296     nsresult rv = NS_OK;
02297     txThreeState doe;
02298     rv = getYesNoAttr(aAttributes, aAttrCount,
02299                       txXSLTAtoms::disableOutputEscaping, PR_FALSE, aState,
02300                       doe);
02301     NS_ENSURE_SUCCESS(rv, rv);
02302 
02303     aState.mDOE = doe == eTrue;
02304 
02305     return aState.pushHandlerTable(gTxTextHandler);
02306 }
02307 
02308 nsresult
02309 txFnEndText(txStylesheetCompilerState& aState)
02310 {
02311     aState.mDOE = MB_FALSE;
02312     aState.popHandlerTable();
02313     return NS_OK;
02314 }
02315 
02316 nsresult
02317 txFnTextText(const nsAString& aStr, txStylesheetCompilerState& aState)
02318 {
02319     nsAutoPtr<txInstruction> instr(new txText(aStr, aState.mDOE));
02320     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
02321 
02322     nsresult rv = aState.addInstruction(instr);
02323     NS_ENSURE_SUCCESS(rv, rv);
02324 
02325     return NS_OK;
02326 }
02327 
02328 /*
02329   xsl:value-of
02330 
02331   txValueOf
02332 */
02333 nsresult
02334 txFnStartValueOf(PRInt32 aNamespaceID,
02335                  nsIAtom* aLocalName,
02336                  nsIAtom* aPrefix,
02337                  txStylesheetAttr* aAttributes,
02338                  PRInt32 aAttrCount,
02339                  txStylesheetCompilerState& aState)
02340 {
02341     nsresult rv = NS_OK;
02342 
02343     txThreeState doe;
02344     rv = getYesNoAttr(aAttributes, aAttrCount,
02345                      txXSLTAtoms::disableOutputEscaping, PR_FALSE, aState,
02346                      doe);
02347     NS_ENSURE_SUCCESS(rv, rv);
02348 
02349     nsAutoPtr<Expr> select;
02350     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_TRUE,
02351                      aState, select);
02352     NS_ENSURE_SUCCESS(rv, rv);
02353 
02354     nsAutoPtr<txInstruction> instr(new txValueOf(select, doe == eTrue));
02355     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
02356 
02357     rv = aState.addInstruction(instr);
02358     NS_ENSURE_SUCCESS(rv, rv);
02359 
02360     return aState.pushHandlerTable(gTxIgnoreHandler);
02361 }
02362 
02363 nsresult
02364 txFnEndValueOf(txStylesheetCompilerState& aState)
02365 {
02366     aState.popHandlerTable();
02367     return NS_OK;
02368 }
02369 
02370 /*
02371     xsl:variable
02372     
02373     txPushRTFHandler     --- (for RTF-parameters)
02374     [children]           /
02375     txSetVariable      
02376 */
02377 nsresult
02378 txFnStartVariable(PRInt32 aNamespaceID,
02379                   nsIAtom* aLocalName,
02380                   nsIAtom* aPrefix,
02381                   txStylesheetAttr* aAttributes,
02382                   PRInt32 aAttrCount,
02383                   txStylesheetCompilerState& aState)
02384 {
02385     nsresult rv = NS_OK;
02386 
02387     txExpandedName name;
02388     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
02389                       aState, name);
02390     NS_ENSURE_SUCCESS(rv, rv);
02391 
02392     nsAutoPtr<Expr> select;
02393     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_FALSE,
02394                      aState, select);
02395     NS_ENSURE_SUCCESS(rv, rv);
02396 
02397     nsAutoPtr<txSetVariable> var(new txSetVariable(name, select));
02398     NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
02399 
02400     if (var->mValue) {
02401         // XXX should be gTxErrorHandler?
02402         rv = aState.pushHandlerTable(gTxIgnoreHandler);
02403         NS_ENSURE_SUCCESS(rv, rv);
02404     }
02405     else {
02406         rv = aState.pushHandlerTable(gTxVariableHandler);
02407         NS_ENSURE_SUCCESS(rv, rv);
02408     }
02409 
02410     rv = aState.pushObject(var);
02411     NS_ENSURE_SUCCESS(rv, rv);
02412 
02413     var.forget();
02414 
02415     return NS_OK;
02416 }
02417 
02418 nsresult
02419 txFnEndVariable(txStylesheetCompilerState& aState)
02420 {
02421     nsAutoPtr<txSetVariable> var(NS_STATIC_CAST(txSetVariable*,
02422                                                 aState.popObject()));
02423 
02424     txHandlerTable* prev = aState.mHandlerTable;
02425     aState.popHandlerTable();
02426 
02427     if (prev == gTxVariableHandler) {
02428         // No children were found.
02429         NS_ASSERTION(!var->mValue,
02430                      "There shouldn't be a select-expression here");
02431         var->mValue = new txLiteralExpr(EmptyString());
02432         NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY);
02433     }
02434 
02435     nsresult rv = aState.addVariable(var->mName);
02436     NS_ENSURE_SUCCESS(rv, rv);
02437 
02438     nsAutoPtr<txInstruction> instr(var.forget());
02439     rv = aState.addInstruction(instr);
02440     NS_ENSURE_SUCCESS(rv, rv);
02441 
02442     return NS_OK;
02443 }
02444 
02445 nsresult
02446 txFnStartElementStartRTF(PRInt32 aNamespaceID,
02447                          nsIAtom* aLocalName,
02448                          nsIAtom* aPrefix,
02449                          txStylesheetAttr* aAttributes,
02450                          PRInt32 aAttrCount,
02451                          txStylesheetCompilerState& aState)
02452 {
02453     nsAutoPtr<txInstruction> instr(new txPushRTFHandler);
02454     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
02455 
02456     nsresult rv = aState.addInstruction(instr);
02457     NS_ENSURE_SUCCESS(rv, rv);
02458 
02459     aState.mHandlerTable = gTxTemplateHandler;
02460 
02461     return NS_XSLT_GET_NEW_HANDLER;
02462 }
02463 
02464 nsresult
02465 txFnTextStartRTF(const nsAString& aStr, txStylesheetCompilerState& aState)
02466 {
02467     TX_RETURN_IF_WHITESPACE(aStr, aState);
02468 
02469     nsAutoPtr<txInstruction> instr(new txPushRTFHandler);
02470     NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
02471 
02472     nsresult rv = aState.addInstruction(instr);
02473     NS_ENSURE_SUCCESS(rv, rv);
02474 
02475     aState.mHandlerTable = gTxTemplateHandler;
02476 
02477     return NS_XSLT_GET_NEW_HANDLER;
02478 }
02479 
02480 /*
02481     xsl:when
02482     
02483     (see xsl:choose)
02484 */
02485 nsresult
02486 txFnStartWhen(PRInt32 aNamespaceID,
02487               nsIAtom* aLocalName,
02488               nsIAtom* aPrefix,
02489               txStylesheetAttr* aAttributes,
02490               PRInt32 aAttrCount,
02491               txStylesheetCompilerState& aState)
02492 {
02493     nsresult rv = NS_OK;
02494 
02495     nsAutoPtr<Expr> test;
02496     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::test, PR_TRUE,
02497                      aState, test);
02498     NS_ENSURE_SUCCESS(rv, rv);
02499 
02500     nsAutoPtr<txConditionalGoto> condGoto(new txConditionalGoto(test, nsnull));
02501     NS_ENSURE_TRUE(condGoto, NS_ERROR_OUT_OF_MEMORY);
02502 
02503     rv = aState.pushPtr(condGoto);
02504     NS_ENSURE_SUCCESS(rv, rv);
02505 
02506     nsAutoPtr<txInstruction> instr(condGoto.forget());
02507     rv = aState.addInstruction(instr);
02508     NS_ENSURE_SUCCESS(rv, rv);
02509 
02510     return aState.pushHandlerTable(gTxTemplateHandler);
02511 }
02512 
02513 nsresult
02514 txFnEndWhen(txStylesheetCompilerState& aState)
02515 {
02516     aState.popHandlerTable();
02517     nsAutoPtr<txGoTo> gotoinstr(new txGoTo(nsnull));
02518     NS_ENSURE_TRUE(gotoinstr, NS_ERROR_OUT_OF_MEMORY);
02519     
02520     nsresult rv = aState.mChooseGotoList->add(gotoinstr);
02521     NS_ENSURE_SUCCESS(rv, rv);
02522 
02523     nsAutoPtr<txInstruction> instr(gotoinstr.forget());
02524     rv = aState.addInstruction(instr);
02525     NS_ENSURE_SUCCESS(rv, rv);
02526 
02527     txConditionalGoto* condGoto =
02528         NS_STATIC_CAST(txConditionalGoto*, aState.popPtr());
02529     rv = aState.addGotoTarget(&condGoto->mTarget);
02530     NS_ENSURE_SUCCESS(rv, rv);
02531 
02532     return NS_OK;
02533 }
02534 
02535 /*
02536     xsl:with-param
02537     
02538     txPushRTFHandler   -- for RTF-parameters
02539     [children]         /
02540     txSetParam
02541 */
02542 nsresult
02543 txFnStartWithParam(PRInt32 aNamespaceID,
02544                    nsIAtom* aLocalName,
02545                    nsIAtom* aPrefix,
02546                    txStylesheetAttr* aAttributes,
02547                    PRInt32 aAttrCount,
02548                    txStylesheetCompilerState& aState)
02549 {
02550     nsresult rv = NS_OK;
02551 
02552     txExpandedName name;
02553     rv = getQNameAttr(aAttributes, aAttrCount, txXSLTAtoms::name, PR_TRUE,
02554                       aState, name);
02555     NS_ENSURE_SUCCESS(rv, rv);
02556 
02557     nsAutoPtr<Expr> select;
02558     rv = getExprAttr(aAttributes, aAttrCount, txXSLTAtoms::select, PR_FALSE,
02559                      aState, select);
02560     NS_ENSURE_SUCCESS(rv, rv);
02561 
02562     nsAutoPtr<txSetParam> var(new txSetParam(name, select));
02563     NS_ENSURE_TRUE(var, NS_ERROR_OUT_OF_MEMORY);
02564 
02565     if (var->mValue) {
02566         // XXX should be gTxErrorHandler?
02567         rv = aState.pushHandlerTable(gTxIgnoreHandler);
02568         NS_ENSURE_SUCCESS(rv, rv);
02569     }
02570     else {
02571         rv = aState.pushHandlerTable(gTxVariableHandler);
02572         NS_ENSURE_SUCCESS(rv, rv);
02573     }
02574 
02575     rv = aState.pushObject(var);
02576     NS_ENSURE_SUCCESS(rv, rv);
02577 
02578     var.forget();
02579 
02580     return NS_OK;
02581 }
02582 
02583 nsresult
02584 txFnEndWithParam(txStylesheetCompilerState& aState)
02585 {
02586     nsAutoPtr<txSetParam> var(NS_STATIC_CAST(txSetParam*, aState.popObject()));
02587     txHandlerTable* prev = aState.mHandlerTable;
02588     aState.popHandlerTable();
02589 
02590     if (prev == gTxVariableHandler) {
02591         // No children were found.
02592         NS_ASSERTION(!var->mValue,
02593                      "There shouldn't be a select-expression here");
02594         var->mValue = new txLiteralExpr(EmptyString());
02595         NS_ENSURE_TRUE(var->mValue, NS_ERROR_OUT_OF_MEMORY);
02596     }
02597 
02598     nsAutoPtr<txInstruction> instr(var.forget());
02599     nsresult rv = aState.addInstruction(instr);
02600     NS_ENSURE_SUCCESS(rv, rv);
02601 
02602     return NS_OK;
02603 }
02604 
02605 /*
02606     Unknown instruction
02607 
02608     [fallbacks]           if one or more xsl:fallbacks are found
02609     or
02610     txErrorInstruction    otherwise
02611 */
02612 nsresult
02613 txFnStartUnknownInstruction(PRInt32 aNamespaceID,
02614                             nsIAtom* aLocalName,
02615                             nsIAtom* aPrefix,
02616                             txStylesheetAttr* aAttributes,
02617                             PRInt32 aAttrCount,
02618                             txStylesheetCompilerState& aState)
02619 {
02620     NS_ASSERTION(!aState.mSearchingForFallback,
02621                  "bad nesting of unknown-instruction and fallback handlers");
02622     aState.mSearchingForFallback = PR_TRUE;
02623 
02624     return aState.pushHandlerTable(gTxFallbackHandler);
02625 }
02626 
02627 nsresult
02628 txFnEndUnknownInstruction(txStylesheetCompilerState& aState)
02629 {
02630     aState.popHandlerTable();
02631 
02632     if (aState.mSearchingForFallback) {
02633         nsAutoPtr<txInstruction> instr(new txErrorInstruction());
02634         NS_ENSURE_TRUE(instr, NS_ERROR_OUT_OF_MEMORY);
02635 
02636         nsresult rv = aState.addInstruction(instr);
02637         NS_ENSURE_SUCCESS(rv, rv);
02638     }
02639 
02640     aState.mSearchingForFallback = PR_FALSE;
02641 
02642     return NS_OK;
02643 }
02644 
02649 struct txHandlerTableData {
02650     txElementHandler mOtherHandler;
02651     txElementHandler mLREHandler;
02652     HandleTextFn mTextHandler;
02653 };
02654 
02655 const txHandlerTableData gTxIgnoreTableData = {
02656   // Other
02657   { 0, 0, txFnStartElementIgnore, txFnEndElementIgnore },
02658   // LRE
02659   { 0, 0, txFnStartElementIgnore, txFnEndElementIgnore },
02660   // Text
02661   txFnTextIgnore
02662 };
02663 
02664 const txElementHandler gTxRootElementHandlers[] = {
02665   { kNameSpaceID_XSLT, "stylesheet", txFnStartStylesheet, txFnEndStylesheet },
02666   { kNameSpaceID_XSLT, "transform", txFnStartStylesheet, txFnEndStylesheet }
02667 };
02668 
02669 const txHandlerTableData gTxRootTableData = {
02670   // Other
02671   { 0, 0, txFnStartElementError, txFnEndElementError },
02672   // LRE
02673   { 0, 0, txFnStartLREStylesheet, txFnEndLREStylesheet },
02674   // Text
02675   txFnTextError
02676 };
02677 
02678 const txHandlerTableData gTxEmbedTableData = {
02679   // Other
02680   { 0, 0, txFnStartEmbed, txFnEndEmbed },
02681   // LRE
02682   { 0, 0, txFnStartElementIgnore, txFnEndElementIgnore },
02683   // Text
02684   txFnTextIgnore
02685 };
02686 
02687 const txElementHandler gTxTopElementHandlers[] = {
02688   { kNameSpaceID_XSLT, "attribute-set", txFnStartAttributeSet, txFnEndAttributeSet },
02689   { kNameSpaceID_XSLT, "decimal-format", txFnStartDecimalFormat, txFnEndDecimalFormat },
02690   { kNameSpaceID_XSLT, "include", txFnStartInclude, txFnEndInclude },
02691   { kNameSpaceID_XSLT, "key", txFnStartKey, txFnEndKey },
02692   { kNameSpaceID_XSLT, "output", txFnStartOutput, txFnEndOutput },
02693   { kNameSpaceID_XSLT, "param", txFnStartTopVariable, txFnEndTopVariable },
02694   { kNameSpaceID_XSLT, "preserve-space", txFnStartStripSpace, txFnEndStripSpace },
02695   { kNameSpaceID_XSLT, "strip-space", txFnStartStripSpace, txFnEndStripSpace },
02696   { kNameSpaceID_XSLT, "template", txFnStartTemplate, txFnEndTemplate },
02697   { kNameSpaceID_XSLT, "variable", txFnStartTopVariable, txFnEndTopVariable }
02698 };
02699 
02700 const txHandlerTableData gTxTopTableData = {
02701   // Other
02702   { 0, 0, txFnStartOtherTop, txFnEndOtherTop },
02703   // LRE
02704   { 0, 0, txFnStartOtherTop, txFnEndOtherTop },
02705   // Text
02706   txFnTextIgnore
02707 };
02708 
02709 const txElementHandler gTxTemplateElementHandlers[] = {
02710   { kNameSpaceID_XSLT, "apply-imports", txFnStartApplyImports, txFnEndApplyImports },
02711   { kNameSpaceID_XSLT, "apply-templates", txFnStartApplyTemplates, txFnEndApplyTemplates },
02712   { kNameSpaceID_XSLT, "attribute", txFnStartAttribute, txFnEndAttribute },
02713   { kNameSpaceID_XSLT, "call-template", txFnStartCallTemplate, txFnEndCallTemplate },
02714   { kNameSpaceID_XSLT, "choose", txFnStartChoose, txFnEndChoose },
02715   { kNameSpaceID_XSLT, "comment", txFnStartComment, txFnEndComment },
02716   { kNameSpaceID_XSLT, "copy", txFnStartCopy, txFnEndCopy },
02717   { kNameSpaceID_XSLT, "copy-of", txFnStartCopyOf, txFnEndCopyOf },
02718   { kNameSpaceID_XSLT, "element", txFnStartElement, txFnEndElement },
02719   { kNameSpaceID_XSLT, "fallback", txFnStartElementSetIgnore, txFnEndElementSetIgnore },
02720   { kNameSpaceID_XSLT, "for-each", txFnStartForEach, txFnEndForEach },
02721   { kNameSpaceID_XSLT, "if", txFnStartIf, txFnEndIf },
02722   { kNameSpaceID_XSLT, "message", txFnStartMessage, txFnEndMessage },
02723   { kNameSpaceID_XSLT, "number", txFnStartNumber, txFnEndNumber },
02724   { kNameSpaceID_XSLT, "processing-instruction", txFnStartPI, txFnEndPI },
02725   { kNameSpaceID_XSLT, "text", txFnStartText, txFnEndText },
02726   { kNameSpaceID_XSLT, "value-of", txFnStartValueOf, txFnEndValueOf },
02727   { kNameSpaceID_XSLT, "variable", txFnStartVariable, txFnEndVariable }
02728 };
02729 
02730 const txHandlerTableData gTxTemplateTableData = {
02731   // Other
02732   { 0, 0, txFnStartUnknownInstruction, txFnEndUnknownInstruction },
02733   // LRE
02734   { 0, 0, txFnStartLRE, txFnEndLRE },
02735   // Text
02736   txFnText
02737 };
02738 
02739 const txHandlerTableData gTxTextTableData = {
02740   // Other
02741   { 0, 0, txFnStartElementError, txFnEndElementError },
02742   // LRE
02743   { 0, 0, txFnStartElementError, txFnEndElementError },
02744   // Text
02745   txFnTextText
02746 };
02747 
02748 const txElementHandler gTxApplyTemplatesElementHandlers[] = {
02749   { kNameSpaceID_XSLT, "sort", txFnStartSort, txFnEndSort },
02750   { kNameSpaceID_XSLT, "with-param", txFnStartWithParam, txFnEndWithParam }
02751 };
02752 
02753 const txHandlerTableData gTxApplyTemplatesTableData = {
02754   // Other
02755   { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore }, // should this be error?
02756   // LRE
02757   { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore },
02758   // Text
02759   txFnTextIgnore
02760 };
02761 
02762 const txElementHandler gTxCallTemplateElementHandlers[] = {
02763   { kNameSpaceID_XSLT, "with-param", txFnStartWithParam, txFnEndWithParam }
02764 };
02765 
02766 const txHandlerTableData gTxCallTemplateTableData = {
02767   // Other
02768   { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore }, // should this be error?
02769   // LRE
02770   { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore },
02771   // Text
02772   txFnTextIgnore
02773 };
02774 
02775 const txHandlerTableData gTxVariableTableData = {
02776   // Other
02777   { 0, 0, txFnStartElementStartRTF, 0 },
02778   // LRE
02779   { 0, 0, txFnStartElementStartRTF, 0 },
02780   // Text
02781   txFnTextStartRTF
02782 };
02783 
02784 const txElementHandler gTxForEachElementHandlers[] = {
02785   { kNameSpaceID_XSLT, "sort", txFnStartSort, txFnEndSort }
02786 };
02787 
02788 const txHandlerTableData gTxForEachTableData = {
02789   // Other
02790   { 0, 0, txFnStartElementContinueTemplate, 0 },
02791   // LRE
02792   { 0, 0, txFnStartElementContinueTemplate, 0 },
02793   // Text
02794   txFnTextContinueTemplate
02795 };
02796 
02797 const txHandlerTableData gTxTopVariableTableData = {
02798   // Other
02799   { 0, 0, txFnStartElementStartTopVar, 0 },
02800   // LRE
02801   { 0, 0, txFnStartElementStartTopVar, 0 },
02802   // Text
02803   txFnTextStartTopVar
02804 };
02805 
02806 const txElementHandler gTxChooseElementHandlers[] = {
02807   { kNameSpaceID_XSLT, "otherwise", txFnStartOtherwise, txFnEndOtherwise },
02808   { kNameSpaceID_XSLT, "when", txFnStartWhen, txFnEndWhen }
02809 };
02810 
02811 const txHandlerTableData gTxChooseTableData = {
02812   // Other
02813   { 0, 0, txFnStartElementError, 0 },
02814   // LRE
02815   { 0, 0, txFnStartElementError, 0 },
02816   // Text
02817   txFnTextError
02818 };
02819 
02820 const txElementHandler gTxParamElementHandlers[] = {
02821   { kNameSpaceID_XSLT, "param", txFnStartParam, txFnEndParam }
02822 };
02823 
02824 const txHandlerTableData gTxParamTableData = {
02825   // Other
02826   { 0, 0, txFnStartElementContinueTemplate, 0 },
02827   // LRE
02828   { 0, 0, txFnStartElementContinueTemplate, 0 },
02829   // Text
02830   txFnTextContinueTemplate
02831 };
02832 
02833 const txElementHandler gTxImportElementHandlers[] = {
02834   { kNameSpaceID_XSLT, "import", txFnStartImport, txFnEndImport }
02835 };
02836 
02837 const txHandlerTableData gTxImportTableData = {
02838   // Other
02839   { 0, 0, txFnStartElementContinueTopLevel, 0 },
02840   // LRE
02841   { 0, 0, txFnStartOtherTop, txFnEndOtherTop }, // XXX what should we do here?
02842   // Text
02843   txFnTextIgnore  // XXX what should we do here?
02844 };
02845 
02846 const txElementHandler gTxAttributeSetElementHandlers[] = {
02847   { kNameSpaceID_XSLT, "attribute", txFnStartAttribute, txFnEndAttribute }
02848 };
02849 
02850 const txHandlerTableData gTxAttributeSetTableData = {
02851   // Other
02852   { 0, 0, txFnStartElementError, 0 },
02853   // LRE
02854   { 0, 0, txFnStartElementError, 0 },
02855   // Text
02856   txFnTextError
02857 };
02858 
02859 const txElementHandler gTxFallbackElementHandlers[] = {
02860   { kNameSpaceID_XSLT, "fallback", txFnStartFallback, txFnEndFallback }
02861 };
02862 
02863 const txHandlerTableData gTxFallbackTableData = {
02864   // Other
02865   { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore },
02866   // LRE
02867   { 0, 0, txFnStartElementSetIgnore, txFnEndElementSetIgnore },
02868   // Text
02869   txFnTextIgnore
02870 };
02871 
02872 
02873 
02877 txHandlerTable::txHandlerTable(const HandleTextFn aTextHandler,
02878                                const txElementHandler* aLREHandler,
02879                                const txElementHandler* aOtherHandler)
02880   : mTextHandler(aTextHandler),
02881     mLREHandler(aLREHandler),
02882     mOtherHandler(aOtherHandler),
02883     mHandlers(PR_FALSE)
02884 {
02885 }
02886 
02887 nsresult
02888 txHandlerTable::init(const txElementHandler* aHandlers, PRUint32 aCount)
02889 {
02890     nsresult rv = NS_OK;
02891 
02892     PRUint32 i;
02893     for (i = 0; i < aCount; ++i) {
02894         nsCOMPtr<nsIAtom> nameAtom = do_GetAtom(aHandlers->mLocalName);
02895         txExpandedName name(aHandlers->mNamespaceID, nameAtom);
02896         // XXX this cast is a reinterpret_cast, which is sad
02897         rv = mHandlers.add(name, (TxObject*)aHandlers);
02898         NS_ENSURE_SUCCESS(rv, rv);
02899 
02900         ++aHandlers;
02901     }
02902     return NS_OK;
02903 }
02904 
02905 const txElementHandler*
02906 txHandlerTable::find(PRInt32 aNamespaceID, nsIAtom* aLocalName)
02907 {
02908     txExpandedName name(aNamespaceID, aLocalName);
02909     // XXX this cast is a reinterpret_cast, same sad story as in ::init
02910     const txElementHandler* handler =
02911         (const txElementHandler*)mHandlers.get(name);
02912     if (!handler) {
02913         handler = mOtherHandler;
02914     }
02915     return handler;
02916 }
02917 
02918 #define INIT_HANDLER(_name)                                          \
02919     gTx##_name##Handler =                                            \
02920         new txHandlerTable(gTx##_name##TableData.mTextHandler,       \
02921                            &gTx##_name##TableData.mLREHandler,       \
02922                            &gTx##_name##TableData.mOtherHandler);    \
02923     if (!gTx##_name##Handler)                                        \
02924         return PR_FALSE
02925 
02926 #define INIT_HANDLER_WITH_ELEMENT_HANDLERS(_name)                    \
02927     INIT_HANDLER(_name);                                             \
02928                                                                      \
02929     rv = gTx##_name##Handler->init(gTx##_name##ElementHandlers,      \
02930                                    NS_ARRAY_LENGTH(gTx##_name##ElementHandlers)); \
02931     if (NS_FAILED(rv))                                               \
02932         return PR_FALSE
02933 
02934 #define SHUTDOWN_HANDLER(_name)                                      \
02935     delete gTx##_name##Handler;                                      \
02936     gTx##_name##Handler = nsnull
02937 
02938 // static
02939 MBool
02940 txHandlerTable::init()
02941 {
02942     nsresult rv = NS_OK;
02943 
02944     INIT_HANDLER_WITH_ELEMENT_HANDLERS(Root);
02945     INIT_HANDLER(Embed);
02946     INIT_HANDLER_WITH_ELEMENT_HANDLERS(Top);
02947     INIT_HANDLER(Ignore);
02948     INIT_HANDLER_WITH_ELEMENT_HANDLERS(Template);
02949     INIT_HANDLER(Text);
02950     INIT_HANDLER_WITH_ELEMENT_HANDLERS(ApplyTemplates);
02951     INIT_HANDLER_WITH_ELEMENT_HANDLERS(CallTemplate);
02952     INIT_HANDLER(Variable);
02953     INIT_HANDLER_WITH_ELEMENT_HANDLERS(ForEach);
02954     INIT_HANDLER(TopVariable);
02955     INIT_HANDLER_WITH_ELEMENT_HANDLERS(Choose);
02956     INIT_HANDLER_WITH_ELEMENT_HANDLERS(Param);
02957     INIT_HANDLER_WITH_ELEMENT_HANDLERS(Import);
02958     INIT_HANDLER_WITH_ELEMENT_HANDLERS(AttributeSet);
02959     INIT_HANDLER_WITH_ELEMENT_HANDLERS(Fallback);
02960 
02961     return MB_TRUE;
02962 }
02963 
02964 // static
02965 void
02966 txHandlerTable::shutdown()
02967 {
02968     SHUTDOWN_HANDLER(Root);
02969     SHUTDOWN_HANDLER(Top);
02970     SHUTDOWN_HANDLER(Ignore);
02971     SHUTDOWN_HANDLER(Template);
02972     SHUTDOWN_HANDLER(Text);
02973     SHUTDOWN_HANDLER(ApplyTemplates);
02974     SHUTDOWN_HANDLER(CallTemplate);
02975     SHUTDOWN_HANDLER(Variable);
02976     SHUTDOWN_HANDLER(ForEach);
02977     SHUTDOWN_HANDLER(TopVariable);
02978     SHUTDOWN_HANDLER(Choose);
02979     SHUTDOWN_HANDLER(Param);
02980     SHUTDOWN_HANDLER(Import);
02981     SHUTDOWN_HANDLER(AttributeSet);
02982     SHUTDOWN_HANDLER(Fallback);
02983 }