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