Compare commits
2 Commits
tags/JONAS
...
M15-patch
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
53866ece4f | ||
|
|
350be55313 |
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a AdditiveExpr, an binary expression that
|
||||
* performs an additive operation between it's lvalue and rvalue:
|
||||
* + : addition
|
||||
* - : subtraction
|
||||
**/
|
||||
|
||||
#include "Expr.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
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* AdditiveExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
|
||||
double rightDbl = Double::NaN;
|
||||
ExprResult* exprRes = 0;
|
||||
|
||||
if ( rightExpr ) {
|
||||
exprRes = rightExpr->evaluate(context, cs);
|
||||
if ( exprRes ) rightDbl = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
||||
double leftDbl = Double::NaN;
|
||||
if ( leftExpr ) {
|
||||
exprRes = leftExpr->evaluate(context, cs);
|
||||
if ( exprRes ) leftDbl = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
||||
double result = 0;
|
||||
|
||||
switch ( op ) {
|
||||
case SUBTRACTION:
|
||||
result = leftDbl - rightDbl;
|
||||
break;
|
||||
default:
|
||||
result = leftDbl + rightDbl;
|
||||
break;
|
||||
}
|
||||
return new NumberResult(result);
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void AdditiveExpr::toString(String& str) {
|
||||
|
||||
if ( leftExpr ) leftExpr->toString(str);
|
||||
else str.append("null");
|
||||
|
||||
switch ( op ) {
|
||||
case SUBTRACTION:
|
||||
str.append(" - ");
|
||||
break;
|
||||
default:
|
||||
str.append(" + ");
|
||||
break;
|
||||
}
|
||||
if ( rightExpr ) rightExpr->toString(str);
|
||||
else str.append("null");
|
||||
|
||||
} //-- toString
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* AttributeValueTemplate
|
||||
**/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
/**
|
||||
* Create a new AttributeValueTemplate
|
||||
**/
|
||||
AttributeValueTemplate::AttributeValueTemplate() {};
|
||||
|
||||
/**
|
||||
* Default destructor
|
||||
**/
|
||||
AttributeValueTemplate::~AttributeValueTemplate() {
|
||||
ListIterator* iter = expressions.iterator();
|
||||
while ( iter->hasNext() ) {
|
||||
iter->next(); //advance iterator to allow remove
|
||||
Expr* expr = (Expr*)iter->remove();
|
||||
delete expr;
|
||||
}
|
||||
delete iter;
|
||||
|
||||
} //-- ~AttributeValueTemplate
|
||||
|
||||
/**
|
||||
* Adds the given Expr to this AttributeValueTemplate
|
||||
**/
|
||||
void AttributeValueTemplate::addExpr(Expr* expr) {
|
||||
if (expr) expressions.add(expr);
|
||||
} //-- addExpr
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* AttributeValueTemplate::evaluate(Node* context, ContextState* cs) {
|
||||
ListIterator* iter = expressions.iterator();
|
||||
String result;
|
||||
while ( iter->hasNext() ) {
|
||||
Expr* expr = (Expr*)iter->next();
|
||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
||||
exprResult->stringValue(result);
|
||||
delete exprResult;
|
||||
}
|
||||
delete iter;
|
||||
return new StringResult(result);
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void AttributeValueTemplate::toString(String& str) {
|
||||
ListIterator* iter = expressions.iterator();
|
||||
while ( iter->hasNext() ) {
|
||||
str.append('{');
|
||||
Expr* expr = (Expr*)iter->next();
|
||||
expr->toString(str);
|
||||
str.append('}');
|
||||
}
|
||||
delete iter;
|
||||
} //-- toString
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Marc Schefer, schefer@xo3.com
|
||||
* -- fixed a bug regarding Or expressions
|
||||
* - If the left hand was false, the right hand expression
|
||||
* was not getting checked.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Represents a BooleanExpr, a binary expression that
|
||||
* performs a boolean operation between it's lvalue and rvalue.
|
||||
**/
|
||||
|
||||
#include "Expr.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
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* BooleanExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
|
||||
MBool lval = MB_FALSE;
|
||||
ExprResult* exprRes = 0;
|
||||
if ( leftExpr ) {
|
||||
exprRes = leftExpr->evaluate(context, cs);
|
||||
if ( exprRes ) lval = exprRes->booleanValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
||||
|
||||
//-- check left expression for early decision
|
||||
if (( op == OR ) && (lval)) return new BooleanResult(MB_TRUE);
|
||||
else if ((op == AND) && (!lval)) return new BooleanResult(MB_FALSE);
|
||||
|
||||
MBool rval = MB_FALSE;
|
||||
if ( rightExpr ) {
|
||||
exprRes = rightExpr->evaluate(context, cs);
|
||||
if ( exprRes ) rval = exprRes->booleanValue();
|
||||
delete exprRes;
|
||||
}
|
||||
//-- just use rval, since we already checked lval
|
||||
return new BooleanResult(rval);
|
||||
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void BooleanExpr::toString(String& str) {
|
||||
|
||||
if ( leftExpr ) leftExpr->toString(str);
|
||||
else str.append("null");
|
||||
|
||||
switch ( op ) {
|
||||
case OR:
|
||||
str.append(" or ");
|
||||
break;
|
||||
default:
|
||||
str.append(" and ");
|
||||
break;
|
||||
}
|
||||
if ( rightExpr ) rightExpr->toString(str);
|
||||
else str.append("null");
|
||||
|
||||
} //-- toString
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Marina Mechtcheriakova, mmarina@mindspring.com
|
||||
* -- added lang() implementation
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
#include "Names.h"
|
||||
|
||||
/**
|
||||
* Creates a default BooleanFunctionCall, which always evaluates to False
|
||||
**/
|
||||
BooleanFunctionCall::BooleanFunctionCall(short type) : FunctionCall()
|
||||
{
|
||||
switch ( type ) {
|
||||
case TX_BOOLEAN :
|
||||
name = XPathNames::BOOLEAN_FN;
|
||||
break;
|
||||
case TX_LANG:
|
||||
name = XPathNames::LANG_FN;
|
||||
break;
|
||||
case TX_NOT :
|
||||
name = XPathNames::NOT_FN;
|
||||
break;
|
||||
case TX_TRUE :
|
||||
name = XPathNames::TRUE_FN;
|
||||
break;
|
||||
default:
|
||||
name = XPathNames::FALSE_FN;
|
||||
break;
|
||||
}
|
||||
this->type = type;
|
||||
} //-- BooleanFunctionCall
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* BooleanFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
MBool result = MB_FALSE;
|
||||
ListIterator* iter = params.iterator();
|
||||
Expr* param = 0;
|
||||
String err;
|
||||
|
||||
|
||||
switch ( type ) {
|
||||
case TX_BOOLEAN :
|
||||
if ( requireParams(1,1,cs) ) {
|
||||
param = (Expr*)iter->next();
|
||||
ExprResult* exprResult = param->evaluate(context, cs);
|
||||
result = exprResult->booleanValue();
|
||||
delete exprResult;
|
||||
}
|
||||
break;
|
||||
case TX_LANG:
|
||||
if ( requireParams(1,1,cs) ) {
|
||||
String arg1, lang;
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg1);
|
||||
lang = ((Element*)context)->getAttribute(XML_LANG_ATTR);
|
||||
arg1.toUpperCase(); // case-insensitive comparison
|
||||
lang.toUpperCase();
|
||||
result = (MBool)(lang.indexOf(arg1) == 0);
|
||||
}
|
||||
break;
|
||||
case TX_NOT :
|
||||
if ( requireParams(1,1,cs) ) {
|
||||
param = (Expr*)iter->next();
|
||||
ExprResult* exprResult = param->evaluate(context, cs);
|
||||
result = (MBool)(!exprResult->booleanValue());
|
||||
delete exprResult;
|
||||
}
|
||||
break;
|
||||
case TX_TRUE :
|
||||
result = MB_TRUE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
delete iter;
|
||||
return new BooleanResult(result);
|
||||
} //-- evaluate
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Boolean Expression result
|
||||
*/
|
||||
|
||||
#include "ExprResult.h"
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
**/
|
||||
BooleanResult::BooleanResult() {
|
||||
value = MB_FALSE;
|
||||
} //-- BooleanResult
|
||||
|
||||
/**
|
||||
* Creates a new BooleanResult with the value of the given MBool parameter
|
||||
* @param boolean the MBool to use for initialization of this BooleanResult's value
|
||||
**/
|
||||
BooleanResult::BooleanResult(MBool boolean) {
|
||||
this->value = boolean;
|
||||
} //-- BooleanResult
|
||||
|
||||
/*
|
||||
* Virtual Methods from ExprResult
|
||||
*/
|
||||
|
||||
short BooleanResult::getResultType() {
|
||||
return ExprResult::BOOLEAN;
|
||||
} //-- getResultType
|
||||
|
||||
void BooleanResult::stringValue(String& str) {
|
||||
if ( value ) str.append("true");
|
||||
else str.append("false");
|
||||
} //-- toString
|
||||
|
||||
MBool BooleanResult::booleanValue() {
|
||||
return this->value;
|
||||
} //-- toBoolean
|
||||
|
||||
double BooleanResult::numberValue() {
|
||||
return ( value ) ? 1.0 : 0.0;
|
||||
} //-- toNumber
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
|
||||
/**
|
||||
* Creates an Error FunctionCall with no error message
|
||||
**/
|
||||
ErrorFunctionCall::ErrorFunctionCall() : FunctionCall(XPathNames::ERROR_FN) {};
|
||||
|
||||
/**
|
||||
* Creates an Error FunctionCall with the given error message
|
||||
**/
|
||||
ErrorFunctionCall::ErrorFunctionCall
|
||||
(const String& errorMsg) : FunctionCall(XPathNames::ERROR_FN)
|
||||
{
|
||||
//-- copy errorMsg
|
||||
this->errorMessage = errorMsg;
|
||||
} //-- ErrorFunctionCall
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* ErrorFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
return new StringResult( errorMessage);
|
||||
} //-- evaluate
|
||||
|
||||
void ErrorFunctionCall::setErrorMessage(String& errorMsg) {
|
||||
//-- copy errorMsg
|
||||
this->errorMessage = errorMsg;
|
||||
} //-- setError
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 Initial Developer of the Original Code is Jonas Sicking.
|
||||
* Portions created by Jonas Sicking are Copyright (C) 2001, Jonas Sicking.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking, sicking@bigfoot.com
|
||||
* -- original author.
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
Expr::~Expr() {
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context.
|
||||
*/
|
||||
MBool Expr::matches(Node* node, Node* context, ContextState* cs)
|
||||
{
|
||||
NS_ASSERTION(0, "Expr::matches() called");
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default priority of this Expr based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
*/
|
||||
double Expr::getDefaultPriority(Node* node, Node* context, ContextState* cs)
|
||||
{
|
||||
NS_ASSERTION(0, "Expr::matches() called");
|
||||
return 0;
|
||||
}
|
||||
@@ -1,790 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
* Larry Fitzpatick, OpenText, lef@opentext.com
|
||||
* -- 19990806
|
||||
* - changed constant short declarations in many of the classes
|
||||
* with enumerations, commented with //--LF
|
||||
* Jonas Sicking, sicking@bigfoot.com
|
||||
* -- removal of Patterns and some restructuring
|
||||
* in the class set
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef TRANSFRMX_EXPR_H
|
||||
#define TRANSFRMX_EXPR_H
|
||||
|
||||
|
||||
#include "TxString.h"
|
||||
#include "ErrorObserver.h"
|
||||
#include "NodeSet.h"
|
||||
#include "Stack.h"
|
||||
#include "ExprResult.h"
|
||||
#include "baseutils.h"
|
||||
#include "TxObject.h"
|
||||
#include "primitives.h"
|
||||
#include "NamespaceResolver.h"
|
||||
|
||||
/*
|
||||
XPath class definitions.
|
||||
Much of this code was ported from XSL:P.
|
||||
*/
|
||||
|
||||
//necessary prototypes
|
||||
class FunctionCall;
|
||||
|
||||
typedef class Expr Pattern;
|
||||
typedef class Expr PatternExpr;
|
||||
|
||||
|
||||
/**
|
||||
* The expression context and state class used when evaluating XPath Expressions.
|
||||
**/
|
||||
class ContextState : public NamespaceResolver, public ErrorObserver {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Returns the value of a given variable binding within the current scope
|
||||
* @param the name to which the desired variable value has been bound
|
||||
* @return the ExprResult which has been bound to the variable with
|
||||
* the given name
|
||||
**/
|
||||
virtual ExprResult* getVariable(String& name) = 0;
|
||||
|
||||
/**
|
||||
* Returns the Stack of context NodeSets
|
||||
* @return the Stack of context NodeSets
|
||||
**/
|
||||
virtual Stack* getNodeSetStack() = 0;
|
||||
|
||||
virtual MBool isStripSpaceAllowed(Node* node) = 0;
|
||||
|
||||
/**
|
||||
* Returns a call to the function that has the given name.
|
||||
* This method is used for XPath Extension Functions.
|
||||
* @return the FunctionCall for the function with the given name.
|
||||
**/
|
||||
virtual FunctionCall* resolveFunctionCall(const String& name) = 0;
|
||||
|
||||
/**
|
||||
* Sorts the given NodeSet by DocumentOrder.
|
||||
* @param nodes the NodeSet to sort
|
||||
*
|
||||
* Note: I will be moving this functionality elsewhere soon
|
||||
**/
|
||||
virtual void sortByDocumentOrder(NodeSet* nodes) = 0;
|
||||
|
||||
}; //-- ContextState
|
||||
|
||||
|
||||
/**
|
||||
* A Base Class for all XSL Expressions
|
||||
**/
|
||||
class Expr : public TxObject {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Virtual destructor, important for subclasses
|
||||
**/
|
||||
virtual ~Expr();
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0;
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Expr based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
virtual void toString(String& str) = 0;
|
||||
|
||||
}; //-- Expr
|
||||
|
||||
/**
|
||||
* This class represents a FunctionCall as defined by the XPath 1.0
|
||||
* Recommendation.
|
||||
**/
|
||||
class FunctionCall : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
static const String INVALID_PARAM_COUNT;
|
||||
static const String INVALID_PARAM_VALUE;
|
||||
|
||||
virtual ~FunctionCall();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs) = 0;
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
/**
|
||||
* Adds the given parameter to this FunctionCall's parameter list
|
||||
* @param expr the Expr to add to this FunctionCall's parameter list
|
||||
**/
|
||||
void addParam(Expr* expr);
|
||||
|
||||
virtual MBool requireParams(int paramCountMin, ContextState* cs);
|
||||
|
||||
virtual MBool requireParams(int paramCountMin,
|
||||
int paramCountMax,
|
||||
ContextState* cs);
|
||||
|
||||
protected:
|
||||
|
||||
List params;
|
||||
|
||||
FunctionCall();
|
||||
FunctionCall(const String& name);
|
||||
|
||||
/**
|
||||
* Evaluates the given Expression and converts it's result to a String.
|
||||
* The value is appended to the given destination String
|
||||
**/
|
||||
void evaluateToString
|
||||
(Expr* expr, Node* context, ContextState* cs, String& dest);
|
||||
|
||||
/**
|
||||
* Evaluates the given Expression and converts it's result to a number.
|
||||
**/
|
||||
double evaluateToNumber(Expr* expr, Node* context, ContextState* cs);
|
||||
|
||||
/*
|
||||
* Evaluates the given Expression and converts it's result to a NodeSet.
|
||||
* If the result is not a NodeSet NULL is returned.
|
||||
*/
|
||||
NodeSet* evaluateToNodeSet(Expr* aExpr, Node* aContext, ContextState* aCs);
|
||||
|
||||
String name;
|
||||
}; //-- FunctionCall
|
||||
|
||||
|
||||
/**
|
||||
* Represents an AttributeValueTemplate
|
||||
**/
|
||||
class AttributeValueTemplate: public Expr {
|
||||
|
||||
public:
|
||||
|
||||
AttributeValueTemplate();
|
||||
|
||||
virtual ~AttributeValueTemplate();
|
||||
|
||||
/**
|
||||
* Adds the given Expr to this AttributeValueTemplate
|
||||
**/
|
||||
void addExpr(Expr* expr);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
List expressions;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* This class represents a NodeTest as defined by the XPath spec
|
||||
*/
|
||||
class txNodeTest {
|
||||
|
||||
public:
|
||||
|
||||
virtual ~txNodeTest() {}
|
||||
|
||||
/*
|
||||
* Determines whether this txNodeTest matches the given node
|
||||
*/
|
||||
virtual MBool matches(Node* aNode, ContextState* aCs) = 0;
|
||||
|
||||
/*
|
||||
* Returns the default priority of this txNodeTest
|
||||
*/
|
||||
virtual double getDefaultPriority() = 0;
|
||||
|
||||
/*
|
||||
* Returns the String representation of this txNodeTest.
|
||||
* @param aDest the String to use when creating the string representation.
|
||||
* The string representation will be appended to the string.
|
||||
*/
|
||||
virtual void toString(String& aDest) = 0;
|
||||
|
||||
};
|
||||
|
||||
/*
|
||||
* This class represents a NameTest as defined by the XPath spec
|
||||
*/
|
||||
class txNameTest : public txNodeTest {
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Creates a new txNameTest with the given type and the given
|
||||
* principal node type
|
||||
*/
|
||||
txNameTest(String& aName, Node::NodeType aNodeType);
|
||||
|
||||
~txNameTest();
|
||||
|
||||
/*
|
||||
* Virtual methods from txNodeTest
|
||||
*/
|
||||
MBool matches(Node* aNode, ContextState* aCs);
|
||||
double getDefaultPriority();
|
||||
void toString(String& aDest);
|
||||
|
||||
private:
|
||||
|
||||
String mPrefix;
|
||||
txAtom* mLocalName;
|
||||
Node::NodeType mNodeType;
|
||||
};
|
||||
|
||||
/*
|
||||
* This class represents a NodeType as defined by the XPath spec
|
||||
*/
|
||||
class txNodeTypeTest : public txNodeTest {
|
||||
|
||||
public:
|
||||
|
||||
enum NodeType {
|
||||
COMMENT_TYPE,
|
||||
TEXT_TYPE,
|
||||
PI_TYPE,
|
||||
NODE_TYPE
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a new txNodeTypeTest of the given type
|
||||
*/
|
||||
txNodeTypeTest(NodeType aNodeType);
|
||||
|
||||
~txNodeTypeTest();
|
||||
|
||||
/*
|
||||
* Sets the name of the node to match. Only availible for pi nodes
|
||||
*/
|
||||
void setNodeName(const String& aName);
|
||||
|
||||
/*
|
||||
* Virtual methods from txNodeTest
|
||||
*/
|
||||
MBool matches(Node* aNode, ContextState* aCs);
|
||||
double getDefaultPriority();
|
||||
void toString(String& aDest);
|
||||
|
||||
private:
|
||||
NodeType mNodeType;
|
||||
txAtom* mNodeName;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents an ordered list of Predicates,
|
||||
* for use with Step and Filter Expressions
|
||||
**/
|
||||
class PredicateList {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new PredicateList
|
||||
**/
|
||||
PredicateList();
|
||||
/**
|
||||
* Destructor, will delete all Expressions in the list, so remove
|
||||
* any you may need
|
||||
**/
|
||||
virtual ~PredicateList();
|
||||
|
||||
/**
|
||||
* Adds the given Expr to the list
|
||||
* @param expr the Expr to add to the list
|
||||
**/
|
||||
void add(Expr* expr);
|
||||
|
||||
|
||||
void evaluatePredicates(NodeSet* nodes, ContextState* cs);
|
||||
|
||||
/**
|
||||
* returns true if this predicate list is empty
|
||||
**/
|
||||
MBool isEmpty();
|
||||
|
||||
/**
|
||||
* Returns the String representation of this PredicateList.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this PredicateList.
|
||||
**/
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
//-- list of predicates
|
||||
List predicates;
|
||||
}; //-- PredicateList
|
||||
|
||||
class LocationStep : public PredicateList, public Expr {
|
||||
|
||||
public:
|
||||
|
||||
// Axis Identifier Types
|
||||
//-- LF changed from static const short to enum
|
||||
enum LocationStepType {
|
||||
ANCESTOR_AXIS = 0,
|
||||
ANCESTOR_OR_SELF_AXIS,
|
||||
ATTRIBUTE_AXIS,
|
||||
CHILD_AXIS,
|
||||
DESCENDANT_AXIS,
|
||||
DESCENDANT_OR_SELF_AXIS,
|
||||
FOLLOWING_AXIS,
|
||||
FOLLOWING_SIBLING_AXIS,
|
||||
NAMESPACE_AXIS,
|
||||
PARENT_AXIS,
|
||||
PRECEDING_AXIS,
|
||||
PRECEDING_SIBLING_AXIS,
|
||||
SELF_AXIS
|
||||
};
|
||||
|
||||
/**
|
||||
* 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(txNodeTest* aNodeTest, LocationStepType aAxisIdentifier);
|
||||
|
||||
/**
|
||||
* Destructor, will delete all predicates and the given NodeExpr
|
||||
**/
|
||||
virtual ~LocationStep();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
|
||||
txNodeTest* mNodeTest;
|
||||
LocationStepType mAxisIdentifier;
|
||||
|
||||
void fromDescendants(Node* context, ContextState* cs, NodeSet* nodes);
|
||||
void fromDescendantsRev(Node* context, ContextState* cs, NodeSet* nodes);
|
||||
|
||||
}; //-- LocationStep
|
||||
|
||||
|
||||
class FilterExpr : public PredicateList, public Expr {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new FilterExpr using the given Expr
|
||||
* @param expr the Expr to use for evaluation
|
||||
**/
|
||||
FilterExpr(Expr* expr);
|
||||
|
||||
/**
|
||||
* Destructor, will delete all predicates and the given Expr
|
||||
**/
|
||||
virtual ~FilterExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
Expr* expr;
|
||||
|
||||
}; //-- FilterExpr
|
||||
|
||||
|
||||
class NumberExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
NumberExpr(double dbl);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
|
||||
double _value;
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a String expression
|
||||
**/
|
||||
class StringExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
StringExpr(const String& value);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
|
||||
String value;
|
||||
}; //-- StringExpr
|
||||
|
||||
|
||||
/**
|
||||
* Represents an AdditiveExpr, a binary expression that
|
||||
* performs an additive operation between it's lvalue and rvalue:
|
||||
* + : add
|
||||
* - : subtract
|
||||
**/
|
||||
class AdditiveExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
//-- AdditiveExpr Types
|
||||
//-- LF, changed from static const short to enum
|
||||
enum _AdditiveExprType { ADDITION = 1, SUBTRACTION };
|
||||
|
||||
AdditiveExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||
~AdditiveExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
short op;
|
||||
Expr* leftExpr;
|
||||
Expr* rightExpr;
|
||||
}; //-- AdditiveExpr
|
||||
|
||||
/**
|
||||
* Represents an UnaryExpr. Returns the negative value of it's expr.
|
||||
**/
|
||||
class UnaryExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
UnaryExpr(Expr* expr);
|
||||
~UnaryExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
Expr* expr;
|
||||
}; //-- UnaryExpr
|
||||
|
||||
/**
|
||||
* Represents a BooleanExpr, a binary expression that
|
||||
* performs a boolean operation between it's lvalue and rvalue.
|
||||
**/
|
||||
class BooleanExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
//-- BooleanExpr Types
|
||||
enum _BooleanExprType { AND = 1, OR };
|
||||
|
||||
BooleanExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||
~BooleanExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
short op;
|
||||
Expr* leftExpr;
|
||||
Expr* rightExpr;
|
||||
}; //-- BooleanExpr
|
||||
|
||||
/**
|
||||
* Represents a MultiplicativeExpr, a binary expression that
|
||||
* performs a multiplicative operation between it's lvalue and rvalue:
|
||||
* * : multiply
|
||||
* mod : modulus
|
||||
* div : divide
|
||||
*
|
||||
**/
|
||||
class MultiplicativeExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
//-- MultiplicativeExpr Types
|
||||
//-- LF, changed from static const short to enum
|
||||
enum _MultiplicativeExprType { DIVIDE = 1, MULTIPLY, MODULUS };
|
||||
|
||||
MultiplicativeExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||
~MultiplicativeExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
short op;
|
||||
Expr* leftExpr;
|
||||
Expr* rightExpr;
|
||||
}; //-- MultiplicativeExpr
|
||||
|
||||
/**
|
||||
* Represents a RelationalExpr, an expression that compares it's lvalue
|
||||
* to it's rvalue using:
|
||||
* = : equal to
|
||||
* < : less than
|
||||
* > : greater than
|
||||
* <= : less than or equal to
|
||||
* >= : greater than or equal to
|
||||
*
|
||||
**/
|
||||
class RelationalExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
//-- RelationalExpr Types
|
||||
//-- LF, changed from static const short to enum
|
||||
enum _RelationalExprType {
|
||||
EQUAL = 1,
|
||||
NOT_EQUAL,
|
||||
LESS_THAN,
|
||||
GREATER_THAN,
|
||||
LESS_OR_EQUAL,
|
||||
GREATER_OR_EQUAL
|
||||
};
|
||||
|
||||
RelationalExpr(Expr* leftExpr, Expr* rightExpr, short op);
|
||||
~RelationalExpr();
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
short op;
|
||||
Expr* leftExpr;
|
||||
Expr* rightExpr;
|
||||
|
||||
MBool compareResults(ExprResult* left, ExprResult* right);
|
||||
}; //-- RelationalExpr
|
||||
|
||||
/**
|
||||
* VariableRefExpr
|
||||
* Represents a variable reference ($refname)
|
||||
**/
|
||||
class VariableRefExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
VariableRefExpr(const String& name);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
String name;
|
||||
|
||||
}; //-- VariableRefExpr
|
||||
|
||||
/**
|
||||
* Represents a PathExpr
|
||||
**/
|
||||
class PathExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
//-- Path Operators
|
||||
//-- RELATIVE_OP is the default
|
||||
//-- LF, changed from static const short to enum
|
||||
enum PathOperator { RELATIVE_OP, DESCENDANT_OP };
|
||||
|
||||
/**
|
||||
* Creates a new PathExpr
|
||||
**/
|
||||
PathExpr();
|
||||
|
||||
/**
|
||||
* Destructor, will delete all Expressions
|
||||
**/
|
||||
virtual ~PathExpr();
|
||||
|
||||
/**
|
||||
* Adds the Expr to this PathExpr
|
||||
* @param expr the Expr to add to this PathExpr
|
||||
**/
|
||||
void addExpr(Expr* expr, PathOperator pathOp);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
|
||||
struct PathExprItem {
|
||||
Expr* expr;
|
||||
PathOperator pathOp;
|
||||
};
|
||||
|
||||
List expressions;
|
||||
|
||||
/**
|
||||
* Selects from the descendants of the context node
|
||||
* all nodes that match the Expr
|
||||
* -- this will be moving to a Utility class
|
||||
**/
|
||||
void evalDescendants(Expr* expr,
|
||||
Node* context,
|
||||
ContextState* cs,
|
||||
NodeSet* resNodes);
|
||||
|
||||
}; //-- PathExpr
|
||||
|
||||
/**
|
||||
* This class represents a RootExpr, which only matches the Document node
|
||||
**/
|
||||
class RootExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new RootExpr
|
||||
* @param aSerialize should this RootExpr be serialized
|
||||
*/
|
||||
RootExpr(MBool aSerialize);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
// When a RootExpr is used in a PathExpr it shouldn't be serialized
|
||||
MBool mSerialize;
|
||||
|
||||
}; //-- RootExpr
|
||||
|
||||
/**
|
||||
* Represents a UnionExpr
|
||||
**/
|
||||
class UnionExpr : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new UnionExpr
|
||||
**/
|
||||
UnionExpr();
|
||||
|
||||
/**
|
||||
* Destructor, will delete all Path Expressions
|
||||
**/
|
||||
virtual ~UnionExpr();
|
||||
|
||||
/**
|
||||
* Adds the PathExpr to this UnionExpr
|
||||
* @param expr the Expr to add to this UnionExpr
|
||||
**/
|
||||
void addExpr(Expr* expr);
|
||||
|
||||
/**
|
||||
* Virtual methods from Expr
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
virtual MBool matches(Node* node, Node* context, ContextState* cs);
|
||||
virtual double getDefaultPriority(Node* node, Node* context, ContextState* cs);
|
||||
virtual void toString(String& dest);
|
||||
|
||||
private:
|
||||
|
||||
List expressions;
|
||||
|
||||
}; //-- UnionExpr
|
||||
|
||||
/* */
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1,508 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
* -- fixed bug with '<=' and '>=' reported by Bob Miller
|
||||
*
|
||||
* Bob Miller, Oblix Inc., kbob@oblix.com
|
||||
* -- fixed bug with single quotes inside double quotes
|
||||
*
|
||||
* Marina Mechtcheriakova, mmarina@mindspring.com
|
||||
* -- Fixed bug in parse method so that we make sure we check for
|
||||
* axis identifier wild cards, such as ancestor::*
|
||||
*
|
||||
* Axel Hecht <axel@pike.org>
|
||||
* -- big beating, general overhaul
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Lexical analyzer for XPath expressions
|
||||
**/
|
||||
|
||||
#include "ExprLexer.h"
|
||||
|
||||
//---------------------------/
|
||||
//- Implementation of Token -/
|
||||
//---------------------------/
|
||||
|
||||
|
||||
/**
|
||||
* 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 String& value, short type)
|
||||
{
|
||||
this->type = type;
|
||||
//-- make copy of value String
|
||||
this->value = value;
|
||||
} //-- Token
|
||||
|
||||
Token::Token(UNICODE_CHAR 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 -/
|
||||
//-------------------------------/
|
||||
|
||||
/*
|
||||
* Complex Tokens
|
||||
*/
|
||||
//-- Nodetype tokens
|
||||
const String ExprLexer::COMMENT = "comment";
|
||||
const String ExprLexer::NODE = "node";
|
||||
const String ExprLexer::PROC_INST = "processing-instruction";
|
||||
const String ExprLexer::TEXT = "text";
|
||||
|
||||
//-- boolean
|
||||
const String ExprLexer::AND = "and";
|
||||
const String ExprLexer::OR = "or";
|
||||
|
||||
//-- multiplicative operators
|
||||
const String ExprLexer::MODULUS = "mod";
|
||||
const String ExprLexer::DIVIDE = "div";
|
||||
|
||||
/**
|
||||
* The set of Lexer error messages
|
||||
**/
|
||||
const String ExprLexer::error_message[] =
|
||||
{
|
||||
"VariableReference expected",
|
||||
"Operator expected",
|
||||
"Literal is not closed",
|
||||
": not expected",
|
||||
"! not expected, use != or not()",
|
||||
"found a unkown character"
|
||||
};
|
||||
|
||||
//---------------/
|
||||
//- Contructors -/
|
||||
//---------------/
|
||||
|
||||
/**
|
||||
* Creates a new ExprLexer using the given String
|
||||
**/
|
||||
ExprLexer::ExprLexer(const String& 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()
|
||||
{
|
||||
//-- delete tokens
|
||||
currentItem = firstItem;
|
||||
while (currentItem) {
|
||||
TokenListItem* temp = currentItem->next;
|
||||
delete currentItem->token;
|
||||
delete currentItem;
|
||||
currentItem = temp;
|
||||
}
|
||||
} //-- ~ExprLexer
|
||||
|
||||
|
||||
MBool ExprLexer::hasMoreTokens()
|
||||
{
|
||||
return (currentItem != 0);
|
||||
} //-- hasMoreTokens
|
||||
|
||||
Token* ExprLexer::nextToken()
|
||||
{
|
||||
if (currentItem) {
|
||||
Token* token = currentItem->token;
|
||||
currentItem = currentItem->next;
|
||||
return token;
|
||||
}
|
||||
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 (!firstItem)
|
||||
firstItem = tlItem;
|
||||
lastItem = tlItem;
|
||||
prevToken = token;
|
||||
++tokenCount;
|
||||
} //-- addToken
|
||||
|
||||
/**
|
||||
* 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)
|
||||
{
|
||||
if (!token || token->type == Token::NULL_TOKEN)
|
||||
return MB_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
|
||||
|
||||
/**
|
||||
* Parses the given String into the set of Tokens
|
||||
**/
|
||||
void ExprLexer::parse(const String& pattern)
|
||||
{
|
||||
if (pattern.isEmpty())
|
||||
return;
|
||||
|
||||
String tokenBuffer;
|
||||
PRInt32 iter = 0, start;
|
||||
PRInt32 size = pattern.length();
|
||||
short defType;
|
||||
UNICODE_CHAR ch;
|
||||
|
||||
//-- initialize previous token, this will automatically get
|
||||
//-- deleted when it goes out of scope
|
||||
Token nullToken('\0', Token::NULL_TOKEN);
|
||||
|
||||
prevToken = &nullToken;
|
||||
|
||||
while (iter < size) {
|
||||
|
||||
ch = pattern.charAt(iter);
|
||||
defType = Token::CNAME;
|
||||
|
||||
if (ch==DOLLAR_SIGN) {
|
||||
if (++iter == size || !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
|
||||
}
|
||||
else
|
||||
defType = Token::VAR_REFERENCE;
|
||||
}
|
||||
// just reuse the QName parsing, which will use defType
|
||||
// the token to construct
|
||||
|
||||
if (isLetter(ch)) {
|
||||
// NCName, can get QName or OperatorName;
|
||||
// FunctionName, NodeName, and AxisSpecifier may want whitespace,
|
||||
// and are dealt with below
|
||||
start = iter;
|
||||
while (++iter < size &&
|
||||
isNCNameChar(pattern.charAt(iter))) /* just go */ ;
|
||||
PRInt32 end = iter;
|
||||
if (pattern.charAt(iter)==COLON) {
|
||||
// try QName or wildcard, might need to step back for axis
|
||||
if (++iter < size)
|
||||
if (isLetter(pattern.charAt(iter)))
|
||||
while (++iter < size &&
|
||||
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
|
||||
}
|
||||
if (nextIsOperatorToken(prevToken)) {
|
||||
if (pattern.subString(start,end,subStr).isEqual(AND))
|
||||
defType = Token::AND_OP;
|
||||
else if (pattern.subString(start,end,subStr).isEqual(OR))
|
||||
defType = Token::OR_OP;
|
||||
else if (pattern.subString(start,end,subStr).isEqual(MODULUS))
|
||||
defType = Token::MODULUS_OP;
|
||||
else if (pattern.subString(start,end,subStr).isEqual(DIVIDE))
|
||||
defType = Token::DIVIDE_OP;
|
||||
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
|
||||
}
|
||||
}
|
||||
addToken(new Token(pattern.subString(start,iter,subStr),defType));
|
||||
}
|
||||
else if (isDigit(ch)) {
|
||||
start = iter;
|
||||
while (++iter < size &&
|
||||
isDigit(pattern.charAt(iter))) /* just go */;
|
||||
if (pattern.charAt(iter)=='.')
|
||||
while (++iter < size &&
|
||||
isDigit(pattern.charAt(iter))) /* just go */;
|
||||
addToken(new Token(pattern.subString(start,iter,subStr),Token::NUMBER));
|
||||
}
|
||||
else {
|
||||
switch (ch) {
|
||||
//-- ignore whitespace
|
||||
case SPACE:
|
||||
case TX_TAB:
|
||||
case TX_CR:
|
||||
case TX_LF:
|
||||
++iter;
|
||||
break;
|
||||
case S_QUOTE :
|
||||
case D_QUOTE :
|
||||
start=iter;
|
||||
iter = pattern.indexOf(ch,start+1);
|
||||
if (iter==NOT_FOUND) {
|
||||
// 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
|
||||
}
|
||||
else {
|
||||
addToken(new Token(pattern.subString(start+1,iter,subStr),
|
||||
Token::LITERAL));
|
||||
++iter;
|
||||
}
|
||||
break;
|
||||
case PERIOD:
|
||||
// period can be .., .(DIGITS)+ or ., check next
|
||||
if (++iter < size) {
|
||||
ch=pattern.charAt(iter);
|
||||
if (isDigit(ch)) {
|
||||
start=iter-1;
|
||||
while (++iter < size &&
|
||||
isDigit(pattern.charAt(iter))) /* just go */;
|
||||
addToken(new Token(pattern.subString(start,iter,subStr),
|
||||
Token::NUMBER));
|
||||
}
|
||||
else if (ch==PERIOD) {
|
||||
addToken(new Token(pattern.subString(iter-1,iter++,subStr),
|
||||
Token::PARENT_NODE));
|
||||
}
|
||||
else
|
||||
addToken(new Token(PERIOD, 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
|
||||
}
|
||||
break;
|
||||
case FORWARD_SLASH :
|
||||
if (++iter < size && pattern.charAt(iter)==ch) {
|
||||
addToken(new Token(pattern.subString(iter-1,++iter,subStr),
|
||||
Token::ANCESTOR_OP));
|
||||
}
|
||||
else {
|
||||
addToken(new Token(ch, Token::PARENT_OP));
|
||||
}
|
||||
break;
|
||||
case BANG : // can only be !=
|
||||
if (++iter < size && pattern.charAt(iter)==EQUAL) {
|
||||
addToken(new Token(pattern.subString(iter-1,++iter,subStr),
|
||||
Token::NOT_EQUAL_OP));
|
||||
}
|
||||
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;
|
||||
case EQUAL:
|
||||
addToken(new Token(ch,Token::EQUAL_OP));
|
||||
++iter;
|
||||
break;
|
||||
case L_ANGLE:
|
||||
if (++iter < size && pattern.charAt(iter)==EQUAL) {
|
||||
addToken(new Token(pattern.subString(iter-1,++iter,subStr),
|
||||
Token::LESS_OR_EQUAL_OP));
|
||||
}
|
||||
else
|
||||
addToken(new Token(ch,Token::LESS_THAN_OP));
|
||||
break;
|
||||
case R_ANGLE:
|
||||
if (++iter < size && pattern.charAt(iter)==EQUAL) {
|
||||
addToken(new Token(pattern.subString(iter-1,++iter,subStr),
|
||||
Token::GREATER_OR_EQUAL_OP));
|
||||
}
|
||||
else
|
||||
addToken(new Token(ch,Token::GREATER_THAN_OP));
|
||||
break;
|
||||
case HYPHEN :
|
||||
addToken(new Token(ch,Token::SUBTRACTION_OP));
|
||||
++iter;
|
||||
break;
|
||||
case ASTERIX:
|
||||
if (nextIsOperatorToken(prevToken))
|
||||
addToken(new Token(ch,Token::MULTIPLY_OP));
|
||||
else
|
||||
addToken(new Token(ch,Token::CNAME));
|
||||
++iter;
|
||||
break;
|
||||
case L_PAREN:
|
||||
if (prevToken->type == Token::CNAME) {
|
||||
if (prevToken->value.isEqual(COMMENT))
|
||||
prevToken->type = Token::COMMENT;
|
||||
else if (prevToken->value.isEqual(NODE))
|
||||
prevToken->type = Token::NODE;
|
||||
else if (prevToken->value.isEqual(PROC_INST))
|
||||
prevToken->type = Token::PROC_INST;
|
||||
else if (prevToken->value.isEqual(TEXT))
|
||||
prevToken->type = Token::TEXT;
|
||||
else
|
||||
prevToken->type = Token::FUNCTION_NAME;
|
||||
}
|
||||
++iter;
|
||||
addToken(new Token(ch,Token::L_PAREN));
|
||||
break;
|
||||
case R_PAREN:
|
||||
++iter;
|
||||
addToken(new Token(ch,Token::R_PAREN));
|
||||
break;
|
||||
case L_BRACKET:
|
||||
++iter;
|
||||
addToken(new Token(ch,Token::L_BRACKET));
|
||||
break;
|
||||
case R_BRACKET:
|
||||
++iter;
|
||||
addToken(new Token(ch,Token::R_BRACKET));
|
||||
break;
|
||||
case COMMA:
|
||||
++iter;
|
||||
addToken(new Token(ch,Token::COMMA));
|
||||
break;
|
||||
case AT_SIGN :
|
||||
++iter;
|
||||
addToken(new Token(ch,Token::AT_SIGN));
|
||||
break;
|
||||
case PLUS:
|
||||
++iter;
|
||||
addToken(new Token(ch,Token::ADDITION_OP));
|
||||
break;
|
||||
case VERT_BAR:
|
||||
++iter;
|
||||
addToken(new Token(ch,Token::UNION_OP));
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
} //-- parse
|
||||
|
||||
@@ -1,277 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Larry Fitzpatrick
|
||||
* -- changed constant short declarations in Token and ExprLexer to
|
||||
* enumerations, commented with //--LF
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef MITREXSL_EXPRLEXER_H
|
||||
#define MITREXSL_EXPRLEXER_H
|
||||
|
||||
#include "TxString.h"
|
||||
#include "baseutils.h"
|
||||
|
||||
/**
|
||||
* A Token class for the ExprLexer.
|
||||
*
|
||||
* This class was ported from XSL:P, an open source Java based
|
||||
* XSLT processor, written by yours truly.
|
||||
**/
|
||||
class Token {
|
||||
|
||||
public:
|
||||
|
||||
//---------------/
|
||||
//- Token Types -/
|
||||
//---------------/
|
||||
|
||||
//-- LF - changed from static const short declarations to enum
|
||||
//-- token types
|
||||
enum TokenType {
|
||||
//-- Trivial Tokens
|
||||
ERROR = 0,
|
||||
NULL_TOKEN,
|
||||
LITERAL,
|
||||
NUMBER,
|
||||
CNAME,
|
||||
FUNCTION_NAME,
|
||||
VAR_REFERENCE,
|
||||
PARENT_NODE,
|
||||
SELF_NODE,
|
||||
R_PAREN,
|
||||
R_BRACKET, // 10
|
||||
/**
|
||||
* 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 -/
|
||||
//-------------/
|
||||
|
||||
//-- boolean ops
|
||||
AND_OP, // 16
|
||||
OR_OP,
|
||||
|
||||
//-- relational
|
||||
EQUAL_OP, // 18
|
||||
NOT_EQUAL_OP,
|
||||
LESS_THAN_OP,
|
||||
GREATER_THAN_OP,
|
||||
LESS_OR_EQUAL_OP,
|
||||
GREATER_OR_EQUAL_OP,
|
||||
//-- additive operators
|
||||
ADDITION_OP, // 24
|
||||
SUBTRACTION_OP,
|
||||
//-- multiplicative
|
||||
DIVIDE_OP , // 26
|
||||
MULTIPLY_OP,
|
||||
MODULUS_OP,
|
||||
//-- path operators
|
||||
PARENT_OP, // 29
|
||||
ANCESTOR_OP,
|
||||
UNION_OP,
|
||||
/**
|
||||
* end of tokens for 3.7, bullet 1 -/
|
||||
**/
|
||||
//-- node type tokens
|
||||
COMMENT, // 32
|
||||
NODE,
|
||||
PROC_INST,
|
||||
TEXT,
|
||||
|
||||
//-- Special endtoken
|
||||
END // 36
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
**/
|
||||
Token();
|
||||
Token(short type);
|
||||
Token(const String& value, short type);
|
||||
Token(UNICODE_CHAR uniChar, short type);
|
||||
/**
|
||||
* Copy Constructor
|
||||
**/
|
||||
Token(const Token& token);
|
||||
|
||||
~Token();
|
||||
String value;
|
||||
short type;
|
||||
}; //--Token
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
|
||||
|
||||
public:
|
||||
|
||||
/*
|
||||
* Trivial Tokens
|
||||
*/
|
||||
//-- LF, changed to enum
|
||||
enum _TrivialTokens {
|
||||
D_QUOTE = '\"',
|
||||
S_QUOTE = '\'',
|
||||
L_PAREN = '(',
|
||||
R_PAREN = ')',
|
||||
L_BRACKET = '[',
|
||||
R_BRACKET = ']',
|
||||
L_ANGLE = '<',
|
||||
R_ANGLE = '>',
|
||||
COMMA = ',',
|
||||
PERIOD = '.',
|
||||
ASTERIX = '*',
|
||||
FORWARD_SLASH = '/',
|
||||
EQUAL = '=',
|
||||
BANG = '!',
|
||||
VERT_BAR = '|',
|
||||
AT_SIGN = '@',
|
||||
DOLLAR_SIGN = '$',
|
||||
PLUS = '+',
|
||||
HYPHEN = '-',
|
||||
COLON = ':',
|
||||
//-- whitespace tokens
|
||||
SPACE = ' ',
|
||||
TX_TAB = '\t',
|
||||
TX_CR = '\n',
|
||||
TX_LF = '\r'
|
||||
};
|
||||
|
||||
enum _error_consts {
|
||||
ERROR_UNRESOLVED_VAR_REFERENCE = 0,
|
||||
ERROR_OP_EXPECTED,
|
||||
ERROR_UNCLOSED_LITERAL,
|
||||
ERROR_COLON,
|
||||
ERROR_BANG,
|
||||
ERROR_UNKNOWN_CHAR
|
||||
};
|
||||
static const String error_message[];
|
||||
PRInt32 errorPos;
|
||||
short errorCode;
|
||||
|
||||
/*
|
||||
* Complex Tokens
|
||||
*/
|
||||
//-- Nodetype tokens
|
||||
static const String COMMENT;
|
||||
static const String NODE;
|
||||
static const String PROC_INST;
|
||||
static const String TEXT;
|
||||
|
||||
//-- boolean
|
||||
static const String AND;
|
||||
static const String OR;
|
||||
|
||||
//-- Multiplicative
|
||||
static const String MODULUS;
|
||||
static const String DIVIDE;
|
||||
|
||||
/*
|
||||
* Default Token Set
|
||||
*/
|
||||
static const Token TOKENS[];
|
||||
static const short NUMBER_OF_TOKENS;
|
||||
|
||||
/**
|
||||
* Constructor for ExprLexer
|
||||
**/
|
||||
ExprLexer(const String& 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;
|
||||
};
|
||||
|
||||
TokenListItem* currentItem;
|
||||
TokenListItem* firstItem;
|
||||
TokenListItem* lastItem;
|
||||
|
||||
int tokenCount;
|
||||
|
||||
Token* prevToken;
|
||||
Token endToken;
|
||||
|
||||
void addToken(Token* token);
|
||||
|
||||
/**
|
||||
* 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);
|
||||
|
||||
/**
|
||||
* Returns true if the given character represents an Alpha letter
|
||||
* Implemented in ExprLexerChars.cpp
|
||||
**/
|
||||
static MBool isLetter(UNICODE_CHAR ch);
|
||||
|
||||
/**
|
||||
* Returns true if the given character represents a numeric letter (digit)
|
||||
* Implemented in ExprLexerChars.cpp
|
||||
**/
|
||||
static MBool isDigit(UNICODE_CHAR ch);
|
||||
|
||||
/**
|
||||
* Returns true if the given character is an allowable NCName character
|
||||
* Implemented in ExprLexerChars.cpp
|
||||
**/
|
||||
static MBool isNCNameChar(UNICODE_CHAR ch);
|
||||
|
||||
String subStr;
|
||||
void parse(const String& pattern);
|
||||
|
||||
}; //-- ExprLexer
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,372 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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 mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Axel Hecht. Portions
|
||||
* created by Axel Hecht are Copyright (C) 2001 Axel Hecht. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Axel Hecht <axel@pike.org> (Original Author)
|
||||
*/
|
||||
|
||||
#include "ExprLexer.h"
|
||||
|
||||
// macros for inclusion of char range headers
|
||||
#define TX_CHAR_RANGE(ch, a, b) if (ch < a) return MB_FALSE; \
|
||||
if (ch <= b) return MB_TRUE
|
||||
#define TX_MATCH_CHAR(ch, a) if (ch < a) return MB_FALSE; \
|
||||
if (ch == a) return MB_TRUE
|
||||
|
||||
/**
|
||||
* Returns true if the given character represents a numeric letter (digit)
|
||||
**/
|
||||
MBool ExprLexer::isDigit(UNICODE_CHAR ch)
|
||||
{
|
||||
TX_CHAR_RANGE(ch, '0', '9');
|
||||
return MB_FALSE;
|
||||
} //-- isDigit
|
||||
|
||||
/**
|
||||
* Returns true if the given character represents an Alpha letter
|
||||
**/
|
||||
MBool ExprLexer::isLetter(UNICODE_CHAR ch)
|
||||
{
|
||||
/* Letter = BaseChar | Ideographic; and _ */
|
||||
TX_CHAR_RANGE(ch, 0x0041, 0x005A);
|
||||
TX_MATCH_CHAR(ch, 0x005F); /* '_' */
|
||||
TX_CHAR_RANGE(ch, 0x0061, 0x007A);
|
||||
TX_CHAR_RANGE(ch, 0x00C0, 0x00D6);
|
||||
TX_CHAR_RANGE(ch, 0x00D8, 0x00F6);
|
||||
TX_CHAR_RANGE(ch, 0x00F8, 0x00FF);
|
||||
TX_CHAR_RANGE(ch, 0x0100, 0x0131);
|
||||
TX_CHAR_RANGE(ch, 0x0134, 0x013E);
|
||||
TX_CHAR_RANGE(ch, 0x0141, 0x0148);
|
||||
TX_CHAR_RANGE(ch, 0x014A, 0x017E);
|
||||
TX_CHAR_RANGE(ch, 0x0180, 0x01C3);
|
||||
TX_CHAR_RANGE(ch, 0x01CD, 0x01F0);
|
||||
TX_CHAR_RANGE(ch, 0x01F4, 0x01F5);
|
||||
TX_CHAR_RANGE(ch, 0x01FA, 0x0217);
|
||||
TX_CHAR_RANGE(ch, 0x0250, 0x02A8);
|
||||
TX_CHAR_RANGE(ch, 0x02BB, 0x02C1);
|
||||
TX_MATCH_CHAR(ch, 0x0386);
|
||||
TX_CHAR_RANGE(ch, 0x0388, 0x038A);
|
||||
TX_MATCH_CHAR(ch, 0x038C);
|
||||
TX_CHAR_RANGE(ch, 0x038E, 0x03A1);
|
||||
TX_CHAR_RANGE(ch, 0x03A3, 0x03CE);
|
||||
TX_CHAR_RANGE(ch, 0x03D0, 0x03D6);
|
||||
TX_MATCH_CHAR(ch, 0x03DA);
|
||||
TX_MATCH_CHAR(ch, 0x03DC);
|
||||
TX_MATCH_CHAR(ch, 0x03DE);
|
||||
TX_MATCH_CHAR(ch, 0x03E0);
|
||||
TX_CHAR_RANGE(ch, 0x03E2, 0x03F3);
|
||||
TX_CHAR_RANGE(ch, 0x0401, 0x040C);
|
||||
TX_CHAR_RANGE(ch, 0x040E, 0x044F);
|
||||
TX_CHAR_RANGE(ch, 0x0451, 0x045C);
|
||||
TX_CHAR_RANGE(ch, 0x045E, 0x0481);
|
||||
TX_CHAR_RANGE(ch, 0x0490, 0x04C4);
|
||||
TX_CHAR_RANGE(ch, 0x04C7, 0x04C8);
|
||||
TX_CHAR_RANGE(ch, 0x04CB, 0x04CC);
|
||||
TX_CHAR_RANGE(ch, 0x04D0, 0x04EB);
|
||||
TX_CHAR_RANGE(ch, 0x04EE, 0x04F5);
|
||||
TX_CHAR_RANGE(ch, 0x04F8, 0x04F9);
|
||||
TX_CHAR_RANGE(ch, 0x0531, 0x0556);
|
||||
TX_MATCH_CHAR(ch, 0x0559);
|
||||
TX_CHAR_RANGE(ch, 0x0561, 0x0586);
|
||||
TX_CHAR_RANGE(ch, 0x05D0, 0x05EA);
|
||||
TX_CHAR_RANGE(ch, 0x05F0, 0x05F2);
|
||||
TX_CHAR_RANGE(ch, 0x0621, 0x063A);
|
||||
TX_CHAR_RANGE(ch, 0x0641, 0x064A);
|
||||
TX_CHAR_RANGE(ch, 0x0671, 0x06B7);
|
||||
TX_CHAR_RANGE(ch, 0x06BA, 0x06BE);
|
||||
TX_CHAR_RANGE(ch, 0x06C0, 0x06CE);
|
||||
TX_CHAR_RANGE(ch, 0x06D0, 0x06D3);
|
||||
TX_MATCH_CHAR(ch, 0x06D5);
|
||||
TX_CHAR_RANGE(ch, 0x06E5, 0x06E6);
|
||||
TX_CHAR_RANGE(ch, 0x0905, 0x0939);
|
||||
TX_MATCH_CHAR(ch, 0x093D);
|
||||
TX_CHAR_RANGE(ch, 0x0958, 0x0961);
|
||||
TX_CHAR_RANGE(ch, 0x0985, 0x098C);
|
||||
TX_CHAR_RANGE(ch, 0x098F, 0x0990);
|
||||
TX_CHAR_RANGE(ch, 0x0993, 0x09A8);
|
||||
TX_CHAR_RANGE(ch, 0x09AA, 0x09B0);
|
||||
TX_MATCH_CHAR(ch, 0x09B2);
|
||||
TX_CHAR_RANGE(ch, 0x09B6, 0x09B9);
|
||||
TX_CHAR_RANGE(ch, 0x09DC, 0x09DD);
|
||||
TX_CHAR_RANGE(ch, 0x09DF, 0x09E1);
|
||||
TX_CHAR_RANGE(ch, 0x09F0, 0x09F1);
|
||||
TX_CHAR_RANGE(ch, 0x0A05, 0x0A0A);
|
||||
TX_CHAR_RANGE(ch, 0x0A0F, 0x0A10);
|
||||
TX_CHAR_RANGE(ch, 0x0A13, 0x0A28);
|
||||
TX_CHAR_RANGE(ch, 0x0A2A, 0x0A30);
|
||||
TX_CHAR_RANGE(ch, 0x0A32, 0x0A33);
|
||||
TX_CHAR_RANGE(ch, 0x0A35, 0x0A36);
|
||||
TX_CHAR_RANGE(ch, 0x0A38, 0x0A39);
|
||||
TX_CHAR_RANGE(ch, 0x0A59, 0x0A5C);
|
||||
TX_MATCH_CHAR(ch, 0x0A5E);
|
||||
TX_CHAR_RANGE(ch, 0x0A72, 0x0A74);
|
||||
TX_CHAR_RANGE(ch, 0x0A85, 0x0A8B);
|
||||
TX_MATCH_CHAR(ch, 0x0A8D);
|
||||
TX_CHAR_RANGE(ch, 0x0A8F, 0x0A91);
|
||||
TX_CHAR_RANGE(ch, 0x0A93, 0x0AA8);
|
||||
TX_CHAR_RANGE(ch, 0x0AAA, 0x0AB0);
|
||||
TX_CHAR_RANGE(ch, 0x0AB2, 0x0AB3);
|
||||
TX_CHAR_RANGE(ch, 0x0AB5, 0x0AB9);
|
||||
TX_MATCH_CHAR(ch, 0x0ABD);
|
||||
TX_MATCH_CHAR(ch, 0x0AE0);
|
||||
TX_CHAR_RANGE(ch, 0x0B05, 0x0B0C);
|
||||
TX_CHAR_RANGE(ch, 0x0B0F, 0x0B10);
|
||||
TX_CHAR_RANGE(ch, 0x0B13, 0x0B28);
|
||||
TX_CHAR_RANGE(ch, 0x0B2A, 0x0B30);
|
||||
TX_CHAR_RANGE(ch, 0x0B32, 0x0B33);
|
||||
TX_CHAR_RANGE(ch, 0x0B36, 0x0B39);
|
||||
TX_MATCH_CHAR(ch, 0x0B3D);
|
||||
TX_CHAR_RANGE(ch, 0x0B5C, 0x0B5D);
|
||||
TX_CHAR_RANGE(ch, 0x0B5F, 0x0B61);
|
||||
TX_CHAR_RANGE(ch, 0x0B85, 0x0B8A);
|
||||
TX_CHAR_RANGE(ch, 0x0B8E, 0x0B90);
|
||||
TX_CHAR_RANGE(ch, 0x0B92, 0x0B95);
|
||||
TX_CHAR_RANGE(ch, 0x0B99, 0x0B9A);
|
||||
TX_MATCH_CHAR(ch, 0x0B9C);
|
||||
TX_CHAR_RANGE(ch, 0x0B9E, 0x0B9F);
|
||||
TX_CHAR_RANGE(ch, 0x0BA3, 0x0BA4);
|
||||
TX_CHAR_RANGE(ch, 0x0BA8, 0x0BAA);
|
||||
TX_CHAR_RANGE(ch, 0x0BAE, 0x0BB5);
|
||||
TX_CHAR_RANGE(ch, 0x0BB7, 0x0BB9);
|
||||
TX_CHAR_RANGE(ch, 0x0C05, 0x0C0C);
|
||||
TX_CHAR_RANGE(ch, 0x0C0E, 0x0C10);
|
||||
TX_CHAR_RANGE(ch, 0x0C12, 0x0C28);
|
||||
TX_CHAR_RANGE(ch, 0x0C2A, 0x0C33);
|
||||
TX_CHAR_RANGE(ch, 0x0C35, 0x0C39);
|
||||
TX_CHAR_RANGE(ch, 0x0C60, 0x0C61);
|
||||
TX_CHAR_RANGE(ch, 0x0C85, 0x0C8C);
|
||||
TX_CHAR_RANGE(ch, 0x0C8E, 0x0C90);
|
||||
TX_CHAR_RANGE(ch, 0x0C92, 0x0CA8);
|
||||
TX_CHAR_RANGE(ch, 0x0CAA, 0x0CB3);
|
||||
TX_CHAR_RANGE(ch, 0x0CB5, 0x0CB9);
|
||||
TX_MATCH_CHAR(ch, 0x0CDE);
|
||||
TX_CHAR_RANGE(ch, 0x0CE0, 0x0CE1);
|
||||
TX_CHAR_RANGE(ch, 0x0D05, 0x0D0C);
|
||||
TX_CHAR_RANGE(ch, 0x0D0E, 0x0D10);
|
||||
TX_CHAR_RANGE(ch, 0x0D12, 0x0D28);
|
||||
TX_CHAR_RANGE(ch, 0x0D2A, 0x0D39);
|
||||
TX_CHAR_RANGE(ch, 0x0D60, 0x0D61);
|
||||
TX_CHAR_RANGE(ch, 0x0E01, 0x0E2E);
|
||||
TX_MATCH_CHAR(ch, 0x0E30);
|
||||
TX_CHAR_RANGE(ch, 0x0E32, 0x0E33);
|
||||
TX_CHAR_RANGE(ch, 0x0E40, 0x0E45);
|
||||
TX_CHAR_RANGE(ch, 0x0E81, 0x0E82);
|
||||
TX_MATCH_CHAR(ch, 0x0E84);
|
||||
TX_CHAR_RANGE(ch, 0x0E87, 0x0E88);
|
||||
TX_MATCH_CHAR(ch, 0x0E8A);
|
||||
TX_MATCH_CHAR(ch, 0x0E8D);
|
||||
TX_CHAR_RANGE(ch, 0x0E94, 0x0E97);
|
||||
TX_CHAR_RANGE(ch, 0x0E99, 0x0E9F);
|
||||
TX_CHAR_RANGE(ch, 0x0EA1, 0x0EA3);
|
||||
TX_MATCH_CHAR(ch, 0x0EA5);
|
||||
TX_MATCH_CHAR(ch, 0x0EA7);
|
||||
TX_CHAR_RANGE(ch, 0x0EAA, 0x0EAB);
|
||||
TX_CHAR_RANGE(ch, 0x0EAD, 0x0EAE);
|
||||
TX_MATCH_CHAR(ch, 0x0EB0);
|
||||
TX_CHAR_RANGE(ch, 0x0EB2, 0x0EB3);
|
||||
TX_MATCH_CHAR(ch, 0x0EBD);
|
||||
TX_CHAR_RANGE(ch, 0x0EC0, 0x0EC4);
|
||||
TX_CHAR_RANGE(ch, 0x0F40, 0x0F47);
|
||||
TX_CHAR_RANGE(ch, 0x0F49, 0x0F69);
|
||||
TX_CHAR_RANGE(ch, 0x10A0, 0x10C5);
|
||||
TX_CHAR_RANGE(ch, 0x10D0, 0x10F6);
|
||||
TX_MATCH_CHAR(ch, 0x1100);
|
||||
TX_CHAR_RANGE(ch, 0x1102, 0x1103);
|
||||
TX_CHAR_RANGE(ch, 0x1105, 0x1107);
|
||||
TX_MATCH_CHAR(ch, 0x1109);
|
||||
TX_CHAR_RANGE(ch, 0x110B, 0x110C);
|
||||
TX_CHAR_RANGE(ch, 0x110E, 0x1112);
|
||||
TX_MATCH_CHAR(ch, 0x113C);
|
||||
TX_MATCH_CHAR(ch, 0x113E);
|
||||
TX_MATCH_CHAR(ch, 0x1140);
|
||||
TX_MATCH_CHAR(ch, 0x114C);
|
||||
TX_MATCH_CHAR(ch, 0x114E);
|
||||
TX_MATCH_CHAR(ch, 0x1150);
|
||||
TX_CHAR_RANGE(ch, 0x1154, 0x1155);
|
||||
TX_MATCH_CHAR(ch, 0x1159);
|
||||
TX_CHAR_RANGE(ch, 0x115F, 0x1161);
|
||||
TX_MATCH_CHAR(ch, 0x1163);
|
||||
TX_MATCH_CHAR(ch, 0x1165);
|
||||
TX_MATCH_CHAR(ch, 0x1167);
|
||||
TX_MATCH_CHAR(ch, 0x1169);
|
||||
TX_CHAR_RANGE(ch, 0x116D, 0x116E);
|
||||
TX_CHAR_RANGE(ch, 0x1172, 0x1173);
|
||||
TX_MATCH_CHAR(ch, 0x1175);
|
||||
TX_MATCH_CHAR(ch, 0x119E);
|
||||
TX_MATCH_CHAR(ch, 0x11A8);
|
||||
TX_MATCH_CHAR(ch, 0x11AB);
|
||||
TX_CHAR_RANGE(ch, 0x11AE, 0x11AF);
|
||||
TX_CHAR_RANGE(ch, 0x11B7, 0x11B8);
|
||||
TX_MATCH_CHAR(ch, 0x11BA);
|
||||
TX_CHAR_RANGE(ch, 0x11BC, 0x11C2);
|
||||
TX_MATCH_CHAR(ch, 0x11EB);
|
||||
TX_MATCH_CHAR(ch, 0x11F0);
|
||||
TX_MATCH_CHAR(ch, 0x11F9);
|
||||
TX_CHAR_RANGE(ch, 0x1E00, 0x1E9B);
|
||||
TX_CHAR_RANGE(ch, 0x1EA0, 0x1EF9);
|
||||
TX_CHAR_RANGE(ch, 0x1F00, 0x1F15);
|
||||
TX_CHAR_RANGE(ch, 0x1F18, 0x1F1D);
|
||||
TX_CHAR_RANGE(ch, 0x1F20, 0x1F45);
|
||||
TX_CHAR_RANGE(ch, 0x1F48, 0x1F4D);
|
||||
TX_CHAR_RANGE(ch, 0x1F50, 0x1F57);
|
||||
TX_MATCH_CHAR(ch, 0x1F59);
|
||||
TX_MATCH_CHAR(ch, 0x1F5B);
|
||||
TX_MATCH_CHAR(ch, 0x1F5D);
|
||||
TX_CHAR_RANGE(ch, 0x1F5F, 0x1F7D);
|
||||
TX_CHAR_RANGE(ch, 0x1F80, 0x1FB4);
|
||||
TX_CHAR_RANGE(ch, 0x1FB6, 0x1FBC);
|
||||
TX_MATCH_CHAR(ch, 0x1FBE);
|
||||
TX_CHAR_RANGE(ch, 0x1FC2, 0x1FC4);
|
||||
TX_CHAR_RANGE(ch, 0x1FC6, 0x1FCC);
|
||||
TX_CHAR_RANGE(ch, 0x1FD0, 0x1FD3);
|
||||
TX_CHAR_RANGE(ch, 0x1FD6, 0x1FDB);
|
||||
TX_CHAR_RANGE(ch, 0x1FE0, 0x1FEC);
|
||||
TX_CHAR_RANGE(ch, 0x1FF2, 0x1FF4);
|
||||
TX_CHAR_RANGE(ch, 0x1FF6, 0x1FFC);
|
||||
TX_MATCH_CHAR(ch, 0x2126);
|
||||
TX_CHAR_RANGE(ch, 0x212A, 0x212B);
|
||||
TX_MATCH_CHAR(ch, 0x212E);
|
||||
TX_CHAR_RANGE(ch, 0x2180, 0x2182);
|
||||
TX_MATCH_CHAR(ch, 0x3007);
|
||||
TX_CHAR_RANGE(ch, 0x3021, 0x3029);
|
||||
TX_CHAR_RANGE(ch, 0x3041, 0x3094);
|
||||
TX_CHAR_RANGE(ch, 0x30A1, 0x30FA);
|
||||
TX_CHAR_RANGE(ch, 0x3105, 0x312C);
|
||||
TX_CHAR_RANGE(ch, 0x4E00, 0x9FA5);
|
||||
TX_CHAR_RANGE(ch, 0xAC00, 0xD7A3);
|
||||
return MB_FALSE;
|
||||
} //-- isAlphaChar
|
||||
|
||||
/**
|
||||
* Returns true if the given character is an allowable NCName character
|
||||
**/
|
||||
MBool ExprLexer::isNCNameChar(UNICODE_CHAR ch)
|
||||
{
|
||||
/* NCNameChar = Letter | Digit ('0'-'9') | '.' | '-' | '_' |
|
||||
CombiningChar | Extender */
|
||||
if (isLetter(ch)) return MB_TRUE; /* Letter | '_' */
|
||||
|
||||
TX_CHAR_RANGE(ch, 0x002D, 0x002E); /* '-' | '.' */
|
||||
TX_CHAR_RANGE(ch, 0x0030, 0x0039); /* Digit */
|
||||
TX_MATCH_CHAR(ch, 0x00B7);
|
||||
TX_MATCH_CHAR(ch, 0x02D0);
|
||||
TX_MATCH_CHAR(ch, 0x02D1);
|
||||
TX_CHAR_RANGE(ch, 0x0300, 0x0345);
|
||||
TX_CHAR_RANGE(ch, 0x0360, 0x0361);
|
||||
TX_MATCH_CHAR(ch, 0x0387);
|
||||
TX_CHAR_RANGE(ch, 0x0483, 0x0486);
|
||||
TX_CHAR_RANGE(ch, 0x0591, 0x05A1);
|
||||
TX_CHAR_RANGE(ch, 0x05A3, 0x05B9);
|
||||
TX_CHAR_RANGE(ch, 0x05BB, 0x05BD);
|
||||
TX_MATCH_CHAR(ch, 0x05BF);
|
||||
TX_CHAR_RANGE(ch, 0x05C1, 0x05C2);
|
||||
TX_MATCH_CHAR(ch, 0x05C4);
|
||||
TX_MATCH_CHAR(ch, 0x0640);
|
||||
TX_CHAR_RANGE(ch, 0x064B, 0x0652);
|
||||
TX_MATCH_CHAR(ch, 0x0670);
|
||||
TX_CHAR_RANGE(ch, 0x06D6, 0x06DC);
|
||||
TX_CHAR_RANGE(ch, 0x06DD, 0x06DF);
|
||||
TX_CHAR_RANGE(ch, 0x06E0, 0x06E4);
|
||||
TX_CHAR_RANGE(ch, 0x06E7, 0x06E8);
|
||||
TX_CHAR_RANGE(ch, 0x06EA, 0x06ED);
|
||||
TX_CHAR_RANGE(ch, 0x0901, 0x0903);
|
||||
TX_MATCH_CHAR(ch, 0x093C);
|
||||
TX_CHAR_RANGE(ch, 0x093E, 0x094C);
|
||||
TX_MATCH_CHAR(ch, 0x094D);
|
||||
TX_CHAR_RANGE(ch, 0x0951, 0x0954);
|
||||
TX_CHAR_RANGE(ch, 0x0962, 0x0963);
|
||||
TX_CHAR_RANGE(ch, 0x0981, 0x0983);
|
||||
TX_MATCH_CHAR(ch, 0x09BC);
|
||||
TX_MATCH_CHAR(ch, 0x09BE);
|
||||
TX_MATCH_CHAR(ch, 0x09BF);
|
||||
TX_CHAR_RANGE(ch, 0x09C0, 0x09C4);
|
||||
TX_CHAR_RANGE(ch, 0x09C7, 0x09C8);
|
||||
TX_CHAR_RANGE(ch, 0x09CB, 0x09CD);
|
||||
TX_MATCH_CHAR(ch, 0x09D7);
|
||||
TX_CHAR_RANGE(ch, 0x09E2, 0x09E3);
|
||||
TX_MATCH_CHAR(ch, 0x0A02);
|
||||
TX_MATCH_CHAR(ch, 0x0A3C);
|
||||
TX_MATCH_CHAR(ch, 0x0A3E);
|
||||
TX_MATCH_CHAR(ch, 0x0A3F);
|
||||
TX_CHAR_RANGE(ch, 0x0A40, 0x0A42);
|
||||
TX_CHAR_RANGE(ch, 0x0A47, 0x0A48);
|
||||
TX_CHAR_RANGE(ch, 0x0A4B, 0x0A4D);
|
||||
TX_CHAR_RANGE(ch, 0x0A70, 0x0A71);
|
||||
TX_CHAR_RANGE(ch, 0x0A81, 0x0A83);
|
||||
TX_MATCH_CHAR(ch, 0x0ABC);
|
||||
TX_CHAR_RANGE(ch, 0x0ABE, 0x0AC5);
|
||||
TX_CHAR_RANGE(ch, 0x0AC7, 0x0AC9);
|
||||
TX_CHAR_RANGE(ch, 0x0ACB, 0x0ACD);
|
||||
TX_CHAR_RANGE(ch, 0x0B01, 0x0B03);
|
||||
TX_MATCH_CHAR(ch, 0x0B3C);
|
||||
TX_CHAR_RANGE(ch, 0x0B3E, 0x0B43);
|
||||
TX_CHAR_RANGE(ch, 0x0B47, 0x0B48);
|
||||
TX_CHAR_RANGE(ch, 0x0B4B, 0x0B4D);
|
||||
TX_CHAR_RANGE(ch, 0x0B56, 0x0B57);
|
||||
TX_CHAR_RANGE(ch, 0x0B82, 0x0B83);
|
||||
TX_CHAR_RANGE(ch, 0x0BBE, 0x0BC2);
|
||||
TX_CHAR_RANGE(ch, 0x0BC6, 0x0BC8);
|
||||
TX_CHAR_RANGE(ch, 0x0BCA, 0x0BCD);
|
||||
TX_MATCH_CHAR(ch, 0x0BD7);
|
||||
TX_CHAR_RANGE(ch, 0x0C01, 0x0C03);
|
||||
TX_CHAR_RANGE(ch, 0x0C3E, 0x0C44);
|
||||
TX_CHAR_RANGE(ch, 0x0C46, 0x0C48);
|
||||
TX_CHAR_RANGE(ch, 0x0C4A, 0x0C4D);
|
||||
TX_CHAR_RANGE(ch, 0x0C55, 0x0C56);
|
||||
TX_CHAR_RANGE(ch, 0x0C82, 0x0C83);
|
||||
TX_CHAR_RANGE(ch, 0x0CBE, 0x0CC4);
|
||||
TX_CHAR_RANGE(ch, 0x0CC6, 0x0CC8);
|
||||
TX_CHAR_RANGE(ch, 0x0CCA, 0x0CCD);
|
||||
TX_CHAR_RANGE(ch, 0x0CD5, 0x0CD6);
|
||||
TX_CHAR_RANGE(ch, 0x0D02, 0x0D03);
|
||||
TX_CHAR_RANGE(ch, 0x0D3E, 0x0D43);
|
||||
TX_CHAR_RANGE(ch, 0x0D46, 0x0D48);
|
||||
TX_CHAR_RANGE(ch, 0x0D4A, 0x0D4D);
|
||||
TX_MATCH_CHAR(ch, 0x0D57);
|
||||
TX_MATCH_CHAR(ch, 0x0E31);
|
||||
TX_CHAR_RANGE(ch, 0x0E34, 0x0E3A);
|
||||
TX_MATCH_CHAR(ch, 0x0E46);
|
||||
TX_CHAR_RANGE(ch, 0x0E47, 0x0E4E);
|
||||
TX_MATCH_CHAR(ch, 0x0EB1);
|
||||
TX_CHAR_RANGE(ch, 0x0EB4, 0x0EB9);
|
||||
TX_CHAR_RANGE(ch, 0x0EBB, 0x0EBC);
|
||||
TX_MATCH_CHAR(ch, 0x0EC6);
|
||||
TX_CHAR_RANGE(ch, 0x0EC8, 0x0ECD);
|
||||
TX_CHAR_RANGE(ch, 0x0F18, 0x0F19);
|
||||
TX_MATCH_CHAR(ch, 0x0F35);
|
||||
TX_MATCH_CHAR(ch, 0x0F37);
|
||||
TX_MATCH_CHAR(ch, 0x0F39);
|
||||
TX_MATCH_CHAR(ch, 0x0F3E);
|
||||
TX_MATCH_CHAR(ch, 0x0F3F);
|
||||
TX_CHAR_RANGE(ch, 0x0F71, 0x0F84);
|
||||
TX_CHAR_RANGE(ch, 0x0F86, 0x0F8B);
|
||||
TX_CHAR_RANGE(ch, 0x0F90, 0x0F95);
|
||||
TX_MATCH_CHAR(ch, 0x0F97);
|
||||
TX_CHAR_RANGE(ch, 0x0F99, 0x0FAD);
|
||||
TX_CHAR_RANGE(ch, 0x0FB1, 0x0FB7);
|
||||
TX_MATCH_CHAR(ch, 0x0FB9);
|
||||
TX_CHAR_RANGE(ch, 0x20D0, 0x20DC);
|
||||
TX_MATCH_CHAR(ch, 0x20E1);
|
||||
TX_MATCH_CHAR(ch, 0x3005);
|
||||
TX_CHAR_RANGE(ch, 0x302A, 0x302F);
|
||||
TX_CHAR_RANGE(ch, 0x3031, 0x3035);
|
||||
TX_MATCH_CHAR(ch, 0x3099);
|
||||
TX_MATCH_CHAR(ch, 0x309A);
|
||||
TX_CHAR_RANGE(ch, 0x309D, 0x309E);
|
||||
TX_CHAR_RANGE(ch, 0x30FC, 0x30FE);
|
||||
return MB_FALSE;
|
||||
} //-- isNCNameChar
|
||||
@@ -1,914 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Olivier Gerardin, ogerardin@vo.lu
|
||||
* -- added support for number function calls
|
||||
* -- fixed a bug in CreateExpr (@xxx=/yyy was parsed as @xxx=@xxx/yyy)
|
||||
*
|
||||
* Marina Mechtcheriakova
|
||||
* -- added support for lang()
|
||||
* -- fixed bug in ::parsePredicates,
|
||||
* made sure we continue looking for more predicates.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* ExprParser
|
||||
* This class is used to parse XSL Expressions
|
||||
* @see ExprLexer
|
||||
**/
|
||||
|
||||
#include "ExprParser.h"
|
||||
#include "FunctionLib.h"
|
||||
#include "Names.h"
|
||||
|
||||
/**
|
||||
* Creates a new ExprParser
|
||||
**/
|
||||
ExprParser::ExprParser() {};
|
||||
|
||||
/**
|
||||
* Default Destructor
|
||||
**/
|
||||
ExprParser::~ExprParser() {};
|
||||
|
||||
/**
|
||||
* Creates an Attribute Value Template using the given value
|
||||
* This should move to XSLProcessor class
|
||||
**/
|
||||
AttributeValueTemplate* ExprParser::createAttributeValueTemplate
|
||||
(const String& attValue)
|
||||
{
|
||||
|
||||
AttributeValueTemplate* avt = new AttributeValueTemplate();
|
||||
|
||||
if (attValue.isEmpty())
|
||||
return avt; //XXX should return 0, but that causes crash in lre12
|
||||
|
||||
PRInt32 size = attValue.length();
|
||||
int cc = 0;
|
||||
UNICODE_CHAR nextCh;
|
||||
UNICODE_CHAR ch;
|
||||
String buffer;
|
||||
MBool inExpr = MB_FALSE;
|
||||
MBool inLiteral = MB_FALSE;
|
||||
UNICODE_CHAR endLiteral;
|
||||
|
||||
nextCh = attValue.charAt(cc);
|
||||
while (cc++ < size) {
|
||||
ch = nextCh;
|
||||
nextCh = cc != size ? attValue.charAt(cc) : 0;
|
||||
|
||||
// if in literal just add ch to buffer
|
||||
if (inLiteral && (ch != endLiteral)) {
|
||||
buffer.append(ch);
|
||||
continue;
|
||||
}
|
||||
switch ( ch ) {
|
||||
case '\'' :
|
||||
case '"' :
|
||||
buffer.append(ch);
|
||||
if (inLiteral)
|
||||
inLiteral = MB_FALSE;
|
||||
else if (inExpr) {
|
||||
inLiteral = MB_TRUE;
|
||||
endLiteral = ch;
|
||||
}
|
||||
break;
|
||||
case '{' :
|
||||
if (!inExpr) {
|
||||
// Ignore case where we find two {
|
||||
if (nextCh == ch) {
|
||||
buffer.append(ch); //-- append '{'
|
||||
cc++;
|
||||
nextCh = cc != size ? attValue.charAt(cc) : 0;
|
||||
}
|
||||
else {
|
||||
if (!buffer.isEmpty())
|
||||
avt->addExpr(new StringExpr(buffer));
|
||||
buffer.clear();
|
||||
inExpr = MB_TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
buffer.append(ch); //-- simply append '{'
|
||||
break;
|
||||
case '}':
|
||||
if (inExpr) {
|
||||
inExpr = MB_FALSE;
|
||||
Expr* expr = createExpr(buffer);
|
||||
if (!expr) {
|
||||
delete avt;
|
||||
return 0;
|
||||
}
|
||||
avt->addExpr(expr);
|
||||
buffer.clear();
|
||||
}
|
||||
else if (nextCh == ch) {
|
||||
buffer.append(ch);
|
||||
cc++;
|
||||
nextCh = cc != size ? attValue.charAt(cc) : 0;
|
||||
}
|
||||
else {
|
||||
//XXX ErrorReport: unmatched '}' found
|
||||
delete avt;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
buffer.append(ch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (inExpr) {
|
||||
//XXX ErrorReport: ending '}' missing
|
||||
delete avt;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!buffer.isEmpty())
|
||||
avt->addExpr(new StringExpr(buffer));
|
||||
|
||||
return avt;
|
||||
|
||||
} //-- createAttributeValueTemplate
|
||||
|
||||
Expr* ExprParser::createExpr(const String& aExpression)
|
||||
{
|
||||
ExprLexer lexer(aExpression);
|
||||
return createExpr(lexer);
|
||||
} //-- createExpr
|
||||
|
||||
Pattern* ExprParser::createPattern(const String& aPattern)
|
||||
{
|
||||
ExprLexer lexer(aPattern);
|
||||
return createUnionExpr(lexer);
|
||||
} //-- createPatternExpr
|
||||
|
||||
//--------------------/
|
||||
//- 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) {
|
||||
//-- additive ops
|
||||
case Token::ADDITION_OP :
|
||||
return new AdditiveExpr(left, right, AdditiveExpr::ADDITION);
|
||||
case Token::SUBTRACTION_OP:
|
||||
return new AdditiveExpr(left, right, AdditiveExpr::SUBTRACTION);
|
||||
|
||||
//-- case boolean ops
|
||||
case Token::AND_OP:
|
||||
return new BooleanExpr(left, right, BooleanExpr::AND);
|
||||
case Token::OR_OP:
|
||||
return new BooleanExpr(left, right, BooleanExpr::OR);
|
||||
|
||||
//-- equality ops
|
||||
case Token::EQUAL_OP :
|
||||
return new RelationalExpr(left, right, RelationalExpr::EQUAL);
|
||||
case Token::NOT_EQUAL_OP :
|
||||
return new RelationalExpr(left, right, RelationalExpr::NOT_EQUAL);
|
||||
|
||||
//-- relational ops
|
||||
case Token::LESS_THAN_OP:
|
||||
return new RelationalExpr(left, right, RelationalExpr::LESS_THAN);
|
||||
case Token::GREATER_THAN_OP:
|
||||
return new RelationalExpr(left, right, RelationalExpr::GREATER_THAN);
|
||||
case Token::LESS_OR_EQUAL_OP:
|
||||
return new RelationalExpr(left, right, RelationalExpr::LESS_OR_EQUAL);
|
||||
case Token::GREATER_OR_EQUAL_OP:
|
||||
return new RelationalExpr(left, right, RelationalExpr::GREATER_OR_EQUAL);
|
||||
|
||||
//-- 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:
|
||||
break;
|
||||
|
||||
}
|
||||
return 0;
|
||||
//return new ErrorExpr();
|
||||
} //-- createBinaryExpr
|
||||
|
||||
|
||||
Expr* ExprParser::createExpr(ExprLexer& lexer) {
|
||||
|
||||
MBool done = MB_FALSE;
|
||||
|
||||
Expr* expr = 0;
|
||||
|
||||
Stack exprs;
|
||||
Stack ops;
|
||||
|
||||
while (!done) {
|
||||
|
||||
MBool unary = MB_FALSE;
|
||||
while (lexer.peek()->type == Token::SUBTRACTION_OP) {
|
||||
unary = !unary;
|
||||
lexer.nextToken();
|
||||
}
|
||||
|
||||
expr = createUnionExpr(lexer);
|
||||
if (!expr)
|
||||
break;
|
||||
|
||||
if (unary)
|
||||
expr = new UnaryExpr(expr);
|
||||
|
||||
Token* tok = lexer.nextToken();
|
||||
switch (tok->type) {
|
||||
case Token::ADDITION_OP:
|
||||
case Token::DIVIDE_OP:
|
||||
//-- boolean ops
|
||||
case Token::AND_OP :
|
||||
case Token::OR_OP :
|
||||
//-- equality ops
|
||||
case Token::EQUAL_OP:
|
||||
case Token::NOT_EQUAL_OP:
|
||||
//-- relational ops
|
||||
case Token::LESS_THAN_OP:
|
||||
case Token::GREATER_THAN_OP:
|
||||
case Token::LESS_OR_EQUAL_OP:
|
||||
case Token::GREATER_OR_EQUAL_OP:
|
||||
//-- multiplicative ops
|
||||
case Token::MODULUS_OP:
|
||||
case Token::MULTIPLY_OP:
|
||||
case Token::SUBTRACTION_OP:
|
||||
{
|
||||
while (!exprs.empty() &&
|
||||
precedenceLevel(tok->type)
|
||||
<= precedenceLevel(((Token*)ops.peek())->type)) {
|
||||
expr = createBinaryExpr((Expr*)exprs.pop(),
|
||||
expr,
|
||||
(Token*)ops.pop());
|
||||
}
|
||||
exprs.push(expr);
|
||||
ops.push(tok);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
lexer.pushBack();
|
||||
done = MB_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure expr != 0
|
||||
if (!expr) {
|
||||
while (!exprs.empty()) {
|
||||
delete (Expr*)exprs.pop();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (!exprs.empty()) {
|
||||
expr = createBinaryExpr((Expr*)exprs.pop(), expr, (Token*)ops.pop());
|
||||
}
|
||||
|
||||
return expr;
|
||||
|
||||
} //-- createExpr
|
||||
|
||||
Expr* ExprParser::createFilterExpr(ExprLexer& lexer) {
|
||||
|
||||
Token* tok = lexer.nextToken();
|
||||
|
||||
Expr* expr = 0;
|
||||
switch (tok->type) {
|
||||
case Token::FUNCTION_NAME :
|
||||
lexer.pushBack();
|
||||
expr = createFunctionCall(lexer);
|
||||
break;
|
||||
case Token::VAR_REFERENCE :
|
||||
expr = new VariableRefExpr(tok->value);
|
||||
break;
|
||||
case Token::L_PAREN:
|
||||
expr = createExpr(lexer);
|
||||
if (!expr)
|
||||
return 0;
|
||||
|
||||
if (lexer.nextToken()->type != Token::R_PAREN) {
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: right parenthesis expected
|
||||
delete expr;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
case Token::LITERAL :
|
||||
expr = new StringExpr(tok->value);
|
||||
break;
|
||||
case Token::NUMBER:
|
||||
{
|
||||
expr = new NumberExpr(Double::toDouble(tok->value));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// this should never ever happen.
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: error in parser, please report on bugzilla.mozilla.org
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
if (!expr)
|
||||
return 0;
|
||||
|
||||
if (lexer.peek()->type == Token::L_BRACKET) {
|
||||
|
||||
FilterExpr* filterExpr = new FilterExpr(expr);
|
||||
|
||||
//-- handle predicates
|
||||
if (!parsePredicates(filterExpr, lexer)) {
|
||||
delete filterExpr;
|
||||
return 0;
|
||||
}
|
||||
expr = filterExpr;
|
||||
}
|
||||
|
||||
return expr;
|
||||
|
||||
} //-- createFilterExpr
|
||||
|
||||
FunctionCall* ExprParser::createFunctionCall(ExprLexer& lexer) {
|
||||
|
||||
FunctionCall* fnCall = 0;
|
||||
|
||||
Token* tok = lexer.nextToken();
|
||||
if (tok->type != Token::FUNCTION_NAME) {
|
||||
//XXX ErrorReport: error in parser, please report on bugzilla.mozilla.org
|
||||
return 0;
|
||||
}
|
||||
|
||||
String fnName = tok->value;
|
||||
|
||||
//-- compare function names
|
||||
//-- * we should hash these names for speed
|
||||
|
||||
if (XPathNames::BOOLEAN_FN.isEqual(tok->value)) {
|
||||
fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_BOOLEAN);
|
||||
}
|
||||
else if (XPathNames::CONCAT_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::CONCAT);
|
||||
}
|
||||
else if (XPathNames::CONTAINS_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::CONTAINS);
|
||||
}
|
||||
else if (XPathNames::COUNT_FN.isEqual(tok->value)) {
|
||||
fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::COUNT);
|
||||
}
|
||||
else if (XPathNames::FALSE_FN.isEqual(tok->value)) {
|
||||
fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_FALSE);
|
||||
}
|
||||
else if (XPathNames::ID_FN.isEqual(tok->value)) {
|
||||
fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::ID);
|
||||
}
|
||||
else if (XPathNames::LANG_FN.isEqual(tok->value)) {
|
||||
fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_LANG);
|
||||
}
|
||||
else if (XPathNames::LAST_FN.isEqual(tok->value)) {
|
||||
fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::LAST);
|
||||
}
|
||||
else if (XPathNames::LOCAL_NAME_FN.isEqual(tok->value)) {
|
||||
fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::LOCAL_NAME);
|
||||
}
|
||||
else if (XPathNames::NAME_FN.isEqual(tok->value)) {
|
||||
fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::NAME);
|
||||
}
|
||||
else if (XPathNames::NAMESPACE_URI_FN.isEqual(tok->value)) {
|
||||
fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::NAMESPACE_URI);
|
||||
}
|
||||
else if (XPathNames::NORMALIZE_SPACE_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::NORMALIZE_SPACE);
|
||||
}
|
||||
else if (XPathNames::NOT_FN.isEqual(tok->value)) {
|
||||
fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_NOT);
|
||||
}
|
||||
else if (XPathNames::POSITION_FN.isEqual(tok->value)) {
|
||||
fnCall = new NodeSetFunctionCall(NodeSetFunctionCall::POSITION);
|
||||
}
|
||||
else if (XPathNames::STARTS_WITH_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::STARTS_WITH);
|
||||
}
|
||||
else if (XPathNames::STRING_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::STRING);
|
||||
}
|
||||
else if (XPathNames::STRING_LENGTH_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::STRING_LENGTH);
|
||||
}
|
||||
else if (XPathNames::SUBSTRING_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING);
|
||||
}
|
||||
else if (XPathNames::SUBSTRING_AFTER_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING_AFTER);
|
||||
}
|
||||
else if (XPathNames::SUBSTRING_BEFORE_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::SUBSTRING_BEFORE);
|
||||
}
|
||||
else if (XPathNames::SUM_FN.isEqual(tok->value)) {
|
||||
fnCall = new NumberFunctionCall(NumberFunctionCall::SUM);
|
||||
}
|
||||
else if (XPathNames::TRANSLATE_FN.isEqual(tok->value)) {
|
||||
fnCall = new StringFunctionCall(StringFunctionCall::TRANSLATE);
|
||||
}
|
||||
else if (XPathNames::TRUE_FN.isEqual(tok->value)) {
|
||||
fnCall = new BooleanFunctionCall(BooleanFunctionCall::TX_TRUE);
|
||||
}
|
||||
else if (XPathNames::NUMBER_FN.isEqual(tok->value)) {
|
||||
fnCall = new NumberFunctionCall(NumberFunctionCall::NUMBER);
|
||||
}
|
||||
else if (XPathNames::ROUND_FN.isEqual(tok->value)) {
|
||||
fnCall = new NumberFunctionCall(NumberFunctionCall::ROUND);
|
||||
}
|
||||
else if (XPathNames::CEILING_FN.isEqual(tok->value)) {
|
||||
fnCall = new NumberFunctionCall(NumberFunctionCall::CEILING);
|
||||
}
|
||||
else if (XPathNames::FLOOR_FN.isEqual(tok->value)) {
|
||||
fnCall = new NumberFunctionCall(NumberFunctionCall::FLOOR);
|
||||
}
|
||||
else {
|
||||
//-- Most likely an Extension Function, or error, but it's
|
||||
//-- not our job to report an invalid function call here
|
||||
fnCall = new ExtensionFunctionCall(fnName);
|
||||
}
|
||||
|
||||
//-- handle parametes
|
||||
if (!parseParameters(fnCall, lexer)) {
|
||||
delete fnCall;
|
||||
return 0;
|
||||
}
|
||||
return fnCall;
|
||||
} //-- createFunctionCall
|
||||
|
||||
LocationStep* ExprParser::createLocationStep(ExprLexer& lexer) {
|
||||
|
||||
//-- child axis is default
|
||||
LocationStep::LocationStepType axisIdentifier = LocationStep::CHILD_AXIS;
|
||||
txNodeTest* nodeTest = 0;
|
||||
|
||||
//-- get Axis Identifier or AbbreviatedStep, if present
|
||||
Token* tok = lexer.peek();
|
||||
switch (tok->type) {
|
||||
case Token::AXIS_IDENTIFIER:
|
||||
{
|
||||
//-- eat token
|
||||
lexer.nextToken();
|
||||
//-- should switch to a hash here for speed if necessary
|
||||
if (ANCESTOR_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::ANCESTOR_AXIS;
|
||||
}
|
||||
else if (ANCESTOR_OR_SELF_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::ANCESTOR_OR_SELF_AXIS;
|
||||
}
|
||||
else if (ATTRIBUTE_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::ATTRIBUTE_AXIS;
|
||||
}
|
||||
else if (CHILD_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::CHILD_AXIS;
|
||||
}
|
||||
else if (DESCENDANT_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::DESCENDANT_AXIS;
|
||||
}
|
||||
else if (DESCENDANT_OR_SELF_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::DESCENDANT_OR_SELF_AXIS;
|
||||
}
|
||||
else if (FOLLOWING_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::FOLLOWING_AXIS;
|
||||
}
|
||||
else if (FOLLOWING_SIBLING_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::FOLLOWING_SIBLING_AXIS;
|
||||
}
|
||||
else if (NAMESPACE_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::NAMESPACE_AXIS;
|
||||
}
|
||||
else if (PARENT_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::PARENT_AXIS;
|
||||
}
|
||||
else if (PRECEDING_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::PRECEDING_AXIS;
|
||||
}
|
||||
else if (PRECEDING_SIBLING_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::PRECEDING_SIBLING_AXIS;
|
||||
}
|
||||
else if (SELF_AXIS.isEqual(tok->value)) {
|
||||
axisIdentifier = LocationStep::SELF_AXIS;
|
||||
}
|
||||
else {
|
||||
//XXX ErrorReport: unknow axis
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case Token::AT_SIGN:
|
||||
//-- eat token
|
||||
lexer.nextToken();
|
||||
axisIdentifier = LocationStep::ATTRIBUTE_AXIS;
|
||||
break;
|
||||
case Token::PARENT_NODE :
|
||||
//-- eat token
|
||||
lexer.nextToken();
|
||||
axisIdentifier = LocationStep::PARENT_AXIS;
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
if (!nodeTest) {
|
||||
//XXX out of memory
|
||||
return 0;
|
||||
}
|
||||
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;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
//-- get NodeTest unless an AbbreviatedStep was found
|
||||
if (!nodeTest) {
|
||||
tok = lexer.nextToken();
|
||||
|
||||
switch (tok->type) {
|
||||
case Token::CNAME :
|
||||
switch (axisIdentifier) {
|
||||
case LocationStep::ATTRIBUTE_AXIS:
|
||||
nodeTest = new txNameTest(tok->value, Node::ATTRIBUTE_NODE);
|
||||
break;
|
||||
// XXX Namespace: handle namespaces here
|
||||
default:
|
||||
nodeTest = new txNameTest(tok->value, Node::ELEMENT_NODE);
|
||||
break;
|
||||
}
|
||||
if (!nodeTest) {
|
||||
//XXX ErrorReport: out of memory
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
nodeTest = createNodeTest(lexer);
|
||||
if (!nodeTest) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LocationStep* lstep = new LocationStep(nodeTest, axisIdentifier);
|
||||
if (!lstep) {
|
||||
//XXX out of memory
|
||||
delete nodeTest;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//-- handle predicates
|
||||
if (!parsePredicates(lstep, lexer)) {
|
||||
delete lstep;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return lstep;
|
||||
} //-- createLocationPath
|
||||
|
||||
/**
|
||||
* This method only handles comment(), text(), processing-instructing() and node()
|
||||
*
|
||||
**/
|
||||
txNodeTest* ExprParser::createNodeTest(ExprLexer& lexer) {
|
||||
|
||||
txNodeTest* nodeTest = 0;
|
||||
|
||||
Token* nodeTok = lexer.nextToken();
|
||||
|
||||
switch (nodeTok->type) {
|
||||
case Token::COMMENT:
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::COMMENT_TYPE);
|
||||
break;
|
||||
case Token::NODE :
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::NODE_TYPE);
|
||||
break;
|
||||
case Token::PROC_INST :
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::PI_TYPE);
|
||||
break;
|
||||
case Token::TEXT :
|
||||
nodeTest = new txNodeTypeTest(txNodeTypeTest::TEXT_TYPE);
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
// XXX ErrorReport: unexpected token
|
||||
return 0;
|
||||
}
|
||||
if (!nodeTest) {
|
||||
//XXX out of memory
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (lexer.nextToken()->type != Token::L_PAREN) {
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: left parenthesis expected
|
||||
delete nodeTest;
|
||||
return 0;
|
||||
}
|
||||
if (nodeTok->type == Token::PROC_INST &&
|
||||
lexer.peek()->type == Token::LITERAL) {
|
||||
Token* tok = lexer.nextToken();
|
||||
((txNodeTypeTest*)nodeTest)->setNodeName(tok->value);
|
||||
}
|
||||
if (lexer.nextToken()->type != Token::R_PAREN) {
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: right parenthesis expected (or literal for pi)
|
||||
delete nodeTest;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return nodeTest;
|
||||
} //-- createNodeExpr
|
||||
|
||||
/**
|
||||
* Creates a PathExpr using the given ExprLexer
|
||||
* @param lexer the ExprLexer for retrieving Tokens
|
||||
**/
|
||||
Expr* ExprParser::createPathExpr(ExprLexer& lexer) {
|
||||
|
||||
Expr* expr = 0;
|
||||
|
||||
Token* tok = lexer.peek();
|
||||
|
||||
// is this a root expression?
|
||||
if (tok->type == Token::PARENT_OP) {
|
||||
lexer.nextToken();
|
||||
if (!isLocationStepToken(lexer.peek()))
|
||||
return new RootExpr(MB_TRUE);
|
||||
|
||||
lexer.pushBack();
|
||||
}
|
||||
|
||||
// parse first step (possibly a FilterExpr)
|
||||
if (tok->type != Token::PARENT_OP &&
|
||||
tok->type != Token::ANCESTOR_OP) {
|
||||
if (isFilterExprToken(tok)) {
|
||||
expr = createFilterExpr(lexer);
|
||||
}
|
||||
else
|
||||
expr = createLocationStep(lexer);
|
||||
|
||||
if (!expr)
|
||||
return 0;
|
||||
|
||||
// is this a singlestep path expression?
|
||||
tok = lexer.peek();
|
||||
if (tok->type != Token::PARENT_OP &&
|
||||
tok->type != Token::ANCESTOR_OP)
|
||||
return expr;
|
||||
}
|
||||
else {
|
||||
expr = new RootExpr(MB_FALSE);
|
||||
if (!expr) {
|
||||
// XXX ErrorReport: out of memory
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// 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);
|
||||
|
||||
// this is ugly
|
||||
while (1) {
|
||||
PathExpr::PathOperator pathOp;
|
||||
tok = lexer.nextToken();
|
||||
switch (tok->type) {
|
||||
case Token::ANCESTOR_OP :
|
||||
pathOp = PathExpr::DESCENDANT_OP;
|
||||
break;
|
||||
case Token::PARENT_OP :
|
||||
pathOp = PathExpr::RELATIVE_OP;
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
return pathExpr;
|
||||
}
|
||||
|
||||
expr = createLocationStep(lexer);
|
||||
if (!expr) {
|
||||
delete pathExpr;
|
||||
return 0;
|
||||
}
|
||||
|
||||
pathExpr->addExpr(expr, pathOp);
|
||||
}
|
||||
|
||||
return pathExpr;
|
||||
} //-- createPathExpr
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
|
||||
Expr* expr = createPathExpr(lexer);
|
||||
if (!expr)
|
||||
return 0;
|
||||
|
||||
if (lexer.peek()->type != Token::UNION_OP)
|
||||
return expr;
|
||||
|
||||
UnionExpr* unionExpr = new UnionExpr();
|
||||
unionExpr->addExpr(expr);
|
||||
|
||||
while (lexer.peek()->type == Token::UNION_OP) {
|
||||
lexer.nextToken(); //-- eat token
|
||||
|
||||
expr = createPathExpr(lexer);
|
||||
if (!expr) {
|
||||
delete unionExpr;
|
||||
return 0;
|
||||
}
|
||||
unionExpr->addExpr(expr);
|
||||
}
|
||||
|
||||
return unionExpr;
|
||||
} //-- createUnionExpr
|
||||
|
||||
MBool ExprParser::isFilterExprToken(Token* token) {
|
||||
switch (token->type) {
|
||||
case Token::LITERAL:
|
||||
case Token::NUMBER:
|
||||
case Token::FUNCTION_NAME:
|
||||
case Token::VAR_REFERENCE:
|
||||
case Token::L_PAREN: // grouping expr
|
||||
return MB_TRUE;
|
||||
default:
|
||||
return MB_FALSE;
|
||||
}
|
||||
} //-- isFilterExprToken
|
||||
|
||||
MBool ExprParser::isLocationStepToken(Token* token) {
|
||||
switch (token->type) {
|
||||
case Token::AXIS_IDENTIFIER :
|
||||
case Token::AT_SIGN :
|
||||
case Token::PARENT_NODE :
|
||||
case Token::SELF_NODE :
|
||||
return MB_TRUE;
|
||||
default:
|
||||
return isNodeTypeToken(token);
|
||||
}
|
||||
} //-- isLocationStepToken
|
||||
|
||||
MBool ExprParser::isNodeTypeToken(Token* token) {
|
||||
switch (token->type) {
|
||||
case Token::CNAME:
|
||||
case Token::COMMENT:
|
||||
case Token::NODE :
|
||||
case Token::PROC_INST :
|
||||
case Token::TEXT :
|
||||
return MB_TRUE;
|
||||
default:
|
||||
return MB_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
|
||||
* @return 0 if successful, or a String pointer to the error message
|
||||
**/
|
||||
MBool ExprParser::parsePredicates(PredicateList* predicateList, ExprLexer& lexer) {
|
||||
|
||||
while (lexer.peek()->type == Token::L_BRACKET) {
|
||||
//-- eat Token
|
||||
lexer.nextToken();
|
||||
|
||||
Expr* expr = createExpr(lexer);
|
||||
if (!expr)
|
||||
return MB_FALSE;
|
||||
|
||||
predicateList->add(expr);
|
||||
|
||||
if (lexer.nextToken()->type != Token::R_BRACKET) {
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: right bracket expected
|
||||
return MB_FALSE;
|
||||
}
|
||||
}
|
||||
return MB_TRUE;
|
||||
|
||||
} //-- parsePredicates
|
||||
|
||||
|
||||
/**
|
||||
* Using the given lexer, parses the tokens if they represent a parameter list
|
||||
* 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) {
|
||||
|
||||
if (lexer.nextToken()->type != Token::L_PAREN) {
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: left parenthesis expected
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
if (lexer.peek()->type == Token::R_PAREN) {
|
||||
lexer.nextToken();
|
||||
return MB_TRUE;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
Expr* expr = createExpr(lexer);
|
||||
if (!expr)
|
||||
return MB_FALSE;
|
||||
|
||||
fnCall->addParam(expr);
|
||||
|
||||
switch (lexer.nextToken()->type) {
|
||||
case Token::R_PAREN :
|
||||
return MB_TRUE;
|
||||
case Token::COMMA: //-- param separator
|
||||
break;
|
||||
default:
|
||||
lexer.pushBack();
|
||||
//XXX ErrorReport: right parenthesis or comma expected
|
||||
return MB_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return MB_FALSE;
|
||||
|
||||
} //-- parseParameters
|
||||
|
||||
short ExprParser::precedenceLevel(short tokenType) {
|
||||
switch (tokenType) {
|
||||
case Token::OR_OP:
|
||||
return 1;
|
||||
case Token::AND_OP:
|
||||
return 2;
|
||||
//-- equality
|
||||
case Token::EQUAL_OP:
|
||||
case Token::NOT_EQUAL_OP:
|
||||
return 3;
|
||||
//-- relational
|
||||
case Token::LESS_THAN_OP:
|
||||
case Token::GREATER_THAN_OP:
|
||||
case Token::LESS_OR_EQUAL_OP:
|
||||
case Token::GREATER_OR_EQUAL_OP:
|
||||
return 4;
|
||||
//-- additive operators
|
||||
case Token::ADDITION_OP:
|
||||
case Token::SUBTRACTION_OP:
|
||||
return 5;
|
||||
//-- multiplicative
|
||||
case Token::DIVIDE_OP:
|
||||
case Token::MULTIPLY_OP:
|
||||
case Token::MODULUS_OP:
|
||||
return 6;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
} //-- precedenceLevel
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* ExprParser
|
||||
* This class is used to parse XSL Expressions
|
||||
* @see ExprLexer
|
||||
**/
|
||||
|
||||
#ifndef MITREXSL_EXPRPARSER_H
|
||||
#define MITREXSL_EXPRPARSER_H
|
||||
|
||||
#include "TxString.h"
|
||||
#include "ExprLexer.h"
|
||||
#include "Expr.h"
|
||||
#include "List.h"
|
||||
|
||||
class ExprParser {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new ExprParser
|
||||
**/
|
||||
ExprParser();
|
||||
|
||||
/**
|
||||
* destroys the ExprParser
|
||||
**/
|
||||
~ExprParser();
|
||||
|
||||
Expr* createExpr(const String& aExpression);
|
||||
Pattern* createPattern(const String& aPattern);
|
||||
|
||||
/**
|
||||
* Creates an Attribute Value Template using the given value
|
||||
**/
|
||||
AttributeValueTemplate* createAttributeValueTemplate(const String& attValue);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
|
||||
Expr* createBinaryExpr (Expr* left, Expr* right, Token* op);
|
||||
Expr* createExpr (ExprLexer& lexer);
|
||||
Expr* createFilterExpr (ExprLexer& lexer);
|
||||
FunctionCall* createFunctionCall (ExprLexer& lexer);
|
||||
LocationStep* createLocationStep (ExprLexer& lexer);
|
||||
txNodeTest* createNodeTest (ExprLexer& lexer);
|
||||
Expr* createPathExpr (ExprLexer& lexer);
|
||||
Expr* createUnionExpr (ExprLexer& lexer);
|
||||
|
||||
MBool isFilterExprToken (Token* tok);
|
||||
MBool isLocationStepToken (Token* tok);
|
||||
MBool isNodeTypeToken (Token* tok);
|
||||
|
||||
static short precedenceLevel (short tokenType);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @return 0 if successful, or a String pointer to the error message
|
||||
**/
|
||||
MBool parsePredicates(PredicateList* predicateList, ExprLexer& lexer);
|
||||
MBool parseParameters(FunctionCall* fnCall, ExprLexer& lexer);
|
||||
|
||||
|
||||
}; //-- ExprParser
|
||||
|
||||
#endif
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
* Larry Fitzpatrick, OpenText, lef@opentext.com
|
||||
* -- changed constant short result types to enum
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TRANSFRMX_EXPRRESULT_H
|
||||
#define TRANSFRMX_EXPRRESULT_H
|
||||
|
||||
#include "TxObject.h"
|
||||
#include "primitives.h"
|
||||
|
||||
/*
|
||||
* ExprResult
|
||||
*
|
||||
* Classes Represented:
|
||||
* BooleanResult, ExprResult, NumberResult, StringResult
|
||||
*
|
||||
* Note: for NodeSet, see NodeSet.h
|
||||
*/
|
||||
|
||||
class ExprResult : public TxObject {
|
||||
|
||||
public:
|
||||
|
||||
//-- ResultTypes
|
||||
enum ResultType {
|
||||
NODESET = 1,
|
||||
STRING,
|
||||
BOOLEAN,
|
||||
TREE_FRAGMENT,
|
||||
NUMBER
|
||||
};
|
||||
|
||||
virtual ~ExprResult() {};
|
||||
|
||||
/**
|
||||
* Returns the type of ExprResult represented
|
||||
* @return the type of ExprResult represented
|
||||
**/
|
||||
virtual short getResultType() = 0;
|
||||
|
||||
/**
|
||||
* Creates a String representation of this ExprResult
|
||||
* @param str the destination string to append the String representation to.
|
||||
**/
|
||||
virtual void stringValue(String& str) = 0;
|
||||
|
||||
/**
|
||||
* Converts this ExprResult to a Boolean (MBool) value
|
||||
* @return the Boolean value
|
||||
**/
|
||||
virtual MBool booleanValue() = 0;
|
||||
|
||||
/**
|
||||
* Converts this ExprResult to a Number (double) value
|
||||
* @return the Number value
|
||||
**/
|
||||
virtual double numberValue() = 0;
|
||||
|
||||
};
|
||||
|
||||
class BooleanResult : public ExprResult {
|
||||
|
||||
public:
|
||||
|
||||
BooleanResult();
|
||||
BooleanResult(MBool boolean);
|
||||
|
||||
virtual short getResultType();
|
||||
virtual void stringValue(String& str);
|
||||
virtual MBool booleanValue();
|
||||
virtual double numberValue();
|
||||
|
||||
private:
|
||||
MBool value;
|
||||
};
|
||||
|
||||
class NumberResult : public ExprResult {
|
||||
|
||||
public:
|
||||
|
||||
NumberResult();
|
||||
NumberResult(double dbl);
|
||||
|
||||
double getValue() const;
|
||||
MBool isNaN() const;
|
||||
|
||||
virtual short getResultType();
|
||||
virtual void stringValue(String& str);
|
||||
virtual MBool booleanValue();
|
||||
virtual double numberValue();
|
||||
|
||||
private:
|
||||
double value;
|
||||
|
||||
};
|
||||
|
||||
|
||||
class StringResult : public ExprResult {
|
||||
|
||||
public:
|
||||
|
||||
StringResult();
|
||||
StringResult(const String& str);
|
||||
StringResult(const char* str);
|
||||
|
||||
virtual short getResultType();
|
||||
virtual void stringValue(String& str);
|
||||
virtual MBool booleanValue();
|
||||
virtual double numberValue();
|
||||
|
||||
|
||||
private:
|
||||
String value;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,123 +0,0 @@
|
||||
/*
|
||||
* 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 XSL:P XSLT processor.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Keith Visco.
|
||||
* Portions created by Keith Visco are Copyright (C) 1999, 2000 Keith Visco.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
|
||||
|
||||
const String ExtensionFunctionCall::UNDEFINED_FUNCTION = "Undefined Function: ";
|
||||
|
||||
/**
|
||||
* Creates an ExtensionFunctionCall with the given function name.
|
||||
* @param name the name of the extension function which to invoke
|
||||
**/
|
||||
ExtensionFunctionCall::ExtensionFunctionCall(const String& name) : FunctionCall(name)
|
||||
{
|
||||
this->fname = name;
|
||||
this->fnCall = 0;
|
||||
|
||||
} //-- ExtensionFunctionCall
|
||||
|
||||
/**
|
||||
* Deletes an instance of ExtensionFunctioncall
|
||||
**/
|
||||
ExtensionFunctionCall::~ExtensionFunctionCall() {
|
||||
delete fnCall;
|
||||
} //-- ~ExtensionFunctionCall
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* ExtensionFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
//-- check for existing function call resolution
|
||||
|
||||
if (!fnCall) {
|
||||
fnCall = cs->resolveFunctionCall(fname);
|
||||
|
||||
if (!fnCall) {
|
||||
String err(UNDEFINED_FUNCTION);
|
||||
err.append(fname);
|
||||
return new StringResult(err);
|
||||
}
|
||||
|
||||
//copy parameters
|
||||
ListIterator* iter = params.iterator();
|
||||
while (iter->hasNext()) {
|
||||
fnCall->addParam( new ExprWrapper( (Expr*) iter->next() ) );
|
||||
}
|
||||
delete iter;
|
||||
}
|
||||
|
||||
//-- delegate
|
||||
return fnCall->evaluate(context, cs);
|
||||
|
||||
} //-- evaluate
|
||||
|
||||
//---------------------------------/
|
||||
//- Implementation of ExprWrapper -/
|
||||
//---------------------------------/
|
||||
|
||||
/**
|
||||
* Creates a new ExprWrapper for the given Expr
|
||||
**/
|
||||
ExprWrapper::ExprWrapper(Expr* expr) {
|
||||
this->expr = expr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor for ExprWrapper
|
||||
**/
|
||||
ExprWrapper::~ExprWrapper() {
|
||||
//-- DO NOTHING!
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* ExprWrapper::evaluate(Node* context, ContextState* cs) {
|
||||
//-- just delegate
|
||||
if (!expr) return 0; // <-- hopefully this will never happen
|
||||
return expr->evaluate(context, cs);
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void ExprWrapper::toString(String& str) {
|
||||
//-- just delegate
|
||||
if (expr) expr->toString(str);
|
||||
} //-- toString
|
||||
|
||||
@@ -1,129 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
* Bob Miller, kbob@oblix.com
|
||||
* -- plugged core leak.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
//-- 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 -/
|
||||
//-----------------------------/
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ProcessorState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
* @see Expr
|
||||
**/
|
||||
ExprResult* FilterExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
if (!context || !expr)
|
||||
return new NodeSet;
|
||||
|
||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
||||
if (!exprResult)
|
||||
return 0;
|
||||
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
// Result is a nodeset, filter it.
|
||||
cs->sortByDocumentOrder((NodeSet*)exprResult);
|
||||
evaluatePredicates((NodeSet*)exprResult, cs);
|
||||
}
|
||||
else if(!isEmpty()) {
|
||||
// We can't filter a non-nodeset
|
||||
String err("Expecting nodeset as result of: ");
|
||||
expr->toString(err);
|
||||
cs->recieveError(err);
|
||||
delete exprResult;
|
||||
return new NodeSet;
|
||||
}
|
||||
|
||||
return exprResult;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double FilterExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
NS_ASSERTION(0, "FilterExpr is not allowed in Patterns");
|
||||
|
||||
if (isEmpty())
|
||||
return expr->getDefaultPriority(node, context, cs);
|
||||
return 0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool FilterExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
if (!expr)
|
||||
return MB_FALSE;
|
||||
|
||||
ExprResult* exprResult = evaluate(node, cs);
|
||||
if (!exprResult)
|
||||
return MB_FALSE;
|
||||
|
||||
MBool result = MB_FALSE;
|
||||
if(exprResult->getResultType() == ExprResult::NODESET)
|
||||
result = ((NodeSet*)exprResult)->contains(node);
|
||||
|
||||
delete exprResult;
|
||||
return result;
|
||||
|
||||
} //-- matches
|
||||
|
||||
/**
|
||||
* Creates a String representation of this Expr
|
||||
* @param str the destination String to append to
|
||||
* @see Expr
|
||||
**/
|
||||
void FilterExpr::toString(String& str) {
|
||||
if ( expr ) expr->toString(str);
|
||||
else str.append("null");
|
||||
PredicateList::toString(str);
|
||||
} //-- toString
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
/**
|
||||
* This class represents a FunctionCall as defined by the XSL Working Draft
|
||||
**/
|
||||
|
||||
const String FunctionCall::INVALID_PARAM_COUNT =
|
||||
"invalid number of parameters for function: ";
|
||||
|
||||
const String FunctionCall::INVALID_PARAM_VALUE =
|
||||
"invalid parameter value for function: ";
|
||||
|
||||
//- Constructors -/
|
||||
|
||||
/**
|
||||
* Creates a new FunctionCall
|
||||
**/
|
||||
FunctionCall::FunctionCall() {
|
||||
this->name = "void";
|
||||
} //-- FunctionCall
|
||||
|
||||
/**
|
||||
* Creates a new FunctionCall with the given function
|
||||
* Note: The object references in parameters will be deleted when this
|
||||
* FunctionCall gets destroyed.
|
||||
**/
|
||||
FunctionCall::FunctionCall(const String& name)
|
||||
{
|
||||
//-- copy name
|
||||
this->name = name;
|
||||
} //-- FunctionCall
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
**/
|
||||
FunctionCall::~FunctionCall()
|
||||
{
|
||||
ListIterator* iter = params.iterator();
|
||||
while (iter->hasNext()) {
|
||||
iter->next();
|
||||
Expr* expr = (Expr*) iter->remove();
|
||||
delete expr;
|
||||
}
|
||||
delete iter;
|
||||
} //-- ~FunctionCall
|
||||
|
||||
//------------------/
|
||||
//- Public Methods -/
|
||||
//------------------/
|
||||
|
||||
/**
|
||||
* Adds the given parameter to this FunctionCall's parameter list
|
||||
* @param expr the Expr to add to this FunctionCall's parameter list
|
||||
**/
|
||||
void FunctionCall::addParam(Expr* expr)
|
||||
{
|
||||
if (expr)
|
||||
params.add(expr);
|
||||
} //-- addParam
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Expr based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double FunctionCall::getDefaultPriority(Node* node,
|
||||
Node* context,
|
||||
ContextState* cs)
|
||||
{
|
||||
return 0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool FunctionCall::matches(Node* node, Node* context, ContextState* cs)
|
||||
{
|
||||
MBool result = MB_FALSE;
|
||||
ExprResult* exprResult = evaluate(node, cs);
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* nodes = (NodeSet*)exprResult;
|
||||
result = (nodes->contains(node));
|
||||
}
|
||||
delete exprResult;
|
||||
return result;
|
||||
} //-- matches
|
||||
|
||||
/**
|
||||
* Evaluates the given Expression and converts it's result to a String.
|
||||
* The value is appended to the given destination String
|
||||
**/
|
||||
void FunctionCall::evaluateToString(Expr* expr, Node* context,
|
||||
ContextState* cs, String& dest)
|
||||
{
|
||||
if (!expr)
|
||||
return;
|
||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
||||
exprResult->stringValue(dest);
|
||||
delete exprResult;
|
||||
} //-- evaluateToString
|
||||
|
||||
/**
|
||||
* Evaluates the given Expression and converts it's result to a number.
|
||||
**/
|
||||
double FunctionCall::evaluateToNumber(Expr* expr, Node* context,
|
||||
ContextState* cs)
|
||||
{
|
||||
double result = Double::NaN;
|
||||
if (!expr)
|
||||
return result;
|
||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
||||
result = exprResult->numberValue();
|
||||
delete exprResult;
|
||||
return result;
|
||||
} //-- evaluateToNumber
|
||||
|
||||
/*
|
||||
* Evaluates the given Expression and converts its result to a NodeSet.
|
||||
* If the result is not a NodeSet NULL is returned.
|
||||
*/
|
||||
NodeSet* FunctionCall::evaluateToNodeSet(Expr* aExpr,
|
||||
Node* aContext,
|
||||
ContextState* aCs)
|
||||
{
|
||||
NS_ASSERTION(aExpr, "Missing expression to evaluate");
|
||||
|
||||
ExprResult* exprResult = aExpr->evaluate(aContext, aCs);
|
||||
if (!exprResult)
|
||||
return 0;
|
||||
|
||||
if (exprResult->getResultType() != ExprResult::NODESET) {
|
||||
String err("NodeSet expected as argument");
|
||||
aCs->recieveError(err);
|
||||
delete exprResult;
|
||||
return 0;
|
||||
}
|
||||
|
||||
NodeSet* nodes = (NodeSet*)exprResult;
|
||||
aCs->sortByDocumentOrder(nodes);
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called to check number of parameters
|
||||
**/
|
||||
MBool FunctionCall::requireParams (int paramCountMin,
|
||||
int paramCountMax,
|
||||
ContextState* cs)
|
||||
{
|
||||
int argc = params.getLength();
|
||||
if ((argc < paramCountMin) || (argc > paramCountMax)) {
|
||||
String err(INVALID_PARAM_COUNT);
|
||||
toString(err);
|
||||
cs->recieveError(err);
|
||||
return MB_FALSE;
|
||||
}
|
||||
return MB_TRUE;
|
||||
} //-- requireParams
|
||||
|
||||
/**
|
||||
* Called to check number of parameters
|
||||
**/
|
||||
MBool FunctionCall::requireParams(int paramCountMin, ContextState* cs)
|
||||
{
|
||||
int argc = params.getLength();
|
||||
if (argc < paramCountMin) {
|
||||
String err(INVALID_PARAM_COUNT);
|
||||
toString(err);
|
||||
cs->recieveError(err);
|
||||
return MB_FALSE;
|
||||
}
|
||||
return MB_TRUE;
|
||||
} //-- requireParams
|
||||
|
||||
/**
|
||||
* Returns the String representation of this NodeExpr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this NodeExpr.
|
||||
**/
|
||||
void FunctionCall::toString(String& dest)
|
||||
{
|
||||
dest.append(this->name);
|
||||
dest.append('(');
|
||||
//-- add parameters
|
||||
ListIterator* iterator = params.iterator();
|
||||
int argc = 0;
|
||||
while (iterator->hasNext()) {
|
||||
if (argc > 0)
|
||||
dest.append(',');
|
||||
Expr* expr = (Expr*)iterator->next();
|
||||
expr->toString(dest);
|
||||
++argc;
|
||||
}
|
||||
delete iterator;
|
||||
dest.append(')');
|
||||
} //-- toString
|
||||
|
||||
@@ -1,353 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Olivier Gerardin, ogerardin@vo.lu
|
||||
* -- added number functions
|
||||
*
|
||||
* Marina Mechtcheriakova
|
||||
* -- added support for lang function
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef TRANSFRMX_FUNCTIONLIB_H
|
||||
#define TRANSFRMX_FUNCTIONLIB_H
|
||||
|
||||
|
||||
#include "TxString.h"
|
||||
#include "primitives.h"
|
||||
#include "ExprResult.h"
|
||||
#include "Expr.h"
|
||||
|
||||
|
||||
class XPathNames {
|
||||
|
||||
public:
|
||||
//-- Function Names
|
||||
static const String BOOLEAN_FN;
|
||||
static const String CONCAT_FN;
|
||||
static const String CONTAINS_FN;
|
||||
static const String COUNT_FN ;
|
||||
static const String FALSE_FN;
|
||||
static const String ID_FN;
|
||||
static const String LANG_FN;
|
||||
static const String LAST_FN;
|
||||
static const String LOCAL_NAME_FN;
|
||||
static const String NAME_FN;
|
||||
static const String NAMESPACE_URI_FN;
|
||||
static const String NORMALIZE_SPACE_FN;
|
||||
static const String NOT_FN;
|
||||
static const String POSITION_FN;
|
||||
static const String STARTS_WITH_FN;
|
||||
static const String STRING_FN;
|
||||
static const String STRING_LENGTH_FN;
|
||||
static const String SUBSTRING_FN;
|
||||
static const String SUBSTRING_AFTER_FN;
|
||||
static const String SUBSTRING_BEFORE_FN;
|
||||
static const String SUM_FN;
|
||||
static const String TRANSLATE_FN;
|
||||
static const String TRUE_FN;
|
||||
// OG+
|
||||
static const String NUMBER_FN;
|
||||
static const String ROUND_FN;
|
||||
static const String CEILING_FN;
|
||||
static const String FLOOR_FN;
|
||||
// OG-
|
||||
|
||||
|
||||
//-- internal XSL processor functions
|
||||
static const String ERROR_FN;
|
||||
|
||||
|
||||
}; //-- XPathNames
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* The following are definitions for the XPath functions
|
||||
*
|
||||
* <PRE>
|
||||
* Modifications:
|
||||
* 20000418: Keith Visco
|
||||
* -- added ExtensionFunctionCall
|
||||
*
|
||||
* 19990805: Keith Visco
|
||||
* - added NodeSetFunctionCall
|
||||
* - moved position() function into NodeSetFunctionCall
|
||||
* - removed PositionFunctionCall
|
||||
* 19990806: Larry Fitzpatrick
|
||||
* - changed constant short declarations for BooleanFunctionCall
|
||||
* with enumerations
|
||||
* 19990806: Keith Visco
|
||||
* - added StringFunctionCall
|
||||
* - stated using Larry's enum suggestion instead of using static const shorts,
|
||||
* as you can see, I am a Java developer! ;-)
|
||||
* </PRE>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents the Set of boolean functions
|
||||
**/
|
||||
class BooleanFunctionCall : public FunctionCall {
|
||||
|
||||
public:
|
||||
|
||||
enum booleanFunctions { TX_BOOLEAN = 1, TX_FALSE, TX_LANG, TX_NOT, TX_TRUE };
|
||||
|
||||
/**
|
||||
* Creates a BooleanFunctionCall of the given type
|
||||
**/
|
||||
BooleanFunctionCall(short type);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
private:
|
||||
short type;
|
||||
}; //-- BooleanFunctionCall
|
||||
|
||||
/**
|
||||
* Internal Function created when there is an Error during parsing
|
||||
* an Expression
|
||||
**/
|
||||
class ErrorFunctionCall : public FunctionCall {
|
||||
public:
|
||||
|
||||
ErrorFunctionCall();
|
||||
ErrorFunctionCall(const String& errorMsg);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
void setErrorMessage(String& errorMsg);
|
||||
|
||||
private:
|
||||
|
||||
String errorMessage;
|
||||
|
||||
}; //-- ErrorFunctionCall
|
||||
|
||||
|
||||
/**
|
||||
* Used for extension functions
|
||||
**/
|
||||
class ExtensionFunctionCall : public FunctionCall {
|
||||
|
||||
public:
|
||||
|
||||
static const String UNDEFINED_FUNCTION;
|
||||
|
||||
/**
|
||||
* Creates a new ExtensionFunctionCall with the given function name
|
||||
* @param name the name of the extension function
|
||||
**/
|
||||
ExtensionFunctionCall(const String& name);
|
||||
|
||||
/**
|
||||
* Destructor for extension function call
|
||||
**/
|
||||
virtual ~ExtensionFunctionCall();
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
private:
|
||||
|
||||
String fname;
|
||||
FunctionCall* fnCall;
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* This class is used by ExtensionFunctionCall, to prevent deletion
|
||||
* of the parameter expressions, by the resolved function call. The implementation
|
||||
* for this class is in ExtensionFunctionCall.cpp
|
||||
**/
|
||||
class ExprWrapper : public Expr {
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
* Creates a new ExprWrapper for the given Expr
|
||||
**/
|
||||
ExprWrapper(Expr* expr);
|
||||
|
||||
/**
|
||||
* Destructor for ExprWrapper
|
||||
**/
|
||||
virtual ~ExprWrapper();
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
virtual void toString(String& str);
|
||||
|
||||
private:
|
||||
|
||||
Expr* expr;
|
||||
|
||||
}; //-- ExprWrapper
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* A representation of the XPath NodeSet funtions
|
||||
*/
|
||||
class NodeSetFunctionCall : public FunctionCall {
|
||||
|
||||
public:
|
||||
|
||||
enum NodeSetFunctions {
|
||||
COUNT, // count()
|
||||
ID, // id()
|
||||
LAST, // last()
|
||||
LOCAL_NAME, // local-name()
|
||||
NAMESPACE_URI, // namespace-uri()
|
||||
NAME, // name()
|
||||
POSITION // position()
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a NodeSetFunctionCall of the given type
|
||||
*/
|
||||
NodeSetFunctionCall(NodeSetFunctions aType);
|
||||
|
||||
/*
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
private:
|
||||
NodeSetFunctions mType;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Represents the XPath String Function Calls
|
||||
**/
|
||||
class StringFunctionCall : public FunctionCall {
|
||||
|
||||
public:
|
||||
|
||||
enum stringFunctions {
|
||||
CONCAT = 1, //-- concat()
|
||||
CONTAINS, //-- contains()
|
||||
NORMALIZE_SPACE, //-- normalize-space()
|
||||
STARTS_WITH, //-- starts-with()
|
||||
STRING, //-- string()
|
||||
STRING_LENGTH, //-- string-length()
|
||||
SUBSTRING, //-- substring()
|
||||
SUBSTRING_AFTER, //-- substring-after()
|
||||
SUBSTRING_BEFORE, //-- substring-before()
|
||||
TRANSLATE //-- translate()
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a String function of the given type
|
||||
**/
|
||||
StringFunctionCall(short type);
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
private:
|
||||
short type;
|
||||
}; //-- StringFunctionCall
|
||||
|
||||
|
||||
/*
|
||||
* Represents the XPath Number Function Calls
|
||||
*/
|
||||
class NumberFunctionCall : public FunctionCall {
|
||||
|
||||
public:
|
||||
|
||||
enum NumberFunctions {
|
||||
NUMBER, // number()
|
||||
ROUND, // round()
|
||||
FLOOR, // floor()
|
||||
CEILING, // ceiling()
|
||||
SUM // sum()
|
||||
};
|
||||
|
||||
/*
|
||||
* Creates a Number function of the given type
|
||||
*/
|
||||
NumberFunctionCall(NumberFunctions type);
|
||||
|
||||
/*
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
virtual ExprResult* evaluate(Node* context, ContextState* cs);
|
||||
|
||||
private:
|
||||
NumberFunctions mType;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,322 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
Implementation of an XPath LocationStep
|
||||
*/
|
||||
|
||||
#include "Expr.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(txNodeTest* aNodeTest,
|
||||
LocationStepType aAxisIdentifier)
|
||||
{
|
||||
mNodeTest = aNodeTest;
|
||||
mAxisIdentifier = aAxisIdentifier;
|
||||
} //-- LocationStep
|
||||
|
||||
/**
|
||||
* Destroys this LocationStep
|
||||
* All predicates will be deleted
|
||||
* The NodeExpr will be deleted
|
||||
**/
|
||||
LocationStep::~LocationStep() {
|
||||
delete mNodeTest;
|
||||
} //-- ~LocationStep
|
||||
|
||||
//-----------------------------/
|
||||
//- Virtual methods from Expr -/
|
||||
//-----------------------------/
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ProcessorState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
* @see Expr
|
||||
**/
|
||||
ExprResult* LocationStep::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
NodeSet* nodes = new NodeSet();
|
||||
if (!context || !mNodeTest || !nodes)
|
||||
return nodes;
|
||||
|
||||
Node* node = context;
|
||||
switch (mAxisIdentifier) {
|
||||
case ANCESTOR_AXIS :
|
||||
node = context->getXPathParent();
|
||||
//-- do not break here
|
||||
case ANCESTOR_OR_SELF_AXIS :
|
||||
while (node) {
|
||||
if (mNodeTest->matches(node, cs)) {
|
||||
nodes->add(node);
|
||||
}
|
||||
node = node->getXPathParent();
|
||||
}
|
||||
break;
|
||||
case ATTRIBUTE_AXIS :
|
||||
{
|
||||
NamedNodeMap* atts = context->getAttributes();
|
||||
if ( atts ) {
|
||||
for ( PRUint32 i = 0; i < atts->getLength(); i++ ) {
|
||||
Node* attr = atts->item(i);
|
||||
if (mNodeTest->matches(attr, cs))
|
||||
nodes->add(attr);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DESCENDANT_OR_SELF_AXIS :
|
||||
if (mNodeTest->matches(context, cs))
|
||||
nodes->add(context);
|
||||
//-- do not break here
|
||||
case DESCENDANT_AXIS :
|
||||
fromDescendants(context, cs, nodes);
|
||||
break;
|
||||
case FOLLOWING_AXIS :
|
||||
{
|
||||
if ( node->getNodeType() == Node::ATTRIBUTE_NODE) {
|
||||
node = node->getXPathParent();
|
||||
fromDescendants(node, cs, nodes);
|
||||
}
|
||||
while (node && !node->getNextSibling()) {
|
||||
node = node->getXPathParent();
|
||||
}
|
||||
while (node) {
|
||||
node = node->getNextSibling();
|
||||
|
||||
if (mNodeTest->matches(node, cs))
|
||||
nodes->add(node);
|
||||
|
||||
if (node->hasChildNodes())
|
||||
fromDescendants(node, cs, nodes);
|
||||
|
||||
while (node && !node->getNextSibling()) {
|
||||
node = node->getParentNode();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case FOLLOWING_SIBLING_AXIS :
|
||||
node = context->getNextSibling();
|
||||
while (node) {
|
||||
if (mNodeTest->matches(node, cs))
|
||||
nodes->add(node);
|
||||
node = node->getNextSibling();
|
||||
}
|
||||
break;
|
||||
case NAMESPACE_AXIS : //-- not yet implemented
|
||||
#if 0
|
||||
// XXX DEBUG OUTPUT
|
||||
cout << "namespace axis not yet implemented"<<endl;
|
||||
#endif
|
||||
break;
|
||||
case PARENT_AXIS :
|
||||
{
|
||||
Node* parent = context->getXPathParent();
|
||||
if (mNodeTest->matches(parent, cs))
|
||||
nodes->add(parent);
|
||||
break;
|
||||
}
|
||||
case PRECEDING_AXIS :
|
||||
while (node && !node->getPreviousSibling()) {
|
||||
node = node->getXPathParent();
|
||||
}
|
||||
while (node) {
|
||||
node = node->getPreviousSibling();
|
||||
|
||||
if (node->hasChildNodes())
|
||||
fromDescendantsRev(node, cs, nodes);
|
||||
|
||||
if (mNodeTest->matches(node, cs))
|
||||
nodes->add(node);
|
||||
|
||||
while (node && !node->getPreviousSibling()) {
|
||||
node = node->getParentNode();
|
||||
}
|
||||
}
|
||||
break;
|
||||
case PRECEDING_SIBLING_AXIS:
|
||||
node = context->getPreviousSibling();
|
||||
while (node) {
|
||||
if (mNodeTest->matches(node, cs))
|
||||
nodes->add(node);
|
||||
node = node->getPreviousSibling();
|
||||
}
|
||||
break;
|
||||
case SELF_AXIS :
|
||||
if (mNodeTest->matches(context, cs))
|
||||
nodes->add(context);
|
||||
break;
|
||||
default: //-- Children Axis
|
||||
{
|
||||
Node* tmpNode = context->getFirstChild();
|
||||
while (tmpNode) {
|
||||
if (mNodeTest->matches(tmpNode, cs))
|
||||
nodes->add(tmpNode);
|
||||
tmpNode = tmpNode->getNextSibling();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} //-- switch
|
||||
|
||||
//-- apply predicates
|
||||
evaluatePredicates(nodes, cs);
|
||||
|
||||
return nodes;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double LocationStep::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
if (isEmpty())
|
||||
return mNodeTest->getDefaultPriority();
|
||||
return 0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
|
||||
void LocationStep::fromDescendants(Node* context, ContextState* cs, NodeSet* nodes) {
|
||||
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
Node* child = context->getFirstChild();
|
||||
while (child) {
|
||||
if (mNodeTest->matches(child, cs))
|
||||
nodes->add(child);
|
||||
//-- check childs descendants
|
||||
if (child->hasChildNodes())
|
||||
fromDescendants(child, cs, nodes);
|
||||
|
||||
child = child->getNextSibling();
|
||||
}
|
||||
|
||||
} //-- fromDescendants
|
||||
|
||||
void LocationStep::fromDescendantsRev(Node* context, ContextState* cs, NodeSet* nodes) {
|
||||
|
||||
if (!context)
|
||||
return;
|
||||
|
||||
Node* child = context->getLastChild();
|
||||
while (child) {
|
||||
//-- check childs descendants
|
||||
if (child->hasChildNodes())
|
||||
fromDescendantsRev(child, cs, nodes);
|
||||
|
||||
if (mNodeTest->matches(child, cs))
|
||||
nodes->add(child);
|
||||
|
||||
child = child->getPreviousSibling();
|
||||
}
|
||||
|
||||
} //-- fromDescendantsRev
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool LocationStep::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
if (!mNodeTest || !node)
|
||||
return MB_FALSE;
|
||||
|
||||
if (!mNodeTest->matches(node, cs))
|
||||
return MB_FALSE;
|
||||
|
||||
MBool result = MB_TRUE;
|
||||
if (!isEmpty()) {
|
||||
NodeSet* nodes = (NodeSet*)evaluate(node->getXPathParent(),cs);
|
||||
result = nodes->contains(node);
|
||||
delete nodes;
|
||||
}
|
||||
else if (mAxisIdentifier == CHILD_AXIS ) {
|
||||
if (!node->getParentNode())
|
||||
result = MB_FALSE;
|
||||
}
|
||||
|
||||
return result;
|
||||
|
||||
} //-- matches
|
||||
|
||||
/**
|
||||
* Creates a String representation of this Expr
|
||||
* @param str the destination String to append to
|
||||
* @see Expr
|
||||
**/
|
||||
void LocationStep::toString(String& str) {
|
||||
switch (mAxisIdentifier) {
|
||||
case ANCESTOR_AXIS :
|
||||
str.append("ancestor::");
|
||||
break;
|
||||
case ANCESTOR_OR_SELF_AXIS :
|
||||
str.append("ancestor-or-self::");
|
||||
break;
|
||||
case ATTRIBUTE_AXIS:
|
||||
str.append("@");
|
||||
break;
|
||||
case DESCENDANT_AXIS:
|
||||
str.append("descendant::");
|
||||
break;
|
||||
case DESCENDANT_OR_SELF_AXIS:
|
||||
str.append("descendant-or-self::");
|
||||
break;
|
||||
case FOLLOWING_AXIS :
|
||||
str.append("following::");
|
||||
break;
|
||||
case FOLLOWING_SIBLING_AXIS:
|
||||
str.append("following-sibling::");
|
||||
break;
|
||||
case NAMESPACE_AXIS:
|
||||
str.append("namespace::");
|
||||
break;
|
||||
case PARENT_AXIS :
|
||||
str.append("parent::");
|
||||
break;
|
||||
case PRECEDING_AXIS :
|
||||
str.append("preceding::");
|
||||
break;
|
||||
case PRECEDING_SIBLING_AXIS :
|
||||
str.append("preceding-sibling::");
|
||||
break;
|
||||
case SELF_AXIS :
|
||||
str.append("self::");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (mNodeTest)
|
||||
mNodeTest->toString(str);
|
||||
|
||||
PredicateList::toString(str);
|
||||
} //-- toString
|
||||
|
||||
@@ -1,86 +0,0 @@
|
||||
#
|
||||
# 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 Axel Hecht are Copyright (C) Axel Hecht.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Axel Hecht <axel@pike.org>
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
ifndef TX_EXE
|
||||
MODULE = transformiix
|
||||
REQUIRES = string \
|
||||
xpcom \
|
||||
dom \
|
||||
layout \
|
||||
content \
|
||||
widget \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
CPPSRCS = AdditiveExpr.cpp \
|
||||
AttributeValueTemplate.cpp \
|
||||
BooleanExpr.cpp \
|
||||
BooleanFunctionCall.cpp \
|
||||
BooleanResult.cpp \
|
||||
ErrorFunctionCall.cpp \
|
||||
Expr.cpp \
|
||||
ExprLexer.cpp \
|
||||
ExprLexerChars.cpp \
|
||||
ExprParser.cpp \
|
||||
ExtensionFunctionCall.cpp \
|
||||
FilterExpr.cpp \
|
||||
FunctionCall.cpp \
|
||||
LocationStep.cpp \
|
||||
MultiplicativeExpr.cpp \
|
||||
NodeSet.cpp \
|
||||
NodeSetFunctionCall.cpp \
|
||||
NumberExpr.cpp \
|
||||
NumberFunctionCall.cpp \
|
||||
NumberResult.cpp \
|
||||
PathExpr.cpp \
|
||||
PredicateList.cpp \
|
||||
RelationalExpr.cpp \
|
||||
RootExpr.cpp \
|
||||
StringExpr.cpp \
|
||||
StringFunctionCall.cpp \
|
||||
StringResult.cpp \
|
||||
txNameTest.cpp \
|
||||
txNodeTypeTest.cpp \
|
||||
UnionExpr.cpp \
|
||||
UnaryExpr.cpp \
|
||||
VariableRefExpr.cpp \
|
||||
XPathNames.cpp
|
||||
ifndef TX_EXE
|
||||
CPPSRCS += XPathProcessor.cpp \
|
||||
nsNodeSet.cpp
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
INCLUDES += -I$(srcdir)/../base -I$(srcdir)/../xml \
|
||||
-I$(srcdir)/../xml/dom \
|
||||
-I$(srcdir)/../xslt -I$(srcdir)/../xslt/util \
|
||||
-I$(srcdir)/../xslt/functions \
|
||||
-I$(srcdir)
|
||||
|
||||
libs:: $(OBJS)
|
||||
@@ -1,151 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* NaN/Infinity code copied from the JS-library with permission from
|
||||
* Netscape Communications Corporation: http://www.mozilla.org/js
|
||||
* http://lxr.mozilla.org/seamonkey/source/js/src/jsinterp.c
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Represents a MultiplicativeExpr, an binary expression that
|
||||
* performs a multiplicative operation between it's lvalue and rvalue:
|
||||
* * : multiply
|
||||
* mod : modulus
|
||||
* div : divide
|
||||
**/
|
||||
|
||||
#include "Expr.h"
|
||||
#include <math.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
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* MultiplicativeExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
|
||||
double rightDbl = Double::NaN;
|
||||
ExprResult* exprRes = 0;
|
||||
|
||||
if ( rightExpr ) {
|
||||
exprRes = rightExpr->evaluate(context, cs);
|
||||
if ( exprRes ) rightDbl = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
||||
double leftDbl = Double::NaN;
|
||||
if ( leftExpr ) {
|
||||
exprRes = leftExpr->evaluate(context, cs);
|
||||
if ( exprRes ) leftDbl = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
}
|
||||
|
||||
double result = 0;
|
||||
|
||||
switch ( op ) {
|
||||
case DIVIDE:
|
||||
if (rightDbl == 0) {
|
||||
#ifdef XP_PC
|
||||
/* XXX MSVC miscompiles such that (NaN == 0) */
|
||||
if (Double::isNaN(rightDbl))
|
||||
result = Double::NaN;
|
||||
else
|
||||
#endif
|
||||
if (leftDbl == 0 || Double::isNaN(leftDbl))
|
||||
result = Double::NaN;
|
||||
else if (Double::isNeg(leftDbl) ^ Double::isNeg(rightDbl))
|
||||
result = Double::NEGATIVE_INFINITY;
|
||||
else
|
||||
result = Double::POSITIVE_INFINITY;
|
||||
}
|
||||
else
|
||||
result = leftDbl / rightDbl;
|
||||
break;
|
||||
case MODULUS:
|
||||
if (rightDbl == 0) {
|
||||
result = Double::NaN;
|
||||
}
|
||||
else {
|
||||
#ifdef XP_PC
|
||||
/* Workaround MS fmod bug where 42 % (1/0) => NaN, not 42. */
|
||||
if (!Double::isInfinite(leftDbl) && Double::isInfinite(rightDbl))
|
||||
result = leftDbl;
|
||||
else
|
||||
#endif
|
||||
result = fmod(leftDbl, rightDbl);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
result = leftDbl * rightDbl;
|
||||
break;
|
||||
}
|
||||
return new NumberResult(result);
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void MultiplicativeExpr::toString(String& str) {
|
||||
|
||||
if ( leftExpr ) leftExpr->toString(str);
|
||||
else str.append("null");
|
||||
|
||||
switch ( op ) {
|
||||
case DIVIDE:
|
||||
str.append(" div ");
|
||||
break;
|
||||
case MODULUS:
|
||||
str.append(" mod ");
|
||||
break;
|
||||
default:
|
||||
str.append(" * ");
|
||||
break;
|
||||
}
|
||||
if ( rightExpr ) rightExpr->toString(str);
|
||||
else str.append("null");
|
||||
|
||||
} //-- toString
|
||||
|
||||
@@ -1,356 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Larry Fitzpatrick, OpenText, lef@opentext.com
|
||||
* -- moved initialization of DEFAULT_SIZE from NodeSet.h to here
|
||||
*
|
||||
* Olivier Gerardin, ogerardin@vo.lu
|
||||
* -- fixed numberValue()
|
||||
*
|
||||
*/
|
||||
|
||||
#include "NodeSet.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#ifdef TX_EXE
|
||||
#include <iostream.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* NodeSet
|
||||
* This class was ported from XSL:P.
|
||||
**/
|
||||
|
||||
|
||||
//-------------/
|
||||
//- Constants -/
|
||||
//-------------/
|
||||
const int NodeSet::DEFAULT_SIZE = 25;
|
||||
|
||||
|
||||
//----------------/
|
||||
//- Constructors -/
|
||||
//----------------/
|
||||
|
||||
/**
|
||||
* Creates a new NodeSet with the default Size
|
||||
**/
|
||||
NodeSet::NodeSet() {
|
||||
initialize(DEFAULT_SIZE);
|
||||
} //-- NodeSet
|
||||
|
||||
/**
|
||||
* Creates a new NodeSet with the default Size
|
||||
**/
|
||||
NodeSet::NodeSet(int size) {
|
||||
initialize(size);
|
||||
} //-- NodeSet
|
||||
|
||||
/**
|
||||
* Creates a new NodeSet, copying the Node references from the source
|
||||
* NodeSet
|
||||
**/
|
||||
NodeSet::NodeSet(const NodeSet& source) {
|
||||
initialize(source.size());
|
||||
source.copyInto(*this);
|
||||
} //--NodeSet
|
||||
|
||||
/**
|
||||
* Helper method for Constructors
|
||||
**/
|
||||
void NodeSet::initialize(int size) {
|
||||
checkDuplicates = MB_TRUE;
|
||||
elements = new Node*[size];
|
||||
for ( int i = 0; i < size; i++ ) elements[i] = 0;
|
||||
elementCount = 0;
|
||||
bufferSize = size;
|
||||
initialSize = size;
|
||||
} //-- initialize
|
||||
|
||||
/**
|
||||
* Destructor for NodeSet
|
||||
**/
|
||||
NodeSet::~NodeSet() {
|
||||
delete [] elements;
|
||||
} //-- ~NodeSet
|
||||
|
||||
/**
|
||||
* Adds the specified Node to this NodeSet if it is not already
|
||||
* contained within in this NodeSet.
|
||||
* @param node the Node to add to the NodeSet
|
||||
* @return true if the Node is added to the NodeSet
|
||||
**/
|
||||
MBool NodeSet::add(Node* node) {
|
||||
|
||||
if (node) {
|
||||
if (checkDuplicates && contains(node)) return MB_FALSE;
|
||||
if (elementCount == bufferSize) increaseSize();
|
||||
elements[elementCount++] = node;
|
||||
return MB_TRUE;
|
||||
}
|
||||
return MB_FALSE;
|
||||
} //-- add
|
||||
|
||||
/**
|
||||
* Adds the specified Node to the NodeSet at the specified index,
|
||||
* as long as the Node is not already contained within the set
|
||||
* @param node the Node to add to the NodeSet
|
||||
* @return true if the Node is added to the NodeSet. If the index is
|
||||
* out of bounds the Node will not be added to the set and false will be returned.
|
||||
**/
|
||||
MBool NodeSet::add(int index, Node* node)
|
||||
{
|
||||
if (!node || (index < 0) || (index > elementCount)) return MB_FALSE;
|
||||
|
||||
if (checkDuplicates && contains(node)) return MB_FALSE;
|
||||
|
||||
// make sure we have room to add the object
|
||||
if (elementCount == bufferSize) increaseSize();
|
||||
|
||||
if (index == elementCount) {
|
||||
elements[elementCount++] = node;
|
||||
}
|
||||
else {
|
||||
shiftUp(index);
|
||||
elements[index] = node;
|
||||
++elementCount;
|
||||
}
|
||||
return MB_TRUE;
|
||||
} //-- add
|
||||
|
||||
/**
|
||||
* Removes all elements from the list
|
||||
**/
|
||||
void NodeSet::clear() {
|
||||
for (int i = 0; i < elementCount; i++) {
|
||||
elements[i] = 0;
|
||||
}
|
||||
elementCount = 0;
|
||||
} //-- clear
|
||||
|
||||
/**
|
||||
* Returns true if the specified Node is contained in the set.
|
||||
* if the specfied Node is null, then if the NodeSet contains a null
|
||||
* value, true will be returned.
|
||||
* @param node the element to search the NodeSet for
|
||||
* @return true if specified Node is contained in the NodeSet
|
||||
**/
|
||||
MBool NodeSet::contains(Node* node) {
|
||||
return (MBool)(indexOf(node) >= 0);
|
||||
} //-- contains
|
||||
|
||||
/**
|
||||
* Copies the elements of this NodeSet, into the destination NodeSet
|
||||
**/
|
||||
void NodeSet::copyInto(NodeSet& dest) const {
|
||||
for ( int i = 0; i < elementCount; i++ ) dest.add(elements[i]);
|
||||
} //-- copyInto
|
||||
|
||||
/**
|
||||
* Returns the Node at the specified position in this NodeSet.
|
||||
* @param index the position of the Node to return
|
||||
**/
|
||||
Node* NodeSet::get(int index) {
|
||||
if ((index < 0) || index >= elementCount) return 0;
|
||||
return elements[index];
|
||||
} //-- get
|
||||
|
||||
/**
|
||||
* Returns true if duplicate checking is enabled, otherwise false.
|
||||
*
|
||||
* @return true if duplicate checking is enabled, otherwise false.
|
||||
**/
|
||||
MBool NodeSet::getDuplicateChecking() {
|
||||
return checkDuplicates;
|
||||
} //-- getDuplicateChecking
|
||||
|
||||
/**
|
||||
* Returns the index of the specified Node,
|
||||
* or -1 if the Node is not contained in the NodeSet
|
||||
* @param node the Node to get the index for
|
||||
**/
|
||||
int NodeSet::indexOf(Node* node) {
|
||||
for (int i = 0; i < elementCount; i++)
|
||||
if (node == elements[i]) return i;
|
||||
return -1;
|
||||
} //-- indexOf
|
||||
|
||||
/**
|
||||
* Returns true if there are no Nodes in the NodeSet.
|
||||
* @return true if there are no Nodes in the NodeSet.
|
||||
**/
|
||||
MBool NodeSet::isEmpty() {
|
||||
return (elementCount == 0) ? MB_TRUE : MB_FALSE;
|
||||
} //-- isEmpty
|
||||
|
||||
/**
|
||||
* Removes the Node at the specified index from the NodeSet
|
||||
* @param index the position in the NodeSet to remove the Node from
|
||||
* @return the Node that was removed from the list
|
||||
**/
|
||||
Node* NodeSet::remove(int index) {
|
||||
|
||||
if ((index < 0) || (index >= elementCount)) return 0;
|
||||
|
||||
Node* node = elements[index];
|
||||
shiftDown(index+1);
|
||||
--elementCount;
|
||||
return node;
|
||||
} //-- remove
|
||||
|
||||
/**
|
||||
* Removes the the specified Node from the NodeSet
|
||||
* @param node the Node to remove from the NodeSet
|
||||
* @return true if the Node was removed from the list
|
||||
**/
|
||||
MBool NodeSet::remove(Node* node) {
|
||||
int index = indexOf(node);
|
||||
|
||||
if (index > -1) {
|
||||
remove(index);
|
||||
}
|
||||
else return MB_FALSE;
|
||||
|
||||
return MB_TRUE;
|
||||
} //-- remove
|
||||
|
||||
/**
|
||||
* Enables or disables checking for duplicates. By default
|
||||
* the #add method will check for duplicate nodes. This should
|
||||
* only be disabled when no possibility of duplicates could occur.
|
||||
*
|
||||
* @param checkDuplicates an MBool indicating, when true, to perform duplicate checking,
|
||||
* otherwise duplicate checking is disabled.
|
||||
**/
|
||||
void NodeSet::setDuplicateChecking(MBool checkDuplicates) {
|
||||
this->checkDuplicates = checkDuplicates;
|
||||
} //-- setDuplicateChecking
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the NodeSet
|
||||
* @return the number of elements in the NodeSet
|
||||
**/
|
||||
int NodeSet::size() const{
|
||||
return elementCount;
|
||||
} //-- size
|
||||
|
||||
/**
|
||||
* Creates a String representation of this NodeSet
|
||||
* @param str the destination string to append the String representation to.
|
||||
**/
|
||||
void NodeSet::toString(String& str) {
|
||||
str.append("#NodeSet");
|
||||
} //-- toString
|
||||
|
||||
//-------------------/
|
||||
//- Private Methods -/
|
||||
//-------------------/
|
||||
|
||||
/**
|
||||
* increase the NodeSet capacity by a factor of its initial size
|
||||
**/
|
||||
void NodeSet::increaseSize() {
|
||||
|
||||
bufferSize += bufferSize;
|
||||
Node** tmpNodes = elements;
|
||||
elements = new Node*[bufferSize];
|
||||
int i=0;
|
||||
for (i=0;i < elementCount; i++) elements[i] = tmpNodes[i];
|
||||
for (;i<bufferSize;i++)elements[i] = 0;
|
||||
delete [] tmpNodes;
|
||||
|
||||
} //-- increaseSize
|
||||
|
||||
/**
|
||||
* Shifts all elements at the specified index to down by 1
|
||||
**/
|
||||
void NodeSet::shiftDown(int index) {
|
||||
if ((index <= 0) || (index > elementCount)) return;
|
||||
|
||||
//-- from Java
|
||||
//-- System.arraycopy(elements, index, elements, index - 1, elementCount - index);
|
||||
for (int i = index; i < elementCount; i++) {
|
||||
elements[i-1] = elements[i];
|
||||
}
|
||||
|
||||
elements[elementCount-1] = 0;
|
||||
} //-- shiftDown
|
||||
|
||||
/**
|
||||
* Shifts all elements at the specified index up by 1
|
||||
**/
|
||||
void NodeSet::shiftUp(int index) {
|
||||
if (index == elementCount) return;
|
||||
if (elementCount == bufferSize) increaseSize();
|
||||
|
||||
//-- from Java
|
||||
//-- System.arraycopy(elements, index, elements, index + 1, elementCount - index);
|
||||
for (int i = elementCount; i > index; i--) {
|
||||
elements[i] = elements[i-1];
|
||||
}
|
||||
} //-- shiftUp
|
||||
|
||||
//------------------------------------/
|
||||
//- Virtual Methods from: ExprResult -/
|
||||
//------------------------------------/
|
||||
|
||||
/**
|
||||
* Returns the type of ExprResult represented
|
||||
* @return the type of ExprResult represented
|
||||
**/
|
||||
short NodeSet::getResultType() {
|
||||
return ExprResult::NODESET;
|
||||
} //-- getResultType
|
||||
|
||||
/**
|
||||
* Converts this ExprResult to a Boolean (MBool) value
|
||||
* @return the Boolean value
|
||||
**/
|
||||
MBool NodeSet::booleanValue() {
|
||||
return (MBool) (size() > 0);
|
||||
} //- booleanValue
|
||||
|
||||
/**
|
||||
* Converts this ExprResult to a Number (double) value
|
||||
* @return the Number value
|
||||
**/
|
||||
double NodeSet::numberValue() {
|
||||
// OG+
|
||||
// As per the XPath spec, the number value of a node-set is the number value
|
||||
// of its string value.
|
||||
String str;
|
||||
stringValue(str);
|
||||
return Double::toDouble(str);
|
||||
// OG-
|
||||
} //-- numberValue
|
||||
|
||||
/**
|
||||
* Creates a String representation of this ExprResult
|
||||
* @param str the destination string to append the String representation to.
|
||||
**/
|
||||
void NodeSet::stringValue(String& str) {
|
||||
if ( size()>0) {
|
||||
// XXX Sort by document order here
|
||||
XMLDOMUtils::getNodeValue(get(0), &str);
|
||||
}
|
||||
} //-- stringValue
|
||||
@@ -1,242 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Larry Fitzpatrick, OpenText, lef@opentext.com
|
||||
* -- moved initialization of DEFAULT_SIZE to NodeSet.cpp
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* NodeSet
|
||||
**/
|
||||
|
||||
#ifndef TRANSFRMX_NODESET_H
|
||||
#define TRANSFRMX_NODESET_H
|
||||
|
||||
#include "dom.h"
|
||||
#include "ExprResult.h"
|
||||
|
||||
class NodeSet : public ExprResult
|
||||
{
|
||||
|
||||
public:
|
||||
|
||||
//----------------/
|
||||
//- Constructors -/
|
||||
//----------------/
|
||||
|
||||
/**
|
||||
* Creates a new NodeSet with the default Size
|
||||
**/
|
||||
NodeSet();
|
||||
|
||||
/**
|
||||
* Creates a new NodeSet with the specified Size
|
||||
**/
|
||||
NodeSet(int size);
|
||||
|
||||
/**
|
||||
* Creates a new NodeSet using the given NodeSet
|
||||
**/
|
||||
NodeSet(const NodeSet& source);
|
||||
|
||||
/**
|
||||
* Destructor for NodeSet, will not delete Node References
|
||||
**/
|
||||
virtual ~NodeSet();
|
||||
|
||||
/**
|
||||
* Adds the specified Node to this NodeSet if it is not already
|
||||
* contained within in this NodeSet.
|
||||
* @param node the Node to add to the NodeSet
|
||||
* @return true if the Node is added to the NodeSet
|
||||
**/
|
||||
MBool add(Node* node);
|
||||
|
||||
/**
|
||||
* Adds the specified Node to the NodeSet at the specified index,
|
||||
* as long as the Node is not already contained within the set
|
||||
* @param node the Node to add to the NodeSet
|
||||
* @return true if the Node is added to the NodeSet
|
||||
* @exception IndexOutOfBoundsException
|
||||
**/
|
||||
MBool add(int index, Node* node);
|
||||
|
||||
/**
|
||||
* Removes all elements from the list
|
||||
**/
|
||||
void clear();
|
||||
|
||||
/**
|
||||
* Returns true if the specified Node is contained in the set.
|
||||
* if the specfied Node is null, then if the NodeSet contains a null
|
||||
* value, true will be returned.
|
||||
* @param node the element to search the NodeSet for
|
||||
* @return true if specified Node is contained in the NodeSet
|
||||
**/
|
||||
MBool contains(Node* node);
|
||||
|
||||
/**
|
||||
* Copies the elements of this NodeSet, into the destination NodeSet
|
||||
**/
|
||||
void copyInto(NodeSet& dest) const;
|
||||
|
||||
/**
|
||||
* Returns the Node at the specified position in this NodeSet.
|
||||
* @param index the position of the Node to return
|
||||
* @exception IndexOutOfBoundsException
|
||||
**/
|
||||
Node* get(int index);
|
||||
|
||||
/**
|
||||
* Returns true if duplicate checking is enabled, otherwise false.
|
||||
*
|
||||
* @return true if duplicate checking is enabled, otherwise false.
|
||||
**/
|
||||
MBool getDuplicateChecking();
|
||||
|
||||
/**
|
||||
* Returns the index of the specified Node,
|
||||
* or -1 if the Node is not contained in the NodeSet
|
||||
* @param node the Node to get the index for
|
||||
**/
|
||||
int indexOf(Node* node);
|
||||
|
||||
/**
|
||||
* Returns true if there are no Nodes in the NodeSet.
|
||||
* @return true if there are no Nodes in the NodeSet.
|
||||
**/
|
||||
MBool isEmpty();
|
||||
|
||||
/**
|
||||
* Removes the Node at the specified index from the NodeSet
|
||||
* @param index the position in the NodeSet to remove the Node from
|
||||
* @return the Node that was removed from the list
|
||||
**/
|
||||
Node* remove(int index);
|
||||
|
||||
/**
|
||||
* Removes the the specified Node from the NodeSet
|
||||
* @param node the Node to remove from the NodeSet
|
||||
* @return true if the Node was removed from the list
|
||||
**/
|
||||
MBool remove(Node* node);
|
||||
|
||||
/**
|
||||
* Enables or disables checking for duplicates. By default
|
||||
* the #add method will check for duplicate nodes. This should
|
||||
* only be disabled when no possibility of duplicates could occur.
|
||||
*
|
||||
* @param checkDuplicates an MBool indicating, when true, to perform duplicate checking,
|
||||
* otherwise duplicate checking is disabled.
|
||||
**/
|
||||
void setDuplicateChecking(MBool checkDuplicates);
|
||||
|
||||
/**
|
||||
* Returns the number of elements in the NodeSet
|
||||
* @return the number of elements in the NodeSet
|
||||
**/
|
||||
int size() const;
|
||||
|
||||
/**
|
||||
* Creates a String representation of this NodeSet
|
||||
* @param str the destination string to append the String representation to.
|
||||
**/
|
||||
void toString(String& str);
|
||||
|
||||
//------------------------------------/
|
||||
//- Virtual Methods from: ExprResult -/
|
||||
//------------------------------------/
|
||||
|
||||
/**
|
||||
* Returns the type of ExprResult represented
|
||||
* @return the type of ExprResult represented
|
||||
**/
|
||||
virtual short getResultType();
|
||||
|
||||
/**
|
||||
* Converts this ExprResult to a Boolean (MBool) value
|
||||
* @return the Boolean value
|
||||
**/
|
||||
virtual MBool booleanValue();
|
||||
|
||||
/**
|
||||
* Converts this ExprResult to a Number (double) value
|
||||
* @return the Number value
|
||||
**/
|
||||
virtual double numberValue();
|
||||
|
||||
/**
|
||||
* Creates a String representation of this ExprResult
|
||||
* @param str the destination string to append the String representation to.
|
||||
**/
|
||||
virtual void stringValue(String& str);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
//-------------------/
|
||||
//- Private Members -/
|
||||
//-------------------/
|
||||
|
||||
static const int DEFAULT_SIZE;
|
||||
|
||||
Node** elements;
|
||||
|
||||
int initialSize;
|
||||
int bufferSize;
|
||||
|
||||
MBool checkDuplicates;
|
||||
|
||||
/**
|
||||
* The next available location in the elements array
|
||||
**/
|
||||
int elementCount;
|
||||
|
||||
//-------------------/
|
||||
//- Private Methods -/
|
||||
//-------------------/
|
||||
|
||||
/**
|
||||
* Helper method for constructors
|
||||
**/
|
||||
void initialize(int size);
|
||||
|
||||
/**
|
||||
* increase the NodeSet capacity by a factor of its initial size
|
||||
**/
|
||||
void increaseSize();
|
||||
|
||||
/**
|
||||
* Shifts all elements at the specified index to down by 1
|
||||
**/
|
||||
void shiftDown(int index);
|
||||
|
||||
/**
|
||||
* Shifts all elements at the specified index up by 1
|
||||
**/
|
||||
void shiftUp(int index);
|
||||
|
||||
}; //-- NodeSet
|
||||
|
||||
#endif
|
||||
@@ -1,235 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Marina Mechtcheriakova, mmarina@mindspring.com
|
||||
* -- changed some behavoir to be more compliant with spec
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NodeSetFunctionCall
|
||||
* A representation of the XPath NodeSet funtions
|
||||
*/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include "Tokenizer.h"
|
||||
#include "txAtom.h"
|
||||
|
||||
/*
|
||||
* Creates a NodeSetFunctionCall of the given type
|
||||
*/
|
||||
NodeSetFunctionCall::NodeSetFunctionCall(NodeSetFunctions aType)
|
||||
{
|
||||
mType = aType;
|
||||
switch (aType) {
|
||||
case COUNT:
|
||||
name = XPathNames::COUNT_FN;
|
||||
break;
|
||||
case ID:
|
||||
name = XPathNames::ID_FN;
|
||||
break;
|
||||
case LAST:
|
||||
name = XPathNames::LAST_FN;
|
||||
break;
|
||||
case LOCAL_NAME:
|
||||
name = XPathNames::LOCAL_NAME_FN;
|
||||
break;
|
||||
case NAME:
|
||||
name = XPathNames::NAME_FN;
|
||||
break;
|
||||
case NAMESPACE_URI:
|
||||
name = XPathNames::NAMESPACE_URI_FN;
|
||||
break;
|
||||
case POSITION:
|
||||
name = XPathNames::POSITION_FN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* NodeSetFunctionCall::evaluate(Node* aContext, ContextState* aCs) {
|
||||
ListIterator iter(¶ms);
|
||||
switch (mType) {
|
||||
case COUNT:
|
||||
{
|
||||
if (!requireParams(1, 1, aCs))
|
||||
return new StringResult("error");
|
||||
|
||||
NodeSet* nodes;
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext, aCs);
|
||||
if (!nodes)
|
||||
return new StringResult("error");
|
||||
|
||||
double count = nodes->size();
|
||||
delete nodes;
|
||||
return new NumberResult(count);
|
||||
}
|
||||
case ID:
|
||||
{
|
||||
if (!requireParams(1, 1, aCs))
|
||||
return new StringResult("error");
|
||||
|
||||
ExprResult* exprResult;
|
||||
exprResult = ((Expr*)iter.next())->evaluate(aContext, aCs);
|
||||
if (!exprResult)
|
||||
return new StringResult("error");
|
||||
|
||||
NodeSet* resultSet = new NodeSet();
|
||||
if (!resultSet) {
|
||||
// XXX ErrorReport: out of memory
|
||||
return 0;
|
||||
}
|
||||
|
||||
Document* contextDoc;
|
||||
if (aContext->getNodeType() == Node::DOCUMENT_NODE)
|
||||
contextDoc = (Document*)aContext;
|
||||
else
|
||||
contextDoc = aContext->getOwnerDocument();
|
||||
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
NodeSet* nodes = (NodeSet*)exprResult;
|
||||
int i;
|
||||
for (i = 0; i < nodes->size(); i++) {
|
||||
String idList, id;
|
||||
XMLDOMUtils::getNodeValue(nodes->get(i), &idList);
|
||||
txTokenizer tokenizer(idList);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
tokenizer.nextToken(id);
|
||||
resultSet->add(contextDoc->getElementById(id));
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
String idList, id;
|
||||
exprResult->stringValue(idList);
|
||||
txTokenizer tokenizer(idList);
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
tokenizer.nextToken(id);
|
||||
resultSet->add(contextDoc->getElementById(id));
|
||||
}
|
||||
}
|
||||
delete exprResult;
|
||||
|
||||
return resultSet;
|
||||
}
|
||||
case LAST:
|
||||
{
|
||||
if (!requireParams(0, 0, aCs))
|
||||
return new StringResult("error");
|
||||
|
||||
NodeSet* contextNodeSet = (NodeSet*)aCs->getNodeSetStack()->peek();
|
||||
if (!contextNodeSet) {
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
||||
return new NumberResult(contextNodeSet->size());
|
||||
}
|
||||
case LOCAL_NAME:
|
||||
case NAME:
|
||||
case NAMESPACE_URI:
|
||||
{
|
||||
if (!requireParams(0, 1, aCs))
|
||||
return new StringResult("error");
|
||||
|
||||
Node* node = 0;
|
||||
// Check for optional arg
|
||||
if (iter.hasNext()) {
|
||||
NodeSet* nodes;
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), aContext, aCs);
|
||||
if (!nodes)
|
||||
return new StringResult("error");
|
||||
|
||||
if (nodes->isEmpty()) {
|
||||
delete nodes;
|
||||
return new StringResult();
|
||||
}
|
||||
node = nodes->get(0);
|
||||
delete nodes;
|
||||
}
|
||||
else {
|
||||
node = aContext;
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
case LOCAL_NAME:
|
||||
{
|
||||
String localName;
|
||||
txAtom* localNameAtom;
|
||||
node->getLocalName(&localNameAtom);
|
||||
if (localNameAtom) {
|
||||
// Node has a localName
|
||||
TX_GET_ATOM_STRING(localNameAtom, localName);
|
||||
TX_RELEASE_ATOM(localNameAtom);
|
||||
}
|
||||
|
||||
return new StringResult(localName);
|
||||
}
|
||||
case NAMESPACE_URI:
|
||||
{
|
||||
return new StringResult(node->getNamespaceURI());
|
||||
}
|
||||
case NAME:
|
||||
{
|
||||
switch (node->getNodeType()) {
|
||||
case Node::ATTRIBUTE_NODE:
|
||||
case Node::ELEMENT_NODE:
|
||||
case Node::PROCESSING_INSTRUCTION_NODE:
|
||||
// XXX Namespace: namespaces have a name
|
||||
return new StringResult(node->getNodeName());
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return new StringResult();
|
||||
}
|
||||
}
|
||||
}
|
||||
case POSITION:
|
||||
{
|
||||
if (!requireParams(0, 0, aCs))
|
||||
return new StringResult("error");
|
||||
|
||||
NodeSet* contextNodeSet = (NodeSet*)aCs->getNodeSetStack()->peek();
|
||||
if (!contextNodeSet) {
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
||||
return new NumberResult(contextNodeSet->indexOf(aContext) + 1);
|
||||
}
|
||||
}
|
||||
|
||||
String err("Internal error");
|
||||
aCs->recieveError(err);
|
||||
return new StringResult("error");
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
//--------------/
|
||||
//- NumberExpr -/
|
||||
//--------------/
|
||||
|
||||
NumberExpr::NumberExpr(double dbl) {
|
||||
_value = dbl;
|
||||
} //-- NumberExpr
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* NumberExpr::evaluate(Node* context, ContextState* cs) {
|
||||
return new NumberResult(_value);
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void NumberExpr::toString(String& str) {
|
||||
Double::toString(_value, str);
|
||||
} //-- toString
|
||||
|
||||
@@ -1,147 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Olivier Gerardin, ogerardin@vo.lu
|
||||
* -- original author.
|
||||
*
|
||||
* Nisheeth Ranjan, nisheeth@netscape.com
|
||||
* -- implemented rint function, which was not available on Windows.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* NumberFunctionCall
|
||||
* A representation of the XPath Number funtions
|
||||
*/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include <math.h>
|
||||
|
||||
/*
|
||||
* Creates a NumberFunctionCall of the given type
|
||||
*/
|
||||
NumberFunctionCall::NumberFunctionCall(NumberFunctions aType) {
|
||||
mType = aType;
|
||||
switch (mType) {
|
||||
case ROUND:
|
||||
name = XPathNames::ROUND_FN;
|
||||
break;
|
||||
case CEILING:
|
||||
name = XPathNames::CEILING_FN;
|
||||
break;
|
||||
case FLOOR:
|
||||
name = XPathNames::FLOOR_FN;
|
||||
break;
|
||||
case SUM:
|
||||
name = XPathNames::SUM_FN;
|
||||
break;
|
||||
case NUMBER:
|
||||
name = XPathNames::NUMBER_FN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context Node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
*/
|
||||
ExprResult* NumberFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
ListIterator iter(¶ms);
|
||||
|
||||
if (mType == NUMBER) {
|
||||
if (!requireParams(0, 1, cs))
|
||||
return new StringResult("error");
|
||||
}
|
||||
else {
|
||||
if (!requireParams(1, 1, cs))
|
||||
return new StringResult("error");
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
case CEILING:
|
||||
{
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), context, cs);
|
||||
if (Double::isNaN(dbl) || Double::isInfinite(dbl))
|
||||
return new NumberResult(dbl);
|
||||
|
||||
if (Double::isNeg(dbl) && dbl > -1)
|
||||
return new NumberResult(0 * dbl);
|
||||
|
||||
return new NumberResult(ceil(dbl));
|
||||
}
|
||||
case FLOOR:
|
||||
{
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), context, cs);
|
||||
if (Double::isNaN(dbl) ||
|
||||
Double::isInfinite(dbl) ||
|
||||
(dbl == 0 && Double::isNeg(dbl)))
|
||||
return new NumberResult(dbl);
|
||||
|
||||
return new NumberResult(floor(dbl));
|
||||
}
|
||||
case ROUND:
|
||||
{
|
||||
double dbl = evaluateToNumber((Expr*)iter.next(), context, cs);
|
||||
if (Double::isNaN(dbl) || Double::isInfinite(dbl))
|
||||
return new NumberResult(dbl);
|
||||
|
||||
if (Double::isNeg(dbl) && dbl >= -0.5)
|
||||
return new NumberResult(0 * dbl);
|
||||
|
||||
return new NumberResult(floor(dbl + 0.5));
|
||||
}
|
||||
case SUM:
|
||||
{
|
||||
NodeSet* nodes;
|
||||
nodes = evaluateToNodeSet((Expr*)iter.next(), context, cs);
|
||||
|
||||
if (!nodes)
|
||||
return new StringResult("error");
|
||||
|
||||
double res = 0;
|
||||
int i;
|
||||
for (i = 0; i < nodes->size(); i++) {
|
||||
String resultStr;
|
||||
XMLDOMUtils::getNodeValue(nodes->get(i), &resultStr);
|
||||
res += Double::toDouble(resultStr);
|
||||
}
|
||||
delete nodes;
|
||||
|
||||
return new NumberResult(res);
|
||||
}
|
||||
case NUMBER:
|
||||
{
|
||||
if (iter.hasNext())
|
||||
return new NumberResult(
|
||||
evaluateToNumber((Expr*)iter.next(), context, cs));
|
||||
|
||||
String resultStr;
|
||||
XMLDOMUtils::getNodeValue(context, &resultStr);
|
||||
return new NumberResult(Double::toDouble(resultStr));
|
||||
}
|
||||
}
|
||||
return new StringResult("error");
|
||||
}
|
||||
@@ -1,72 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* NumberResult
|
||||
* Represents the a number as the result of evaluating an Expr
|
||||
**/
|
||||
|
||||
#include "ExprResult.h"
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
**/
|
||||
NumberResult::NumberResult() {
|
||||
value = 0.0;
|
||||
} //-- NumberResult
|
||||
|
||||
/**
|
||||
* Creates a new NumberResult with the value of the given double parameter
|
||||
* @param dbl the double to use for initialization of this NumberResult's value
|
||||
**/
|
||||
NumberResult::NumberResult(double dbl) {
|
||||
this->value = dbl;
|
||||
} //-- NumberResult
|
||||
|
||||
/*
|
||||
* Virtual Methods from ExprResult
|
||||
*/
|
||||
|
||||
short NumberResult::getResultType() {
|
||||
return ExprResult::NUMBER;
|
||||
} //-- getResultType
|
||||
|
||||
void NumberResult::stringValue(String& str) {
|
||||
Double::toString(value, str);
|
||||
} //-- stringValue
|
||||
|
||||
MBool NumberResult::booleanValue() {
|
||||
// OG+
|
||||
// As per the XPath spec, the boolean value of a number is true if and only if
|
||||
// it is neither positive 0 nor negative 0 nor NaN
|
||||
return (MBool)(value != 0.0 && !Double::isNaN(value));
|
||||
// OG-
|
||||
} //-- booleanValue
|
||||
|
||||
double NumberResult::numberValue() {
|
||||
return this->value;
|
||||
} //-- numberValue
|
||||
|
||||
@@ -1,297 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Bob Miller, kbob@oblix.com
|
||||
* -- plugged core leak.
|
||||
*
|
||||
* Marina Mechtcheriakova, mmarina@mindspring.com
|
||||
* -- fixed bug in PathExpr::matches
|
||||
* - foo//bar would not match properly if there was more than
|
||||
* one node in the NodeSet (nodes) on the final iteration
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "XMLUtils.h"
|
||||
|
||||
//------------/
|
||||
//- PathExpr -/
|
||||
//------------/
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new PathExpr
|
||||
**/
|
||||
PathExpr::PathExpr()
|
||||
{
|
||||
//-- do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor, will delete all Expressions
|
||||
**/
|
||||
PathExpr::~PathExpr()
|
||||
{
|
||||
ListIterator* iter = expressions.iterator();
|
||||
while (iter->hasNext()) {
|
||||
iter->next();
|
||||
PathExprItem* pxi = (PathExprItem*)iter->remove();
|
||||
delete pxi->expr;
|
||||
delete pxi;
|
||||
}
|
||||
delete iter;
|
||||
} //-- ~PathExpr
|
||||
|
||||
/**
|
||||
* Adds the Expr to this PathExpr
|
||||
* @param expr the Expr to add to this PathExpr
|
||||
**/
|
||||
void PathExpr::addExpr(Expr* expr, 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);
|
||||
}
|
||||
} //-- addPattenExpr
|
||||
|
||||
//-----------------------------/
|
||||
//- Virtual methods from Expr -/
|
||||
//-----------------------------/
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* PathExpr::evaluate(Node* context, ContextState* cs)
|
||||
{
|
||||
//-- add selectExpr functionality here
|
||||
|
||||
if (!context || (expressions.getLength() == 0))
|
||||
return new NodeSet(0);
|
||||
|
||||
NodeSet* nodes = new NodeSet();
|
||||
if (!nodes) {
|
||||
// XXX ErrorReport: out of memory
|
||||
NS_ASSERTION(0, "out of memory");
|
||||
return 0;
|
||||
}
|
||||
nodes->add(context);
|
||||
|
||||
ListIterator iter(&expressions);
|
||||
PathExprItem* pxi;
|
||||
|
||||
while ((pxi = (PathExprItem*)iter.next())) {
|
||||
NodeSet* tmpNodes = 0;
|
||||
for (int i = 0; i < nodes->size(); i++) {
|
||||
Node* node = nodes->get(i);
|
||||
|
||||
NodeSet* resNodes;
|
||||
if (pxi->pathOp == DESCENDANT_OP) {
|
||||
resNodes = new NodeSet;
|
||||
evalDescendants(pxi->expr, node, cs, resNodes);
|
||||
}
|
||||
else {
|
||||
ExprResult *res = pxi->expr->evaluate(node, cs);
|
||||
if (!res || (res->getResultType() != ExprResult::NODESET)) {
|
||||
//XXX ErrorReport: report nonnodeset error
|
||||
delete res;
|
||||
res = new NodeSet;
|
||||
}
|
||||
resNodes = (NodeSet*)res;
|
||||
}
|
||||
|
||||
if (tmpNodes) {
|
||||
resNodes->copyInto(*tmpNodes);
|
||||
delete resNodes;
|
||||
}
|
||||
else
|
||||
tmpNodes = resNodes;
|
||||
|
||||
}
|
||||
delete nodes;
|
||||
nodes = tmpNodes;
|
||||
if (!nodes || (nodes->size() == 0)) break;
|
||||
}
|
||||
return nodes;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Selects from the descendants of the context node
|
||||
* all nodes that match the Expr
|
||||
* -- this will be moving to a Utility class
|
||||
**/
|
||||
void PathExpr::evalDescendants (Expr* expr, Node* context,
|
||||
ContextState* cs, NodeSet* resNodes)
|
||||
{
|
||||
ExprResult *res = expr->evaluate(context, cs);
|
||||
if (!res || (res->getResultType() != ExprResult::NODESET)) {
|
||||
//XXX ErrorReport: report nonnodeset error
|
||||
}
|
||||
else
|
||||
((NodeSet*)res)->copyInto(*resNodes);
|
||||
delete res;
|
||||
|
||||
MBool filterWS = cs->isStripSpaceAllowed(context);
|
||||
|
||||
Node* child = context->getFirstChild();
|
||||
while (child) {
|
||||
if (!(filterWS &&
|
||||
(child->getNodeType() == Node::TEXT_NODE ||
|
||||
child->getNodeType() == Node::CDATA_SECTION_NODE) &&
|
||||
XMLUtils::shouldStripTextnode(child->getNodeValue())))
|
||||
evalDescendants(expr, child, cs, resNodes);
|
||||
child = child->getNextSibling();
|
||||
}
|
||||
} //-- evalDescendants
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double PathExpr::getDefaultPriority(Node* node, Node* context,
|
||||
ContextState* cs)
|
||||
{
|
||||
int size = expressions.getLength();
|
||||
if (size > 1)
|
||||
return 0.5;
|
||||
|
||||
return ((PathExprItem*)expressions.get(0))->
|
||||
expr->getDefaultPriority(node, context, cs);
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this Expr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool PathExpr::matches(Node* node, Node* context, ContextState* cs)
|
||||
{
|
||||
/*
|
||||
* The idea is to split up a path into blocks separated by descendant
|
||||
* operators. For example "foo/bar//baz/bop//ying/yang" is split up into
|
||||
* three blocks. The "ying/yang" block is handled by the first while-loop
|
||||
* and the "foo/bar" and "baz/bop" blocks are handled by the second
|
||||
* while-loop.
|
||||
* A block is considered matched when we find a list of ancestors that
|
||||
* match the block. If there are more than one list of ancestors that
|
||||
* match a block we only need to find the one furthermost down in the
|
||||
* tree.
|
||||
*/
|
||||
|
||||
if (!node || (expressions.getLength() == 0))
|
||||
return MB_FALSE;
|
||||
|
||||
ListIterator iter(&expressions);
|
||||
iter.resetToEnd();
|
||||
|
||||
PathExprItem* pxi;
|
||||
PathOperator pathOp = RELATIVE_OP;
|
||||
|
||||
while (pathOp == RELATIVE_OP) {
|
||||
|
||||
pxi = (PathExprItem*)iter.previous();
|
||||
if (!pxi)
|
||||
return MB_TRUE; // We've stepped through the entire list
|
||||
|
||||
if (!node || !pxi->expr->matches(node, 0, cs))
|
||||
return MB_FALSE;
|
||||
|
||||
node = node->getXPathParent();
|
||||
pathOp = pxi->pathOp;
|
||||
}
|
||||
|
||||
// We have at least one DESCENDANT_OP
|
||||
|
||||
Node* blockStart = node;
|
||||
ListIterator blockIter(iter);
|
||||
|
||||
while ((pxi = (PathExprItem*)iter.previous())) {
|
||||
|
||||
if (!node)
|
||||
return MB_FALSE; // There are more steps in the current block
|
||||
// then ancestors of the tested node
|
||||
|
||||
if (!pxi->expr->matches(node, 0, cs)) {
|
||||
// Didn't match. We restart at beginning of block using a new
|
||||
// start node
|
||||
iter = blockIter;
|
||||
blockStart = blockStart->getXPathParent();
|
||||
node = blockStart;
|
||||
}
|
||||
else {
|
||||
node = node->getXPathParent();
|
||||
if (pxi->pathOp == DESCENDANT_OP) {
|
||||
// We've matched an entire block. Set new start iter and start node
|
||||
blockIter = iter;
|
||||
blockStart = node;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return MB_TRUE;
|
||||
|
||||
} //-- matches
|
||||
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void PathExpr::toString(String& dest)
|
||||
{
|
||||
ListIterator iter(&expressions);
|
||||
|
||||
PathExprItem* pxi = (PathExprItem*)iter.next();
|
||||
if (pxi) {
|
||||
NS_ASSERTION(pxi->pathOp == RELATIVE_OP,
|
||||
"First step should be relative");
|
||||
pxi->expr->toString(dest);
|
||||
}
|
||||
|
||||
while ((pxi = (PathExprItem*)iter.next())) {
|
||||
switch (pxi->pathOp) {
|
||||
case DESCENDANT_OP:
|
||||
dest.append("//");
|
||||
break;
|
||||
case RELATIVE_OP:
|
||||
dest.append('/');
|
||||
break;
|
||||
}
|
||||
pxi->expr->toString(dest);
|
||||
}
|
||||
} //-- toString
|
||||
@@ -1,129 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
/*
|
||||
* Represents an ordered list of Predicates,
|
||||
* for use with Step and Filter Expressions
|
||||
*/
|
||||
|
||||
PredicateList::PredicateList()
|
||||
{
|
||||
} // PredicateList
|
||||
|
||||
/*
|
||||
* Destructor, will delete all Expressions in the list
|
||||
*/
|
||||
PredicateList::~PredicateList()
|
||||
{
|
||||
txListIterator iter(&predicates);
|
||||
while (iter.hasNext()) {
|
||||
iter.next();
|
||||
Expr* expr = (Expr*)iter.remove();
|
||||
delete expr;
|
||||
}
|
||||
} // ~PredicateList
|
||||
|
||||
/*
|
||||
* Adds the given Expr to the list
|
||||
* @param expr the Expr to add to the list
|
||||
*/
|
||||
void PredicateList::add(Expr* expr)
|
||||
{
|
||||
predicates.add(expr);
|
||||
} // add
|
||||
|
||||
void PredicateList::evaluatePredicates(NodeSet* nodes, ContextState* cs)
|
||||
{
|
||||
NS_ASSERTION(nodes, "called evaluatePredicates with NULL NodeSet");
|
||||
if (!nodes)
|
||||
return;
|
||||
|
||||
cs->getNodeSetStack()->push(nodes);
|
||||
NodeSet newNodes;
|
||||
// optimize; set DuplicateChecking to MB_FALSE,
|
||||
// restore original state later
|
||||
// we only work with |Node|s already in the NodeSet, so they
|
||||
// have been checked already, no need to check again in here.
|
||||
MBool ndsCheckDupl = nodes->getDuplicateChecking();
|
||||
nodes->setDuplicateChecking(MB_FALSE);
|
||||
newNodes.setDuplicateChecking(MB_FALSE);
|
||||
txListIterator iter(&predicates);
|
||||
while (iter.hasNext()) {
|
||||
Expr* expr = (Expr*)iter.next();
|
||||
/*
|
||||
* add nodes to newNodes that match the expression
|
||||
* or, if the result is a number, add the node with the right
|
||||
* position
|
||||
*/
|
||||
newNodes.clear();
|
||||
int nIdx;
|
||||
for (nIdx = 0; nIdx < nodes->size(); nIdx++) {
|
||||
Node* node = nodes->get(nIdx);
|
||||
ExprResult* exprResult = expr->evaluate(node, cs);
|
||||
if (!exprResult)
|
||||
break;
|
||||
switch(exprResult->getResultType()) {
|
||||
case ExprResult::NUMBER :
|
||||
// handle default, [position() == numberValue()]
|
||||
if ((double)(nIdx+1) == exprResult->numberValue())
|
||||
newNodes.add(node);
|
||||
break;
|
||||
default:
|
||||
if (exprResult->booleanValue())
|
||||
newNodes.add(node);
|
||||
break;
|
||||
}
|
||||
delete exprResult;
|
||||
}
|
||||
// Move new NodeSet to the current one
|
||||
nodes->clear();
|
||||
newNodes.copyInto(*nodes);
|
||||
}
|
||||
cs->getNodeSetStack()->pop();
|
||||
// restore DuplicateChecking of NodeSet
|
||||
nodes->setDuplicateChecking(ndsCheckDupl);
|
||||
} // evaluatePredicates
|
||||
|
||||
/*
|
||||
* returns true if this predicate list is empty
|
||||
*/
|
||||
MBool PredicateList::isEmpty()
|
||||
{
|
||||
return (MBool)(predicates.getLength() == 0);
|
||||
} // isEmpty
|
||||
|
||||
void PredicateList::toString(String& dest)
|
||||
{
|
||||
txListIterator iter(&predicates);
|
||||
while (iter.hasNext()) {
|
||||
Expr* expr = (Expr*) iter.next();
|
||||
dest.append("[");
|
||||
expr->toString(dest);
|
||||
dest.append("]");
|
||||
}
|
||||
} // toString
|
||||
|
||||
@@ -1,255 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* NaN/Infinity code copied from the JS-library with permission from
|
||||
* Netscape Communications Corporation: http://www.mozilla.org/js
|
||||
* http://lxr.mozilla.org/seamonkey/source/js/src/jsinterp.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
|
||||
//------------------/
|
||||
//- RelationalExpr -/
|
||||
//------------------/
|
||||
|
||||
RelationalExpr::RelationalExpr(Expr* leftExpr, Expr* rightExpr, short op) {
|
||||
this->op = op;
|
||||
this->leftExpr = leftExpr;
|
||||
this->rightExpr = rightExpr;
|
||||
} //-- RelationalExpr
|
||||
|
||||
RelationalExpr::~RelationalExpr() {
|
||||
delete leftExpr;
|
||||
delete rightExpr;
|
||||
} //-- ~RelationalExpr
|
||||
|
||||
/**
|
||||
* Compares the two ExprResults based on XPath 1.0 Recommendation (section 3.4)
|
||||
**/
|
||||
MBool RelationalExpr::compareResults(ExprResult* left, ExprResult* right) {
|
||||
|
||||
|
||||
short ltype = left->getResultType();
|
||||
short rtype = right->getResultType();
|
||||
|
||||
MBool result = MB_FALSE;
|
||||
|
||||
//-- handle case for just Left NodeSet or Both NodeSets
|
||||
if (ltype == ExprResult::NODESET) {
|
||||
NodeSet* nodeSet = (NodeSet*)left;
|
||||
for ( int i = 0; i < nodeSet->size(); i++) {
|
||||
String str;
|
||||
Node* node = nodeSet->get(i);
|
||||
XMLDOMUtils::getNodeValue(node, &str);
|
||||
StringResult strResult(str);
|
||||
result = compareResults(&strResult, right);
|
||||
if ( result ) break;
|
||||
}
|
||||
}
|
||||
//-- handle case for Just Right NodeSet
|
||||
else if ( rtype == ExprResult::NODESET) {
|
||||
NodeSet* nodeSet = (NodeSet*)right;
|
||||
for ( int i = 0; i < nodeSet->size(); i++) {
|
||||
String str;
|
||||
Node* node = nodeSet->get(i);
|
||||
XMLDOMUtils::getNodeValue(node, &str);
|
||||
StringResult strResult(str);
|
||||
result = compareResults(left, &strResult);
|
||||
if ( result ) break;
|
||||
}
|
||||
}
|
||||
//-- neither NodeSet
|
||||
else {
|
||||
if ( op == NOT_EQUAL) {
|
||||
|
||||
if ((ltype == ExprResult::BOOLEAN)
|
||||
|| (rtype == ExprResult::BOOLEAN)) {
|
||||
result = (left->booleanValue() != right->booleanValue());
|
||||
}
|
||||
else if ((ltype == ExprResult::NUMBER) ||
|
||||
(rtype == ExprResult::NUMBER)) {
|
||||
double lval = left->numberValue();
|
||||
double rval = right->numberValue();
|
||||
#ifdef XP_PC
|
||||
if (Double::isNaN(lval) || Double::isNaN(rval))
|
||||
result = MB_TRUE;
|
||||
else
|
||||
result = (lval != rval);
|
||||
#else
|
||||
result = (lval != rval);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
String lStr;
|
||||
left->stringValue(lStr);
|
||||
String rStr;
|
||||
right->stringValue(rStr);
|
||||
result = !lStr.isEqual(rStr);
|
||||
}
|
||||
}
|
||||
else if ( op == EQUAL) {
|
||||
|
||||
if ((ltype == ExprResult::BOOLEAN)
|
||||
|| (rtype == ExprResult::BOOLEAN)) {
|
||||
result = (left->booleanValue() == right->booleanValue());
|
||||
}
|
||||
else if ((ltype == ExprResult::NUMBER) ||
|
||||
(rtype == ExprResult::NUMBER)) {
|
||||
double lval = left->numberValue();
|
||||
double rval = right->numberValue();
|
||||
#ifdef XP_PC
|
||||
if (Double::isNaN(lval) || Double::isNaN(rval))
|
||||
result = MB_FALSE;
|
||||
else
|
||||
result = (lval == rval);
|
||||
#else
|
||||
result = (lval == rval);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
String lStr;
|
||||
left->stringValue(lStr);
|
||||
String rStr;
|
||||
right->stringValue(rStr);
|
||||
result = lStr.isEqual(rStr);
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
double leftDbl = left->numberValue();
|
||||
double rightDbl = right->numberValue();
|
||||
switch( op ) {
|
||||
case LESS_THAN:
|
||||
#ifdef XP_PC
|
||||
if (Double::isNaN(leftDbl) || Double::isNaN(rightDbl))
|
||||
result = MB_FALSE;
|
||||
else
|
||||
result = (leftDbl < rightDbl);
|
||||
#else
|
||||
result = (leftDbl < rightDbl);
|
||||
#endif
|
||||
break;
|
||||
case LESS_OR_EQUAL:
|
||||
#ifdef XP_PC
|
||||
if (Double::isNaN(leftDbl) || Double::isNaN(rightDbl))
|
||||
result = MB_FALSE;
|
||||
else
|
||||
result = (leftDbl <= rightDbl);
|
||||
#else
|
||||
result = (leftDbl <= rightDbl);
|
||||
#endif
|
||||
break;
|
||||
case GREATER_THAN :
|
||||
#ifdef XP_PC
|
||||
if (Double::isNaN(leftDbl) || Double::isNaN(rightDbl))
|
||||
result = MB_FALSE;
|
||||
else
|
||||
result = (leftDbl > rightDbl);
|
||||
#else
|
||||
result = (leftDbl > rightDbl);
|
||||
#endif
|
||||
break;
|
||||
case GREATER_OR_EQUAL:
|
||||
#ifdef XP_PC
|
||||
if (Double::isNaN(leftDbl) || Double::isNaN(rightDbl))
|
||||
result = MB_FALSE;
|
||||
else
|
||||
result = (leftDbl >= rightDbl);
|
||||
#else
|
||||
result = (leftDbl >= rightDbl);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} //-- compareResult
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* RelationalExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
//-- get result of left expression
|
||||
ExprResult* lResult = 0;
|
||||
if ( leftExpr ) lResult = leftExpr->evaluate(context, cs);
|
||||
else return new BooleanResult();
|
||||
|
||||
//-- get result of right expr
|
||||
ExprResult* rResult = 0;
|
||||
if ( rightExpr ) rResult = rightExpr->evaluate(context, cs);
|
||||
else {
|
||||
delete lResult;
|
||||
return new BooleanResult();
|
||||
}
|
||||
BooleanResult* boolResult = new BooleanResult(compareResults(lResult, rResult));
|
||||
delete lResult;
|
||||
delete rResult;
|
||||
return boolResult;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void RelationalExpr::toString(String& str) {
|
||||
|
||||
if ( leftExpr ) leftExpr->toString(str);
|
||||
else str.append("null");
|
||||
|
||||
switch ( op ) {
|
||||
case NOT_EQUAL:
|
||||
str.append("!=");
|
||||
break;
|
||||
case LESS_THAN:
|
||||
str.append("<");
|
||||
break;
|
||||
case LESS_OR_EQUAL:
|
||||
str.append("<=");
|
||||
break;
|
||||
case GREATER_THAN :
|
||||
str.append(">");
|
||||
break;
|
||||
case GREATER_OR_EQUAL:
|
||||
str.append(">=");
|
||||
break;
|
||||
default:
|
||||
str.append("=");
|
||||
break;
|
||||
}
|
||||
|
||||
if ( rightExpr ) rightExpr->toString(str);
|
||||
else str.append("null");
|
||||
|
||||
} //-- toString
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
/**
|
||||
* Creates a new RootExpr
|
||||
* @param aSerialize should this RootExpr be serialized
|
||||
*/
|
||||
RootExpr::RootExpr(MBool aSerialize) {
|
||||
mSerialize = aSerialize;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* RootExpr::evaluate(Node* context, ContextState* cs) {
|
||||
NodeSet* nodeSet = new NodeSet();
|
||||
if (!nodeSet) {
|
||||
// XXX ErrorReport: out of memory
|
||||
NS_ASSERTION(0, "out of memory");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!context)
|
||||
return nodeSet;
|
||||
|
||||
if (context->getNodeType() != Node::DOCUMENT_NODE)
|
||||
nodeSet->add(context->getOwnerDocument());
|
||||
else
|
||||
nodeSet->add(context);
|
||||
|
||||
return nodeSet;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double RootExpr::getDefaultPriority(Node* node, Node* context, ContextState* cs) {
|
||||
return 0.5;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this NodeExpr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool RootExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
return node && (node->getNodeType() == Node::DOCUMENT_NODE);
|
||||
} //-- matches
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void RootExpr::toString(String& dest) {
|
||||
if (mSerialize)
|
||||
dest.append('/');
|
||||
} //-- toString
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
/**
|
||||
* StringExpr
|
||||
**/
|
||||
|
||||
/**
|
||||
* Creates a new StringExpr
|
||||
**/
|
||||
StringExpr::StringExpr(const String& value) {
|
||||
//-- copy value
|
||||
this->value.append(value);
|
||||
} //-- StringExpr
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* StringExpr::evaluate(Node* context, ContextState* cs) {
|
||||
return new StringResult(value);
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void StringExpr::toString(String& str) {
|
||||
UNICODE_CHAR ch = '\'';
|
||||
if (value.indexOf(ch) != NOT_FOUND)
|
||||
ch = '\"';
|
||||
str.append(ch);
|
||||
str.append(value);
|
||||
str.append(ch);
|
||||
} //-- toString
|
||||
|
||||
@@ -1,289 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* StringFunctionCall
|
||||
* A representation of the XPath String funtions
|
||||
**/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
#include "XMLUtils.h"
|
||||
#include "XMLDOMUtils.h"
|
||||
#include <math.h>
|
||||
|
||||
/**
|
||||
* Creates a StringFunctionCall of the given type
|
||||
**/
|
||||
StringFunctionCall::StringFunctionCall(short type) : FunctionCall() {
|
||||
this->type = type;
|
||||
switch ( type ) {
|
||||
case CONCAT:
|
||||
name = XPathNames::CONCAT_FN;
|
||||
break;
|
||||
case CONTAINS:
|
||||
name = XPathNames::CONTAINS_FN;
|
||||
break;
|
||||
case STARTS_WITH:
|
||||
name = XPathNames::STARTS_WITH_FN;
|
||||
break;
|
||||
case STRING_LENGTH:
|
||||
name = XPathNames::STRING_LENGTH_FN;
|
||||
break;
|
||||
case SUBSTRING:
|
||||
name = XPathNames::SUBSTRING_FN;
|
||||
break;
|
||||
case SUBSTRING_AFTER:
|
||||
name = XPathNames::SUBSTRING_AFTER_FN;
|
||||
break;
|
||||
case SUBSTRING_BEFORE:
|
||||
name = XPathNames::SUBSTRING_BEFORE_FN;
|
||||
break;
|
||||
case TRANSLATE:
|
||||
name = XPathNames::TRANSLATE_FN;
|
||||
break;
|
||||
default:
|
||||
name = XPathNames::STRING_FN;
|
||||
break;
|
||||
}
|
||||
} //-- StringFunctionCall
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* StringFunctionCall::evaluate(Node* context, ContextState* cs) {
|
||||
ListIterator* iter = params.iterator();
|
||||
PRInt32 argc = params.getLength();
|
||||
String err;
|
||||
ExprResult* result = 0;
|
||||
switch ( type ) {
|
||||
case CONCAT :
|
||||
if ( requireParams(2, cs) ) {
|
||||
String resultStr;
|
||||
while(iter->hasNext()) {
|
||||
evaluateToString((Expr*)iter->next(),context, cs, resultStr);
|
||||
}
|
||||
result = new StringResult(resultStr);
|
||||
}
|
||||
else result = new StringResult("");
|
||||
break;
|
||||
case CONTAINS :
|
||||
if ( requireParams(2, 2, cs) ) {
|
||||
String arg1, arg2;
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg1);
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg2);
|
||||
result = new BooleanResult((MBool)(arg1.indexOf(arg2) >= 0));
|
||||
}
|
||||
else result = new BooleanResult(MB_FALSE);
|
||||
break;
|
||||
|
||||
case NORMALIZE_SPACE:
|
||||
if ( requireParams(0, 1, cs) ) {
|
||||
String resultStr;
|
||||
if ( argc == 1)
|
||||
evaluateToString((Expr*)iter->next(),context, cs, resultStr);
|
||||
else
|
||||
XMLDOMUtils::getNodeValue(context, &resultStr);
|
||||
// Leading & Trailing Whitespace
|
||||
resultStr.trim();
|
||||
MBool hasSpace = MB_FALSE;
|
||||
PRInt32 dest=0;
|
||||
String normed(resultStr.length());
|
||||
UNICODE_CHAR current;
|
||||
for (PRInt32 src=0; src<resultStr.length(); src++) {
|
||||
current=resultStr.charAt(src);
|
||||
if (current==' ' || current=='\n' ||
|
||||
current=='\t' || current=='\r') {
|
||||
if (!hasSpace) {
|
||||
normed.replace(dest,' ');
|
||||
dest++;
|
||||
hasSpace=MB_TRUE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
normed.replace(dest,current);
|
||||
dest++;
|
||||
hasSpace=MB_FALSE;
|
||||
}
|
||||
}
|
||||
result = new StringResult(normed);
|
||||
}
|
||||
else result = new StringResult("");
|
||||
break;
|
||||
case STARTS_WITH :
|
||||
if ( requireParams(2, 2, cs) ) {
|
||||
String arg1, arg2;
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg1);
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg2);
|
||||
result = new BooleanResult((MBool)(arg1.indexOf(arg2) == 0));
|
||||
}
|
||||
else result = new BooleanResult(MB_FALSE);
|
||||
break;
|
||||
case STRING_LENGTH:
|
||||
if ( requireParams(0, 1, cs) ) {
|
||||
String resultStr;
|
||||
if ( argc == 1) {
|
||||
evaluateToString((Expr*)iter->next(),context, cs, resultStr);
|
||||
}
|
||||
else XMLDOMUtils::getNodeValue(context, &resultStr);
|
||||
result = new NumberResult( (double) resultStr.length());
|
||||
}
|
||||
else result = new NumberResult(0.0);
|
||||
break;
|
||||
case SUBSTRING:
|
||||
if ( requireParams(2, 3, cs) ) {
|
||||
String src;
|
||||
evaluateToString((Expr*)iter->next(),context, cs, src);
|
||||
double dbl = evaluateToNumber((Expr*)iter->next(), context, cs);
|
||||
|
||||
//-- check for NaN
|
||||
if ( Double::isNaN(dbl)) {
|
||||
result = new StringResult("");
|
||||
break;
|
||||
}
|
||||
|
||||
//-- check for -Infinity
|
||||
MBool startsNegInf = (dbl==Double::NEGATIVE_INFINITY);
|
||||
|
||||
PRInt32 startIdx = startsNegInf?0:(PRInt32)floor(dbl+.5);
|
||||
PRInt32 endIdx = src.length()+1;
|
||||
if ( argc == 3) {
|
||||
dbl = evaluateToNumber((Expr*)iter->next(),context, cs);
|
||||
if (startsNegInf) {
|
||||
result = new StringResult("");
|
||||
break;
|
||||
}
|
||||
if (dbl == Double::POSITIVE_INFINITY) ; //already complete
|
||||
else if ( Double::isNaN(dbl) ||
|
||||
dbl == Double::NEGATIVE_INFINITY ||
|
||||
dbl < 0 )
|
||||
endIdx = 0;
|
||||
else endIdx = startIdx+(PRInt32)floor(dbl+.5);
|
||||
}
|
||||
String resultStr;
|
||||
//-- strings are indexed starting at 1 for XSL
|
||||
//-- adjust to a 0-based index
|
||||
endIdx--;
|
||||
if (startIdx<1){
|
||||
startIdx = 0;
|
||||
} else {
|
||||
startIdx--;
|
||||
}
|
||||
|
||||
src.subString(startIdx,endIdx,resultStr);
|
||||
result = new StringResult(resultStr);
|
||||
}
|
||||
else result = new StringResult("");
|
||||
break;
|
||||
|
||||
case SUBSTRING_AFTER:
|
||||
if ( requireParams(2, 2, cs) ) {
|
||||
String arg1, arg2;
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg1);
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg2);
|
||||
PRInt32 idx = arg1.indexOf(arg2);
|
||||
if ((idx >= 0)&&(idx<arg1.length())) {
|
||||
PRInt32 len = arg2.length();
|
||||
arg2.clear();
|
||||
arg1.subString(idx+len,arg2);
|
||||
result = new StringResult(arg2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = new StringResult("");
|
||||
break;
|
||||
case SUBSTRING_BEFORE:
|
||||
if ( requireParams(2, 2, cs) ) {
|
||||
String arg1, arg2;
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg1);
|
||||
evaluateToString((Expr*)iter->next(),context, cs, arg2);
|
||||
PRInt32 idx = arg1.indexOf(arg2);
|
||||
if ((idx >= 0)&&(idx<arg1.length())) {
|
||||
arg2.clear();
|
||||
arg1.subString(0,idx,arg2);
|
||||
result = new StringResult(arg2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
result = new StringResult("");
|
||||
break;
|
||||
case TRANSLATE:
|
||||
if ( requireParams(3, 3, cs) ) {
|
||||
String src;
|
||||
evaluateToString((Expr*)iter->next(),context, cs, src);
|
||||
|
||||
if (src.isEmpty()) {
|
||||
result = new StringResult("");
|
||||
break;
|
||||
}
|
||||
|
||||
String oldChars, newChars;
|
||||
evaluateToString((Expr*)iter->next(),context, cs, oldChars);
|
||||
evaluateToString((Expr*)iter->next(),context, cs, newChars);
|
||||
PRInt32 size = src.length();
|
||||
UNICODE_CHAR* chars = src.toUnicode(new UNICODE_CHAR[size]);
|
||||
src.clear();
|
||||
PRInt32 i;
|
||||
for (i = 0; i < size; i++) {
|
||||
PRInt32 idx = oldChars.indexOf(chars[i]);
|
||||
if (idx >= 0) {
|
||||
if (idx < newChars.length())
|
||||
src.append(newChars.charAt(idx));
|
||||
}
|
||||
else {
|
||||
src.append(chars[i]);
|
||||
}
|
||||
}
|
||||
delete chars;
|
||||
result = new StringResult(src);
|
||||
}
|
||||
else
|
||||
result = new StringResult("");
|
||||
break;
|
||||
|
||||
default : //-- string( object? )
|
||||
if ( requireParams(0, 1, cs) ) {
|
||||
String resultStr;
|
||||
if (iter->hasNext()) {
|
||||
evaluateToString((Expr*)iter->next(),context, cs, resultStr);
|
||||
}
|
||||
else {
|
||||
XMLDOMUtils::getNodeValue(context, &resultStr);
|
||||
if ( cs->isStripSpaceAllowed(context) &&
|
||||
XMLUtils::shouldStripTextnode(resultStr))
|
||||
resultStr = "";
|
||||
}
|
||||
result = new StringResult(resultStr);
|
||||
}
|
||||
else result = new StringResult("");
|
||||
break;
|
||||
}
|
||||
delete iter;
|
||||
return result;
|
||||
} //-- evaluate
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* StringResult
|
||||
* Represents a String as a Result of evaluating an Expr
|
||||
**/
|
||||
#include "ExprResult.h"
|
||||
|
||||
/**
|
||||
* Default Constructor
|
||||
**/
|
||||
StringResult::StringResult() {
|
||||
} //-- StringResult
|
||||
|
||||
/**
|
||||
* Creates a new StringResult with the value of the given String parameter
|
||||
* @param str the String to use for initialization of this StringResult's value
|
||||
**/
|
||||
StringResult::StringResult(const String& str) {
|
||||
//-- copy str
|
||||
this->value = str;
|
||||
} //-- StringResult
|
||||
|
||||
/**
|
||||
* Creates a new StringResult with the value of the given String parameter
|
||||
* @param str the String to use for initialization of this StringResult's value
|
||||
**/
|
||||
StringResult::StringResult(const char* str) {
|
||||
//-- copy str
|
||||
this->value = str;
|
||||
} //-- StringResult
|
||||
|
||||
/*
|
||||
* Virtual Methods from ExprResult
|
||||
*/
|
||||
|
||||
short StringResult::getResultType() {
|
||||
return ExprResult::STRING;
|
||||
} //-- getResultType
|
||||
|
||||
void StringResult::stringValue(String& str) {
|
||||
str.append(this->value);
|
||||
} //-- stringValue
|
||||
|
||||
MBool StringResult::booleanValue() {
|
||||
return !value.isEmpty();
|
||||
} //-- booleanValue
|
||||
|
||||
double StringResult::numberValue() {
|
||||
return Double::toDouble(value);
|
||||
} //-- numberValue
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* 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 Initial Developer of the Original Code is Jonas Sicking.
|
||||
* Portions created by Jonas Sicking are Copyright (C) 2001, Jonas Sicking.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking, sicking@bigfoot.com
|
||||
* -- original author.
|
||||
*
|
||||
* NaN/Infinity code copied from the JS-library with permission from
|
||||
* Netscape Communications Corporation: http://www.mozilla.org/js
|
||||
* http://lxr.mozilla.org/seamonkey/source/js/src/jsinterp.c
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.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
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation.
|
||||
* @return the result of the evaluation.
|
||||
*/
|
||||
ExprResult* UnaryExpr::evaluate(Node* context, ContextState* cs)
|
||||
{
|
||||
ExprResult* exprRes = expr->evaluate(context, cs);
|
||||
double value = exprRes->numberValue();
|
||||
delete exprRes;
|
||||
#ifdef HPUX
|
||||
/*
|
||||
* Negation of a zero doesn't produce a negative
|
||||
* zero on HPUX. Perform the operation by multiplying with
|
||||
* -1.
|
||||
*/
|
||||
return new NumberResult(-1 * value);
|
||||
#else
|
||||
return new NumberResult(-value);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
*/
|
||||
void UnaryExpr::toString(String& str)
|
||||
{
|
||||
if (!expr)
|
||||
return;
|
||||
str.append('-');
|
||||
expr->toString(str);
|
||||
}
|
||||
@@ -1,154 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
//-------------/
|
||||
//- UnionExpr -/
|
||||
//-------------/
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new UnionExpr
|
||||
**/
|
||||
UnionExpr::UnionExpr() {
|
||||
//-- do nothing
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor, will delete all Path Expressions
|
||||
**/
|
||||
UnionExpr::~UnionExpr() {
|
||||
ListIterator* iter = expressions.iterator();
|
||||
while (iter->hasNext()) {
|
||||
iter->next();
|
||||
delete (Expr*)iter->remove();
|
||||
}
|
||||
delete iter;
|
||||
} //-- ~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);
|
||||
} //-- addExpr
|
||||
|
||||
//-----------------------------/
|
||||
//- Virtual methods from Expr -/
|
||||
//-----------------------------/
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* UnionExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
if (!context || (expressions.getLength() == 0))
|
||||
return new NodeSet(0);
|
||||
|
||||
NodeSet* nodes = new NodeSet();
|
||||
|
||||
txListIterator iter(&expressions);
|
||||
|
||||
while (iter.hasNext()) {
|
||||
Expr* expr = (Expr*)iter.next();
|
||||
ExprResult* exprResult = expr->evaluate(context, cs);
|
||||
if (exprResult &&
|
||||
exprResult->getResultType() == ExprResult::NODESET) {
|
||||
((NodeSet*)exprResult)->copyInto(*nodes);
|
||||
}
|
||||
delete exprResult;
|
||||
}
|
||||
|
||||
return nodes;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the default priority of this Pattern based on the given Node,
|
||||
* context Node, and ContextState.
|
||||
**/
|
||||
double UnionExpr::getDefaultPriority(Node* node, Node* context,
|
||||
ContextState* cs)
|
||||
{
|
||||
//-- find highest priority
|
||||
double priority = Double::NEGATIVE_INFINITY;
|
||||
ListIterator iter(&expressions);
|
||||
while (iter.hasNext()) {
|
||||
Expr* expr = (Expr*)iter.next();
|
||||
double tmpPriority = expr->getDefaultPriority(node, context, cs);
|
||||
if (tmpPriority > priority && expr->matches(node, context, cs))
|
||||
priority = tmpPriority;
|
||||
}
|
||||
return priority;
|
||||
} //-- getDefaultPriority
|
||||
|
||||
/**
|
||||
* Determines whether this UnionExpr matches the given node within
|
||||
* the given context
|
||||
**/
|
||||
MBool UnionExpr::matches(Node* node, Node* context, ContextState* cs) {
|
||||
|
||||
ListIterator* iter = expressions.iterator();
|
||||
|
||||
while (iter->hasNext()) {
|
||||
Expr* expr = (Expr*)iter->next();
|
||||
if (expr->matches(node, context, cs)) {
|
||||
delete iter;
|
||||
return MB_TRUE;
|
||||
}
|
||||
}
|
||||
delete iter;
|
||||
return MB_FALSE;
|
||||
} //-- matches
|
||||
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void UnionExpr::toString(String& dest) {
|
||||
ListIterator* iter = expressions.iterator();
|
||||
|
||||
short count = 0;
|
||||
while (iter->hasNext()) {
|
||||
//-- set operator
|
||||
if (count > 0)
|
||||
dest.append(" | ");
|
||||
((Expr*)iter->next())->toString(dest);
|
||||
++count;
|
||||
}
|
||||
delete iter;
|
||||
} //-- toString
|
||||
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
|
||||
//-------------------/
|
||||
//- VariableRefExpr -/
|
||||
//-------------------/
|
||||
|
||||
/**
|
||||
* Creates a VariableRefExpr with the given variable name
|
||||
**/
|
||||
VariableRefExpr::VariableRefExpr(const String& name) {
|
||||
this->name = name;
|
||||
} //-- VariableRefExpr
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
* @param ps the ContextState containing the stack information needed
|
||||
* for evaluation
|
||||
* @return the result of the evaluation
|
||||
**/
|
||||
ExprResult* VariableRefExpr::evaluate(Node* context, ContextState* cs) {
|
||||
|
||||
ExprResult* exprResult = cs->getVariable(name);
|
||||
//-- make copy to prevent deletetion
|
||||
//-- I know, I should add a #copy method to ExprResult, I will
|
||||
ExprResult* copyOfResult = 0;
|
||||
|
||||
if ( exprResult ) {
|
||||
switch ( exprResult->getResultType() ) {
|
||||
//-- BooleanResult
|
||||
case ExprResult::BOOLEAN :
|
||||
copyOfResult = new BooleanResult(exprResult->booleanValue());
|
||||
break;
|
||||
//-- NodeSet
|
||||
case ExprResult::NODESET :
|
||||
{
|
||||
NodeSet* src = (NodeSet*)exprResult;
|
||||
NodeSet* dest = new NodeSet(src->size());
|
||||
for ( int i = 0; i < src->size(); i++)
|
||||
dest->add(src->get(i));
|
||||
copyOfResult = dest;
|
||||
break;
|
||||
}
|
||||
//-- NumberResult
|
||||
case ExprResult::NUMBER :
|
||||
copyOfResult = new NumberResult(exprResult->numberValue());
|
||||
break;
|
||||
//-- StringResult
|
||||
default:
|
||||
String tmp;
|
||||
exprResult->stringValue(tmp);
|
||||
StringResult* strResult = new StringResult(tmp);
|
||||
copyOfResult = strResult;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else copyOfResult = new StringResult();
|
||||
|
||||
return copyOfResult;
|
||||
} //-- evaluate
|
||||
|
||||
/**
|
||||
* Returns the String representation of this Expr.
|
||||
* @param dest the String to use when creating the String
|
||||
* representation. The String representation will be appended to
|
||||
* any data in the destination String, to allow cascading calls to
|
||||
* other #toString() methods for Expressions.
|
||||
* @return the String representation of this Expr.
|
||||
**/
|
||||
void VariableRefExpr::toString(String& str) {
|
||||
str.append('$');
|
||||
str.append(name);
|
||||
} //-- toString
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
/*
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
* Marina Mechtcheriakova, mmarina@mindspring.com
|
||||
* -- added LANG_FN
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* XPath names
|
||||
**/
|
||||
|
||||
#include "FunctionLib.h"
|
||||
|
||||
//-- Function Names
|
||||
const String XPathNames::BOOLEAN_FN = "boolean";
|
||||
const String XPathNames::CONCAT_FN = "concat";
|
||||
const String XPathNames::CONTAINS_FN = "contains";
|
||||
const String XPathNames::COUNT_FN = "count";
|
||||
const String XPathNames::FALSE_FN = "false";
|
||||
const String XPathNames::ID_FN = "id";
|
||||
const String XPathNames::LAST_FN = "last";
|
||||
const String XPathNames::LOCAL_NAME_FN = "local-name";
|
||||
const String XPathNames::NAME_FN = "name";
|
||||
const String XPathNames::NAMESPACE_URI_FN = "namespace-uri";
|
||||
const String XPathNames::NORMALIZE_SPACE_FN = "normalize-space";
|
||||
const String XPathNames::NOT_FN = "not";
|
||||
const String XPathNames::POSITION_FN = "position";
|
||||
const String XPathNames::STARTS_WITH_FN = "starts-with";
|
||||
const String XPathNames::STRING_FN = "string";
|
||||
const String XPathNames::STRING_LENGTH_FN = "string-length";
|
||||
const String XPathNames::SUBSTRING_FN = "substring";
|
||||
const String XPathNames::SUBSTRING_AFTER_FN = "substring-after";
|
||||
const String XPathNames::SUBSTRING_BEFORE_FN = "substring-before";
|
||||
const String XPathNames::SUM_FN = "sum";
|
||||
const String XPathNames::TRANSLATE_FN = "translate";
|
||||
const String XPathNames::TRUE_FN = "true";
|
||||
// OG+
|
||||
const String XPathNames::NUMBER_FN = "number";
|
||||
const String XPathNames::ROUND_FN = "round";
|
||||
const String XPathNames::CEILING_FN = "ceiling";
|
||||
const String XPathNames::FLOOR_FN = "floor";
|
||||
// OG-
|
||||
//Marina M. boolean function lang
|
||||
const String XPathNames::LANG_FN = "lang";
|
||||
|
||||
//-- internal XSL processor functions
|
||||
const String XPathNames::ERROR_FN = "error";
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Van der Beken, peterv@netscape.com
|
||||
*
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "XPathProcessor.h"
|
||||
#include "dom.h"
|
||||
#include "ProcessorState.h"
|
||||
#include "Expr.h"
|
||||
#include "nsNodeSet.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
|
||||
|
||||
// QueryInterface implementation for XPathProcessor
|
||||
NS_INTERFACE_MAP_BEGIN(XPathProcessor)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIXPathNodeSelector)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(XPathProcessor)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(XPathProcessor)
|
||||
NS_IMPL_RELEASE(XPathProcessor)
|
||||
|
||||
|
||||
/*
|
||||
* Creates a new XPathProcessor
|
||||
*/
|
||||
XPathProcessor::XPathProcessor()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
/*
|
||||
* Default destructor
|
||||
*/
|
||||
XPathProcessor::~XPathProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
/* nsIDOMNodeList selectNodes (in nsIDOMNode aContextNode, in DOMString aPattern); */
|
||||
NS_IMETHODIMP XPathProcessor::SelectNodes(nsIDOMNode *aContextNode,
|
||||
const nsAReadableString & aPattern,
|
||||
nsIDOMNodeList **_retval)
|
||||
{
|
||||
String pattern(PromiseFlatString(aPattern).get());
|
||||
|
||||
nsCOMPtr<nsIDOMDocument> aOwnerDOMDocument;
|
||||
aContextNode->GetOwnerDocument(getter_AddRefs(aOwnerDOMDocument));
|
||||
nsCOMPtr<nsIDocument> aOwnerDocument = do_QueryInterface(aOwnerDOMDocument);
|
||||
Document* aDocument = new Document(aOwnerDOMDocument);
|
||||
Node* aNode = aDocument->createWrapper(aContextNode);
|
||||
|
||||
ProcessorState* aProcessorState = new ProcessorState();
|
||||
ExprParser aParser;
|
||||
|
||||
Expr* aExpression = aParser.createExpr(pattern);
|
||||
ExprResult* exprResult = aExpression->evaluate(aNode, aProcessorState);
|
||||
nsNodeSet* resultSet;
|
||||
if (exprResult->getResultType() == ExprResult::NODESET) {
|
||||
resultSet = new nsNodeSet((NodeSet*)exprResult);
|
||||
}
|
||||
else {
|
||||
// Return an empty nodeset
|
||||
resultSet = new nsNodeSet(nsnull);
|
||||
}
|
||||
*_retval = resultSet;
|
||||
NS_ADDREF(*_retval);
|
||||
|
||||
delete aProcessorState;
|
||||
delete exprResult;
|
||||
delete aExpression;
|
||||
delete aDocument;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Van der Beken, peterv@netscape.com
|
||||
*
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef XPathProcessor_h__
|
||||
#define XPathProcessor_h__
|
||||
|
||||
#include "nsIXPathNodeSelector.h"
|
||||
|
||||
/* e4172588-1dd1-11b2-bf09-ec309437245a */
|
||||
#define TRANSFORMIIX_XPATH_PROCESSOR_CID \
|
||||
{ 0xe4172588, 0x1dd1, 0x11b2, {0xbf, 0x09, 0xec, 0x30, 0x94, 0x37, 0x24, 0x5a} }
|
||||
|
||||
#define TRANSFORMIIX_XPATH_PROCESSOR_CONTRACTID \
|
||||
"@mozilla.org/xpath-nodeselector;1"
|
||||
|
||||
/**
|
||||
* A class for processing an XPath query
|
||||
**/
|
||||
class XPathProcessor : public nsIXPathNodeSelector
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a new XPathProcessor
|
||||
**/
|
||||
XPathProcessor();
|
||||
|
||||
/**
|
||||
* Default destructor for XPathProcessor
|
||||
**/
|
||||
virtual ~XPathProcessor();
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIXPathNodeSelector interface
|
||||
NS_DECL_NSIXPATHNODESELECTOR
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,90 +0,0 @@
|
||||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape 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/NPL/
|
||||
#
|
||||
# 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 mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
MODULE = transformiix
|
||||
REQUIRES = string \
|
||||
xpcom \
|
||||
dom \
|
||||
widget \
|
||||
content \
|
||||
$(NULL)
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
!if defined(TX_EXE)
|
||||
DEFINES=$(DEFINES) -DTX_EXE
|
||||
!endif
|
||||
|
||||
CPP_OBJS= \
|
||||
.\$(OBJDIR)\AdditiveExpr.obj \
|
||||
.\$(OBJDIR)\AttributeValueTemplate.obj \
|
||||
.\$(OBJDIR)\BooleanExpr.obj \
|
||||
.\$(OBJDIR)\BooleanFunctionCall.obj \
|
||||
.\$(OBJDIR)\BooleanResult.obj \
|
||||
.\$(OBJDIR)\ErrorFunctionCall.obj \
|
||||
.\$(OBJDIR)\Expr.obj \
|
||||
.\$(OBJDIR)\ExprLexer.obj \
|
||||
.\$(OBJDIR)\ExprLexerChars.obj \
|
||||
.\$(OBJDIR)\ExprParser.obj \
|
||||
.\$(OBJDIR)\ExtensionFunctionCall.obj \
|
||||
.\$(OBJDIR)\FilterExpr.obj \
|
||||
.\$(OBJDIR)\FunctionCall.obj \
|
||||
.\$(OBJDIR)\LocationStep.obj \
|
||||
.\$(OBJDIR)\MultiplicativeExpr.obj \
|
||||
.\$(OBJDIR)\NodeSet.obj \
|
||||
.\$(OBJDIR)\NodeSetFunctionCall.obj \
|
||||
.\$(OBJDIR)\NumberExpr.obj \
|
||||
.\$(OBJDIR)\NumberFunctionCall.obj \
|
||||
.\$(OBJDIR)\NumberResult.obj \
|
||||
.\$(OBJDIR)\PathExpr.obj \
|
||||
.\$(OBJDIR)\PredicateList.obj \
|
||||
.\$(OBJDIR)\RelationalExpr.obj \
|
||||
.\$(OBJDIR)\RootExpr.obj \
|
||||
.\$(OBJDIR)\StringExpr.obj \
|
||||
.\$(OBJDIR)\StringFunctionCall.obj \
|
||||
.\$(OBJDIR)\StringResult.obj \
|
||||
.\$(OBJDIR)\txNameTest.obj \
|
||||
.\$(OBJDIR)\txNodeTypeTest.obj \
|
||||
.\$(OBJDIR)\UnionExpr.obj \
|
||||
.\$(OBJDIR)\UnaryExpr.obj \
|
||||
.\$(OBJDIR)\VariableRefExpr.obj \
|
||||
.\$(OBJDIR)\XPathNames.obj \
|
||||
!if !defined(TX_EXE)
|
||||
.\$(OBJDIR)\nsNodeSet.obj \
|
||||
.\$(OBJDIR)\XPathProcessor.obj \
|
||||
!endif
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
$(NULL)
|
||||
|
||||
LINCS=-I$(PUBLIC)\xpcom \
|
||||
-I..\base -I..\xml -I..\xml\dom -I..\xslt \
|
||||
-I..\xslt\functions -I..\xslt\util
|
||||
|
||||
LCFLAGS = \
|
||||
$(LCFLAGS) \
|
||||
$(DEFINES) \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
libs:: $(OBJDIR) $(CPP_OBJS)
|
||||
@@ -1,85 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Van der Beken, peterv@netscape.com
|
||||
*
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsNodeSet.h"
|
||||
#include "nsIDOMClassInfo.h"
|
||||
|
||||
static NS_DEFINE_CID(kDOMScriptObjectFactoryCID, NS_DOM_SCRIPT_OBJECT_FACTORY_CID);
|
||||
|
||||
|
||||
// QueryInterface implementation for nsNodeSet
|
||||
NS_INTERFACE_MAP_BEGIN(nsNodeSet)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNodeList)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_ENTRY_DOM_CLASSINFO(NodeSet)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
|
||||
NS_IMPL_ADDREF(nsNodeSet)
|
||||
NS_IMPL_RELEASE(nsNodeSet)
|
||||
|
||||
|
||||
nsNodeSet::nsNodeSet(NodeSet* aNodeSet) {
|
||||
NS_INIT_ISUPPORTS();
|
||||
mScriptObject = nsnull;
|
||||
|
||||
if (aNodeSet) {
|
||||
for (int i=0; i < aNodeSet->size(); i++) {
|
||||
mNodes.AppendElement(aNodeSet->get(i)->getNSObj());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsNodeSet::~nsNodeSet() {
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeSet::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
|
||||
{
|
||||
*aReturn = nsnull;
|
||||
mNodes.QueryElementAt(aIndex, NS_GET_IID(nsIDOMNode), (void**)aReturn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNodeSet::GetLength(PRUint32* aLength)
|
||||
{
|
||||
mNodes.Count(aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Netscape 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/NPL/
|
||||
*
|
||||
* 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 mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 1998
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Peter Van der Beken, peterv@netscape.com
|
||||
*
|
||||
*
|
||||
* 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 NPL, 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 NPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#ifndef TRANSFRMX_NS_NODESET_H
|
||||
#define TRANSFRMX_NS_NODESET_H
|
||||
|
||||
#include "NodeSet.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsSupportsArray.h"
|
||||
|
||||
class nsNodeSet : public nsIDOMNodeList
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Creates a new Mozilla NodeSet from a Transformiix NodeSet
|
||||
**/
|
||||
nsNodeSet(NodeSet* aNodeSet);
|
||||
|
||||
/**
|
||||
* Default destructor for nsNodeSet
|
||||
**/
|
||||
virtual ~nsNodeSet();
|
||||
|
||||
// nsISupports interface
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
// nsIDocumentTransformer interface
|
||||
NS_DECL_NSIDOMNODELIST
|
||||
|
||||
private:
|
||||
void* mScriptObject;
|
||||
nsSupportsArray mNodes;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,113 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txAtoms.h"
|
||||
|
||||
txNameTest::txNameTest(String& aName, Node::NodeType aNodeType)
|
||||
:mNodeType(aNodeType)
|
||||
{
|
||||
int idx = aName.indexOf(':');
|
||||
if (idx >= 0) {
|
||||
aName.subString(0, idx, mPrefix);
|
||||
String localName;
|
||||
aName.subString(idx+1, localName);
|
||||
mLocalName = TX_GET_ATOM(localName);
|
||||
}
|
||||
else {
|
||||
mLocalName = TX_GET_ATOM(aName);
|
||||
}
|
||||
}
|
||||
|
||||
txNameTest::~txNameTest()
|
||||
{
|
||||
TX_IF_RELEASE_ATOM(mLocalName);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines whether this txNodeTest matches the given node
|
||||
*/
|
||||
MBool txNameTest::matches(Node* aNode, ContextState* aCs)
|
||||
{
|
||||
if (!aNode || aNode->getNodeType() != mNodeType)
|
||||
return MB_FALSE;
|
||||
|
||||
// Totally wild?
|
||||
if (mLocalName == txXPathAtoms::_asterix && mPrefix.isEmpty())
|
||||
return MB_TRUE;
|
||||
|
||||
// Compare namespaces
|
||||
if (mPrefix.isEmpty()) {
|
||||
if (aNode->getNamespaceID() != kNameSpaceID_None)
|
||||
return MB_FALSE;
|
||||
}
|
||||
else {
|
||||
String nsURI;
|
||||
aCs->getNameSpaceURIFromPrefix(mPrefix, nsURI);
|
||||
if(!aNode->getNamespaceURI().isEqual(nsURI))
|
||||
return MB_FALSE;
|
||||
}
|
||||
|
||||
// Name wild?
|
||||
if (mLocalName == txXPathAtoms::_asterix)
|
||||
return MB_TRUE;
|
||||
|
||||
// Compare local-names
|
||||
txAtom* localName;
|
||||
aNode->getLocalName(&localName);
|
||||
MBool result = localName == mLocalName;
|
||||
TX_IF_RELEASE_ATOM(localName);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default priority of this txNodeTest
|
||||
*/
|
||||
double txNameTest::getDefaultPriority()
|
||||
{
|
||||
if (mLocalName == txXPathAtoms::_asterix) {
|
||||
if (mPrefix.isEmpty())
|
||||
return -0.5;
|
||||
return -0.25;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the String representation of this txNodeTest.
|
||||
* @param aDest the String to use when creating the string representation.
|
||||
* The string representation will be appended to the string.
|
||||
*/
|
||||
void txNameTest::toString(String& aDest)
|
||||
{
|
||||
if (!mPrefix.isEmpty()) {
|
||||
aDest.append(mPrefix);
|
||||
aDest.append(':');
|
||||
}
|
||||
String localName;
|
||||
TX_GET_ATOM_STRING(mLocalName, localName);
|
||||
aDest.append(localName);
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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 The MITRE Corporation.
|
||||
* Portions created by MITRE are Copyright (C) 1999 The MITRE Corporation.
|
||||
*
|
||||
* Portions created by Keith Visco as a Non MITRE employee,
|
||||
* (C) 1999 Keith Visco. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Keith Visco, kvisco@ziplink.net
|
||||
* -- original author.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "Expr.h"
|
||||
#include "txAtom.h"
|
||||
|
||||
/*
|
||||
* Creates a new txNodeTypeTest of the given type
|
||||
*/
|
||||
txNodeTypeTest::txNodeTypeTest(NodeType aNodeType)
|
||||
{
|
||||
mNodeType = aNodeType;
|
||||
mNodeName = 0;
|
||||
}
|
||||
|
||||
txNodeTypeTest::~txNodeTypeTest()
|
||||
{
|
||||
TX_IF_RELEASE_ATOM(mNodeName);
|
||||
}
|
||||
|
||||
void txNodeTypeTest::setNodeName(const String& aName)
|
||||
{
|
||||
mNodeName = TX_GET_ATOM(aName);
|
||||
}
|
||||
|
||||
/*
|
||||
* Determines whether this txNodeTest matches the given node
|
||||
*/
|
||||
MBool txNodeTypeTest::matches(Node* aNode, ContextState* aCs)
|
||||
{
|
||||
if (!aNode)
|
||||
return MB_FALSE;
|
||||
|
||||
switch (mNodeType) {
|
||||
case COMMENT_TYPE:
|
||||
return aNode->getNodeType() == Node::COMMENT_NODE;
|
||||
case TEXT_TYPE:
|
||||
return (aNode->getNodeType() == Node::TEXT_NODE ||
|
||||
aNode->getNodeType() == Node::CDATA_SECTION_NODE) &&
|
||||
!aCs->isStripSpaceAllowed(aNode);
|
||||
case PI_TYPE:
|
||||
if (aNode->getNodeType() == Node::PROCESSING_INSTRUCTION_NODE) {
|
||||
txAtom* localName;
|
||||
MBool result;
|
||||
result = !mNodeName ||
|
||||
(aNode->getLocalName(&localName) &&
|
||||
localName == mNodeName);
|
||||
TX_IF_RELEASE_ATOM(localName);
|
||||
return result;
|
||||
}
|
||||
return MB_FALSE;
|
||||
case NODE_TYPE:
|
||||
return (aNode->getNodeType() != Node::TEXT_NODE &&
|
||||
aNode->getNodeType() != Node::CDATA_SECTION_NODE) ||
|
||||
!aCs->isStripSpaceAllowed(aNode);
|
||||
}
|
||||
return MB_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the default priority of this txNodeTest
|
||||
*/
|
||||
double txNodeTypeTest::getDefaultPriority()
|
||||
{
|
||||
return mNodeName ? 0 : -0.5;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the String representation of this txNodeTest.
|
||||
* @param aDest the String to use when creating the string representation.
|
||||
* The string representation will be appended to the string.
|
||||
*/
|
||||
void txNodeTypeTest::toString(String& aDest)
|
||||
{
|
||||
switch (mNodeType) {
|
||||
case COMMENT_TYPE:
|
||||
aDest.append("comment()");
|
||||
break;
|
||||
case TEXT_TYPE:
|
||||
aDest.append("text()");
|
||||
break;
|
||||
case PI_TYPE:
|
||||
aDest.append("processing-instruction(");
|
||||
if (mNodeName) {
|
||||
String str;
|
||||
TX_GET_ATOM_STRING(mNodeName, str);
|
||||
aDest.append('\'');
|
||||
aDest.append(str);
|
||||
aDest.append('\'');
|
||||
}
|
||||
aDest.append(')');
|
||||
break;
|
||||
case NODE_TYPE:
|
||||
aDest.append("node()");
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -1,81 +0,0 @@
|
||||
/* -*- 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
|
||||
* Jonas Sicking.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2001
|
||||
* Jonas Sicking. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Jonas Sicking <sicking@bigfoot.com>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
TX_ATOM(_asterix, "*");
|
||||
TX_ATOM(boolean, "boolean");
|
||||
TX_ATOM(ceiling, "ceiling");
|
||||
TX_ATOM(concat, "concat");
|
||||
TX_ATOM(contains, "contains");
|
||||
TX_ATOM(count, "count");
|
||||
TX_ATOM(_false, "false");
|
||||
TX_ATOM(floor, "floor");
|
||||
TX_ATOM(id, "id");
|
||||
TX_ATOM(lang, "lang");
|
||||
TX_ATOM(last, "last");
|
||||
TX_ATOM(localName, "local-name");
|
||||
TX_ATOM(name, "name");
|
||||
TX_ATOM(namespaceUri, "namespace-uri");
|
||||
TX_ATOM(normalizeSpace, "normalize-space");
|
||||
TX_ATOM(_not, "not");
|
||||
TX_ATOM(number, "number");
|
||||
TX_ATOM(position, "position");
|
||||
TX_ATOM(round, "round");
|
||||
TX_ATOM(startsWith, "starts-with");
|
||||
TX_ATOM(string, "string");
|
||||
TX_ATOM(stringLength, "string-length");
|
||||
TX_ATOM(substring, "substring");
|
||||
TX_ATOM(substringAfter, "substring-after");
|
||||
TX_ATOM(substringBefore, "substring-before");
|
||||
TX_ATOM(sum, "sum");
|
||||
TX_ATOM(translate, "translate");
|
||||
TX_ATOM(_true, "true");
|
||||
|
||||
// XPath Axes
|
||||
TX_ATOM(ancestor, "ancestor");
|
||||
TX_ATOM(ancestorOrSelf, "ancestor-or-self");
|
||||
TX_ATOM(attribute, "attribute");
|
||||
TX_ATOM(child, "child");
|
||||
TX_ATOM(descendant, "descendant");
|
||||
TX_ATOM(descendantOrSelf, "descendant-or-self");
|
||||
TX_ATOM(following, "following");
|
||||
TX_ATOM(followingSibling, "following-sibling");
|
||||
TX_ATOM(_namespace, "namespace");
|
||||
TX_ATOM(parent, "parent");
|
||||
TX_ATOM(preceding, "preceding");
|
||||
TX_ATOM(precedingSibling, "preceding-sibling");
|
||||
TX_ATOM(self, "self");
|
||||
105
mozilla/java/dom/jni/javaDOMGlobals.h
Normal file
105
mozilla/java/dom/jni/javaDOMGlobals.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
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 mozilla.org code.
|
||||
|
||||
The Initial Developer of the Original Code is Sun Microsystems,
|
||||
Inc. Portions created by Sun are
|
||||
Copyright (C) 1999 Sun Microsystems, Inc. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributor(s):
|
||||
*/
|
||||
|
||||
#ifndef __JavaDOMGlobals_h__
|
||||
#define __JavaDOMGlobals_h__
|
||||
|
||||
#include "jni.h"
|
||||
#include "prclist.h"
|
||||
#include "nsError.h"
|
||||
|
||||
#ifdef ERROR
|
||||
#undef ERROR
|
||||
#endif
|
||||
|
||||
class nsISupports;
|
||||
class nsIDOMNode;
|
||||
struct PRLogModuleInfo;
|
||||
struct PRLock;
|
||||
|
||||
class JavaDOMGlobals {
|
||||
|
||||
public:
|
||||
static jclass attrClass;
|
||||
static jclass cDataSectionClass;
|
||||
static jclass commentClass;
|
||||
static jclass documentClass;
|
||||
static jclass documentFragmentClass;
|
||||
static jclass documentTypeClass;
|
||||
static jclass domImplementationClass;
|
||||
static jclass elementClass;
|
||||
static jclass entityClass;
|
||||
static jclass entityReferenceClass;
|
||||
static jclass namedNodeMapClass;
|
||||
static jclass nodeClass;
|
||||
static jclass nodeListClass;
|
||||
static jclass notationClass;
|
||||
static jclass processingInstructionClass;
|
||||
static jclass textClass;
|
||||
|
||||
static jfieldID nodePtrFID;
|
||||
static jfieldID nodeListPtrFID;
|
||||
static jfieldID domImplementationPtrFID;
|
||||
|
||||
static jfieldID nodeTypeAttributeFID;
|
||||
static jfieldID nodeTypeCDataSectionFID;
|
||||
static jfieldID nodeTypeCommentFID;
|
||||
static jfieldID nodeTypeDocumentFragmentFID;
|
||||
static jfieldID nodeTypeDocumentFID;
|
||||
static jfieldID nodeTypeDocumentTypeFID;
|
||||
static jfieldID nodeTypeElementFID;
|
||||
static jfieldID nodeTypeEntityFID;
|
||||
static jfieldID nodeTypeEntityReferenceFID;
|
||||
static jfieldID nodeTypeNotationFID;
|
||||
static jfieldID nodeTypeProcessingInstructionFID;
|
||||
static jfieldID nodeTypeTextFID;
|
||||
|
||||
static jclass domExceptionClass;
|
||||
static jmethodID domExceptionInitMID;
|
||||
static jclass runtimeExceptionClass;
|
||||
static jmethodID runtimeExceptionInitMID;
|
||||
|
||||
static const char* const DOM_EXCEPTION_MESSAGE[];
|
||||
|
||||
typedef enum ExceptionType { EXCEPTION_RUNTIME,
|
||||
EXCEPTION_DOM } ExceptionType;
|
||||
|
||||
static PRLogModuleInfo* log;
|
||||
static PRCList garbage;
|
||||
static PRLock* garbageLock;
|
||||
|
||||
static PRInt32 javaMaxInt;
|
||||
|
||||
static void Initialize(JNIEnv *env);
|
||||
static void Destroy(JNIEnv *env);
|
||||
static jobject CreateNodeSubtype(JNIEnv *env,
|
||||
nsIDOMNode *node);
|
||||
|
||||
static void AddToGarbage(nsISupports* domObject);
|
||||
static void TakeOutGarbage();
|
||||
|
||||
static void ThrowException(JNIEnv *env,
|
||||
const char * message = NULL,
|
||||
nsresult rv = NS_OK,
|
||||
ExceptionType exceptionType = EXCEPTION_RUNTIME);
|
||||
};
|
||||
|
||||
#endif /* __JavaDOMGlobals_h__ */
|
||||
Reference in New Issue
Block a user