You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by db...@apache.org on 2002/06/26 03:20:02 UTC
cvs commit: xml-xalan/c/src/XPath XPath.cpp XPath.hpp XPathExpression.cpp XPathExpression.hpp XPathProcessorImpl.cpp XPathProcessorImpl.hpp
dbertoni 2002/06/25 18:20:01
Modified: c/src/XPath XPath.cpp XPath.hpp XPathExpression.cpp
XPathExpression.hpp XPathProcessorImpl.cpp
XPathProcessorImpl.hpp
Log:
Fixed some bugs in parsing match patterns, and implemented calculation of default priority.
Revision Changes Path
1.70 +138 -58 xml-xalan/c/src/XPath/XPath.cpp
Index: XPath.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPath.cpp,v
retrieving revision 1.69
retrieving revision 1.70
diff -u -r1.69 -r1.70
--- XPath.cpp 17 Apr 2002 05:33:42 -0000 1.69
+++ XPath.cpp 26 Jun 2002 01:20:01 -0000 1.70
@@ -370,111 +370,208 @@
+inline const XalanDOMString*
+getStringFromTokenQueue(
+ const XPathExpression& expression,
+ int opPos)
+{
+ const int tokenPosition =
+ expression.getOpCodeMapValue(opPos);
+
+ if (tokenPosition < 0)
+ {
+ return 0;
+ }
+ else
+ {
+ const XObject* const token =
+ expression.getToken(tokenPosition);
+ assert(token != 0);
+
+ return &token->str();
+ }
+}
+
+
+
void
-XPath::getTargetElementStrings(TargetElementStringsVectorType& targetStrings) const
+XPath::getTargetData(TargetDataVectorType& targetData) const
{
int opPos = 2;
- targetStrings.reserve(eDefaultTargetStringsSize);
+ targetData.reserve(eDefaultTargetDataSize);
while(m_expression.m_opMap[opPos] == XPathExpression::eOP_LOCATIONPATHPATTERN)
{
const int nextOpPos = m_expression.getNextOpCodePosition(opPos);
opPos += 2;
-
- while(m_expression.m_opMap[opPos] != XPathExpression::eENDOP)
+
+ int stepCount = 0;
+
+ while(m_expression.getOpCodeMapValue(opPos) != XPathExpression::eENDOP)
{
+ ++stepCount;
+
const int nextStepPos =
m_expression.getNextOpCodePosition(opPos);
- const int nextOp = m_expression.m_opMap[nextStepPos];
+ const int nextOp = m_expression.getOpCodeMapValue(nextStepPos);
- if(nextOp == XPathExpression::eOP_PREDICATE ||
- nextOp == XPathExpression::eOP_PREDICATE_WITH_POSITION ||
- nextOp == XPathExpression::eENDOP)
+ if(nextOp == XPathExpression::eENDOP)
{
- const int stepType = m_expression.m_opMap[opPos];
+ eMatchScore score = eMatchScoreNone;
+
+ const XalanDOMString* targetLocalName = 0;
+
+ TargetData::eTargetType targetType = TargetData::eOther;
+
+ bool fIsAttribute = false;
+
+ const int stepType = m_expression.getOpCodeMapValue(opPos);
opPos += 3;
switch(stepType)
{
case XPathExpression::eOP_FUNCTION:
- targetStrings.push_back(PSEUDONAME_ANY);
+ targetLocalName = &PSEUDONAME_ANY;
+ score = eMatchScoreOther;
+ targetType = TargetData::eAny;
break;
case XPathExpression::eFROM_ROOT:
- targetStrings.push_back(PSEUDONAME_ROOT);
+ targetLocalName = &PSEUDONAME_ROOT;
+ score = eMatchScoreOther;
break;
case XPathExpression::eMATCH_ATTRIBUTE:
+ fIsAttribute = true;
+ // fall through on purpose...
+
case XPathExpression::eMATCH_ANY_ANCESTOR:
case XPathExpression::eMATCH_IMMEDIATE_ANCESTOR:
{
- const int tok = m_expression.m_opMap[opPos];
-
- opPos++;
+ const int tok = m_expression.getOpCodeMapValue(opPos);
switch(tok)
{
case XPathExpression::eNODETYPE_COMMENT:
- targetStrings.push_back(PSEUDONAME_COMMENT);
+ targetLocalName = &PSEUDONAME_COMMENT;
+ score = eMatchScoreNodeTest;
break;
case XPathExpression::eNODETYPE_TEXT:
- targetStrings.push_back(PSEUDONAME_TEXT);
+ targetLocalName = &PSEUDONAME_TEXT;
+ score = eMatchScoreNodeTest;
break;
case XPathExpression::eNODETYPE_NODE:
- targetStrings.push_back(PSEUDONAME_NODE);
+ targetLocalName = &PSEUDONAME_NODE;
+ score = eMatchScoreNodeTest;
break;
case XPathExpression::eNODETYPE_ROOT:
- targetStrings.push_back(PSEUDONAME_ROOT);
+ targetLocalName = &PSEUDONAME_ROOT;
+ score = eMatchScoreNodeTest;
break;
case XPathExpression::eNODETYPE_ANYELEMENT:
- targetStrings.push_back(PSEUDONAME_ANY);
+ targetLocalName = &PSEUDONAME_ANY;
+ score = eMatchScoreNodeTest;
+ targetType = TargetData::eElement;
break;
case XPathExpression::eNODETYPE_PI:
- targetStrings.push_back(PSEUDONAME_PI);
+ {
+ const int argLen =
+ m_expression.getOpCodeMapValue(opPos - 3 + XPathExpression::s_opCodeMapLengthIndex + 1) - 3;
+
+ targetLocalName = &PSEUDONAME_PI;
+
+ if (argLen == 1)
+ {
+ score = eMatchScoreNodeTest;
+ }
+ else if (argLen == 2)
+ {
+ score = eMatchScoreQName;
+ }
+ }
break;
case XPathExpression::eNODENAME:
{
- // Skip the namespace
- const int tokenIndex = m_expression.m_opMap[opPos + 1];
+ const XalanDOMString* const targetNamespace =
+ getStringFromTokenQueue(m_expression, opPos + 1);
- if(tokenIndex >= 0)
- {
- const XalanDOMString& targetName =
- m_expression.m_tokenQueue[tokenIndex].str();
+ targetLocalName =
+ getStringFromTokenQueue(m_expression, opPos + 2);
+
+ targetType = fIsAttribute ?
+ TargetData::eAttribute :
+ TargetData::eElement;
- if(::equals(targetName, PSEUDONAME_ANY) == true)
+ if(targetLocalName != 0)
+ {
+ if(::equals(*targetLocalName, PSEUDONAME_ANY) == true)
{
- targetStrings.push_back(PSEUDONAME_ANY);
+ targetLocalName = &PSEUDONAME_ANY;
+
+ if (targetNamespace == 0 ||
+ ::equals(*targetNamespace, PSEUDONAME_ANY) == true)
+ {
+ score = eMatchScoreNodeTest;
+ }
+ else
+ {
+ score = eMatchScoreNSWild;
+ }
}
else
{
- targetStrings.push_back(targetName);
+ score = eMatchScoreQName;
}
}
else
{
- targetStrings.push_back(PSEUDONAME_ANY);
+ targetLocalName = &PSEUDONAME_ANY;
+
+ if (targetNamespace == 0 ||
+ ::equals(*targetNamespace, PSEUDONAME_ANY) == true)
+ {
+ score = eMatchScoreNodeTest;
+ }
+ else
+ {
+ score = eMatchScoreNSWild;
+ }
}
}
+
break;
default:
- targetStrings.push_back(PSEUDONAME_ANY);
+ targetLocalName = &PSEUDONAME_ANY;
+ score = eMatchScoreNodeTest;
break;
}
}
break;
}
+
+ assert(targetLocalName != 0);
+
+ // If there are multiple steps, or a predicate,
+ // the priority is always eMatchScoreOther.
+ if (stepCount > 1 ||
+ opPos + 3 < nextStepPos)
+ {
+ score = eMatchScoreOther;
+ }
+
+ targetData.push_back(
+ TargetData(*targetLocalName, score, targetType));
}
opPos = nextStepPos;
@@ -502,7 +599,7 @@
score = executeMore(context, opPos, executionContext);
assert(score.null() == false);
- if(score->num() != eMatchScoreNone)
+ if(score->num() != getMatchScoreValue(eMatchScoreNone))
{
break;
}
@@ -2812,7 +2909,14 @@
{
if (isNamespace == false)
{
- score = eMatchScoreNodeTest;
+ if (isTotallyWild == true)
+ {
+ score = eMatchScoreNodeTest;
+ }
+ else
+ {
+ score = eMatchScoreNSWild;
+ }
}
}
else
@@ -3025,30 +3129,6 @@
-inline const XalanDOMString*
-getStringFromTokenQueue(
- const XPathExpression& expression,
- int opPos)
-{
- const int tokenPosition =
- expression.getOpCodeMapValue(opPos);
-
- if (tokenPosition < 0)
- {
- return 0;
- }
- else
- {
- const XObject* const token =
- expression.getToken(tokenPosition);
- assert(token != 0);
-
- return &token->str();
- }
-}
-
-
-
XPath::NodeTester::NodeTester(
const XPath& xpath,
XPathExecutionContext& executionContext,
@@ -3376,7 +3456,7 @@
}
else
{
- return eMatchScoreNodeTest;
+ return eMatchScoreNSWild;
}
}
1.31 +66 -16 xml-xalan/c/src/XPath/XPath.hpp
Index: XPath.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPath.hpp,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- XPath.hpp 24 Oct 2001 15:44:51 -0000 1.30
+++ XPath.hpp 26 Jun 2002 01:20:01 -0000 1.31
@@ -2,7 +2,7 @@
* The Apache Software License, Version 1.1
*
*
- * Copyright (c) 1999 The Apache Software Foundation. All rights
+ * Copyright (c) 1999-2002 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -102,10 +102,69 @@
static const XalanDOMString& PSEUDONAME_OTHER;
static const XalanDOMString& PSEUDONAME_NODE;
+ enum eMatchScore
+ {
+ eMatchScoreNone,
+ eMatchScoreNodeTest,
+ eMatchScoreNSWild,
+ eMatchScoreQName,
+ eMatchScoreOther
+ };
+
+ class TargetData
+ {
+ public:
+
+ enum eTargetType { eAttribute, eElement, eAny, eOther };
+
+ TargetData() :
+ m_string(),
+ m_priority(eMatchScoreNone),
+ m_targetType(eOther)
+ {
+ }
+
+ TargetData(
+ const XalanDOMString& theString,
+ eMatchScore thePriority,
+ eTargetType theTargetType) :
+ m_string(theString),
+ m_priority(thePriority),
+ m_targetType(theTargetType)
+ {
+ }
+
+ const XalanDOMString&
+ getString() const
+ {
+ return m_string;
+ }
+
+ eMatchScore
+ getDefaultPriority() const
+ {
+ return m_priority;
+ }
+
+ eTargetType
+ getTargetType() const
+ {
+ return m_targetType;
+ }
+
+ private:
+
+ XalanDOMString m_string;
+
+ eMatchScore m_priority;
+
+ eTargetType m_targetType;
+ };
+
#if defined(XALAN_NO_NAMESPACES)
- typedef vector<XalanDOMString> TargetElementStringsVectorType;
+ typedef vector<TargetData> TargetDataVectorType;
#else
- typedef std::vector<XalanDOMString> TargetElementStringsVectorType;
+ typedef std::vector<TargetData> TargetDataVectorType;
#endif
@@ -242,15 +301,6 @@
return m_expression;
}
- enum eMatchScore
- {
- eMatchScoreNone,
- eMatchScoreNodeTest,
- eMatchScoreNSWild,
- eMatchScoreQName,
- eMatchScoreOther
- };
-
static double
getMatchScoreValue(eMatchScore score)
{
@@ -313,12 +363,12 @@
}
/**
- * Add the strings for the target element to a vector of strings.
+ * Add the data for the target of match pattern to a vector.
*
- * @param targetStrings vector of strings
+ * @param targetData The vector for the data
*/
void
- getTargetElementStrings(TargetElementStringsVectorType& targetStrings) const;
+ getTargetData(TargetDataVectorType& targetData) const;
/**
* Install a built-in function.
@@ -810,7 +860,7 @@
// Default vector allocation sizes.
enum
{
- eDefaultTargetStringsSize = 5
+ eDefaultTargetDataSize = 5
};
const XObjectPtr
1.35 +3 -1 xml-xalan/c/src/XPath/XPathExpression.cpp
Index: XPathExpression.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathExpression.cpp,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- XPathExpression.cpp 3 Apr 2002 05:13:09 -0000 1.34
+++ XPathExpression.cpp 26 Jun 2002 01:20:01 -0000 1.35
@@ -501,7 +501,7 @@
-void
+XPathExpression::OpCodeMapSizeType
XPathExpression::appendOpCode(eOpCodes theOpCode)
{
const int theOpCodeLength = getOpCodeLength(theOpCode);
@@ -536,6 +536,8 @@
m_opMap[s_opCodeMapLengthIndex] += theOpCodeLength;
}
}
+
+ return m_lastOpCodeIndex;
assert(opCodeMapSize() == OpCodeMapSizeType(opCodeMapLength()));
}
1.27 +7 -4 xml-xalan/c/src/XPath/XPathExpression.hpp
Index: XPathExpression.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathExpression.hpp,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -r1.26 -r1.27
--- XPathExpression.hpp 3 Apr 2002 05:13:09 -0000 1.26
+++ XPathExpression.hpp 26 Jun 2002 01:20:01 -0000 1.27
@@ -887,8 +887,9 @@
* Add an operation code to the list.
*
* @param theOpCode operation code
+ * @return the position of the op code
*/
- void
+ OpCodeMapSizeType
appendOpCode(eOpCodes theOpCode);
/**
@@ -897,15 +898,17 @@
* @param theOpCode operation code
* @param theArgs vector or arguments to supply
*/
- void
+ OpCodeMapSizeType
appendOpCode(eOpCodes theOpCode,
const OpCodeMapValueVectorType& theArgs)
{
- appendOpCode(theOpCode);
+ const OpCodeMapSizeType thePosition = appendOpCode(theOpCode);
setOpCodeArgs(theOpCode,
- m_lastOpCodeIndex,
+ thePosition,
theArgs);
+
+ return thePosition;
}
/**
1.57 +13 -7 xml-xalan/c/src/XPath/XPathProcessorImpl.cpp
Index: XPathProcessorImpl.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathProcessorImpl.cpp,v
retrieving revision 1.56
retrieving revision 1.57
diff -u -r1.56 -r1.57
--- XPathProcessorImpl.cpp 20 Jun 2002 01:01:22 -0000 1.56
+++ XPathProcessorImpl.cpp 26 Jun 2002 01:20:01 -0000 1.57
@@ -1780,7 +1780,7 @@
// This code is disabled for the time being, as
// it needs more testing.
-#if 0
+#if 1
if (equals(m_token, s_positionString) == true &&
m_positionPredicateStack.empty() == false)
{
@@ -2028,12 +2028,14 @@
-void
+int
XPathProcessorImpl::NodeTest(int axisType)
{
assert(m_xpath != 0);
assert(m_expression != 0);
+ int nodeTestPos = -1;
+
if(lookahead(XalanUnicode::charLeftParenthesis, 1) == true)
{
NodeTypesMapType::const_iterator i =
@@ -2048,7 +2050,7 @@
{
nextToken();
- m_expression->appendOpCode((*i).second);
+ nodeTestPos = m_expression->appendOpCode((*i).second);
consumeExpected(XalanUnicode::charLeftParenthesis);
@@ -2122,6 +2124,8 @@
nextToken();
}
+
+ return nodeTestPos;
}
@@ -2417,8 +2421,6 @@
}
else if(lookahead(s_axisString, 1) == true)
{
- matchTypePos = m_expression->opCodeMapLength();
-
if(tokenIs(s_attributeString) == true)
{
axisType = XPathExpression::eMATCH_ATTRIBUTE;
@@ -2427,6 +2429,8 @@
}
else if(tokenIs(s_childString) == true)
{
+ matchTypePos = m_expression->opCodeMapLength();
+
axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;
m_expression->appendOpCode(axisType);
@@ -2441,10 +2445,10 @@
}
else if(tokenIs(XalanUnicode::charSolidus) == true)
{
- matchTypePos = m_expression->opCodeMapLength();
-
if(lookahead(s_axisString, 2) == false)
{
+ matchTypePos = m_expression->opCodeMapLength();
+
axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;
m_expression->appendOpCode(axisType);
@@ -2461,6 +2465,8 @@
}
else if(tokenIs(s_childString) == true)
{
+ matchTypePos = m_expression->opCodeMapLength();
+
axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;
m_expression->appendOpCode(axisType);
1.21 +1 -1 xml-xalan/c/src/XPath/XPathProcessorImpl.hpp
Index: XPathProcessorImpl.hpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/src/XPath/XPathProcessorImpl.hpp,v
retrieving revision 1.20
retrieving revision 1.21
diff -u -r1.20 -r1.21
--- XPathProcessorImpl.hpp 19 Jun 2002 21:00:54 -0000 1.20
+++ XPathProcessorImpl.hpp 26 Jun 2002 01:20:01 -0000 1.21
@@ -663,7 +663,7 @@
| NodeType '(' ')'
| 'processing-instruction' '(' Literal ')'
*/
- void
+ int
NodeTest(int axisType);
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org