diff --git a/extensions/transformiix/resources/xslt.properties b/extensions/transformiix/resources/xslt.properties index 24163abb097d..207b31486965 100644 --- a/extensions/transformiix/resources/xslt.properties +++ b/extensions/transformiix/resources/xslt.properties @@ -38,7 +38,7 @@ 1 = Parsing an XSLT stylesheet failed. 2 = Parsing an XPath expression failed. 4 = XSLT transformation failed. -5 = XSLT/XPath tried to call an unknown function. +5 = Invalid XSLT/XPath function. 6 = XSLT Stylesheet (possibly) contains a recursion. 7 = Attribute value illegal in XSLT 1.0. 8 = An XPath expression was expected to return a NodeSet. @@ -47,6 +47,19 @@ 11 = An XSLT stylesheet does not have an XML mimetype: 12 = An XSLT stylesheet directly or indirectly imports or includes itself: 13 = An XPath function was called with the wrong number of arguments. +14 = An unknown XPath extension function was called. +15 = XPath parse failure: ')' expected: +16 = XPath parse failure: invalid axis: +17 = XPath parse failure: Name or Nodetype test expected: +18 = XPath parse failure: ']' expected: +19 = XPath parse failure: invalid variable name: +20 = XPath parse failure: unexpected end of expression: +21 = XPath parse failure: operator expected: +22 = XPath parse failure: unclosed literal: +23 = XPath parse failure: ':' unexpected: +24 = XPath parse failure: '!' unexpected, negation is not(): +25 = XPath parse failure: illegal character found: +26 = XPath parse failure: binary operator expected: LoadingError = Error loading stylesheet: %S TransformError = Error during XSLT transformation: %S diff --git a/extensions/transformiix/source/base/txError.h b/extensions/transformiix/source/base/txError.h index 9227350792dc..30b7bf79ac32 100644 --- a/extensions/transformiix/source/base/txError.h +++ b/extensions/transformiix/source/base/txError.h @@ -90,4 +90,43 @@ #define NS_ERROR_XPATH_BAD_ARGUMENT_COUNT \ NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 13) +#define NS_ERROR_XPATH_BAD_EXTENSION_FUNCTION \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 14) + +#define NS_ERROR_XPATH_PAREN_EXPECTED \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 15) + +#define NS_ERROR_XPATH_INVALID_AXIS \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 16) + +#define NS_ERROR_XPATH_NO_NODE_TYPE_TEST \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 17) + +#define NS_ERROR_XPATH_BRACKET_EXPECTED \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 18) + +#define NS_ERROR_XPATH_INVALID_VAR_NAME \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 19) + +#define NS_ERROR_XPATH_UNEXPECTED_END \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 20) + +#define NS_ERROR_XPATH_OPERATOR_EXPECTED \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 21) + +#define NS_ERROR_XPATH_UNCLOSED_LITERAL \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 22) + +#define NS_ERROR_XPATH_BAD_COLON \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 23) + +#define NS_ERROR_XPATH_BAD_BANG \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 24) + +#define NS_ERROR_XPATH_ILLEGAL_CHAR \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 25) + +#define NS_ERROR_XPATH_BINARY_EXPECTED \ + NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_XSLT, 26) + #endif // __TX_ERROR diff --git a/extensions/transformiix/source/main/Makefile.in b/extensions/transformiix/source/main/Makefile.in index 7cfc1166d314..1986e7a6c932 100644 --- a/extensions/transformiix/source/main/Makefile.in +++ b/extensions/transformiix/source/main/Makefile.in @@ -26,7 +26,8 @@ VPATH = @srcdir@ include $(DEPTH)/config/autoconf.mk -SIMPLE_PROGRAMS = transformiix$(BIN_SUFFIX) testXalan$(BIN_SUFFIX) +SIMPLE_PROGRAMS = transformiix$(BIN_SUFFIX) testXalan$(BIN_SUFFIX) \ + txTestExpr$(BIN_SUFFIX) ifdef MARK_INC SIMPLE_PROGRAMS += txXSLTMarkDriver$(BIN_SUFFIX) endif diff --git a/extensions/transformiix/source/main/txTestExpr.cpp b/extensions/transformiix/source/main/txTestExpr.cpp new file mode 100644 index 000000000000..784ce2cfc0ff --- /dev/null +++ b/extensions/transformiix/source/main/txTestExpr.cpp @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is TransforMiiX XSLT Processor. + * + * The Initial Developer of the Original Code is + * Axel Hecht. + * Portions created by the Initial Developer are Copyright (C) 2003 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Axel Hecht + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "nsXPCOM.h" +#include "txStandaloneXSLTProcessor.h" +#include "nsString.h" +#include "ExprParser.h" +#include "txIXPathContext.h" + +/** + * A ExprParser test exe + */ + +static const char* kTokens[] = {"(", "concat", "(", "foo", ",", "'", "bar", + "'",")", "//", ".", "[", "preceding-sibling", + "::", "bar", "]", "/", "*", "[", "23", "]", + "|", "node", "(", ")", ")", "<", "3"}; +static const PRUint8 kCount = sizeof(kTokens)/sizeof(char*); + +class ParseContextImpl : public txIParseContext +{ +public: + nsresult + resolveNamespacePrefix(nsIAtom* aPrefix, PRInt32& aID) + { + return NS_ERROR_FAILURE; + } + nsresult + resolveFunctionCall(nsIAtom* aName, PRInt32 aID, FunctionCall*& aFunction) + { + return NS_ERROR_XPATH_UNKNOWN_FUNCTION; + } + PRBool + caseInsensitiveNameTests() + { + return PR_FALSE; + } + void + SetErrorOffset(PRUint32 aOffset) + { + mOff = aOffset; + } + PRUint32 mOff; +}; + +static void doTest(const nsASingleFragmentString& aExpr) +{ + ParseContextImpl ct; + nsAutoPtr expression; + cout << NS_LossyConvertUTF16toASCII(aExpr).get() << endl; + ct.mOff = 0; + nsresult rv = txExprParser::createExpr(aExpr, &ct, + getter_Transfers(expression)); + + cout << "createExpr returned " << hex << rv << dec; + cout << " at " << ct.mOff << endl; + if (NS_FAILED(rv)) { + NS_LossyConvertUTF16toASCII cstring(aExpr); + cout << NS_LossyConvertUTF16toASCII(StringHead(aExpr, ct.mOff)).get(); + cout << " ^ "; + cout << NS_LossyConvertUTF16toASCII(StringTail(aExpr, aExpr.Length()-ct.mOff)).get(); + cout << endl << endl; + } + else { + nsAutoString expr; + expression->toString(expr); + cout << "parsed expression: "; + cout << NS_LossyConvertUTF16toASCII(expr).get() << endl << endl; + } +} + +int main(int argc, char** argv) +{ + using namespace std; + nsresult rv = NS_InitXPCOM2(nsnull, nsnull, nsnull); + NS_ENSURE_SUCCESS(rv, rv); + + if (!txXSLTProcessor::init()) + return 1; + + nsAutoString exprOrig, expr; + nsStringArray exprHead, exprTail; + PRUint8 i, dropStart, dropEnd; + exprHead.AppendString(NS_ConvertASCIItoUTF16(kTokens[0])); + exprTail.AppendString(NS_ConvertASCIItoUTF16(kTokens[kCount - 1])); + for (i = 2; i < kCount; ++i) { + exprHead.AppendString(*exprHead[i - 2] + + NS_ConvertASCIItoUTF16(kTokens[i - 1])); + exprTail.AppendString(NS_ConvertASCIItoUTF16(kTokens[kCount - i]) + + *exprTail[i - 2]); + } + exprOrig = NS_ConvertASCIItoUTF16(kTokens[0]) + *exprTail[kCount - 2]; + cout << NS_LossyConvertUTF16toASCII(exprOrig).get() << endl << endl; + for (dropStart = 0; dropStart < kCount - 2; ++dropStart) { + doTest(*exprTail[kCount - 2 - dropStart]); + for (dropEnd = kCount - 3 - dropStart; dropEnd > 0; --dropEnd) { + expr = *exprHead[dropStart] + *exprTail[dropEnd]; + doTest(expr); + } + doTest(*exprHead[dropStart]); + } + doTest(*exprHead[kCount - 2]); + + txXSLTProcessor::shutdown(); + rv = NS_ShutdownXPCOM(nsnull); + NS_ENSURE_SUCCESS(rv, rv); + return 0; +} diff --git a/extensions/transformiix/source/xpath/AdditiveExpr.cpp b/extensions/transformiix/source/xpath/AdditiveExpr.cpp index 58931d2b3af0..a78df630d55c 100644 --- a/extensions/transformiix/source/xpath/AdditiveExpr.cpp +++ b/extensions/transformiix/source/xpath/AdditiveExpr.cpp @@ -35,20 +35,6 @@ #include "primitives.h" #include "txIXPathContext.h" -/** - * Creates a new AdditiveExpr using the given operator -**/ -AdditiveExpr::AdditiveExpr(Expr* leftExpr, Expr* rightExpr, short op) { - this->op = op; - this->leftExpr = leftExpr; - this->rightExpr = rightExpr; -} //-- AdditiveExpr - -AdditiveExpr::~AdditiveExpr() { - delete leftExpr; - delete rightExpr; -} //-- ~AdditiveExpr - /** * Evaluates this Expr based on the given context node and processor state * @param context the context node for evaluation of this Expr diff --git a/extensions/transformiix/source/xpath/BooleanExpr.cpp b/extensions/transformiix/source/xpath/BooleanExpr.cpp index a6071f6474ff..d4778e04a865 100644 --- a/extensions/transformiix/source/xpath/BooleanExpr.cpp +++ b/extensions/transformiix/source/xpath/BooleanExpr.cpp @@ -38,20 +38,6 @@ #include "ExprResult.h" #include "txIXPathContext.h" -/** - * Creates a new BooleanExpr using the given operator -**/ -BooleanExpr::BooleanExpr(Expr* leftExpr, Expr* rightExpr, short op) { - this->op = op; - this->leftExpr = leftExpr; - this->rightExpr = rightExpr; -} //-- BooleanExpr - -BooleanExpr::~BooleanExpr() { - delete leftExpr; - delete rightExpr; -} //-- ~BooleanExpr - /** * Evaluates this Expr based on the given context node and processor state * @param context the context node for evaluation of this Expr diff --git a/extensions/transformiix/source/xpath/Expr.h b/extensions/transformiix/source/xpath/Expr.h index e703b12276ae..c5fe93885299 100644 --- a/extensions/transformiix/source/xpath/Expr.h +++ b/extensions/transformiix/source/xpath/Expr.h @@ -116,9 +116,12 @@ public: void toString(nsAString& aDest); /** - * Adds the given parameter to this FunctionCall's parameter list - * @param expr the Expr to add to this FunctionCall's parameter list - **/ + * Adds the given parameter to this FunctionCall's parameter list. + * The ownership of the given Expr is passed over to the FunctionCall, + * even on failure. + * @param aExpr the Expr to add to this FunctionCall's parameter list + * @return nsresult indicating out of memory + */ nsresult addParam(Expr* aExpr); /** @@ -294,10 +297,13 @@ public: virtual ~PredicateList(); /** - * Adds the given Expr to the list - * @param expr the Expr to add to the list - **/ - void add(Expr* expr); + * Adds the given Expr to the list. + * The ownership of the given Expr is passed over the PredicateList, + * even on failure. + * @param aExpr the Expr to add to the list + * @return nsresult indicating out of memory + */ + nsresult add(Expr* aExpr); nsresult evaluatePredicates(NodeSet* aNodes, txIMatchContext* aContext); @@ -348,7 +354,12 @@ public: * @param nodeExpr the NodeExpr to use when matching Nodes * @param axisIdentifier the Axis Identifier in which to search for nodes **/ - LocationStep(nsAutoPtr aNodeTest, LocationStepType aAxisIdentifier); + LocationStep(nsAutoPtr& aNodeTest, + LocationStepType aAxisIdentifier) + : mNodeTest(aNodeTest), + mAxisIdentifier(aAxisIdentifier) + { + } TX_DECL_EXPR; @@ -372,18 +383,16 @@ public: /** * Creates a new FilterExpr using the given Expr * @param expr the Expr to use for evaluation - **/ - FilterExpr(Expr* aExpr); - - /** - * Destructor, will delete all predicates and the given Expr - **/ - virtual ~FilterExpr(); + */ + FilterExpr(nsAutoPtr& aExpr) + : expr(aExpr) + { + } TX_DECL_EXPR; private: - Expr* expr; + nsAutoPtr expr; }; //-- FilterExpr @@ -413,15 +422,19 @@ public: //-- LF, changed from static const short to enum enum _AdditiveExprType { ADDITION = 1, SUBTRACTION }; - AdditiveExpr(Expr* leftExpr, Expr* rightExpr, short op); - ~AdditiveExpr(); + AdditiveExpr(nsAutoPtr& aLeftExpr, nsAutoPtr& aRightExpr, + short aOp) + : op(aOp), + leftExpr(aLeftExpr), + rightExpr(aRightExpr) + { + } TX_DECL_EXPR; private: short op; - Expr* leftExpr; - Expr* rightExpr; + nsAutoPtr leftExpr, rightExpr; }; //-- AdditiveExpr /** @@ -431,13 +444,15 @@ class UnaryExpr : public Expr { public: - UnaryExpr(Expr* expr); - ~UnaryExpr(); + UnaryExpr(nsAutoPtr& aExpr) + : expr(aExpr) + { + } TX_DECL_EXPR; private: - Expr* expr; + nsAutoPtr expr; }; //-- UnaryExpr /** @@ -451,15 +466,19 @@ public: //-- BooleanExpr Types enum _BooleanExprType { AND = 1, OR }; - BooleanExpr(Expr* leftExpr, Expr* rightExpr, short op); - ~BooleanExpr(); + BooleanExpr(nsAutoPtr& aLeftExpr, nsAutoPtr& aRightExpr, + short aOp) + : op(aOp), + leftExpr(aLeftExpr), + rightExpr(aRightExpr) + { + } TX_DECL_EXPR; private: short op; - Expr* leftExpr; - Expr* rightExpr; + nsAutoPtr leftExpr, rightExpr; }; //-- BooleanExpr /** @@ -478,15 +497,20 @@ public: //-- LF, changed from static const short to enum enum _MultiplicativeExprType { DIVIDE = 1, MULTIPLY, MODULUS }; - MultiplicativeExpr(Expr* leftExpr, Expr* rightExpr, short op); - ~MultiplicativeExpr(); + MultiplicativeExpr(nsAutoPtr& aLeftExpr, + nsAutoPtr& aRightExpr, + short aOp) + : op(aOp), + leftExpr(aLeftExpr), + rightExpr(aRightExpr) + { + } TX_DECL_EXPR; private: short op; - Expr* leftExpr; - Expr* rightExpr; + nsAutoPtr leftExpr, rightExpr; }; //-- MultiplicativeExpr /** @@ -511,7 +535,14 @@ public: GREATER_OR_EQUAL }; - RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, RelationalExprType aOp); + RelationalExpr(nsAutoPtr& aLeftExpr, nsAutoPtr& aRightExpr, + RelationalExprType aOp) + : mLeftExpr(aLeftExpr), + mRightExpr(aRightExpr), + mOp(aOp) + { + } + TX_DECL_EXPR; @@ -567,15 +598,23 @@ public: /** * Adds the Expr to this PathExpr - * @param expr the Expr to add to this PathExpr - **/ - void addExpr(Expr* expr, PathOperator pathOp); + * The ownership of the given Expr is passed over the PathExpr, + * even on failure. + * @param aExpr the Expr to add to this PathExpr + * @return nsresult indicating out of memory + */ + nsresult addExpr(Expr* aExpr, PathOperator pathOp); TX_DECL_EXPR; private: - struct PathExprItem { - Expr* expr; + class PathExprItem { + public: + PathExprItem(Expr* aExpr, PathOperator aOp) + : expr(aExpr), + pathOp(aOp) + {} + nsAutoPtr expr; PathOperator pathOp; }; @@ -631,9 +670,12 @@ public: /** * Adds the PathExpr to this UnionExpr - * @param expr the Expr to add to this UnionExpr - **/ - void addExpr(Expr* expr); + * The ownership of the given Expr is passed over the UnionExpr, + * even on failure. + * @param aExpr the Expr to add to this UnionExpr + * @return nsresult indicating out of memory + */ + nsresult addExpr(Expr* aExpr); TX_DECL_EXPR; @@ -643,7 +685,6 @@ private: }; //-- UnionExpr -/* */ #endif diff --git a/extensions/transformiix/source/xpath/ExprLexer.cpp b/extensions/transformiix/source/xpath/ExprLexer.cpp index 1bd7833e5ed7..7a8b75188064 100644 --- a/extensions/transformiix/source/xpath/ExprLexer.cpp +++ b/extensions/transformiix/source/xpath/ExprLexer.cpp @@ -36,451 +36,363 @@ /** * Lexical analyzer for XPath expressions -**/ + */ #include "ExprLexer.h" #include "txAtoms.h" -#include "txStringUtils.h" +#include "nsString.h" #include "XMLUtils.h" - //---------------------------/ - //- Implementation of Token -/ -//---------------------------/ - +/** + * Creates a new ExprLexer + */ +txExprLexer::txExprLexer() + : mCurrentItem(nsnull), + mFirstItem(nsnull), + mLastItem(nsnull), + mTokenCount(0) +{ +} /** - * Default constructor for Token -**/ -Token::Token() -{ - this->type =0; -} //-- Token; - -/** - * Constructor for Token - * @param type, the type of Token being represented -**/ -Token::Token(short type) -{ - this->type = type; -} //-- Token; - -/** - * Constructor for Token - * @param value the value of this Token - * @param type, the type of Token being represented -**/ -Token::Token(const nsAString& value, short type) -{ - this->type = type; - //-- make copy of value String - this->value = value; -} //-- Token - -Token::Token(PRUnichar uniChar, short type) -{ - this->type = type; - this->value.Append(uniChar); -} //-- Token - -/** - * Copy Constructor -**/ -Token::Token(const Token& token) -{ - this->type = token.type; - this->value = token.value; -} //-- Token - -/** - * Destructor for Token -**/ -Token::~Token() -{ - //-- currently nothing is needed -} //-- ~Token - - - //--------------------------------/ - //- Implementation of ExprLexer -/ -//-------------------------------/ - - //---------------/ - //- Contructors -/ -//---------------/ - -/** - * Creates a new ExprLexer using the given string -**/ -ExprLexer::ExprLexer(const nsAFlatString& pattern) -{ - firstItem = 0; - lastItem = 0; - tokenCount = 0; - prevToken = 0; - endToken.type = Token::END; - parse(pattern); - currentItem = firstItem; -} //-- ExprLexer - -/** - * Destroys this instance of an ExprLexer -**/ -ExprLexer::~ExprLexer() + * Destroys this instance of an txExprLexer + */ +txExprLexer::~txExprLexer() { //-- delete tokens - currentItem = firstItem; - while (currentItem) { - TokenListItem* temp = currentItem->next; - delete currentItem->token; - delete currentItem; - currentItem = temp; + Token* tok = mFirstItem; + while (tok) { + Token* temp = tok->mNext; + delete tok; + tok = temp; } -} //-- ~ExprLexer + mCurrentItem = nsnull; +} - -MBool ExprLexer::hasMoreTokens() +Token* +txExprLexer::nextToken() { - return (currentItem != 0); -} //-- hasMoreTokens + NS_ASSERTION(mCurrentItem, "nextToken called beyoned the end"); + Token* token = mCurrentItem; + mCurrentItem = mCurrentItem->mNext; + return token; +} -Token* ExprLexer::nextToken() +void +txExprLexer::pushBack() { - if (currentItem) { - Token* token = currentItem->token; - currentItem = currentItem->next; - return token; + mCurrentItem = mCurrentItem ? mCurrentItem->mPrevious : mLastItem; +} + +void +txExprLexer::addToken(Token* aToken) +{ + if (mLastItem) { + aToken->mPrevious = mLastItem; + mLastItem->mNext = aToken; } - return &endToken; -} //-- nextToken - -void ExprLexer::pushBack() -{ - if (!currentItem) - currentItem = lastItem; - else - currentItem = currentItem->previous; -} //-- pushBack - -Token* ExprLexer::peek() -{ - if (currentItem) - return currentItem->token; - return &endToken; -} //-- peek - -void ExprLexer::addToken(Token* token) -{ - TokenListItem* tlItem = new TokenListItem; - tlItem->token = token; - tlItem->next = 0; - if (lastItem) { - tlItem->previous = lastItem; - lastItem->next = tlItem; + if (!mFirstItem) { + mFirstItem = aToken; + mCurrentItem = aToken; } - if (!firstItem) - firstItem = tlItem; - lastItem = tlItem; - prevToken = token; - ++tokenCount; -} //-- addToken + mLastItem = aToken; + ++mTokenCount; +} /** * Returns true if the following Token should be an operator. * This is a helper for the first bullet of [XPath 3.7] * Lexical Structure -**/ -MBool ExprLexer::nextIsOperatorToken(Token* token) + */ +PRBool +txExprLexer::nextIsOperatorToken(Token* aToken) { - if (!token || token->type == Token::NULL_TOKEN) - return MB_FALSE; + if (!aToken || aToken->mType == Token::NULL_TOKEN) { + return PR_FALSE; + } /* This relies on the tokens having the right order in ExprLexer.h */ - if (token->type >= Token::COMMA && - token->type <= Token::UNION_OP) - return MB_FALSE; - return MB_TRUE; -} //-- nextIsOperatorToken + return aToken->mType < Token::COMMA || + aToken->mType > Token::UNION_OP; + +} /** - * Parses the given string into the set of Tokens -**/ -void ExprLexer::parse(const nsAFlatString& pattern) + * Parses the given string into a sequence of Tokens + */ +nsresult +txExprLexer::parse(const nsASingleFragmentString& aPattern) { - if (pattern.IsEmpty()) - return; - - nsAutoString tokenBuffer; - PRUint32 iter = 0, start; - PRUint32 size = pattern.Length(); - short defType; - PRUnichar ch; + iterator start, end; + start = aPattern.BeginReading(mPosition); + aPattern.EndReading(end); + if (start == end) { + return NS_OK; + } //-- initialize previous token, this will automatically get //-- deleted when it goes out of scope - Token nullToken('\0', Token::NULL_TOKEN); + Token nullToken(nsnull, nsnull, Token::NULL_TOKEN); - prevToken = &nullToken; + Token::Type defType; + Token* newToken = nsnull; + Token* prevToken = &nullToken; + PRBool isToken; - while (iter < size) { + while (mPosition < end) { - ch = pattern.CharAt(iter); defType = Token::CNAME; + isToken = PR_TRUE; - if (ch==DOLLAR_SIGN) { - if (++iter == size || !XMLUtils::isLetter(ch=pattern.CharAt(iter))) { - // Error, VariableReference expected - errorPos = iter; - errorCode = ERROR_UNRESOLVED_VAR_REFERENCE; - if (firstItem) - firstItem->token->type=Token::ERROR; - else - addToken(new Token('\0',Token::ERROR)); - iter=size; // bail + if (*mPosition == DOLLAR_SIGN) { + if (++mPosition == end || !XMLUtils::isLetter(*mPosition)) { + return NS_ERROR_XPATH_INVALID_VAR_NAME; } - else - defType = Token::VAR_REFERENCE; + defType = Token::VAR_REFERENCE; } // just reuse the QName parsing, which will use defType // the token to construct - if (XMLUtils::isLetter(ch)) { + if (XMLUtils::isLetter(*mPosition)) { // NCName, can get QName or OperatorName; // FunctionName, NodeName, and AxisSpecifier may want whitespace, // and are dealt with below - start = iter; - while (++iter < size && - XMLUtils::isNCNameChar(pattern.CharAt(iter))) /* just go */ ; - if (iter < size && pattern.CharAt(iter)==COLON) { - // try QName or wildcard, might need to step back for axis - if (++iter < size) - if (XMLUtils::isLetter(pattern.CharAt(iter))) - while (++iter < size && - XMLUtils::isNCNameChar(pattern.CharAt(iter))) /* just go */ ; - else if (pattern.CharAt(iter)=='*' - && defType != Token::VAR_REFERENCE) - ++iter; /* eat wildcard for NameTest, bail for var ref at COLON */ - else - iter--; // step back + start = mPosition; + while (++mPosition < end && XMLUtils::isNCNameChar(*mPosition)) { + /* just go */ } - if (nextIsOperatorToken(prevToken)) { - if (TX_StringEqualsAtom(Substring(pattern, start, iter - start), - txXPathAtoms::_and)) - defType = Token::AND_OP; - else if (TX_StringEqualsAtom(Substring(pattern, start, iter - start), - txXPathAtoms::_or)) - defType = Token::OR_OP; - else if (TX_StringEqualsAtom(Substring(pattern, start, iter - start), - txXPathAtoms::mod)) - defType = Token::MODULUS_OP; - else if (TX_StringEqualsAtom(Substring(pattern, start, iter - start), - txXPathAtoms::div)) - defType = Token::DIVIDE_OP; + if (mPosition < end && *mPosition == COLON) { + // try QName or wildcard, might need to step back for axis + if (++mPosition == end) { + return NS_ERROR_XPATH_UNEXPECTED_END; + } + if (XMLUtils::isLetter(*mPosition)) { + while (++mPosition < end && XMLUtils::isNCNameChar(*mPosition)) { + /* just go */ + } + } + else if (*mPosition == '*' && defType != Token::VAR_REFERENCE) { + // eat wildcard for NameTest, bail for var ref at COLON + ++mPosition; + } else { - // Error "operator expected" - // XXX QUESTION: spec is not too precise - // badops is sure an error, but is bad:ops, too? We say yes! - errorPos = iter; - errorCode = ERROR_OP_EXPECTED; - if (firstItem) - firstItem->token->type=Token::ERROR; - else - addToken(new Token('\0',Token::ERROR)); - iter=size; // bail + --mPosition; // step back } } - addToken(new Token(Substring(pattern, start, iter - start), defType)); + if (nextIsOperatorToken(prevToken)) { + NS_ConvertUTF16toUTF8 opUTF8(Substring(start, mPosition)); + if (txXPathAtoms::_and->EqualsUTF8(opUTF8)) { + defType = Token::AND_OP; + } + else if (txXPathAtoms::_or->EqualsUTF8(opUTF8)) { + defType = Token::OR_OP; + } + else if (txXPathAtoms::mod->EqualsUTF8(opUTF8)) { + defType = Token::MODULUS_OP; + } + else if (txXPathAtoms::div->EqualsUTF8(opUTF8)) { + defType = Token::DIVIDE_OP; + } + else { + // XXX QUESTION: spec is not too precise + // badops is sure an error, but is bad:ops, too? We say yes! + return NS_ERROR_XPATH_OPERATOR_EXPECTED; + } + } + newToken = new Token(start, mPosition, defType); } - else if (isXPathDigit(ch)) { - start = iter; - while (++iter < size && - isXPathDigit(pattern.CharAt(iter))) /* just go */; - if (iter < size && pattern.CharAt(iter) == '.') - while (++iter < size && - isXPathDigit(pattern.CharAt(iter))) /* just go */; - addToken(new Token(Substring(pattern, start, iter - start), - Token::NUMBER)); + else if (isXPathDigit(*mPosition)) { + start = mPosition; + while (++mPosition < end && isXPathDigit(*mPosition)) { + /* just go */ + } + if (mPosition < end && *mPosition == '.') { + while (++mPosition < end && isXPathDigit(*mPosition)) { + /* just go */ + } + } + newToken = new Token(start, mPosition, Token::NUMBER); } else { - switch (ch) { + switch (*mPosition) { //-- ignore whitespace case SPACE: case TX_TAB: case TX_CR: case TX_LF: - ++iter; + ++mPosition; + isToken = PR_FALSE; break; case S_QUOTE : case D_QUOTE : - start=iter; - iter = pattern.FindChar(ch, start + 1); - if ((PRInt32)iter == kNotFound) { - // XXX Error reporting "unclosed literal" - errorPos = start; - errorCode = ERROR_UNCLOSED_LITERAL; - if (firstItem) - firstItem->token->type=Token::ERROR; - else - addToken(new Token('\0',Token::ERROR)); - iter=size; // bail + start = mPosition; + while (++mPosition < end && *mPosition != *start) { + // eat literal } - else { - addToken(new Token(Substring(pattern, start + 1, iter - (start + 1)), - Token::LITERAL)); - ++iter; + if (mPosition == end) { + mPosition = start; + return NS_ERROR_XPATH_UNCLOSED_LITERAL; } + newToken = new Token(start + 1, mPosition, Token::LITERAL); + ++mPosition; break; case PERIOD: // period can be .., .(DIGITS)+ or ., check next - if (++iter < size) { - ch=pattern.CharAt(iter); - if (isXPathDigit(ch)) { - start=iter-1; - while (++iter < size && - isXPathDigit(pattern.CharAt(iter))) /* just go */; - addToken(new Token(Substring(pattern, start, iter - start), - Token::NUMBER)); - } - else if (ch==PERIOD) { - addToken(new Token(Substring(pattern, ++iter - 2, 2), - Token::PARENT_NODE)); - } - else - addToken(new Token(PERIOD, Token::SELF_NODE)); + if (++mPosition == end) { + newToken = new Token(mPosition - 1, Token::SELF_NODE); + } + else if (isXPathDigit(*mPosition)) { + start = mPosition - 1; + while (++mPosition < end && isXPathDigit(*mPosition)) { + /* just go */ + } + newToken = new Token(start, mPosition, Token::NUMBER); + } + else if (*mPosition == PERIOD) { + ++mPosition; + newToken = new Token(mPosition - 2, mPosition, Token::PARENT_NODE); + } + else { + newToken = new Token(mPosition - 1, Token::SELF_NODE); } - else - addToken(new Token(ch, Token::SELF_NODE)); - // iter++ is already in the number test - break; case COLON: // QNames are dealt above, must be axis ident - if (++iter < size && pattern.CharAt(iter) == COLON && - prevToken->type == Token::CNAME) { - prevToken->type = Token::AXIS_IDENTIFIER; - ++iter; - } - else { - // XXX Error report "colon is neither QName nor axis" - errorPos = iter; - errorCode = ERROR_COLON; - if (firstItem) - firstItem->token->type=Token::ERROR; - else - addToken(new Token('\0',Token::ERROR)); - iter=size; // bail + if (++mPosition >= end || *mPosition != COLON || + prevToken->mType != Token::CNAME) { + return NS_ERROR_XPATH_BAD_COLON; } + prevToken->mType = Token::AXIS_IDENTIFIER; + ++mPosition; + isToken = PR_FALSE; break; case FORWARD_SLASH : - if (++iter < size && pattern.CharAt(iter) == ch) { - addToken(new Token(Substring(pattern, ++iter - 2, 2), - Token::ANCESTOR_OP)); + if (++mPosition < end && *mPosition == FORWARD_SLASH) { + ++mPosition; + newToken = new Token(mPosition - 2, mPosition, Token::ANCESTOR_OP); } else { - addToken(new Token(ch, Token::PARENT_OP)); + newToken = new Token(mPosition - 1, Token::PARENT_OP); } break; case BANG : // can only be != - if (++iter < size && pattern.CharAt(iter) == EQUAL) { - addToken(new Token(Substring(pattern, ++iter - 2, 2), - Token::NOT_EQUAL_OP)); + if (++mPosition < end && *mPosition == EQUAL) { + ++mPosition; + newToken = new Token(mPosition - 2, mPosition, Token::NOT_EQUAL_OP); + break; } - else { - // Error ! is not not() - errorPos = iter; - errorCode = ERROR_BANG; - if (firstItem) - firstItem->token->type=Token::ERROR; - else - addToken(new Token('\0',Token::ERROR)); - iter=size; // bail - } - break; + // Error ! is not not() + return NS_ERROR_XPATH_BAD_BANG; case EQUAL: - addToken(new Token(ch,Token::EQUAL_OP)); - ++iter; + newToken = new Token(mPosition, Token::EQUAL_OP); + ++mPosition; break; case L_ANGLE: - if (++iter < size && pattern.CharAt(iter) == EQUAL) { - addToken(new Token(Substring(pattern, ++iter - 2, 2), - Token::LESS_OR_EQUAL_OP)); + if (++mPosition == end) { + return NS_ERROR_XPATH_UNEXPECTED_END; + } + if (*mPosition == EQUAL) { + ++mPosition; + newToken = new Token(mPosition - 2, mPosition, + Token::LESS_OR_EQUAL_OP); + } + else { + newToken = new Token(mPosition - 1, Token::LESS_THAN_OP); } - else - addToken(new Token(ch,Token::LESS_THAN_OP)); break; case R_ANGLE: - if (++iter < size && pattern.CharAt(iter) == EQUAL) { - addToken(new Token(Substring(pattern, ++iter - 2, 2), - Token::GREATER_OR_EQUAL_OP)); + if (++mPosition == end) { + return NS_ERROR_XPATH_UNEXPECTED_END; + } + if (*mPosition == EQUAL) { + ++mPosition; + newToken = new Token(mPosition - 2, mPosition, + Token::GREATER_OR_EQUAL_OP); + } + else { + newToken = new Token(mPosition - 1, Token::GREATER_THAN_OP); } - else - addToken(new Token(ch,Token::GREATER_THAN_OP)); break; case HYPHEN : - addToken(new Token(ch,Token::SUBTRACTION_OP)); - ++iter; + newToken = new Token(mPosition, Token::SUBTRACTION_OP); + ++mPosition; break; case ASTERIX: - if (nextIsOperatorToken(prevToken)) - addToken(new Token(ch,Token::MULTIPLY_OP)); - else - addToken(new Token(ch,Token::CNAME)); - ++iter; + if (nextIsOperatorToken(prevToken)) { + newToken = new Token(mPosition, Token::MULTIPLY_OP); + } + else { + newToken = new Token(mPosition, Token::CNAME); + } + ++mPosition; break; case L_PAREN: - if (prevToken->type == Token::CNAME) { - if (TX_StringEqualsAtom(prevToken->value, txXPathAtoms::comment)) - prevToken->type = Token::COMMENT; - else if (TX_StringEqualsAtom(prevToken->value, txXPathAtoms::node)) - prevToken->type = Token::NODE; - else if (TX_StringEqualsAtom(prevToken->value, - txXPathAtoms::processingInstruction)) - prevToken->type = Token::PROC_INST; - else if (TX_StringEqualsAtom(prevToken->value, txXPathAtoms::text)) - prevToken->type = Token::TEXT; - else - prevToken->type = Token::FUNCTION_NAME; + if (prevToken->mType == Token::CNAME) { + NS_ConvertUTF16toUTF8 utf8Value(prevToken->Value()); + if (txXPathAtoms::comment->EqualsUTF8(utf8Value)) { + prevToken->mType = Token::COMMENT; + } + else if (txXPathAtoms::node->EqualsUTF8(utf8Value)) { + prevToken->mType = Token::NODE; + } + else if (txXPathAtoms::processingInstruction->EqualsUTF8(utf8Value)) { + prevToken->mType = Token::PROC_INST; + } + else if (txXPathAtoms::text->EqualsUTF8(utf8Value)) { + prevToken->mType = Token::TEXT; + } + else { + prevToken->mType = Token::FUNCTION_NAME; + } } - ++iter; - addToken(new Token(ch,Token::L_PAREN)); + newToken = new Token(mPosition, Token::L_PAREN); + ++mPosition; break; case R_PAREN: - ++iter; - addToken(new Token(ch,Token::R_PAREN)); + newToken = new Token(mPosition, Token::R_PAREN); + ++mPosition; break; case L_BRACKET: - ++iter; - addToken(new Token(ch,Token::L_BRACKET)); + newToken = new Token(mPosition, Token::L_BRACKET); + ++mPosition; break; case R_BRACKET: - ++iter; - addToken(new Token(ch,Token::R_BRACKET)); + newToken = new Token(mPosition, Token::R_BRACKET); + ++mPosition; break; case COMMA: - ++iter; - addToken(new Token(ch,Token::COMMA)); + newToken = new Token(mPosition, Token::COMMA); + ++mPosition; break; case AT_SIGN : - ++iter; - addToken(new Token(ch,Token::AT_SIGN)); + newToken = new Token(mPosition, Token::AT_SIGN); + ++mPosition; break; case PLUS: - ++iter; - addToken(new Token(ch,Token::ADDITION_OP)); + newToken = new Token(mPosition, Token::ADDITION_OP); + ++mPosition; break; case VERT_BAR: - ++iter; - addToken(new Token(ch,Token::UNION_OP)); + newToken = new Token(mPosition, Token::UNION_OP); + ++mPosition; break; default: // Error, don't grok character :-( - errorPos = iter; - errorCode = ERROR_UNKNOWN_CHAR; - if (firstItem) - firstItem->token->type=Token::ERROR; - else - addToken(new Token('\0',Token::ERROR)); - iter=size; // bail + return NS_ERROR_XPATH_ILLEGAL_CHAR; } } - } -} //-- parse + if (isToken) { + NS_ENSURE_TRUE(newToken, NS_ERROR_OUT_OF_MEMORY); + NS_ENSURE_TRUE(newToken != mLastItem, NS_ERROR_FAILURE); + prevToken = newToken; + addToken(newToken); + } + } + // add a endToken to the list + newToken = new Token(end, end, Token::END); + if (!newToken) { + return NS_ERROR_OUT_OF_MEMORY; + } + addToken(newToken); + + return NS_OK; +} diff --git a/extensions/transformiix/source/xpath/ExprLexer.h b/extensions/transformiix/source/xpath/ExprLexer.h index e1ebc3861079..2c6bdb42cf2f 100644 --- a/extensions/transformiix/source/xpath/ExprLexer.h +++ b/extensions/transformiix/source/xpath/ExprLexer.h @@ -39,18 +39,15 @@ * * This class was ported from XSL:P, an open source Java based * XSLT processor, written by yours truly. -**/ -class Token { - + */ +class Token +{ public: - //---------------/ - //- Token Types -/ - //---------------/ - - //-- LF - changed from static const short declarations to enum - //-- token types - enum TokenType { + /** + * Token types + */ + enum Type { //-- Trivial Tokens ERROR = 0, NULL_TOKEN, @@ -67,16 +64,16 @@ public: * start of tokens for 3.7, bullet 1 * ExprLexer::nextIsOperatorToken bails if the tokens aren't * consecutive. - **/ + */ COMMA, AT_SIGN, L_PAREN, L_BRACKET, AXIS_IDENTIFIER, - //-------------/ - //- operators -/ - //-------------/ + /** + * operators + */ //-- boolean ops AND_OP, // 16 OR_OP, @@ -101,7 +98,7 @@ public: UNION_OP, /** * end of tokens for 3.7, bullet 1 -/ - **/ + */ //-- node type tokens COMMENT, // 32 NODE, @@ -114,36 +111,83 @@ public: /** - * Default Constructor - **/ - Token(); - Token(short type); - Token(const nsAString& value, short type); - Token(PRUnichar uniChar, short type); - /** - * Copy Constructor - **/ - Token(const Token& token); + * Constructors + */ + typedef nsASingleFragmentString::const_char_iterator iterator; - ~Token(); - nsString value; - short type; -}; //--Token + Token(iterator aStart, iterator aEnd, Type aType) + : mStart(aStart), + mEnd(aEnd), + mType(aType), + mNext(nsnull), + mPrevious(nsnull) + { + } + Token(iterator aChar, Type aType) + : mStart(aChar), + mEnd(aChar + 1), + mType(aType), + mNext(nsnull), + mPrevious(nsnull) + { + } + + const nsDependentSingleFragmentSubstring Value() + { + return Substring(mStart, mEnd); + } + + iterator mStart, mEnd; + Type mType; + Token* mNext; + // XXX mPrevious needed for pushBack(), do we pushBack more than once? + Token* mPrevious; +}; /** * A class for splitting an "Expr" String into tokens and * performing basic Lexical Analysis. * * This class was ported from XSL:P, an open source Java based XSL processor -**/ -class ExprLexer { - + */ +class txExprLexer +{ public: - /* + txExprLexer(); + ~txExprLexer(); + + /** + * Parse the given string. + * returns an error result if lexing failed. + * The given string must outlive the use of the lexer, as the + * generated Tokens point to Substrings of it. + * mPosition points to the offending location in case of an error. + */ + nsresult parse(const nsASingleFragmentString& aPattern); + + typedef nsASingleFragmentString::const_char_iterator iterator; + iterator mPosition; + + /** + * Functions for iterating over the TokenList + */ + + Token* nextToken(); + Token* peek() + { + return mCurrentItem; + } + void pushBack(); + PRBool hasMoreTokens() + { + return (mCurrentItem->mType != Token::END); + } + + /** * Trivial Tokens - */ + */ //-- LF, changed to enum enum _TrivialTokens { D_QUOTE = '\"', @@ -173,77 +217,32 @@ public: TX_LF = '\r' }; - enum _error_consts { - ERROR_UNRESOLVED_VAR_REFERENCE = 0, - ERROR_OP_EXPECTED, - ERROR_UNCLOSED_LITERAL, - ERROR_COLON, - ERROR_BANG, - ERROR_UNKNOWN_CHAR - }; - PRUint32 errorPos; - short errorCode; - - /* - * Default Token Set - */ - static const Token TOKENS[]; - static const short NUMBER_OF_TOKENS; - - /** - * Constructor for ExprLexer - **/ - ExprLexer(const nsAFlatString& pattern); - - ~ExprLexer(); - - /** - * Functions for iterating over the TokenList - **/ - - Token* nextToken(); - Token* peek(); - void pushBack(); - MBool hasMoreTokens(); - private: - struct TokenListItem { - Token* token; - TokenListItem* next; - TokenListItem* previous; - }; + Token* mCurrentItem; + Token* mFirstItem; + Token* mLastItem; - TokenListItem* currentItem; - TokenListItem* firstItem; - TokenListItem* lastItem; + int mTokenCount; - int tokenCount; - - Token* prevToken; - Token endToken; - - void addToken(Token* token); + void addToken(Token* aToken); /** * Returns true if the following Token should be an operator. * This is a helper for the first bullet of [XPath 3.7] * Lexical Structure - **/ - MBool nextIsOperatorToken(Token* token); + */ + PRBool nextIsOperatorToken(Token* aToken); /** * Returns true if the given character represents a numeric letter (digit) * Implemented in ExprLexerChars.cpp - **/ - static MBool isXPathDigit(PRUnichar ch) + */ + static PRBool isXPathDigit(PRUnichar ch) { return (ch >= '0' && ch <= '9'); } - - void parse(const nsAFlatString& pattern); - -}; //-- ExprLexer +}; #endif diff --git a/extensions/transformiix/source/xpath/ExprParser.cpp b/extensions/transformiix/source/xpath/ExprParser.cpp index 995fe0fb9ff6..002fab39779d 100644 --- a/extensions/transformiix/source/xpath/ExprParser.cpp +++ b/extensions/transformiix/source/xpath/ExprParser.cpp @@ -51,7 +51,7 @@ * Creates an Attribute Value Template using the given value * This should move to XSLProcessor class **/ -AttributeValueTemplate* ExprParser::createAttributeValueTemplate +AttributeValueTemplate* txExprParser::createAttributeValueTemplate (const nsAFlatString& attValue, txIParseContext* aContext) { AttributeValueTemplate* avt = new AttributeValueTemplate(); @@ -121,9 +121,15 @@ AttributeValueTemplate* ExprParser::createAttributeValueTemplate case '}': if (inExpr) { inExpr = MB_FALSE; - ExprLexer lexer(buffer); - Expr* expr = createExpr(lexer, aContext); - if (!expr) { + txExprLexer lexer; + nsresult rv = lexer.parse(buffer); + if (NS_FAILED(rv)) { + delete avt; + return 0; + } + Expr* expr; + rv = createExpr(lexer, aContext, &expr); + if (NS_FAILED(rv)) { delete avt; return 0; } @@ -165,75 +171,128 @@ AttributeValueTemplate* ExprParser::createAttributeValueTemplate return avt; -} //-- createAttributeValueTemplate +} -Expr* ExprParser::createExpr(const nsAFlatString& aExpression, - txIParseContext* aContext) +nsresult +txExprParser::createExpr(const nsASingleFragmentString& aExpression, + txIParseContext* aContext, Expr** aExpr) { - ExprLexer lexer(aExpression); - Expr* expr = createExpr(lexer, aContext); - return expr; -} //-- createExpr + NS_ENSURE_ARG_POINTER(aExpr); + *aExpr = nsnull; + if (aExpression.IsEmpty()) { + return NS_OK; + } + txExprLexer lexer; + nsresult rv = lexer.parse(aExpression); + if (NS_FAILED(rv)) { + nsASingleFragmentString::const_char_iterator start; + aExpression.BeginReading(start); + aContext->SetErrorOffset(lexer.mPosition - start); + return rv; + } + rv = createExpr(lexer, aContext, aExpr); + if (NS_SUCCEEDED(rv) && lexer.peek()->mType != Token::END) { + rv = NS_ERROR_XPATH_BINARY_EXPECTED; + } + if (NS_FAILED(rv)) { + nsASingleFragmentString::const_char_iterator start; + aExpression.BeginReading(start); + aContext->SetErrorOffset(lexer.peek()->mStart - start); + } + return rv; +} - //--------------------/ - //- Private Methods -/ -//-------------------/ +/** + * Private Methods + */ /** * Creates a binary Expr for the given operator -**/ -Expr* ExprParser::createBinaryExpr (Expr* left, Expr* right, Token* op) { - if (!op) - return 0; - switch (op->type) { + */ +nsresult +txExprParser::createBinaryExpr(nsAutoPtr& left, nsAutoPtr& right, + Token* op, Expr** aResult) +{ + NS_ASSERTION(op, "internal error"); + *aResult = nsnull; + + Expr* expr = nsnull; + switch (op->mType) { //-- additive ops case Token::ADDITION_OP : - return new AdditiveExpr(left, right, AdditiveExpr::ADDITION); + expr = new AdditiveExpr(left, right, AdditiveExpr::ADDITION); + break; case Token::SUBTRACTION_OP: - return new AdditiveExpr(left, right, AdditiveExpr::SUBTRACTION); + expr = new AdditiveExpr(left, right, AdditiveExpr::SUBTRACTION); + break; //-- case boolean ops case Token::AND_OP: - return new BooleanExpr(left, right, BooleanExpr::AND); + expr = new BooleanExpr(left, right, BooleanExpr::AND); + break; case Token::OR_OP: - return new BooleanExpr(left, right, BooleanExpr::OR); + expr = new BooleanExpr(left, right, BooleanExpr::OR); + break; //-- equality ops case Token::EQUAL_OP : - return new RelationalExpr(left, right, RelationalExpr::EQUAL); + expr = new RelationalExpr(left, right, RelationalExpr::EQUAL); + break; case Token::NOT_EQUAL_OP : - return new RelationalExpr(left, right, RelationalExpr::NOT_EQUAL); + expr = new RelationalExpr(left, right, RelationalExpr::NOT_EQUAL); + break; //-- relational ops case Token::LESS_THAN_OP: - return new RelationalExpr(left, right, RelationalExpr::LESS_THAN); + expr = new RelationalExpr(left, right, RelationalExpr::LESS_THAN); + break; case Token::GREATER_THAN_OP: - return new RelationalExpr(left, right, RelationalExpr::GREATER_THAN); + expr = new RelationalExpr(left, right, + RelationalExpr::GREATER_THAN); + break; case Token::LESS_OR_EQUAL_OP: - return new RelationalExpr(left, right, RelationalExpr::LESS_OR_EQUAL); + expr = new RelationalExpr(left, right, + RelationalExpr::LESS_OR_EQUAL); + break; case Token::GREATER_OR_EQUAL_OP: - return new RelationalExpr(left, right, RelationalExpr::GREATER_OR_EQUAL); + expr = new RelationalExpr(left, right, + RelationalExpr::GREATER_OR_EQUAL); + break; //-- multiplicative ops case Token::DIVIDE_OP : - return new MultiplicativeExpr(left, right, MultiplicativeExpr::DIVIDE); - case Token::MODULUS_OP : - return new MultiplicativeExpr(left, right, MultiplicativeExpr::MODULUS); - case Token::MULTIPLY_OP : - return new MultiplicativeExpr(left, right, MultiplicativeExpr::MULTIPLY); - default: + expr = new MultiplicativeExpr(left, right, + MultiplicativeExpr::DIVIDE); break; - + case Token::MODULUS_OP : + expr = new MultiplicativeExpr(left, right, + MultiplicativeExpr::MODULUS); + break; + case Token::MULTIPLY_OP : + expr = new MultiplicativeExpr(left, right, + MultiplicativeExpr::MULTIPLY); + break; + default: + NS_NOTREACHED("operator tokens should be already checked"); + return NS_ERROR_UNEXPECTED; } - return 0; -} //-- createBinaryExpr + NS_ENSURE_TRUE(expr, NS_ERROR_OUT_OF_MEMORY); + + *aResult = expr; + return NS_OK; +} -Expr* ExprParser::createExpr(ExprLexer& lexer, txIParseContext* aContext) +nsresult +txExprParser::createExpr(txExprLexer& lexer, txIParseContext* aContext, + Expr** aResult) { + *aResult = nsnull; + + nsresult rv = NS_OK; MBool done = MB_FALSE; - Expr* expr = 0; + nsAutoPtr expr; txStack exprs; txStack ops; @@ -241,27 +300,27 @@ Expr* ExprParser::createExpr(ExprLexer& lexer, txIParseContext* aContext) while (!done) { MBool unary = MB_FALSE; - while (lexer.peek()->type == Token::SUBTRACTION_OP) { + while (lexer.peek()->mType == Token::SUBTRACTION_OP) { unary = !unary; lexer.nextToken(); } - expr = createUnionExpr(lexer, aContext); - if (!expr) + rv = createUnionExpr(lexer, aContext, getter_Transfers(expr)); + if (NS_FAILED(rv)) { break; + } if (unary) { Expr* uExpr = new UnaryExpr(expr); if (!uExpr) { - // XXX ErrorReport: out of memory - delete expr; - return 0; + rv = NS_ERROR_OUT_OF_MEMORY; + break; } expr = uExpr; } Token* tok = lexer.nextToken(); - switch (tok->type) { + switch (tok->mType) { case Token::ADDITION_OP: case Token::DIVIDE_OP: //-- boolean ops @@ -280,14 +339,19 @@ Expr* ExprParser::createExpr(ExprLexer& lexer, txIParseContext* aContext) case Token::MULTIPLY_OP: case Token::SUBTRACTION_OP: { - while (!exprs.isEmpty() && - precedenceLevel(tok->type) - <= precedenceLevel(((Token*)ops.peek())->type)) { - expr = createBinaryExpr((Expr*)exprs.pop(), - expr, - (Token*)ops.pop()); + while (!exprs.isEmpty() && precedence(tok) + <= precedence(NS_STATIC_CAST(Token*, ops.peek()))) { + // can't use expr as result due to order of evaluation + nsAutoPtr left(NS_STATIC_CAST(Expr*, exprs.pop())); + nsAutoPtr right(expr); + rv = createBinaryExpr(left, right, + NS_STATIC_CAST(Token*, ops.pop()), + getter_Transfers(expr)); + if (NS_FAILED(rv)) { + break; + } } - exprs.push(expr); + exprs.push(expr.forget()); ops.push(tok); break; } @@ -298,305 +362,293 @@ Expr* ExprParser::createExpr(ExprLexer& lexer, txIParseContext* aContext) } } - // make sure expr != 0 - if (!expr) { - while (!exprs.isEmpty()) { - delete (Expr*)exprs.pop(); - } - return 0; + while (NS_SUCCEEDED(rv) && !exprs.isEmpty()) { + nsAutoPtr left(NS_STATIC_CAST(Expr*, exprs.pop())); + nsAutoPtr right(expr); + rv = createBinaryExpr(left, right, NS_STATIC_CAST(Token*, ops.pop()), + getter_Transfers(expr)); } - + // clean up on error while (!exprs.isEmpty()) { - expr = createBinaryExpr((Expr*)exprs.pop(), expr, (Token*)ops.pop()); + delete NS_STATIC_CAST(Expr*, exprs.pop()); } + NS_ENSURE_SUCCESS(rv, rv); - return expr; + *aResult = expr.forget(); + return NS_OK; +} -} //-- createExpr - -Expr* ExprParser::createFilterExpr(ExprLexer& lexer, txIParseContext* aContext) +nsresult +txExprParser::createFilter(txExprLexer& lexer, txIParseContext* aContext, + Expr** aResult) { + *aResult = nsnull; + + nsresult rv = NS_OK; Token* tok = lexer.nextToken(); - Expr* expr = 0; - switch (tok->type) { + nsAutoPtr expr; + switch (tok->mType) { case Token::FUNCTION_NAME : lexer.pushBack(); - expr = createFunctionCall(lexer, aContext); + rv = createFunctionCall(lexer, aContext, getter_Transfers(expr)); + NS_ENSURE_SUCCESS(rv, rv); break; case Token::VAR_REFERENCE : { nsCOMPtr prefix, lName; PRInt32 nspace; - nsresult rv = resolveQName(tok->value, getter_AddRefs(prefix), + nsresult rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace); - if (NS_FAILED(rv)) { - // XXX error report namespace resolve failed - return 0; - } + NS_ENSURE_SUCCESS(rv, rv); expr = new VariableRefExpr(prefix, lName, nspace); + NS_ENSURE_TRUE(expr, NS_ERROR_OUT_OF_MEMORY); } break; case Token::L_PAREN: - expr = createExpr(lexer, aContext); - if (!expr) - return 0; + rv = createExpr(lexer, aContext, getter_Transfers(expr)); + NS_ENSURE_SUCCESS(rv, rv); - if (lexer.nextToken()->type != Token::R_PAREN) { + if (lexer.nextToken()->mType != Token::R_PAREN) { lexer.pushBack(); - //XXX ErrorReport: right parenthesis expected - delete expr; - return 0; + return NS_ERROR_XPATH_PAREN_EXPECTED; } break; case Token::LITERAL : - expr = new txLiteralExpr(tok->value); + expr = new txLiteralExpr(tok->Value()); + NS_ENSURE_TRUE(expr, NS_ERROR_OUT_OF_MEMORY); break; case Token::NUMBER: { - expr = new txLiteralExpr(Double::toDouble(tok->value)); + expr = new txLiteralExpr(Double::toDouble(tok->Value())); + NS_ENSURE_TRUE(expr, NS_ERROR_OUT_OF_MEMORY); break; } default: - // this should never ever happen. + NS_NOTREACHED("internal error, this is not a filter token"); lexer.pushBack(); - //XXX ErrorReport: error in parser, please report on bugzilla.mozilla.org - return 0; - break; - } - if (!expr) { - // XXX ErrorReport: out of memory - return 0; + return NS_ERROR_UNEXPECTED; } - if (lexer.peek()->type == Token::L_BRACKET) { - - FilterExpr* filterExpr = new FilterExpr(expr); - if (!filterExpr) { - // XXX ErrorReport: out of memory - delete expr; - return 0; - } + if (lexer.peek()->mType == Token::L_BRACKET) { + nsAutoPtr filterExpr(new FilterExpr(expr)); + NS_ENSURE_TRUE(filterExpr, NS_ERROR_OUT_OF_MEMORY); //-- handle predicates - if (!parsePredicates(filterExpr, lexer, aContext)) { - delete filterExpr; - return 0; - } - expr = filterExpr; + rv = parsePredicates(filterExpr, lexer, aContext); + NS_ENSURE_SUCCESS(rv, rv); + expr = filterExpr.forget(); } - return expr; + *aResult = expr.forget(); + return NS_OK; +} -} //-- createFilterExpr - -Expr* ExprParser::createFunctionCall(ExprLexer& lexer, - txIParseContext* aContext) +nsresult +txExprParser::createFunctionCall(txExprLexer& lexer, txIParseContext* aContext, + Expr** aResult) { - FunctionCall* fnCall = 0; + *aResult = nsnull; + + nsAutoPtr fnCall; Token* tok = lexer.nextToken(); - if (tok->type != Token::FUNCTION_NAME) { - //XXX ErrorReport: error in parser, please report on bugzilla.mozilla.org - return 0; - } + NS_ASSERTION(tok->mType == Token::FUNCTION_NAME, "FunctionCall expected"); //-- compare function names - //-- * we should hash these names for speed + nsCOMPtr prefix, lName; + PRInt32 namespaceID; + nsresult rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, + getter_AddRefs(lName), namespaceID); + NS_ENSURE_SUCCESS(rv, rv); - nsresult rv = NS_OK; - - if (TX_StringEqualsAtom(tok->value, txXPathAtoms::boolean)) { - fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_BOOLEAN); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::concat)) { - fnCall = new StringFunctionCall(StringFunctionCall::CONCAT); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::contains)) { - fnCall = new StringFunctionCall(StringFunctionCall::CONTAINS); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::count)) { - fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::COUNT); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::_false)) { - fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_FALSE); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::id)) { - fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::ID); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::lang)) { - fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_LANG); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::last)) { - fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::LAST); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::localName)) { - fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::LOCAL_NAME); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::name)) { - fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::NAME); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::namespaceUri)) { - fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::NAMESPACE_URI); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::normalizeSpace)) { - fnCall = new StringFunctionCall(StringFunctionCall::NORMALIZE_SPACE); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::_not)) { - fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_NOT); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::position)) { - fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::POSITION); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::startsWith)) { - fnCall = new StringFunctionCall(StringFunctionCall::STARTS_WITH); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::string)) { - fnCall = new StringFunctionCall(StringFunctionCall::STRING); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::stringLength)) { - fnCall = new StringFunctionCall(StringFunctionCall::STRING_LENGTH); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::substring)) { - fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::substringAfter)) { - fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING_AFTER); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::substringBefore)) { - fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING_BEFORE); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::sum)) { - fnCall = new NumberFunctionCall(NumberFunctionCall::SUM); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::translate)) { - fnCall = new StringFunctionCall(StringFunctionCall::TRANSLATE); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::_true)) { - fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_TRUE); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::number)) { - fnCall = new NumberFunctionCall(NumberFunctionCall::NUMBER); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::round)) { - fnCall = new NumberFunctionCall(NumberFunctionCall::ROUND); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::ceiling)) { - fnCall = new NumberFunctionCall(NumberFunctionCall::CEILING); - } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::floor)) { - fnCall = new NumberFunctionCall(NumberFunctionCall::FLOOR); - } - else { - nsCOMPtr prefix, lName; - PRInt32 namespaceID; - rv = resolveQName(tok->value, getter_AddRefs(prefix), aContext, - getter_AddRefs(lName), namespaceID); - if (NS_FAILED(rv)) { - // XXX error report namespace resolve failed - return 0; + if (namespaceID == kNameSpaceID_None) { + PRBool isOutOfMem = PR_TRUE; + if (lName == txXPathAtoms::boolean) { + fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_BOOLEAN); } - rv = aContext->resolveFunctionCall(lName, namespaceID, fnCall); - - // XXX We should have an errorfunction that always fails - // and use that here - if (rv == NS_ERROR_NOT_IMPLEMENTED || - rv == NS_ERROR_XPATH_UNKNOWN_FUNCTION) { - NS_ASSERTION(!fnCall, "Now is it implemented or not?"); - if (!parseParameters(0, lexer, aContext)) { - return 0; - } - return new txLiteralExpr(tok->value + - NS_LITERAL_STRING(" not implemented.")); + else if (lName == txXPathAtoms::concat) { + fnCall = new StringFunctionCall(StringFunctionCall::CONCAT); } - - if (NS_FAILED(rv)) { - return 0; + else if (lName == txXPathAtoms::contains) { + fnCall = new StringFunctionCall(StringFunctionCall::CONTAINS); + } + else if (lName == txXPathAtoms::count) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::COUNT); + } + else if (lName == txXPathAtoms::_false) { + fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_FALSE); + } + else if (lName == txXPathAtoms::id) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::ID); + } + else if (lName == txXPathAtoms::lang) { + fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_LANG); + } + else if (lName == txXPathAtoms::last) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::LAST); + } + else if (lName == txXPathAtoms::localName) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::LOCAL_NAME); + } + else if (lName == txXPathAtoms::name) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::NAME); + } + else if (lName == txXPathAtoms::namespaceUri) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::NAMESPACE_URI); + } + else if (lName == txXPathAtoms::normalizeSpace) { + fnCall = new StringFunctionCall(StringFunctionCall::NORMALIZE_SPACE); + } + else if (lName == txXPathAtoms::_not) { + fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_NOT); + } + else if (lName == txXPathAtoms::position) { + fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::POSITION); + } + else if (lName == txXPathAtoms::startsWith) { + fnCall = new StringFunctionCall(StringFunctionCall::STARTS_WITH); + } + else if (lName == txXPathAtoms::string) { + fnCall = new StringFunctionCall(StringFunctionCall::STRING); + } + else if (lName == txXPathAtoms::stringLength) { + fnCall = new StringFunctionCall(StringFunctionCall::STRING_LENGTH); + } + else if (lName == txXPathAtoms::substring) { + fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING); + } + else if (lName == txXPathAtoms::substringAfter) { + fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING_AFTER); + } + else if (lName == txXPathAtoms::substringBefore) { + fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING_BEFORE); + } + else if (lName == txXPathAtoms::sum) { + fnCall = new NumberFunctionCall(NumberFunctionCall::SUM); + } + else if (lName == txXPathAtoms::translate) { + fnCall = new StringFunctionCall(StringFunctionCall::TRANSLATE); + } + else if (lName == txXPathAtoms::_true) { + fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_TRUE); + } + else if (lName == txXPathAtoms::number) { + fnCall = new NumberFunctionCall(NumberFunctionCall::NUMBER); + } + else if (lName == txXPathAtoms::round) { + fnCall = new NumberFunctionCall(NumberFunctionCall::ROUND); + } + else if (lName == txXPathAtoms::ceiling) { + fnCall = new NumberFunctionCall(NumberFunctionCall::CEILING); + } + else if (lName == txXPathAtoms::floor) { + fnCall = new NumberFunctionCall(NumberFunctionCall::FLOOR); + } + else { + // didn't find functioncall here, fnCall should be null + isOutOfMem = PR_FALSE; + } + if (!fnCall && isOutOfMem) { + NS_ERROR("XPath FunctionLib failed on out-of-memory"); + return NS_ERROR_OUT_OF_MEMORY; } } - - // check that internal functions got created properly + // check extension functions and xslt if (!fnCall) { - // XXX ErrorReport: out of memory - return 0; + rv = aContext->resolveFunctionCall(lName, namespaceID, + *getter_Transfers(fnCall)); + + if (rv == NS_ERROR_NOT_IMPLEMENTED) { + // this should just happen for unparsed-entity-uri() + NS_ASSERTION(!fnCall, "Now is it implemented or not?"); + rv = parseParameters(0, lexer, aContext); + NS_ENSURE_SUCCESS(rv, rv); + *aResult = new txLiteralExpr(tok->Value() + + NS_LITERAL_STRING(" not implemented.")); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + return NS_OK; + } + + if (rv == NS_ERROR_XPATH_UNKNOWN_FUNCTION) { + // Don't throw parse error, just error on evaluation + fnCall = new txErrorFunctionCall(lName, namespaceID); + NS_ENSURE_TRUE(fnCall, NS_ERROR_OUT_OF_MEMORY); + } + else if (NS_FAILED(rv)) { + NS_ERROR("Creation of FunctionCall failed"); + return rv; + } } //-- handle parametes - if (!parseParameters(fnCall, lexer, aContext)) { - delete fnCall; - return 0; - } + rv = parseParameters(fnCall, lexer, aContext); + NS_ENSURE_SUCCESS(rv, rv); - return fnCall; -} //-- createFunctionCall + *aResult = fnCall.forget(); + return NS_OK; +} -LocationStep* ExprParser::createLocationStep(ExprLexer& lexer, - txIParseContext* aContext) +nsresult +txExprParser::createLocationStep(txExprLexer& lexer, txIParseContext* aContext, + Expr** aExpr) { + *aExpr = nsnull; + //-- child axis is default LocationStep::LocationStepType axisIdentifier = LocationStep::CHILD_AXIS; nsAutoPtr nodeTest; //-- get Axis Identifier or AbbreviatedStep, if present Token* tok = lexer.peek(); - switch (tok->type) { + switch (tok->mType) { case Token::AXIS_IDENTIFIER: { //-- eat token lexer.nextToken(); - //-- should switch to a hash here for speed if necessary - if (TX_StringEqualsAtom(tok->value, txXPathAtoms::ancestor)) { + nsCOMPtr axis = do_GetAtom(tok->Value()); + if (axis == txXPathAtoms::ancestor) { axisIdentifier = LocationStep::ANCESTOR_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::ancestorOrSelf)) { + else if (axis == txXPathAtoms::ancestorOrSelf) { axisIdentifier = LocationStep::ANCESTOR_OR_SELF_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::attribute)) { + else if (axis == txXPathAtoms::attribute) { axisIdentifier = LocationStep::ATTRIBUTE_AXIS; } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::child)) { + else if (axis == txXPathAtoms::child) { axisIdentifier = LocationStep::CHILD_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::descendant)) { + else if (axis == txXPathAtoms::descendant) { axisIdentifier = LocationStep::DESCENDANT_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::descendantOrSelf)) { + else if (axis == txXPathAtoms::descendantOrSelf) { axisIdentifier = LocationStep::DESCENDANT_OR_SELF_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::following)) { + else if (axis == txXPathAtoms::following) { axisIdentifier = LocationStep::FOLLOWING_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::followingSibling)) { + else if (axis == txXPathAtoms::followingSibling) { axisIdentifier = LocationStep::FOLLOWING_SIBLING_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::_namespace)) { + else if (axis == txXPathAtoms::_namespace) { axisIdentifier = LocationStep::NAMESPACE_AXIS; } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::parent)) { + else if (axis == txXPathAtoms::parent) { axisIdentifier = LocationStep::PARENT_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::preceding)) { + else if (axis == txXPathAtoms::preceding) { axisIdentifier = LocationStep::PRECEDING_AXIS; } - else if (TX_StringEqualsAtom(tok->value, - txXPathAtoms::precedingSibling)) { + else if (axis == txXPathAtoms::precedingSibling) { axisIdentifier = LocationStep::PRECEDING_SIBLING_AXIS; } - else if (TX_StringEqualsAtom(tok->value, txXPathAtoms::self)) { + else if (axis == txXPathAtoms::self) { axisIdentifier = LocationStep::SELF_AXIS; } else { - //XXX ErrorReport: unknow axis - return 0; + return NS_ERROR_XPATH_INVALID_AXIS; } break; } @@ -610,44 +662,34 @@ LocationStep* ExprParser::createLocationStep(ExprLexer& lexer, lexer.nextToken(); axisIdentifier = LocationStep::PARENT_AXIS; nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE); - if (!nodeTest) { - //XXX out of memory - return 0; - } + NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY); break; case Token::SELF_NODE : //-- eat token lexer.nextToken(); axisIdentifier = LocationStep::SELF_AXIS; nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE); - if (!nodeTest) { - //XXX out of memory - return 0; - } + NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY); break; default: break; } //-- get NodeTest unless an AbbreviatedStep was found + nsresult rv = NS_OK; if (!nodeTest) { tok = lexer.nextToken(); - switch (tok->type) { + switch (tok->mType) { case Token::CNAME : { // resolve QName nsCOMPtr prefix, lName; PRInt32 nspace; - nsresult rv = resolveQName(tok->value, - getter_AddRefs(prefix), - aContext, - getter_AddRefs(lName), nspace, - PR_TRUE); - if (NS_FAILED(rv)) { - // XXX error report namespace resolve failed - return 0; - } + rv = resolveQName(tok->Value(), getter_AddRefs(prefix), + aContext, getter_AddRefs(lName), + nspace, PR_TRUE); + NS_ENSURE_SUCCESS(rv, rv); switch (axisIdentifier) { case LocationStep::ATTRIBUTE_AXIS: nodeTest = new txNameTest(prefix, lName, nspace, @@ -658,47 +700,40 @@ LocationStep* ExprParser::createLocationStep(ExprLexer& lexer, Node::ELEMENT_NODE); break; } - } - if (!nodeTest) { - //XXX ErrorReport: out of memory - return 0; + NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY); } break; default: lexer.pushBack(); - nodeTest = createNodeTypeTest(lexer); - if (!nodeTest) { - return 0; - } + rv = createNodeTypeTest(lexer, getter_Transfers(nodeTest)); + NS_ENSURE_SUCCESS(rv, rv); } } - LocationStep* lstep = new LocationStep(nodeTest, axisIdentifier); - if (!lstep) { - //XXX out of memory - return 0; - } + nsAutoPtr lstep(new LocationStep(nodeTest, axisIdentifier)); + NS_ENSURE_TRUE(lstep, NS_ERROR_OUT_OF_MEMORY); //-- handle predicates - if (!parsePredicates(lstep, lexer, aContext)) { - delete lstep; - return 0; - } + rv = parsePredicates(lstep, lexer, aContext); + NS_ENSURE_SUCCESS(rv, rv); - return lstep; -} //-- createLocationPath + *aExpr = lstep.forget(); + return NS_OK; +} /** - * This method only handles comment(), text(), processing-instructing() and node() - * -**/ -txNodeTypeTest* ExprParser::createNodeTypeTest(ExprLexer& lexer) { - - txNodeTypeTest* nodeTest = 0; + * This method only handles comment(), text(), processing-instructing() + * and node() + */ +nsresult +txExprParser::createNodeTypeTest(txExprLexer& lexer, txNodeTest** aTest) +{ + *aTest = 0; + nsAutoPtr nodeTest; Token* nodeTok = lexer.nextToken(); - switch (nodeTok->type) { + switch (nodeTok->mType) { case Token::COMMENT: nodeTest = new txNodeTypeTest(txNodeTypeTest::COMMENT_TYPE); break; @@ -713,94 +748,91 @@ txNodeTypeTest* ExprParser::createNodeTypeTest(ExprLexer& lexer) { break; default: lexer.pushBack(); - // XXX ErrorReport: unexpected token - return 0; - } - if (!nodeTest) { - //XXX out of memory - return 0; + return NS_ERROR_XPATH_NO_NODE_TYPE_TEST; } + NS_ENSURE_TRUE(nodeTest, NS_ERROR_OUT_OF_MEMORY); - if (lexer.nextToken()->type != Token::L_PAREN) { + if (lexer.nextToken()->mType != Token::L_PAREN) { lexer.pushBack(); - //XXX ErrorReport: left parenthesis expected - delete nodeTest; - return 0; + NS_NOTREACHED("txExprLexer doesn't generate nodetypetest without("); + return NS_ERROR_UNEXPECTED; } - if (nodeTok->type == Token::PROC_INST && - lexer.peek()->type == Token::LITERAL) { + if (nodeTok->mType == Token::PROC_INST && + lexer.peek()->mType == Token::LITERAL) { Token* tok = lexer.nextToken(); - nodeTest->setNodeName(tok->value); + nodeTest->setNodeName(tok->Value()); } - if (lexer.nextToken()->type != Token::R_PAREN) { + if (lexer.nextToken()->mType != Token::R_PAREN) { lexer.pushBack(); - //XXX ErrorReport: right parenthesis expected (or literal for pi) - delete nodeTest; - return 0; + return NS_ERROR_XPATH_PAREN_EXPECTED; } - return nodeTest; -} //-- createNodeTypeTest + *aTest = nodeTest.forget(); + return NS_OK; +} /** - * Creates a PathExpr using the given ExprLexer - * @param lexer the ExprLexer for retrieving Tokens -**/ -Expr* ExprParser::createPathExpr(ExprLexer& lexer, txIParseContext* aContext) + * Creates a PathExpr using the given txExprLexer + * @param lexer the txExprLexer for retrieving Tokens + */ +nsresult +txExprParser::createPathExpr(txExprLexer& lexer, txIParseContext* aContext, + Expr** aResult) { - Expr* expr = 0; + *aResult = nsnull; + + nsAutoPtr expr; Token* tok = lexer.peek(); // is this a root expression? - if (tok->type == Token::PARENT_OP) { + if (tok->mType == Token::PARENT_OP) { lexer.nextToken(); - if (!isLocationStepToken(lexer.peek())) - return new RootExpr(MB_TRUE); - + if (!isLocationStepToken(lexer.peek())) { + *aResult = new RootExpr(MB_TRUE); + NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); + return NS_OK; + } lexer.pushBack(); } // parse first step (possibly a FilterExpr) - if (tok->type != Token::PARENT_OP && - tok->type != Token::ANCESTOR_OP) { + nsresult rv = NS_OK; + if (tok->mType != Token::PARENT_OP && + tok->mType != Token::ANCESTOR_OP) { if (isFilterExprToken(tok)) { - expr = createFilterExpr(lexer, aContext); + rv = createFilter(lexer, aContext, getter_Transfers(expr)); } - else - expr = createLocationStep(lexer, aContext); - - if (!expr) - return 0; + else { + rv = createLocationStep(lexer, aContext, getter_Transfers(expr)); + } + NS_ENSURE_SUCCESS(rv, rv); // is this a singlestep path expression? tok = lexer.peek(); - if (tok->type != Token::PARENT_OP && - tok->type != Token::ANCESTOR_OP) - return expr; + if (tok->mType != Token::PARENT_OP && + tok->mType != Token::ANCESTOR_OP) { + *aResult = expr.forget(); + return NS_OK; + } } else { expr = new RootExpr(MB_FALSE); - if (!expr) { - // XXX ErrorReport: out of memory - return 0; - } + NS_ENSURE_TRUE(expr, NS_ERROR_OUT_OF_MEMORY); } // We have a PathExpr containing several steps - PathExpr* pathExpr = new PathExpr(); - if (!pathExpr) { - // XXX ErrorReport: out of memory - delete expr; - return 0; - } - pathExpr->addExpr(expr, PathExpr::RELATIVE_OP); + nsAutoPtr pathExpr(new PathExpr()); + NS_ENSURE_TRUE(pathExpr, NS_ERROR_OUT_OF_MEMORY); + + rv = pathExpr->addExpr(expr.forget(), PathExpr::RELATIVE_OP); + NS_ENSURE_SUCCESS(rv, rv); // this is ugly while (1) { PathExpr::PathOperator pathOp; tok = lexer.nextToken(); - switch (tok->type) { + switch (tok->mType) { case Token::ANCESTOR_OP : pathOp = PathExpr::DESCENDANT_OP; break; @@ -809,125 +841,134 @@ Expr* ExprParser::createPathExpr(ExprLexer& lexer, txIParseContext* aContext) break; default: lexer.pushBack(); - return pathExpr; + *aResult = pathExpr.forget(); + return NS_OK; } - expr = createLocationStep(lexer, aContext); - if (!expr) { - delete pathExpr; - return 0; - } - - pathExpr->addExpr(expr, pathOp); - } + rv = createLocationStep(lexer, aContext, getter_Transfers(expr)); + NS_ENSURE_SUCCESS(rv, rv); - return pathExpr; -} //-- createPathExpr + rv = pathExpr->addExpr(expr.forget(), pathOp); + NS_ENSURE_SUCCESS(rv, rv); + } + NS_NOTREACHED("internal xpath parser error"); + return NS_ERROR_UNEXPECTED; +} /** - * Creates a PathExpr using the given ExprLexer - * XXX temporary use as top of XSLT Pattern - * @param lexer the ExprLexer for retrieving Tokens -**/ -Expr* ExprParser::createUnionExpr(ExprLexer& lexer, txIParseContext* aContext) + * Creates a PathExpr using the given txExprLexer + * @param lexer the txExprLexer for retrieving Tokens + */ +nsresult +txExprParser::createUnionExpr(txExprLexer& lexer, txIParseContext* aContext, + Expr** aResult) { - Expr* expr = createPathExpr(lexer, aContext); - if (!expr) - return 0; + *aResult = nsnull; + + nsAutoPtr expr; + nsresult rv = createPathExpr(lexer, aContext, getter_Transfers(expr)); + NS_ENSURE_SUCCESS(rv, rv); - if (lexer.peek()->type != Token::UNION_OP) - return expr; - - UnionExpr* unionExpr = new UnionExpr(); - if (!unionExpr) { - // XXX ErrorReport: out of memory - delete expr; - return 0; + if (lexer.peek()->mType != Token::UNION_OP) { + *aResult = expr.forget(); + return NS_OK; } - unionExpr->addExpr(expr); - while (lexer.peek()->type == Token::UNION_OP) { + nsAutoPtr unionExpr(new UnionExpr()); + NS_ENSURE_TRUE(unionExpr, NS_ERROR_OUT_OF_MEMORY); + + rv = unionExpr->addExpr(expr.forget()); + NS_ENSURE_SUCCESS(rv, rv); + + while (lexer.peek()->mType == Token::UNION_OP) { lexer.nextToken(); //-- eat token - expr = createPathExpr(lexer, aContext); - if (!expr) { - delete unionExpr; - return 0; - } - unionExpr->addExpr(expr); + rv = createPathExpr(lexer, aContext, getter_Transfers(expr)); + NS_ENSURE_SUCCESS(rv, rv); + + rv = unionExpr->addExpr(expr.forget()); + NS_ENSURE_SUCCESS(rv, rv); } - return unionExpr; -} //-- createUnionExpr + *aResult = unionExpr.forget(); + return NS_OK; +} -MBool ExprParser::isFilterExprToken(Token* token) { - switch (token->type) { +PRBool +txExprParser::isFilterExprToken(Token* aToken) +{ + switch (aToken->mType) { case Token::LITERAL: case Token::NUMBER: case Token::FUNCTION_NAME: case Token::VAR_REFERENCE: case Token::L_PAREN: // grouping expr - return MB_TRUE; + return PR_TRUE; default: - return MB_FALSE; + return PR_FALSE; } -} //-- isFilterExprToken +} -MBool ExprParser::isLocationStepToken(Token* token) { - switch (token->type) { +PRBool +txExprParser::isLocationStepToken(Token* aToken) +{ + switch (aToken->mType) { case Token::AXIS_IDENTIFIER : case Token::AT_SIGN : case Token::PARENT_NODE : case Token::SELF_NODE : - return MB_TRUE; + return PR_TRUE; default: - return isNodeTypeToken(token); + return isNodeTypeToken(aToken); } -} //-- isLocationStepToken +} -MBool ExprParser::isNodeTypeToken(Token* token) { - switch (token->type) { +PRBool +txExprParser::isNodeTypeToken(Token* aToken) +{ + switch (aToken->mType) { case Token::CNAME: case Token::COMMENT: case Token::NODE : case Token::PROC_INST : case Token::TEXT : - return MB_TRUE; + return PR_TRUE; default: - return MB_FALSE; + return PR_FALSE; } -} //-- isNodeTypeToken +} /** * Using the given lexer, parses the tokens if they represent a predicate list * If an error occurs a non-zero String pointer will be returned containing the * error message. * @param predicateList, the PredicateList to add predicate expressions to - * @param lexer the ExprLexer to use for parsing tokens + * @param lexer the txExprLexer to use for parsing tokens * @return 0 if successful, or a String pointer to the error message -**/ -MBool ExprParser::parsePredicates(PredicateList* predicateList, - ExprLexer& lexer, txIParseContext* aContext) + */ +nsresult +txExprParser::parsePredicates(PredicateList* aPredicateList, + txExprLexer& lexer, txIParseContext* aContext) { - while (lexer.peek()->type == Token::L_BRACKET) { + nsAutoPtr expr; + nsresult rv = NS_OK; + while (lexer.peek()->mType == Token::L_BRACKET) { //-- eat Token lexer.nextToken(); - Expr* expr = createExpr(lexer, aContext); - if (!expr) - return MB_FALSE; + rv = createExpr(lexer, aContext, getter_Transfers(expr)); + NS_ENSURE_SUCCESS(rv, rv); - predicateList->add(expr); + rv = aPredicateList->add(expr.forget()); + NS_ENSURE_SUCCESS(rv, rv); - if (lexer.nextToken()->type != Token::R_BRACKET) { + if (lexer.nextToken()->mType != Token::R_BRACKET) { lexer.pushBack(); - //XXX ErrorReport: right bracket expected - return MB_FALSE; + return NS_ERROR_XPATH_BRACKET_EXPECTED; } } - return MB_TRUE; - -} //-- parsePredicates + return NS_OK; +} /** @@ -935,51 +976,54 @@ MBool ExprParser::parsePredicates(PredicateList* predicateList, * If an error occurs a non-zero String pointer will be returned containing the * error message. * @param list, the List to add parameter expressions to - * @param lexer the ExprLexer to use for parsing tokens - * @return MB_TRUE if successful, or a MB_FALSE otherwise -**/ -MBool ExprParser::parseParameters(FunctionCall* fnCall, ExprLexer& lexer, - txIParseContext* aContext) + * @param lexer the txExprLexer to use for parsing tokens + * @return NS_OK if successful, or another rv otherwise + */ +nsresult +txExprParser::parseParameters(FunctionCall* aFnCall, txExprLexer& lexer, + txIParseContext* aContext) { - if (lexer.nextToken()->type != Token::L_PAREN) { + if (lexer.nextToken()->mType != Token::L_PAREN) { lexer.pushBack(); - //XXX ErrorReport: left parenthesis expected - return MB_FALSE; + NS_NOTREACHED("txExprLexer doesn't generate functions without("); + return NS_ERROR_UNEXPECTED; } - if (lexer.peek()->type == Token::R_PAREN) { + if (lexer.peek()->mType == Token::R_PAREN) { lexer.nextToken(); - return MB_TRUE; + return NS_OK; } + nsAutoPtr expr; + nsresult rv = NS_OK; while (1) { - Expr* expr = createExpr(lexer, aContext); - if (!expr) - return MB_FALSE; + rv = createExpr(lexer, aContext, getter_Transfers(expr)); + NS_ENSURE_SUCCESS(rv, rv); - if (fnCall) - fnCall->addParam(expr); - else - delete expr; - - switch (lexer.nextToken()->type) { + if (aFnCall) { + rv = aFnCall->addParam(expr.forget()); + NS_ENSURE_SUCCESS(rv, rv); + } + + switch (lexer.nextToken()->mType) { case Token::R_PAREN : - return MB_TRUE; + return NS_OK; case Token::COMMA: //-- param separator break; default: lexer.pushBack(); - //XXX ErrorReport: right parenthesis or comma expected - return MB_FALSE; + return NS_ERROR_XPATH_PAREN_EXPECTED; } } - return MB_FALSE; + NS_NOTREACHED("internal xpath parser error"); + return NS_ERROR_UNEXPECTED; +} -} //-- parseParameters - -short ExprParser::precedenceLevel(short tokenType) { - switch (tokenType) { +short +txExprParser::precedence(Token* aToken) +{ + switch (aToken->mType) { case Token::OR_OP: return 1; case Token::AND_OP: @@ -1009,10 +1053,11 @@ short ExprParser::precedenceLevel(short tokenType) { return 0; } -nsresult ExprParser::resolveQName(const nsAString& aQName, - nsIAtom** aPrefix, txIParseContext* aContext, - nsIAtom** aLocalName, PRInt32& aNamespace, - PRBool aIsNameTest) +nsresult +txExprParser::resolveQName(const nsAString& aQName, + nsIAtom** aPrefix, txIParseContext* aContext, + nsIAtom** aLocalName, PRInt32& aNamespace, + PRBool aIsNameTest) { aNamespace = kNameSpaceID_None; PRInt32 idx = aQName.FindChar(':'); diff --git a/extensions/transformiix/source/xpath/ExprParser.h b/extensions/transformiix/source/xpath/ExprParser.h index f92a86346132..2bb44c9ff654 100644 --- a/extensions/transformiix/source/xpath/ExprParser.h +++ b/extensions/transformiix/source/xpath/ExprParser.h @@ -35,10 +35,11 @@ #include "baseutils.h" #include "nsIAtom.h" #include "txError.h" +#include "Expr.h" class AttributeValueTemplate; class Expr; -class ExprLexer; +class txExprLexer; class FunctionCall; class LocationStep; class PredicateList; @@ -46,42 +47,57 @@ class Token; class txIParseContext; class txNodeTypeTest; -class ExprParser +class txExprParser { public: - static Expr* createExpr(const nsAFlatString& aExpression, - txIParseContext* aContext); + static nsresult createExpr(const nsASingleFragmentString& aExpression, + txIParseContext* aContext, Expr** aExpr); /** * Creates an Attribute Value Template using the given value - **/ + */ static AttributeValueTemplate* createAttributeValueTemplate (const nsAFlatString& attValue, txIParseContext* aContext); protected: - static Expr* createBinaryExpr(Expr* left, Expr* right, Token* op); - static Expr* createExpr(ExprLexer& lexer, txIParseContext* aContext); - static Expr* createFilterExpr(ExprLexer& lexer, txIParseContext* aContext); - static Expr* createFunctionCall(ExprLexer& lexer, - txIParseContext* aContext); - static LocationStep* createLocationStep(ExprLexer& lexer, - txIParseContext* aContext); - static txNodeTypeTest* createNodeTypeTest(ExprLexer& lexer); - static Expr* createPathExpr(ExprLexer& lexer, txIParseContext* aContext); - static Expr* createUnionExpr(ExprLexer& lexer, txIParseContext* aContext); + /** + * Using nsAutoPtr& to optimize passing the ownership to the + * created binary expression objects. + */ + static nsresult createBinaryExpr(nsAutoPtr& left, + nsAutoPtr& right, Token* op, + Expr** aResult); + static nsresult createExpr(txExprLexer& lexer, txIParseContext* aContext, + Expr** aResult); + static nsresult createFilter(txExprLexer& lexer, txIParseContext* aContext, + Expr** aResult); + static nsresult createFunctionCall(txExprLexer& lexer, + txIParseContext* aContext, + Expr** aResult); + static nsresult createLocationStep(txExprLexer& lexer, + txIParseContext* aContext, + Expr** aResult); + static nsresult createNodeTypeTest(txExprLexer& lexer, + txNodeTest** aResult); + static nsresult createPathExpr(txExprLexer& lexer, + txIParseContext* aContext, + Expr** aResult); + static nsresult createUnionExpr(txExprLexer& lexer, + txIParseContext* aContext, + Expr** aResult); - static MBool isFilterExprToken (Token* tok); - static MBool isLocationStepToken(Token* tok); - static MBool isNodeTypeToken (Token* tok); + static PRBool isFilterExprToken(Token* aToken); + static PRBool isLocationStepToken(Token* aToken); + static PRBool isNodeTypeToken(Token* aToken); - static short precedenceLevel (short tokenType); + static short precedence(Token* aToken); /** * Resolve a QName, given the mContext parse context. * Returns prefix and localName as well as namespace ID - **/ + */ static nsresult resolveQName(const nsAString& aQName, nsIAtom** aPrefix, txIParseContext* aContext, nsIAtom** aLocalName, PRInt32& aNamespace, @@ -95,12 +111,13 @@ protected: * @param predicateList, the PredicateList to add predicate expressions to * @param lexer the ExprLexer to use for parsing tokens * @return 0 if successful, or a String pointer to the error message - **/ - static MBool parsePredicates(PredicateList* predicateList, - ExprLexer& lexer, txIParseContext* aContext); - static MBool parseParameters(FunctionCall* fnCall, - ExprLexer& lexer, txIParseContext* aContext); + */ + static nsresult parsePredicates(PredicateList* aPredicateList, + txExprLexer& lexer, + txIParseContext* aContext); + static nsresult parseParameters(FunctionCall* aFnCall, txExprLexer& lexer, + txIParseContext* aContext); -}; //-- ExprParser +}; #endif diff --git a/extensions/transformiix/source/xpath/FilterExpr.cpp b/extensions/transformiix/source/xpath/FilterExpr.cpp index 9f77dc58056a..86df20bac9c2 100644 --- a/extensions/transformiix/source/xpath/FilterExpr.cpp +++ b/extensions/transformiix/source/xpath/FilterExpr.cpp @@ -31,21 +31,6 @@ //-- Implementation of FilterExpr --/ -/** - * Creates a new FilterExpr using the given Expr - * @param expr the Expr to use for evaluation -**/ -FilterExpr::FilterExpr(Expr* expr) : PredicateList() { - this->expr = expr; -} //-- FilterExpr - -/** - * Destroys this FilterExpr, all predicates and the expr will be deleted -**/ -FilterExpr::~FilterExpr() { - delete expr; -} //-- ~FilterExpr - //-----------------------------/ //- Virtual methods from Expr -/ //-----------------------------/ diff --git a/extensions/transformiix/source/xpath/FunctionCall.cpp b/extensions/transformiix/source/xpath/FunctionCall.cpp index f8d75c52faee..183061eed9df 100644 --- a/extensions/transformiix/source/xpath/FunctionCall.cpp +++ b/extensions/transformiix/source/xpath/FunctionCall.cpp @@ -23,7 +23,7 @@ * */ -#include "Expr.h" +#include "FunctionLib.h" #include "ExprResult.h" #include "nsIAtom.h" #include "txIXPathContext.h" @@ -55,12 +55,16 @@ FunctionCall::~FunctionCall() /** * Adds the given parameter to this FunctionCall's parameter list * @param expr the Expr to add to this FunctionCall's parameter list -**/ -nsresult FunctionCall::addParam(Expr* aExpr) + */ +nsresult +FunctionCall::addParam(Expr* aExpr) { - if (aExpr) - params.add(aExpr); - return NS_OK; + NS_ASSERTION(aExpr, "missing expression"); + nsresult rv = params.add(aExpr); + if (NS_FAILED(rv)) { + delete aExpr; + } + return rv; } //-- addParam /* @@ -183,3 +187,27 @@ void FunctionCall::toString(nsAString& aDest) } aDest.Append(PRUnichar(')')); } + +/** + * Implementation of txErrorFunctionCall + * + * Used for fcp and unknown extension functions. + */ + +nsresult +txErrorFunctionCall::evaluate(txIEvalContext* aContext, + txAExprResult** aResult) +{ + *aResult = nsnull; + + return NS_ERROR_XPATH_BAD_EXTENSION_FUNCTION; +} + +nsresult +txErrorFunctionCall::getNameAtom(nsIAtom** aAtom) +{ + *aAtom = mLName; + NS_IF_ADDREF(*aAtom); + + return NS_OK; +} diff --git a/extensions/transformiix/source/xpath/FunctionLib.h b/extensions/transformiix/source/xpath/FunctionLib.h index b4ef7fa61f84..36dc6ac791eb 100644 --- a/extensions/transformiix/source/xpath/FunctionLib.h +++ b/extensions/transformiix/source/xpath/FunctionLib.h @@ -85,24 +85,26 @@ private: }; //-- BooleanFunctionCall /** - * Internal Function created when there is an Error during parsing - * an Expression -**/ -class ErrorFunctionCall : public FunctionCall { + * Error Function to be used for unknown extension functions and + * forwards-compatible-processing (not implemented, bug XXX) + * + * txErrorFunctionCall returns NS_ERROR_XPATH_UNKNOWN_FUNCTION + * (see FunctionCall.cpp) + */ +class txErrorFunctionCall : public FunctionCall +{ public: - - ErrorFunctionCall(); - ErrorFunctionCall(const nsAString& errorMsg); + txErrorFunctionCall(nsIAtom* aLName, const PRInt32 aID) + : mLName(aLName), + mID(aID) + {} TX_DECL_FUNCTION; - void setErrorMessage(nsAString& errorMsg); - private: - - nsString errorMessage; - -}; //-- ErrorFunctionCall + nsCOMPtr mLName; + PRInt32 mID; +}; /* * A representation of the XPath NodeSet funtions diff --git a/extensions/transformiix/source/xpath/LocationStep.cpp b/extensions/transformiix/source/xpath/LocationStep.cpp index 35b38a8d5786..cca376585e7f 100644 --- a/extensions/transformiix/source/xpath/LocationStep.cpp +++ b/extensions/transformiix/source/xpath/LocationStep.cpp @@ -31,17 +31,6 @@ #include "NodeSet.h" #include "txIXPathContext.h" -/** - * Creates a new LocationStep using the given NodeExpr and Axis Identifier - * @param nodeExpr the NodeExpr to use when matching Nodes - * @param axisIdentifier the Axis Identifier in which to search for nodes -**/ -LocationStep::LocationStep(nsAutoPtr aNodeTest, - LocationStepType aAxisIdentifier) - : mNodeTest(aNodeTest), mAxisIdentifier(aAxisIdentifier) -{ -} //-- LocationStep - //-----------------------------/ //- Virtual methods from Expr -/ //-----------------------------/ diff --git a/extensions/transformiix/source/xpath/MultiplicativeExpr.cpp b/extensions/transformiix/source/xpath/MultiplicativeExpr.cpp index 1618a77c4c35..b75d6f30bb2c 100644 --- a/extensions/transformiix/source/xpath/MultiplicativeExpr.cpp +++ b/extensions/transformiix/source/xpath/MultiplicativeExpr.cpp @@ -41,20 +41,6 @@ #include "primitives.h" #include "txIXPathContext.h" -/** - * Creates a new MultiplicativeExpr using the given operator -**/ -MultiplicativeExpr::MultiplicativeExpr(Expr* leftExpr, Expr* rightExpr, short op) { - this->op = op; - this->leftExpr = leftExpr; - this->rightExpr = rightExpr; -} //-- MultiplicativeExpr - -MultiplicativeExpr::~MultiplicativeExpr() { - delete leftExpr; - delete rightExpr; -} //-- ~MultiplicativeExpr - /** * Evaluates this Expr based on the given context node and processor state * @param context the context node for evaluation of this Expr diff --git a/extensions/transformiix/source/xpath/PathExpr.cpp b/extensions/transformiix/source/xpath/PathExpr.cpp index 27c6fc538d68..3673e2ec1127 100644 --- a/extensions/transformiix/source/xpath/PathExpr.cpp +++ b/extensions/transformiix/source/xpath/PathExpr.cpp @@ -56,9 +56,7 @@ PathExpr::~PathExpr() { txListIterator iter(&expressions); while (iter.hasNext()) { - PathExprItem* pxi = (PathExprItem*)iter.next(); - delete pxi->expr; - delete pxi; + delete NS_STATIC_CAST(PathExprItem*, iter.next()); } } //-- ~PathExpr @@ -66,22 +64,22 @@ PathExpr::~PathExpr() * Adds the Expr to this PathExpr * @param expr the Expr to add to this PathExpr **/ -void PathExpr::addExpr(Expr* expr, PathOperator pathOp) +nsresult +PathExpr::addExpr(Expr* aExpr, PathOperator pathOp) { NS_ASSERTION(expressions.getLength() > 0 || pathOp == RELATIVE_OP, "First step has to be relative in PathExpr"); - if (expr) { - PathExprItem* pxi = new PathExprItem; - if (!pxi) { - // XXX ErrorReport: out of memory - NS_ASSERTION(0, "out of memory"); - return; - } - pxi->expr = expr; - pxi->pathOp = pathOp; - expressions.add(pxi); + PathExprItem* pxi = new PathExprItem(aExpr, pathOp); + if (!pxi) { + delete aExpr; + return NS_ERROR_OUT_OF_MEMORY; } -} //-- addPattenExpr + nsresult rv = expressions.add(pxi); + if (NS_FAILED(rv)) { + delete pxi; + } + return rv; +} //-- addExpr //-----------------------------/ //- Virtual methods from Expr -/ diff --git a/extensions/transformiix/source/xpath/PredicateList.cpp b/extensions/transformiix/source/xpath/PredicateList.cpp index 51e92963e95d..ec456d24dde2 100644 --- a/extensions/transformiix/source/xpath/PredicateList.cpp +++ b/extensions/transformiix/source/xpath/PredicateList.cpp @@ -51,9 +51,15 @@ PredicateList::~PredicateList() * Adds the given Expr to the list * @param expr the Expr to add to the list */ -void PredicateList::add(Expr* expr) +nsresult +PredicateList::add(Expr* aExpr) { - predicates.add(expr); + NS_ASSERTION(aExpr, "missing expression"); + nsresult rv = predicates.add(aExpr); + if (NS_FAILED(rv)) { + delete aExpr; + } + return rv; } // add nsresult diff --git a/extensions/transformiix/source/xpath/RelationalExpr.cpp b/extensions/transformiix/source/xpath/RelationalExpr.cpp index 1f45fbdf7a25..dd819b84dff2 100644 --- a/extensions/transformiix/source/xpath/RelationalExpr.cpp +++ b/extensions/transformiix/source/xpath/RelationalExpr.cpp @@ -32,12 +32,6 @@ #include "XMLDOMUtils.h" #include "txIXPathContext.h" -RelationalExpr::RelationalExpr(Expr* aLeftExpr, Expr* aRightExpr, - RelationalExprType aOp) - : mLeftExpr(aLeftExpr), mRightExpr(aRightExpr), mOp(aOp) -{ -} - /** * Compares the two ExprResults based on XPath 1.0 Recommendation (section 3.4) */ diff --git a/extensions/transformiix/source/xpath/UnaryExpr.cpp b/extensions/transformiix/source/xpath/UnaryExpr.cpp index 2b6598472335..aa7ab8c80ea9 100644 --- a/extensions/transformiix/source/xpath/UnaryExpr.cpp +++ b/extensions/transformiix/source/xpath/UnaryExpr.cpp @@ -27,16 +27,6 @@ #include "ExprResult.h" #include "txIXPathContext.h" -UnaryExpr::UnaryExpr(Expr* expr) -{ - this->expr = expr; -} - -UnaryExpr::~UnaryExpr() -{ - delete expr; -} - /* * Evaluates this Expr based on the given context node and processor state * @param context the context node for evaluation of this Expr diff --git a/extensions/transformiix/source/xpath/UnionExpr.cpp b/extensions/transformiix/source/xpath/UnionExpr.cpp index 12153e62529e..667b8700a2ad 100644 --- a/extensions/transformiix/source/xpath/UnionExpr.cpp +++ b/extensions/transformiix/source/xpath/UnionExpr.cpp @@ -53,9 +53,14 @@ UnionExpr::~UnionExpr() { * Adds the Expr to this UnionExpr * @param expr the Expr to add to this UnionExpr **/ -void UnionExpr::addExpr(Expr* expr) { - if (expr) - expressions.add(expr); +nsresult +UnionExpr::addExpr(Expr* aExpr) +{ + nsresult rv = expressions.add(aExpr); + if (NS_FAILED(rv)) { + delete aExpr; + } + return rv; } //-- addExpr //-----------------------------/ diff --git a/extensions/transformiix/source/xpath/nsXPathEvaluator.cpp b/extensions/transformiix/source/xpath/nsXPathEvaluator.cpp index f5c753681547..476d48be3d4c 100644 --- a/extensions/transformiix/source/xpath/nsXPathEvaluator.cpp +++ b/extensions/transformiix/source/xpath/nsXPathEvaluator.cpp @@ -89,10 +89,12 @@ nsXPathEvaluator::CreateExpression(const nsAString & aExpression, nsCOMPtr doc = do_QueryReferent(mDocument); ParseContextImpl pContext(aResolver, !doc || doc->IsCaseSensitive()); - Expr* expression = ExprParser::createExpr(PromiseFlatString(aExpression), - &pContext); - if (!expression) + Expr* expression; + rv = ExprParser::createExpr(PromiseFlatString(aExpression), &pContext, + &expression); + if (NS_FAILED(rv)) { return NS_ERROR_DOM_INVALID_EXPRESSION_ERR; + } *aResult = new nsXPathExpression(expression, mRecycler); if (!*aResult) { @@ -179,11 +181,12 @@ nsresult nsXPathEvaluator::ParseContextImpl::resolveNamespacePrefix return gTxNameSpaceManager->RegisterNameSpace(ns, aID); } -nsresult nsXPathEvaluator::ParseContextImpl::resolveFunctionCall(nsIAtom* aName, - PRInt32 aID, - FunctionCall*& aFn) +nsresult +nsXPathEvaluator::ParseContextImpl::resolveFunctionCall(nsIAtom* aName, + PRInt32 aID, + FunctionCall*& aFn) { - return NS_ERROR_XPATH_PARSE_FAILURE; + return NS_ERROR_XPATH_UNKNOWN_FUNCTION; } PRBool nsXPathEvaluator::ParseContextImpl::caseInsensitiveNameTests() @@ -191,9 +194,7 @@ PRBool nsXPathEvaluator::ParseContextImpl::caseInsensitiveNameTests() return !mIsCaseSensitive; } -void nsXPathEvaluator::ParseContextImpl::receiveError(const nsAString& aMsg, - nsresult aRes) +void +nsXPathEvaluator::ParseContextImpl::SetErrorOffset(PRUint32 aOffset) { - mLastError = aRes; - // forward aMsg to console service? } diff --git a/extensions/transformiix/source/xpath/nsXPathEvaluator.h b/extensions/transformiix/source/xpath/nsXPathEvaluator.h index 479e074639a4..e8e71bbc06ba 100644 --- a/extensions/transformiix/source/xpath/nsXPathEvaluator.h +++ b/extensions/transformiix/source/xpath/nsXPathEvaluator.h @@ -93,7 +93,7 @@ private: nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID, FunctionCall*& aFunction); PRBool caseInsensitiveNameTests(); - void receiveError(const nsAString& aMsg, nsresult aRes); + void SetErrorOffset(PRUint32 aOffset); private: nsIDOMXPathNSResolver* mResolver; diff --git a/extensions/transformiix/source/xpath/txIXPathContext.h b/extensions/transformiix/source/xpath/txIXPathContext.h index 7b4804afbd12..9b47daf35f79 100644 --- a/extensions/transformiix/source/xpath/txIXPathContext.h +++ b/extensions/transformiix/source/xpath/txIXPathContext.h @@ -84,7 +84,7 @@ public: /* * Callback to be used by the Parser if errors are detected. */ - virtual void receiveError(const nsAString& aMsg, nsresult aRes) = 0; + virtual void SetErrorOffset(PRUint32 aOffset) = 0; }; /* diff --git a/extensions/transformiix/source/xslt/txPatternParser.cpp b/extensions/transformiix/source/xslt/txPatternParser.cpp index 3cde8c149736..23d7d52badf8 100644 --- a/extensions/transformiix/source/xslt/txPatternParser.cpp +++ b/extensions/transformiix/source/xslt/txPatternParser.cpp @@ -47,8 +47,13 @@ txPattern* txPatternParser::createPattern(const nsAFlatString& aPattern, txIParseContext* aContext) { txPattern* pattern = 0; - ExprLexer lexer(aPattern); - nsresult rv = createUnionPattern(lexer, aContext, pattern); + txExprLexer lexer; + nsresult rv = lexer.parse(aPattern); + if (NS_FAILED(rv)) { + // XXX error report parsing error + return 0; + } + rv = createUnionPattern(lexer, aContext, pattern); if (NS_FAILED(rv)) { // XXX error report parsing error return 0; @@ -56,7 +61,7 @@ txPattern* txPatternParser::createPattern(const nsAFlatString& aPattern, return pattern; } -nsresult txPatternParser::createUnionPattern(ExprLexer& aLexer, +nsresult txPatternParser::createUnionPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { @@ -67,7 +72,7 @@ nsresult txPatternParser::createUnionPattern(ExprLexer& aLexer, if (NS_FAILED(rv)) return rv; - short type = aLexer.peek()->type; + Token::Type type = aLexer.peek()->mType; if (type == Token::END) { aPattern = locPath; return NS_OK; @@ -107,7 +112,7 @@ nsresult txPatternParser::createUnionPattern(ExprLexer& aLexer, return rv; } #endif - type = aLexer.nextToken()->type; + type = aLexer.nextToken()->mType; } while (type == Token::UNION_OP); if (type != Token::END) { @@ -119,7 +124,7 @@ nsresult txPatternParser::createUnionPattern(ExprLexer& aLexer, return NS_OK; } -nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer, +nsresult txPatternParser::createLocPathPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { @@ -130,7 +135,7 @@ nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer, txPattern* stepPattern = 0; txLocPathPattern* pathPattern = 0; - short type = aLexer.peek()->type; + Token::Type type = aLexer.peek()->mType; switch (type) { case Token::ANCESTOR_OP: isChild = MB_FALSE; @@ -140,8 +145,8 @@ nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer, case Token::PARENT_OP: aLexer.nextToken(); isAbsolute = MB_TRUE; - if (aLexer.peek()->type == Token::END || - aLexer.peek()->type == Token::UNION_OP) { + if (aLexer.peek()->mType == Token::END || + aLexer.peek()->mType == Token::UNION_OP) { aPattern = new txRootPattern(MB_TRUE); return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } @@ -149,7 +154,8 @@ nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer, case Token::FUNCTION_NAME: // id(Literal) or key(Literal, Literal) { - nsCOMPtr nameAtom = do_GetAtom(aLexer.nextToken()->value); + nsCOMPtr nameAtom = + do_GetAtom(aLexer.nextToken()->Value()); if (nameAtom == txXPathAtoms::id) { rv = createIdPattern(aLexer, stepPattern); } @@ -169,7 +175,7 @@ nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer, return rv; } - type = aLexer.peek()->type; + type = aLexer.peek()->mType; if (!isAbsolute && type != Token::PARENT_OP && type != Token::ANCESTOR_OP) { aPattern = stepPattern; @@ -221,40 +227,43 @@ nsresult txPatternParser::createLocPathPattern(ExprLexer& aLexer, return NS_ERROR_OUT_OF_MEMORY; } stepPattern = 0; // stepPattern is part of pathPattern now - type = aLexer.peek()->type; + type = aLexer.peek()->mType; } aPattern = pathPattern; return rv; } -nsresult txPatternParser::createIdPattern(ExprLexer& aLexer, +nsresult txPatternParser::createIdPattern(txExprLexer& aLexer, txPattern*& aPattern) { // check for '(' Literal ')' - if (aLexer.nextToken()->type != Token::L_PAREN && - aLexer.peek()->type != Token::LITERAL) + if (aLexer.nextToken()->mType != Token::L_PAREN && + aLexer.peek()->mType != Token::LITERAL) return NS_ERROR_XPATH_PARSE_FAILURE; - const nsString& value = aLexer.nextToken()->value; - if (aLexer.nextToken()->type != Token::R_PAREN) + const nsDependentSingleFragmentSubstring& value = + aLexer.nextToken()->Value(); + if (aLexer.nextToken()->mType != Token::R_PAREN) return NS_ERROR_XPATH_PARSE_FAILURE; aPattern = new txIdPattern(value); return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } -nsresult txPatternParser::createKeyPattern(ExprLexer& aLexer, +nsresult txPatternParser::createKeyPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { // check for '(' Literal, Literal ')' - if (aLexer.nextToken()->type != Token::L_PAREN && - aLexer.peek()->type != Token::LITERAL) + if (aLexer.nextToken()->mType != Token::L_PAREN && + aLexer.peek()->mType != Token::LITERAL) return NS_ERROR_XPATH_PARSE_FAILURE; - const nsString& key = aLexer.nextToken()->value; - if (aLexer.nextToken()->type != Token::COMMA && - aLexer.peek()->type != Token::LITERAL) + const nsDependentSingleFragmentSubstring& key = + aLexer.nextToken()->Value(); + if (aLexer.nextToken()->mType != Token::COMMA && + aLexer.peek()->mType != Token::LITERAL) return NS_ERROR_XPATH_PARSE_FAILURE; - const nsString& value = aLexer.nextToken()->value; - if (aLexer.nextToken()->type != Token::R_PAREN) + const nsDependentSingleFragmentSubstring& value = + aLexer.nextToken()->Value(); + if (aLexer.nextToken()->mType != Token::R_PAREN) return NS_ERROR_XPATH_PARSE_FAILURE; if (!XMLUtils::isValidQName(key)) @@ -271,36 +280,36 @@ nsresult txPatternParser::createKeyPattern(ExprLexer& aLexer, return aPattern ? NS_OK : NS_ERROR_OUT_OF_MEMORY; } -nsresult txPatternParser::createStepPattern(ExprLexer& aLexer, +nsresult txPatternParser::createStepPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern) { nsresult rv = NS_OK; MBool isAttr = MB_FALSE; Token* tok = aLexer.peek(); - if (tok->type == Token::AXIS_IDENTIFIER) { - if (TX_StringEqualsAtom(tok->value, txXPathAtoms::attribute)) { + if (tok->mType == Token::AXIS_IDENTIFIER) { + if (TX_StringEqualsAtom(tok->Value(), txXPathAtoms::attribute)) { isAttr = MB_TRUE; } - else if (!TX_StringEqualsAtom(tok->value, txXPathAtoms::child)) { + else if (!TX_StringEqualsAtom(tok->Value(), txXPathAtoms::child)) { // all done already for CHILD_AXIS, for all others // XXX report unexpected axis error return NS_ERROR_XPATH_PARSE_FAILURE; } aLexer.nextToken(); } - else if (tok->type == Token::AT_SIGN) { + else if (tok->mType == Token::AT_SIGN) { aLexer.nextToken(); isAttr = MB_TRUE; } tok = aLexer.nextToken(); txNodeTest* nodeTest = 0; - if (tok->type == Token::CNAME) { + if (tok->mType == Token::CNAME) { // resolve QName nsCOMPtr prefix, lName; PRInt32 nspace; - rv = resolveQName(tok->value, getter_AddRefs(prefix), aContext, + rv = resolveQName(tok->Value(), getter_AddRefs(prefix), aContext, getter_AddRefs(lName), nspace, PR_TRUE); if (NS_FAILED(rv)) { // XXX error report namespace resolve failed @@ -320,11 +329,8 @@ nsresult txPatternParser::createStepPattern(ExprLexer& aLexer, } else { aLexer.pushBack(); - nodeTest = createNodeTypeTest(aLexer); - if (!nodeTest) { - // XXX error report NodeTest expected - return NS_ERROR_XPATH_PARSE_FAILURE; - } + rv = createNodeTypeTest(aLexer, &nodeTest); + NS_ENSURE_SUCCESS(rv, rv); } txStepPattern* step = new txStepPattern(nodeTest, isAttr); @@ -333,9 +339,10 @@ nsresult txPatternParser::createStepPattern(ExprLexer& aLexer, return NS_ERROR_OUT_OF_MEMORY; } nodeTest = 0; - if (!parsePredicates(step, aLexer, aContext)) { + rv = parsePredicates(step, aLexer, aContext); + if (NS_FAILED(rv)) { delete step; - return NS_ERROR_XPATH_PARSE_FAILURE; + return rv; } aPattern = step; diff --git a/extensions/transformiix/source/xslt/txPatternParser.h b/extensions/transformiix/source/xslt/txPatternParser.h index e4c95fda667d..7787ca459785 100644 --- a/extensions/transformiix/source/xslt/txPatternParser.h +++ b/extensions/transformiix/source/xslt/txPatternParser.h @@ -42,24 +42,24 @@ #include "txXSLTPatterns.h" #include "ExprParser.h" -class txPatternParser : public ExprParser +class txPatternParser : public txExprParser { public: static txPattern* createPattern(const nsAFlatString& aPattern, txIParseContext* aContext); protected: - static nsresult createUnionPattern(ExprLexer& aLexer, + static nsresult createUnionPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern); - static nsresult createLocPathPattern(ExprLexer& aLexer, + static nsresult createLocPathPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern); - static nsresult createIdPattern(ExprLexer& aLexer, + static nsresult createIdPattern(txExprLexer& aLexer, txPattern*& aPattern); - static nsresult createKeyPattern(ExprLexer& aLexer, + static nsresult createKeyPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern); - static nsresult createStepPattern(ExprLexer& aLexer, + static nsresult createStepPattern(txExprLexer& aLexer, txIParseContext* aContext, txPattern*& aPattern); }; diff --git a/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp b/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp index 869cd1a2c335..2ebbd2d4898f 100644 --- a/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp +++ b/extensions/transformiix/source/xslt/txStylesheetCompileHandlers.cpp @@ -189,13 +189,14 @@ getExprAttr(txStylesheetAttr* aAttributes, return rv; } - aExpr = ExprParser::createExpr(attr->mValue, &aState); - if (!aExpr && (aRequired || !aState.fcp())) { - // XXX ErrorReport: XPath parse failure - return NS_ERROR_XPATH_PARSE_FAILURE; + rv = txExprParser::createExpr(attr->mValue, &aState, + getter_Transfers(aExpr)); + if (NS_SUCCEEDED(rv) && !aExpr && (aRequired || !aState.fcp())) { + // XXX ErrorReport: empty required attr + return NS_ERROR_XSLT_PARSE_FAILURE; } - return NS_OK; + return rv; } nsresult @@ -214,7 +215,7 @@ getAVTAttr(txStylesheetAttr* aAttributes, return rv; } - aAVT = ExprParser::createAttributeValueTemplate(attr->mValue, &aState); + aAVT = txExprParser::createAttributeValueTemplate(attr->mValue, &aState); if (!aAVT && (aRequired || !aState.fcp())) { // XXX ErrorReport: XPath parse failure return NS_ERROR_XPATH_PARSE_FAILURE; @@ -1214,7 +1215,7 @@ txFnStartLRE(PRInt32 aNamespaceID, } nsAutoPtr avt( - ExprParser::createAttributeValueTemplate(attr->mValue, &aState)); + txExprParser::createAttributeValueTemplate(attr->mValue, &aState)); NS_ENSURE_TRUE(avt, NS_ERROR_XPATH_PARSE_FAILURE); instr = new txLREAttribute(attr->mNamespaceID, attr->mLocalName, diff --git a/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp b/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp index 308b5fee4ca3..aa75e47fb6e4 100644 --- a/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp +++ b/extensions/transformiix/source/xslt/txStylesheetCompiler.cpp @@ -941,7 +941,7 @@ txStylesheetCompilerState::caseInsensitiveNameTests() } void -txStylesheetCompilerState::receiveError(const nsAString& aMsg, nsresult aRes) +txStylesheetCompilerState::SetErrorOffset(PRUint32 aOffset) { // XXX implement me } diff --git a/extensions/transformiix/source/xslt/txStylesheetCompiler.h b/extensions/transformiix/source/xslt/txStylesheetCompiler.h index da900847523c..85dec8c59e47 100644 --- a/extensions/transformiix/source/xslt/txStylesheetCompiler.h +++ b/extensions/transformiix/source/xslt/txStylesheetCompiler.h @@ -147,7 +147,7 @@ public: nsresult resolveFunctionCall(nsIAtom* aName, PRInt32 aID, FunctionCall*& aFunction); PRBool caseInsensitiveNameTests(); - void receiveError(const nsAString& aMsg, nsresult aRes); + void SetErrorOffset(PRUint32 aOffset); nsRefPtr mStylesheet;