dbertoni    00/05/03 14:21:31

  Modified:    c/src/XPath SimpleNodeLocator.cpp XBoolean.cpp XBoolean.hpp
                        XBooleanStatic.cpp XNodeSet.cpp XNodeSet.hpp
                        XNull.cpp XNull.hpp XNumber.cpp XNumber.hpp
                        XObject.cpp XObject.hpp XObjectFactoryDefault.cpp
                        XPath.cpp XPathExpression.cpp XPathExpression.hpp
                        XPathProcessorImpl.cpp XPathProcessorImpl.hpp
                        XResultTreeFrag.cpp XResultTreeFrag.hpp XString.cpp
                        XString.hpp XUnknown.cpp XUnknown.hpp
  Log:
  New XObject comparison implementation.  Fixed some stuff in 
XPathProcessorImpl and SimpleNodeLocator for namespaces.
  
  Revision  Changes    Path
  1.9       +148 -124  xml-xalan/c/src/XPath/SimpleNodeLocator.cpp
  
  Index: SimpleNodeLocator.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/SimpleNodeLocator.cpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- SimpleNodeLocator.cpp     2000/04/27 15:11:25     1.8
  +++ SimpleNodeLocator.cpp     2000/05/03 21:21:13     1.9
  @@ -59,6 +59,7 @@
   
   
   
  +#include <XalanDOM/XalanAttr.hpp>
   #include <XalanDOM/XalanElement.hpp>
   #include <XalanDOM/XalanNamedNodeMap.hpp>
   #include <XalanDOM/XalanNode.hpp>
  @@ -1394,7 +1395,7 @@
        const XPathExpression&  currentExpression =
                xpath.getExpression();
   
  -     double score = 0.0L;
  +     double score = xpath.s_MatchScoreNone;
   
        const int       testType = currentExpression.getOpCodeMapValue(opPos);
   
  @@ -1405,23 +1406,23 @@
        switch(testType)
        {
        case XPathExpression::eNODETYPE_COMMENT:
  -             score = XalanNode::COMMENT_NODE == nodeType
  -                       ? xpath.s_MatchScoreNodeTest : xpath.s_MatchScoreNone;
  +             if (XalanNode::COMMENT_NODE == nodeType)
  +             {
  +                     score = xpath.s_MatchScoreNodeTest;
  +             }
                break;
   
        case XPathExpression::eNODETYPE_TEXT:
  -       score = (XalanNode::CDATA_SECTION_NODE == nodeType ||
  -                                     XalanNode::TEXT_NODE == nodeType) &&
  -                       executionContext.shouldStripSourceNode(*context) == 
false
  -                       ? xpath.s_MatchScoreNodeTest : xpath.s_MatchScoreNone;
  +             if ((XalanNode::CDATA_SECTION_NODE == nodeType ||
  +                      XalanNode::TEXT_NODE == nodeType) &&
  +                     executionContext.shouldStripSourceNode(*context) == 
false)
  +             {
  +                       score = xpath.s_MatchScoreNodeTest;
  +             }
          break;
   
        case XPathExpression::eNODETYPE_PI:
  -             if(XalanNode::PROCESSING_INSTRUCTION_NODE != nodeType)
  -             {
  -                     score = xpath.s_MatchScoreNone;
  -             }
  -             else
  +             if(XalanNode::PROCESSING_INSTRUCTION_NODE == nodeType)
                {
                        if(argLen == 1)
                        {
  @@ -1436,13 +1437,13 @@
                                        
currentExpression.getToken(tokenPosition);
                                assert(name != 0);
   
  -                             score = equals(context->getNodeName(), 
name->str())
  -                                             ? xpath.s_MatchScoreQName : 
xpath.s_MatchScoreNone;
  +                             if (equals(context->getNodeName(), name->str()) 
== true)
  +                             {
  +                                     score = xpath.s_MatchScoreQName;
  +                             }
                        }
                        else
                        {
  -                             score = xpath.s_MatchScoreNone;
  -
                                executionContext.error("Arg length of 
processing-instruction() node test is incorrect!");
                        }
                }
  @@ -1457,10 +1458,6 @@
                        {
                                score = xpath.s_MatchScoreNodeTest;
                        }
  -                     else
  -                     {
  -                             score = xpath.s_MatchScoreNone;
  -                     }
                }
                else
                {
  @@ -1469,145 +1466,172 @@
                break;
   
        case XPathExpression::eNODETYPE_ROOT:
  -             score = XalanNode::DOCUMENT_FRAGMENT_NODE == nodeType ||
  -                             XalanNode::DOCUMENT_NODE == nodeType ?
  -                                     xpath.s_MatchScoreOther :
  -                                             xpath.s_MatchScoreNone;
  +             if (XalanNode::DOCUMENT_FRAGMENT_NODE == nodeType ||
  +                     XalanNode::DOCUMENT_NODE == nodeType)
  +             {
  +                     score =  xpath.s_MatchScoreOther;
  +             }
                break;
   
        case XPathExpression::eNODENAME:
                {
  -                     bool                                    test = false;
  -
  -                     int                                     queueIndex = 
currentExpression.getOpCodeMapValue(opPos);
  -
  -                     const XalanDOMString    targetNS = queueIndex >= 0 ?
  -                                                                     
currentExpression.getToken(queueIndex)->str() :
  -                                                                             
XalanDOMString();
  -
  -                     opPos++;
  +                     if (nodeType == XalanNode::ATTRIBUTE_NODE || nodeType 
== XalanNode::ELEMENT_NODE)
  +                     {
  +                             bool                                    test = 
false;
   
  -                     // From the draft: "Two expanded names are equal if 
they 
  -                     // have the same local part, and either both have no 
URI or 
  -                     // both have the same URI."
  -                     // "A node test * is true for any node of the principal 
node type. 
  -                     // For example, child::* will select all element 
children of the 
  -                     // context node, and attribute::* will select all 
attributes of 
  -                     // the context node."
  -                     // "A node test can have the form NCName:*. In this 
case, the prefix 
  -                     // is expanded in the same way as with a QName using 
the context 
  -                     // namespace declarations. The node test will be true 
for any node 
  -                     // of the principal type whose expanded name has the 
URI to which 
  -                     // the prefix expands, regardless of the local part of 
the name."
  -                     const bool      isTotallyWild =
  -                                             0 == length(targetNS) &&
  -                                             
currentExpression.getOpCodeMapValue(opPos) == XPathExpression::eELEMWILDCARD;
  +                             int                                     
queueIndex = currentExpression.getOpCodeMapValue(opPos);
   
  -                     const bool      processNamespaces = 
executionContext.getProcessNamespaces();
  +                             const XalanDOMString    targetNS = queueIndex 
>= 0 ?
  +                                                                             
currentExpression.getToken(queueIndex)->str() :
  +                                                                             
        XalanDOMString();
  +
  +                             opPos++;
  +
  +                             // From the draft: "Two expanded names are 
equal if they 
  +                             // have the same local part, and either both 
have no URI or 
  +                             // both have the same URI."
  +                             // "A node test * is true for any node of the 
principal node type. 
  +                             // For example, child::* will select all 
element children of the 
  +                             // context node, and attribute::* will select 
all attributes of 
  +                             // the context node."
  +                             // "A node test can have the form NCName:*. In 
this case, the prefix 
  +                             // is expanded in the same way as with a QName 
using the context 
  +                             // namespace declarations. The node test will 
be true for any node 
  +                             // of the principal type whose expanded name 
has the URI to which 
  +                             // the prefix expands, regardless of the local 
part of the name."
  +                             const bool      isTotallyWild =
  +                                                     0 == length(targetNS) &&
  +                                                     
currentExpression.getOpCodeMapValue(opPos) == XPathExpression::eELEMWILDCARD;
   
  -                     bool            didMatchNS = false;
  +                             const bool      processNamespaces = 
executionContext.getProcessNamespaces();
   
  -                     if(isTotallyWild == false && processNamespaces == true)
  -                     {
  -                             const XalanDOMString    contextNS = 
executionContext.getNamespaceOfNode(*context);
  +                             bool            didMatchNS = false;
   
  -                             if(0 != length(targetNS) && 0 != 
length(contextNS))
  +                             if(isTotallyWild == false && processNamespaces 
== true)
                                {
  -                                     test = equals(contextNS, targetNS);
  +                                     const XalanDOMString    contextNS = 
executionContext.getNamespaceOfNode(*context);
  +
  +                                     if(0 != length(targetNS) && 0 != 
length(contextNS))
  +                                     {
  +                                             test = equals(contextNS, 
targetNS);
   
  -                                     didMatchNS = true;
  +                                             didMatchNS = true;
  +                                     }
  +                                     else
  +                                     {
  +                                             test = 
XPathExpression::eELEMWILDCARD == queueIndex || 
  +                                                0 == length(contextNS) || 0 
== length(contextNS);
  +                                     }
                                }
                                else
                                {
  -                                     test = XPathExpression::eELEMWILDCARD 
== queueIndex || 
  -                                        0 == length(contextNS) || 0 == 
length(contextNS);
  +                                     test = true;
                                }
  -                     }
  -                     else
  -                     {
  -                             test = true;
  -                     }
   
  -                     queueIndex = currentExpression.getOpCodeMapValue(opPos);
  +                             queueIndex = 
currentExpression.getOpCodeMapValue(opPos);
   
  -                     const XalanDOMString    targetLocalName =
  -                                             queueIndex >= 0 ? 
currentExpression.getToken(queueIndex)->str() : XalanDOMString();
  +                             const XalanDOMString    targetLocalName =
  +                                                     queueIndex >= 0 ? 
currentExpression.getToken(queueIndex)->str() : XalanDOMString();
   
  -                     if(test == false)
  -                     {
  -                             score = XPath::s_MatchScoreNone;
  -                     }
  -                     else
  -                     {
  -                             switch(nodeType)
  +                             if(test == true)
                                {
  -                             case XalanNode::ATTRIBUTE_NODE:
  -                                     if(stepType == 
XPathExpression::eFROM_ATTRIBUTES)
  +                                     switch(nodeType)
                                        {
  -                                             assert(context->getNodeType() 
== XalanNode::ATTRIBUTE_NODE);
  -
  -                                             
if(XPathExpression::eELEMWILDCARD == queueIndex)
  +                                     case XalanNode::ATTRIBUTE_NODE:
  +                                             if(stepType == 
XPathExpression::eFROM_ATTRIBUTES ||
  +                                                     stepType == 
XPathExpression::eFROM_NAMESPACE)
                                                {
  -                                                     if(processNamespaces == 
true)
  -                                                     {
  -                                                             const 
XalanDOMString    attrName =
  -                                                                     
context->getNodeName();
  +                                                     
assert(context->getNodeType() == XalanNode::ATTRIBUTE_NODE);
  +
  +                                                     const XalanDOMString    
attrName =
  +                                                                             
context->getNodeName();
   
  -                                                             score = 
!(startsWith(attrName, DOMServices::s_XMLNamespaceWithSeparator) ||
  -                                                                             
  equals(attrName, DOMServices::s_XMLNamespace))
  -                                                                             
? xpath.s_MatchScoreNodeTest : xpath.s_MatchScoreNone;
  +                                                     const bool              
                isNamespace =
  +                                                                     
startsWith(attrName, DOMServices::s_XMLNamespaceWithSeparator) ||
  +                                                                     
equals(attrName, DOMServices::s_XMLNamespace);
  +
  +                                                     
if(XPathExpression::eELEMWILDCARD == queueIndex)
  +                                                     {
  +                                                             if(stepType == 
XPathExpression::eFROM_ATTRIBUTES)
  +                                                             {
  +                                                                     if 
(isNamespace == false)
  +                                                                     {
  +                                                                             
score = xpath.s_MatchScoreNodeTest;
  +                                                                     }
  +                                                             }
  +                                                             else
  +                                                             {
  +                                                                     if 
(isNamespace == true)
  +                                                                     {
  +                                                                             
score = xpath.s_MatchScoreNodeTest;
  +                                                                     }
  +                                                             }
                                                        }
                                                        else
                                                        {
  -                                                             score = 
xpath.s_MatchScoreNodeTest;
  +                                                             if(stepType == 
XPathExpression::eFROM_ATTRIBUTES)
  +                                                             {
  +                                                                     if 
(isNamespace == false)
  +                                                                     {
  +                                                                             
const XalanDOMString    localAttrName =
  +                                                                             
        executionContext.getLocalNameOfNode(*context);
  +
  +                                                                             
if (equals(localAttrName, targetLocalName) == true)
  +                                                                             
{
  +                                                                             
        score = xpath.s_MatchScoreQName;
  +                                                                             
}
  +                                                                     }
  +                                                             }
  +                                                             else
  +                                                             {
  +                                                                     if 
(isNamespace == true)
  +                                                                     {
  +                                                                             
const XalanAttr* const  theAttrNode =
  +                                                                             
        static_cast<const XalanAttr*>(context);
  +                                                                             
assert(theAttrNode != 0);
  +
  +                                                                             
const XalanDOMString    theNamespace =
  +                                                                             
                        theAttrNode->getValue();
  +
  +                                                                             
if (equals(theNamespace, targetLocalName) == true)
  +                                                                             
{
  +                                                                             
        score = xpath.s_MatchScoreQName;
  +                                                                             
}
  +                                                                     }
  +                                                             }
                                                        }
                                                }
  -                                             else
  -                                             {
  -                                                     const XalanDOMString    
localAttrName =
  -                                                             
executionContext.getLocalNameOfNode(*context);
  -
  -                                                     score = 
equals(localAttrName, targetLocalName) ?
  -                                                                     
xpath.s_MatchScoreQName : xpath.s_MatchScoreNone;
  -                                             }
  -                                     }
  -                                     else
  -                                     {
  -                                             score  = xpath.s_MatchScoreNone;
  -                                     }
  -                                     break;
  +                                             break;
   
  -                             case XalanNode::ELEMENT_NODE:
  -                                     if(stepType != 
XPathExpression::eFROM_ATTRIBUTES)
  -                                     {
  -                                             
if(XPathExpression::eELEMWILDCARD == queueIndex)
  -                                             {
  -                                                     score = didMatchNS == 
true ?
  -                                                             
XPath::s_MatchScoreNSWild : XPath::s_MatchScoreNodeTest;
  -                                             }
  -                                             else
  +                                     case XalanNode::ELEMENT_NODE:
  +                                             if(stepType != 
XPathExpression::eFROM_ATTRIBUTES)
                                                {
  -                                                     score = 
equals(executionContext.getLocalNameOfNode(*context), targetLocalName) ?
  -                                                             
xpath.s_MatchScoreQName : xpath.s_MatchScoreNone;
  +                                                     
if(XPathExpression::eELEMWILDCARD == queueIndex)
  +                                                     {
  +                                                             score = 
didMatchNS == true ?
  +                                                                     
XPath::s_MatchScoreNSWild : XPath::s_MatchScoreNodeTest;
  +                                                     }
  +                                                     else
  +                                                     {
  +                                                             if 
(equals(executionContext.getLocalNameOfNode(*context),
  +                                                                             
   targetLocalName) == true)
  +                                                             {
  +                                                                     score = 
xpath.s_MatchScoreQName;
  +                                                             }
  +                                                     }
                                                }
  -                                     }
  -                                     else
  -                                     {
  -                                             score  = xpath.s_MatchScoreNone;
  -                                     }
  -                                     break;
  +                                             break;
   
  -                             default:
  -                                     // Trying to match on anything else 
causes nasty bugs.
  -                                     score  = xpath.s_MatchScoreNone;
  -                                     break;
  -                             } // end switch(nodeType)
  -                     } // end if(test)
  +                                     default:
  +                                             // Trying to match on anything 
else causes nasty bugs.
  +                                             break;
  +                                     } // end switch(nodeType)
  +                             } // end if(test)
  +                     } // end if (nodeType == XalanNode::ATTRIBUTE_NODE || 
nodeType == XalanNode::ELEMENT_NODE)
                } // end case XPathExpression::eNODENAME
                break;
   
        default:
  -             score  = xpath.s_MatchScoreNone;
                break;
        } // end switch(testType)
   
  
  
  
  1.3       +6 -12     xml-xalan/c/src/XPath/XBoolean.cpp
  
  Index: XBoolean.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XBoolean.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XBoolean.cpp      2000/04/11 14:46:11     1.2
  +++ XBoolean.cpp      2000/05/03 21:21:14     1.3
  @@ -68,9 +68,10 @@
   
   
   XBoolean::XBoolean(
  -                     XPathEnvSupport&        support,
  +                     XPathEnvSupport&        envSupport,
  +                     XPathSupport&           support,
                        bool                            val) :
  -     XObject(&support),
  +     XObject(&envSupport, &support),
        m_value(val)
   {
   }
  @@ -78,9 +79,10 @@
   
   
   XBoolean::XBoolean(
  -                     XPathEnvSupport*        support,
  +                     XPathEnvSupport*        envSupport,
  +                     XPathSupport*           support,
                        bool                            val) :
  -     XObject(support),
  +     XObject(envSupport, support),
        m_value(val)
   {
   }
  @@ -221,12 +223,4 @@
   {
        theCallbackObject.Boolean(*this,
                                                          boolean());
  -}
  -
  -
  -
  -bool
  -XBoolean::equals(const XObject&      theRHS) const
  -{
  -     return m_value == theRHS.boolean();
   }
  
  
  
  1.4       +11 -9     xml-xalan/c/src/XPath/XBoolean.hpp
  
  Index: XBoolean.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XBoolean.hpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XBoolean.hpp      2000/04/11 14:46:12     1.3
  +++ XBoolean.hpp      2000/05/03 21:21:14     1.4
  @@ -76,11 +76,14 @@
        /**
         * Construct an XBoolean object from a boolean value
         * 
  -      * @param support XPath environment support class instance
  -      * @param val     boolean value to initialize object
  +      * @param support XPath support class instance
  +      * @param envSupport XPath environment support class instance
  +      * @param val           boolean value to initialize object
         */
  -     XBoolean(XPathEnvSupport&       support,
  -                      bool                           val);
  +     XBoolean(
  +                     XPathEnvSupport&        envSupport,
  +                     XPathSupport&           support,
  +                     bool                            val);
   
        XBoolean(const XBoolean&        source);
   
  @@ -122,16 +125,15 @@
        virtual void
        ProcessXObjectTypeCallback(XObjectTypeCallback&         
theCallbackObject) const;
   
  -     virtual bool
  -     equals(const XObject&   theRHS) const;
  -
   protected:
   
        virtual
        ~XBoolean();
   
  -     XBoolean(XPathEnvSupport*       support,
  -                      bool                           val);
  +     XBoolean(
  +                     XPathEnvSupport*        envSupport,
  +                     XPathSupport*           support,
  +                     bool                            val);
   
   private:
   
  
  
  
  1.3       +1 -0      xml-xalan/c/src/XPath/XBooleanStatic.cpp
  
  Index: XBooleanStatic.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XBooleanStatic.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XBooleanStatic.cpp        2000/04/11 14:46:12     1.2
  +++ XBooleanStatic.cpp        2000/05/03 21:21:14     1.3
  @@ -65,6 +65,7 @@
   
   XBooleanStatic::XBooleanStatic(bool          val) :
        XBoolean(0,
  +                      0,
                         val)
   {
   }
  
  
  
  1.5       +10 -76    xml-xalan/c/src/XPath/XNodeSet.cpp
  
  Index: XNodeSet.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XNodeSet.cpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XNodeSet.cpp      2000/04/20 16:30:57     1.4
  +++ XNodeSet.cpp      2000/05/03 21:21:14     1.5
  @@ -79,8 +79,7 @@
                        XPathEnvSupport&                envSupport,
                        XPathSupport&                   support,
                        const NodeRefListBase&  value) :
  -     XObject(&envSupport),
  -     m_support(support),
  +     XObject(&envSupport, &support),
        m_value(value),
        m_resultTreeFrag()
   {
  @@ -92,8 +91,7 @@
                        XPathEnvSupport&                        envSupport,
                        XPathSupport&                           support,
                        const MutableNodeRefList&       value) :
  -     XObject(&envSupport),
  -     m_support(support),
  +     XObject(&envSupport, &support),
        m_value(value),
        m_resultTreeFrag()
   {
  @@ -105,8 +103,7 @@
                        XPathEnvSupport&        envSupport,
                        XPathSupport&           support,
                        XalanNode&                      value) :
  -     XObject(&envSupport),
  -     m_support(support),
  +     XObject(&envSupport, &support),
        m_value(),
        m_resultTreeFrag()
   {
  @@ -118,7 +115,6 @@
   XNodeSet::XNodeSet(const XNodeSet&   source,
                                   bool                         deepClone) :
        XObject(source),
  -     m_support(source.m_support),
        m_value(source.m_value),
        m_resultTreeFrag(source.m_resultTreeFrag.get() == 0 ?
                                                0 :
  @@ -169,6 +165,8 @@
   XalanDOMString
   XNodeSet::str() const
   {
  +     assert(m_support != 0);
  +
        XalanDOMString  theResult;
   
        if (m_value.getLength() > 0)
  @@ -185,7 +183,7 @@
                }
                else
                {
  -                     theResult = m_support.getNodeData(*theNode);
  +                     theResult = m_support->getNodeData(*theNode);
                }
        }
   
  @@ -203,6 +201,7 @@
   const ResultTreeFragBase&
   XNodeSet::rtree() const
   {
  +     assert(m_support != 0);
        assert(m_envSupport != 0);
   
        if (m_resultTreeFrag.get() == 0)
  @@ -211,7 +210,7 @@
   
                ResultTreeFrag* const   theFrag =
                        new ResultTreeFrag(*m_envSupport->getDOMFactory(),
  -                                                        m_support);
  +                                                        *m_support);
   
                const int       nNodes = m_value.getLength();
   
  @@ -243,6 +242,7 @@
   ResultTreeFragBase&
   XNodeSet::rtree()
   {
  +     assert(m_support != 0);
        assert(m_envSupport != 0);
   
        if (m_resultTreeFrag.get() == 0)
  @@ -251,7 +251,7 @@
   
                ResultTreeFrag* const   theFrag =
                        new ResultTreeFrag(*m_envSupport->getDOMFactory(),
  -                                                        m_support);
  +                                                        *m_support);
   
   #if defined(XALAN_OLD_AUTO_PTR)
                m_resultTreeFrag = auto_ptr<ResultTreeFragBase>(theFrag);
  @@ -310,70 +310,4 @@
   {
        theCallbackObject.NodeSet(*this,
                                                          nodeset());
  -}
  -
  -
  -
  -bool
  -XNodeSet::equals(const XObject&              theRHS) const
  -{
  -     bool                                                    fResult = false;
  -
  -     const XNodeSet::eObjectType     theType =
  -             theRHS.getType();
  -
  -     if (XObject::eTypeNodeSet == theType)
  -     {
  -             // See the XPath spec., section 3.4 for an explanation of this 
lunacy...
  -             // $$$ ToDo: This is still not correct.
  -             const unsigned int      theLHSLength = m_value.getLength();
  -
  -             if (theLHSLength > 0)
  -             {
  -                     const XNodeSet&         theRHSNodeSet = 
static_cast<const XNodeSet&>(theRHS);
  -
  -                     const int                       theRHSLength = 
theRHSNodeSet.m_value.getLength();
  -
  -                     // See if there's at least one pair of nodes in the two 
nodes sets
  -                     // whose "string" values are equal...
  -                     for(unsigned int i = 0; i < theLHSLength && fResult == 
false; i++)
  -                     {
  -                             const XalanNode* const  theCurrent = 
m_value.item(i);
  -                             assert(theCurrent != 0);
  -
  -                             for (int j = 0; j < theRHSLength && fResult == 
false; j++)
  -                             {
  -                                     if 
(::equals(m_support.getNodeData(*theCurrent),
  -                                                              
m_support.getNodeData(*theRHSNodeSet.m_value.item(j))) == true)
  -                                     {
  -                                             fResult = true;
  -                                     }
  -                             }
  -                     }
  -             }
  -     }
  -     else if(XObject::eTypeString == theType ||
  -        XObject::eTypeResultTreeFrag == theType)
  -     {
  -             if (::equals(str(), theRHS.str()) == true)
  -             {
  -                     fResult = true;
  -             }
  -     }
  -     else if(XObject::eTypeBoolean == theType)
  -     {
  -             if (boolean() == theRHS.boolean())
  -             {
  -                     fResult = true;
  -             }
  -     }
  -     else if(XObject::eTypeNumber == theType)
  -     {
  -             if (num() == theRHS.num())
  -             {
  -                     fResult = true;
  -             }
  -     }
  -
  -     return fResult;
   }
  
  
  
  1.5       +0 -5      xml-xalan/c/src/XPath/XNodeSet.hpp
  
  Index: XNodeSet.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XNodeSet.hpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XNodeSet.hpp      2000/04/20 16:30:57     1.4
  +++ XNodeSet.hpp      2000/05/03 21:21:14     1.5
  @@ -180,9 +180,6 @@
        virtual void
        ProcessXObjectTypeCallback(XObjectTypeCallback&         
theCallbackObject) const;
   
  -     virtual bool
  -     equals(const XObject&   theRHS) const;
  -
   private:
   
        // Not implemented...
  @@ -190,8 +187,6 @@
        operator=(const XNodeSet&);
   
        // Data members...
  -     XPathSupport&                                                           
m_support;
  -
        MutableNodeRefList                                                      
m_value;
   
   #if defined(XALAN_NO_NAMESPACES)
  
  
  
  1.3       +1 -9      xml-xalan/c/src/XPath/XNull.cpp
  
  Index: XNull.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XNull.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XNull.cpp 2000/04/11 14:46:13     1.2
  +++ XNull.cpp 2000/05/03 21:21:15     1.3
  @@ -68,7 +68,7 @@
   XNull::XNull(
                        XPathEnvSupport&        envSupport,
                        XPathSupport&           support) :
  -     XObject(&envSupport),
  +     XObject(&envSupport, &support),
        m_resultTreeFrag(new ResultTreeFrag(*envSupport.getDOMFactory(),
                                                                                
support))
   {
  @@ -200,12 +200,4 @@
   XNull::ProcessXObjectTypeCallback(XObjectTypeCallback&       
theCallbackObject) const
   {
        theCallbackObject.Null(*this);
  -}
  -
  -
  -
  -bool
  -XNull::equals(const XObject& theRHS) const
  -{
  -     return theRHS.getType() == eTypeNull;
   }
  
  
  
  1.4       +0 -3      xml-xalan/c/src/XPath/XNull.hpp
  
  Index: XNull.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XNull.hpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XNull.hpp 2000/04/11 14:46:13     1.3
  +++ XNull.hpp 2000/05/03 21:21:15     1.4
  @@ -150,9 +150,6 @@
        virtual void
        ProcessXObjectTypeCallback(XObjectTypeCallback&         
theCallbackObject) const;
   
  -     virtual bool
  -     equals(const XObject&   theRHS) const;
  -
   private:
   
        const std::auto_ptr<ResultTreeFragBase>         m_resultTreeFrag;
  
  
  
  1.3       +2 -22     xml-xalan/c/src/XPath/XNumber.cpp
  
  Index: XNumber.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XNumber.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XNumber.cpp       2000/04/11 14:46:14     1.2
  +++ XNumber.cpp       2000/05/03 21:21:15     1.3
  @@ -70,8 +70,9 @@
   
   XNumber::XNumber(
                        XPathEnvSupport&        envSupport,
  +                     XPathSupport&           support,
                        double                          val) :
  -     XObject(&envSupport),
  +     XObject(&envSupport, &support),
        m_value(val)
   {
   }
  @@ -206,25 +207,4 @@
   {
        theCallbackObject.Number(*this,
                                                         num());
  -}
  -
  -
  -
  -bool
  -XNumber::equals(const XObject&       theRHS) const
  -{
  -     bool                    fResult = false;
  -
  -     if (DoubleSupport::isNaN(m_value) == false)
  -     {
  -             const double    theRHSNumber = theRHS.num();
  -
  -             if (DoubleSupport::isNaN(theRHSNumber) == false &&
  -                     m_value == theRHSNumber)
  -             {
  -                     fResult = true;
  -             }
  -     }
  -
  -     return fResult;
   }
  
  
  
  1.4       +1 -3      xml-xalan/c/src/XPath/XNumber.hpp
  
  Index: XNumber.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XNumber.hpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XNumber.hpp       2000/04/11 14:46:14     1.3
  +++ XNumber.hpp       2000/05/03 21:21:15     1.4
  @@ -85,6 +85,7 @@
         */
        XNumber(
                        XPathEnvSupport&        envSupport,
  +                     XPathSupport&           support,
                        double                          val);
   
        XNumber(const XNumber&  source);
  @@ -129,9 +130,6 @@
   
        virtual void
        ProcessXObjectTypeCallback(XObjectTypeCallback&         
theCallbackObject) const;
  -
  -     virtual bool
  -     equals(const XObject&   theRHS) const;
   
   private:
   
  
  
  
  1.3       +1009 -4   xml-xalan/c/src/XPath/XObject.cpp
  
  Index: XObject.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XObject.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XObject.cpp       2000/04/11 14:46:14     1.2
  +++ XObject.cpp       2000/05/03 21:21:15     1.3
  @@ -63,22 +63,37 @@
   
   
   
  +#include <PlatformSupport/DoubleSupport.hpp>
  +
  +
  +
  +#include <DOMSupport/DOMServices.hpp>
  +
  +
  +
  +#include "NodeRefListBase.hpp"
  +#include "XObjectCompare.hpp"
   #include "XPathEnvSupport.hpp"
   #include "XPathException.hpp"
  +#include "XPathSupport.hpp"
   
   
   
  -XObject::XObject(XPathEnvSupport*    envSupport) :
  +XObject::XObject(
  +                     XPathEnvSupport*        envSupport,
  +                     XPathSupport*           support) :
        FactoryObject(),
  -     m_envSupport(envSupport)
  +     m_envSupport(envSupport),
  +     m_support(support)
   {
   }
   
   
   
  -XObject::XObject(const XObject&      source) :
  +XObject::XObject(const XObject&              source) :
        FactoryObject(),
  -     m_envSupport(source.m_envSupport)
  +     m_envSupport(source.m_envSupport),
  +     m_support(source.m_support)
   {
   }
   
  @@ -109,5 +124,995 @@
        if(shouldThrow == true)
        {
                throw XPathException(msg);
  +     }
  +}
  +
  +
  +
  +XPathSupport*
  +getSupport(const XObject&                    theXObject,
  +                const NodeRefListBase&       theNodeList)
  +{
  +     XPathSupport*   theSupport = theXObject.getSupport();
  +
  +     if (theSupport == 0)
  +     {
  +             theNodeList.getSupport();
  +     }
  +
  +     return theSupport;
  +}
  +
  +
  +
  +
  +const XalanDOMString
  +getStringFromNode(
  +                     const XalanNode&        theNode,
  +                     XPathSupport*           theXPathSupport)
  +{
  +     if (theXPathSupport != 0)
  +     {
  +             return theXPathSupport->getNodeData(theNode);
  +     }
  +     else
  +     {
  +             return DOMServices::getNodeData(theNode);
  +     }
  +}
  +
  +
  +
  +struct
  +getStringFromNodeFunction
  +{
  +     getStringFromNodeFunction(XPathSupport* theSupport = 0) :
  +             m_support(theSupport)
  +     {
  +     }
  +
  +     const XalanDOMString
  +     operator()(const XalanNode&             theNode) const
  +     {
  +             return getStringFromNode(theNode, m_support);
  +     }
  +
  +private:
  +
  +     XPathSupport* const             m_support;
  +};
  +
  +
  +
  +double
  +getNumberFromNode(
  +                     const XalanNode&        theNode,
  +                     XPathSupport*           theXPathSupport)
  +{
  +     return DOMStringToDouble(getStringFromNode(theNode, theXPathSupport));
  +}
  +
  +
  +
  +struct
  +getNumberFromNodeFunction
  +{
  +     getNumberFromNodeFunction(XPathSupport* theSupport = 0) :
  +             m_support(theSupport)
  +     {
  +     }
  +
  +     double
  +     operator()(const XalanNode&             theNode) const
  +     {
  +             return getNumberFromNode(theNode, m_support);
  +     }
  +
  +private:
  +
  +     XPathSupport* const             m_support;
  +};
  +
  +
  +
  +
  +template<class CompareFunction, class TypeFunction>
  +bool
  +doCompareNodeSets(
  +                     const NodeRefListBase&  theLHSNodeSet,
  +                     const NodeRefListBase&  theRHSNodeSet,
  +                     const TypeFunction&             theTypeFunction,
  +                     const CompareFunction&  theCompareFunction)
  +{
  +     // From http://www.w3.org/TR/xpath: 
  +     // If both objects to be compared are node-sets, then the comparison 
  +     // will be true if and only if there is a node in the first node-set 
  +     // and a node in the second node-set such that the result of performing 
  +     // the comparison on the string-values of the two nodes is true.
  +
  +     // Note this little gem from the draft:
  +     // NOTE: If $x is bound to a node-set, then $x="foo" 
  +     // does not mean the same as not($x!="foo"): the former 
  +     // is true if and only if some node in $x has the string-value 
  +     // foo; the latter is true if and only if all nodes in $x have 
  +     // the string-value foo.
  +     bool                            theResult = false;
  +
  +     const unsigned int      len1 = theLHSNodeSet.getLength();
  +     const unsigned int      len2 = theRHSNodeSet.getLength();
  +
  +     for(unsigned int i = 0; i < len1 && theResult == false; i++)
  +     {
  +             const XalanNode* const  theLHSNode = theLHSNodeSet.item(i);
  +             assert(theLHSNode != 0);
  +
  +             const XalanDOMString    s1 =
  +                             theTypeFunction(*theLHSNode);
  +
  +             for(unsigned int k = 0; k < len2 && theResult == false; k++)
  +             {
  +                     const XalanNode* const  theRHSNode = 
theLHSNodeSet.item(i);
  +                     assert(theRHSNode != 0);
  +
  +                     const XalanDOMString    s2 =
  +                                     theTypeFunction(*theLHSNode);
  +
  +                     if(theCompareFunction(s1, s2) == true)
  +                     {
  +                             theResult = true;
  +                     }
  +             }
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
  +template<class CompareFunction, class TypeFunction, class Type>
  +bool
  +doCompare(
  +                     const NodeRefListBase&  theLHSNodeSet,
  +                     const TypeFunction&             theTypeFunction,
  +                     const Type&                             theRHS,
  +                     const CompareFunction&  theCompareFunction)
  +{
  +     bool                            theResult = false;
  +
  +     const unsigned int      len1 = theLHSNodeSet.getLength();
  +
  +     for(unsigned int i = 0; i < len1 && theResult == false; i++)
  +     {
  +             const XalanNode* const  theLHSNode = theLHSNodeSet.item(i);
  +             assert(theLHSNode != 0);
  +
  +             const Type      theLHS = theTypeFunction(*theLHSNode);
  +
  +             if (theCompareFunction(theLHS, theRHS) == true)
  +             {
  +                     theResult = true;
  +             }
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
  +bool
  +equalNodeSet(
  +                     const XObject&                  theLHS,
  +                     const XObject&                  theRHS,
  +                     XObject::eObjectType    theRHSType,
  +                     XPathSupport*                   theXPathSupport)
  +{
  +     bool    theResult = false;
  +
  +     XPathSupport* const             theSupport = theXPathSupport != 0 ?
  +                                                             theXPathSupport 
:
  +                                                             
theRHS.getSupport();
  +
  +     if(theRHSType == XObject::eTypeNodeSet)
  +     {
  +             // Compare as node sets...
  +             theResult = doCompareNodeSets(
  +                             theLHS.nodeset(),
  +                             theRHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             DOMStringEqualsFunction());
  +
  +     }
  +     else if(theRHSType == XObject::eTypeBoolean)
  +     {
  +       // From http://www.w3.org/TR/xpath: 
  +       // If one object to be compared is a node-set and the other is a 
boolean, 
  +       // then the comparison will be true if and only if the result of 
  +       // performing the comparison on the boolean and on the result of 
  +       // converting the node-set to a boolean using the boolean function 
  +       // is true.
  +             const double    num1 = theLHS.boolean() == true ? 1.0 : 0.0;
  +
  +             theResult = DoubleSupport::equal(num1, theRHS.num());
  +     }
  +     else if(theRHSType == XObject::eTypeNumber)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a number, 
  +             // then the comparison will be true if and only if there is a 
  +             // node in the node-set such that the result of performing the 
  +             // comparison on the number to be compared and on the result of 
  +             // converting the string-value of that node to a number using 
  +             // the number function is true. 
  +
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getNumberFromNodeFunction(theSupport),
  +                             theRHS.num(),
  +                             DoubleSupport::equalFunction());
  +     }
  +     else if(theRHSType == XObject::eTypeResultTreeFrag)
  +     {
  +             // hmmm... 
  +             const double    theRHSNumber = theRHS.num();
  +
  +             if(DoubleSupport::isNaN(theRHSNumber) == false)
  +             {
  +                     // Compare as number...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getNumberFromNodeFunction(theSupport),
  +                                     theRHS.num(),
  +                                     DoubleSupport::equalFunction());
  +             }
  +             else
  +             {
  +                     // Compare as string...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getStringFromNodeFunction(theSupport),
  +                                     theRHS.str(),
  +                                     DOMStringEqualsFunction());
  +             }
  +     }
  +     else if(theRHSType == XObject::eTypeString)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a 
  +             // string, then the comparison will be true if and only if 
there 
  +             // is a node in the node-set such that the result of performing 
  +             // the comparison on the string-value of the node and the other 
  +             // string is true. 
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             theRHS.str(),
  +                             DOMStringEqualsFunction());
  +     }
  +     else
  +     {
  +             assert(false);
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
  +bool
  +notEqualNodeSet(
  +                     const XObject&                  theLHS,
  +                     const XObject&                  theRHS,
  +                     XObject::eObjectType    theRHSType,
  +                     XPathSupport*                   theXPathSupport)
  +{
  +     bool    theResult = false;
  +
  +     XPathSupport* const             theSupport = theXPathSupport != 0 ?
  +                                                             theXPathSupport 
:
  +                                                             
theRHS.getSupport();
  +
  +     if(theRHSType == XObject::eTypeNodeSet)
  +     {
  +             // Compare as node sets...
  +             theResult = doCompareNodeSets(
  +                             theLHS.nodeset(),
  +                             theRHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             DOMStringNotEqualsFunction());
  +
  +     }
  +     else if(theRHSType == XObject::eTypeBoolean)
  +     {
  +       // From http://www.w3.org/TR/xpath: 
  +       // If one object to be compared is a node-set and the other is a 
boolean, 
  +       // then the comparison will be true if and only if the result of 
  +       // performing the comparison on the boolean and on the result of 
  +       // converting the node-set to a boolean using the boolean function 
  +       // is true.
  +             const double    num1 = theLHS.boolean() == true ? 1.0 : 0.0;
  +
  +             theResult = DoubleSupport::notEqual(num1, theRHS.num());
  +     }
  +     else if(theRHSType == XObject::eTypeNumber)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a number, 
  +             // then the comparison will be true if and only if there is a 
  +             // node in the node-set such that the result of performing the 
  +             // comparison on the number to be compared and on the result of 
  +             // converting the string-value of that node to a number using 
  +             // the number function is true. 
  +
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getNumberFromNodeFunction(theSupport),
  +                             theRHS.num(),
  +                             DoubleSupport::notEqualFunction());
  +     }
  +     else if(theRHSType == XObject::eTypeResultTreeFrag)
  +     {
  +             // hmmm... 
  +             const double    theRHSNumber = theRHS.num();
  +
  +             if(DoubleSupport::isNaN(theRHSNumber) == false)
  +             {
  +                     // Compare as number...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getNumberFromNodeFunction(theSupport),
  +                                     theRHS.num(),
  +                                     DoubleSupport::notEqualFunction());
  +             }
  +             else
  +             {
  +                     // Compare as string...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getStringFromNodeFunction(theSupport),
  +                                     theRHS.str(),
  +                                     DOMStringNotEqualsFunction());
  +             }
  +     }
  +     else if(theRHSType == XObject::eTypeString)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a 
  +             // string, then the comparison will be true if and only if 
there 
  +             // is a node in the node-set such that the result of performing 
  +             // the comparison on the string-value of the node and the other 
  +             // string is true. 
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             theRHS.str(),
  +                             DOMStringNotEqualsFunction());
  +     }
  +     else
  +     {
  +             assert(false);
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
  +bool
  +lessThanNodeSet(
  +                     const XObject&                  theLHS,
  +                     const XObject&                  theRHS,
  +                     XObject::eObjectType    theRHSType,
  +                     XPathSupport*                   theXPathSupport)
  +{
  +     bool    theResult = false;
  +
  +     XPathSupport* const             theSupport = theXPathSupport != 0 ?
  +                                                             theXPathSupport 
:
  +                                                             
theRHS.getSupport();
  +
  +     if(theRHSType == XObject::eTypeNodeSet)
  +     {
  +             // Compare as node sets...
  +             theResult = doCompareNodeSets(
  +                             theLHS.nodeset(),
  +                             theRHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             DOMStringLessThanFunction());
  +
  +     }
  +     else if(theRHSType == XObject::eTypeBoolean)
  +     {
  +       // From http://www.w3.org/TR/xpath: 
  +       // If one object to be compared is a node-set and the other is a 
boolean, 
  +       // then the comparison will be true if and only if the result of 
  +       // performing the comparison on the boolean and on the result of 
  +       // converting the node-set to a boolean using the boolean function 
  +       // is true.
  +             const double    num1 = theLHS.boolean() == true ? 1.0 : 0.0;
  +
  +             theResult = DoubleSupport::lessThan(num1, theRHS.num());
  +     }
  +     else if(theRHSType == XObject::eTypeNumber)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a number, 
  +             // then the comparison will be true if and only if there is a 
  +             // node in the node-set such that the result of performing the 
  +             // comparison on the number to be compared and on the result of 
  +             // converting the string-value of that node to a number using 
  +             // the number function is true. 
  +
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getNumberFromNodeFunction(theSupport),
  +                             theRHS.num(),
  +                             DoubleSupport::lessThanFunction());
  +     }
  +     else if(theRHSType == XObject::eTypeResultTreeFrag)
  +     {
  +             // hmmm... 
  +             const double    theRHSNumber = theRHS.num();
  +
  +             if(DoubleSupport::isNaN(theRHSNumber) == false)
  +             {
  +                     // Compare as number...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getNumberFromNodeFunction(theSupport),
  +                                     theRHS.num(),
  +                                     DoubleSupport::lessThanFunction());
  +             }
  +             else
  +             {
  +                     // Compare as string...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getStringFromNodeFunction(theSupport),
  +                                     theRHS.str(),
  +                                     DOMStringLessThanFunction());
  +             }
  +     }
  +     else if(theRHSType == XObject::eTypeString)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a 
  +             // string, then the comparison will be true if and only if 
there 
  +             // is a node in the node-set such that the result of performing 
  +             // the comparison on the string-value of the node and the other 
  +             // string is true. 
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             theRHS.str(),
  +                             DOMStringLessThanFunction());
  +     }
  +     else
  +     {
  +             assert(false);
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
  +bool
  +lessThanOrEqualNodeSet(
  +                     const XObject&                  theLHS,
  +                     const XObject&                  theRHS,
  +                     XObject::eObjectType    theRHSType,
  +                     XPathSupport*                   theXPathSupport)
  +{
  +     bool    theResult = false;
  +
  +     XPathSupport* const             theSupport = theXPathSupport != 0 ?
  +                                                             theXPathSupport 
:
  +                                                             
theRHS.getSupport();
  +
  +     if(theRHSType == XObject::eTypeNodeSet)
  +     {
  +             // Compare as node sets...
  +             theResult = doCompareNodeSets(
  +                             theLHS.nodeset(),
  +                             theRHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             DOMStringLessThanOrEqualFunction());
  +
  +     }
  +     else if(theRHSType == XObject::eTypeBoolean)
  +     {
  +       // From http://www.w3.org/TR/xpath: 
  +       // If one object to be compared is a node-set and the other is a 
boolean, 
  +       // then the comparison will be true if and only if the result of 
  +       // performing the comparison on the boolean and on the result of 
  +       // converting the node-set to a boolean using the boolean function 
  +       // is true.
  +             const double    num1 = theLHS.boolean() == true ? 1.0 : 0.0;
  +
  +             theResult = DoubleSupport::lessThanOrEqual(num1, theRHS.num());
  +     }
  +     else if(theRHSType == XObject::eTypeNumber)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a number, 
  +             // then the comparison will be true if and only if there is a 
  +             // node in the node-set such that the result of performing the 
  +             // comparison on the number to be compared and on the result of 
  +             // converting the string-value of that node to a number using 
  +             // the number function is true. 
  +
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getNumberFromNodeFunction(theSupport),
  +                             theRHS.num(),
  +                             DoubleSupport::lessThanOrEqualFunction());
  +     }
  +     else if(theRHSType == XObject::eTypeResultTreeFrag)
  +     {
  +             // hmmm... 
  +             const double    theRHSNumber = theRHS.num();
  +
  +             if(DoubleSupport::isNaN(theRHSNumber) == false)
  +             {
  +                     // Compare as number...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getNumberFromNodeFunction(theSupport),
  +                                     theRHS.num(),
  +                                     
DoubleSupport::lessThanOrEqualFunction());
  +             }
  +             else
  +             {
  +                     // Compare as string...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getStringFromNodeFunction(theSupport),
  +                                     theRHS.str(),
  +                                     DOMStringLessThanOrEqualFunction());
  +             }
  +     }
  +     else if(theRHSType == XObject::eTypeString)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a 
  +             // string, then the comparison will be true if and only if 
there 
  +             // is a node in the node-set such that the result of performing 
  +             // the comparison on the string-value of the node and the other 
  +             // string is true. 
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             theRHS.str(),
  +                             DOMStringLessThanOrEqualFunction());
  +     }
  +     else
  +     {
  +             assert(false);
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
  +bool
  +greaterThanNodeSet(
  +                     const XObject&                  theLHS,
  +                     const XObject&                  theRHS,
  +                     XObject::eObjectType    theRHSType,
  +                     XPathSupport*                   theXPathSupport)
  +{
  +     bool    theResult = false;
  +
  +     XPathSupport* const             theSupport = theXPathSupport != 0 ?
  +                                                             theXPathSupport 
:
  +                                                             
theRHS.getSupport();
  +
  +     if(theRHSType == XObject::eTypeNodeSet)
  +     {
  +             // Compare as node sets...
  +             theResult = doCompareNodeSets(
  +                             theLHS.nodeset(),
  +                             theRHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             DOMStringGreaterThanFunction());
  +
  +     }
  +     else if(theRHSType == XObject::eTypeBoolean)
  +     {
  +       // From http://www.w3.org/TR/xpath: 
  +       // If one object to be compared is a node-set and the other is a 
boolean, 
  +       // then the comparison will be true if and only if the result of 
  +       // performing the comparison on the boolean and on the result of 
  +       // converting the node-set to a boolean using the boolean function 
  +       // is true.
  +             const double    num1 = theLHS.boolean() == true ? 1.0 : 0.0;
  +
  +             theResult = DoubleSupport::greaterThan(num1, theRHS.num());
  +     }
  +     else if(theRHSType == XObject::eTypeNumber)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a number, 
  +             // then the comparison will be true if and only if there is a 
  +             // node in the node-set such that the result of performing the 
  +             // comparison on the number to be compared and on the result of 
  +             // converting the string-value of that node to a number using 
  +             // the number function is true. 
  +
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getNumberFromNodeFunction(theSupport),
  +                             theRHS.num(),
  +                             DoubleSupport::greaterThanFunction());
  +     }
  +     else if(theRHSType == XObject::eTypeResultTreeFrag)
  +     {
  +             // hmmm... 
  +             const double    theRHSNumber = theRHS.num();
  +
  +             if(DoubleSupport::isNaN(theRHSNumber) == false)
  +             {
  +                     // Compare as number...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getNumberFromNodeFunction(theSupport),
  +                                     theRHS.num(),
  +                                     DoubleSupport::greaterThanFunction());
  +             }
  +             else
  +             {
  +                     // Compare as string...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getStringFromNodeFunction(theSupport),
  +                                     theRHS.str(),
  +                                     DOMStringGreaterThanFunction());
  +             }
  +     }
  +     else if(theRHSType == XObject::eTypeString)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a 
  +             // string, then the comparison will be true if and only if 
there 
  +             // is a node in the node-set such that the result of performing 
  +             // the comparison on the string-value of the node and the other 
  +             // string is true. 
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             theRHS.str(),
  +                             DOMStringGreaterThanFunction());
  +     }
  +     else
  +     {
  +             assert(false);
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
  +bool
  +greaterThanOrEqualNodeSet(
  +                     const XObject&                  theLHS,
  +                     const XObject&                  theRHS,
  +                     XObject::eObjectType    theRHSType,
  +                     XPathSupport*                   theXPathSupport)
  +{
  +     bool    theResult = false;
  +
  +     XPathSupport* const             theSupport = theXPathSupport != 0 ?
  +                                                             theXPathSupport 
:
  +                                                             
theRHS.getSupport();
  +
  +     if(theRHSType == XObject::eTypeNodeSet)
  +     {
  +             // Compare as node sets...
  +             theResult = doCompareNodeSets(
  +                             theLHS.nodeset(),
  +                             theRHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             DOMStringGreaterThanOrEqualFunction());
  +
  +     }
  +     else if(theRHSType == XObject::eTypeBoolean)
  +     {
  +       // From http://www.w3.org/TR/xpath: 
  +       // If one object to be compared is a node-set and the other is a 
boolean, 
  +       // then the comparison will be true if and only if the result of 
  +       // performing the comparison on the boolean and on the result of 
  +       // converting the node-set to a boolean using the boolean function 
  +       // is true.
  +             const double    num1 = theLHS.boolean() == true ? 1.0 : 0.0;
  +
  +             theResult = DoubleSupport::greaterThanOrEqual(num1, 
theRHS.num());
  +     }
  +     else if(theRHSType == XObject::eTypeNumber)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a number, 
  +             // then the comparison will be true if and only if there is a 
  +             // node in the node-set such that the result of performing the 
  +             // comparison on the number to be compared and on the result of 
  +             // converting the string-value of that node to a number using 
  +             // the number function is true. 
  +
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getNumberFromNodeFunction(theSupport),
  +                             theRHS.num(),
  +                             DoubleSupport::greaterThanOrEqualFunction());
  +     }
  +     else if(theRHSType == XObject::eTypeResultTreeFrag)
  +     {
  +             // hmmm... 
  +             const double    theRHSNumber = theRHS.num();
  +
  +             if(DoubleSupport::isNaN(theRHSNumber) == false)
  +             {
  +                     // Compare as number...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getNumberFromNodeFunction(theSupport),
  +                                     theRHS.num(),
  +                                     
DoubleSupport::greaterThanOrEqualFunction());
  +             }
  +             else
  +             {
  +                     // Compare as string...
  +                     theResult = doCompare(
  +                                     theLHS.nodeset(),
  +                                     getStringFromNodeFunction(theSupport),
  +                                     theRHS.str(),
  +                                     DOMStringGreaterThanOrEqualFunction());
  +             }
  +     }
  +     else if(theRHSType == XObject::eTypeString)
  +     {
  +             // From http://www.w3.org/TR/xpath: 
  +             // If one object to be compared is a node-set and the other is 
a 
  +             // string, then the comparison will be true if and only if 
there 
  +             // is a node in the node-set such that the result of performing 
  +             // the comparison on the string-value of the node and the other 
  +             // string is true. 
  +             theResult = doCompare(
  +                             theLHS.nodeset(),
  +                             getStringFromNodeFunction(theSupport),
  +                             theRHS.str(),
  +                             DOMStringGreaterThanOrEqualFunction());
  +     }
  +     else
  +     {
  +             assert(false);
  +     }
  +
  +     return theResult;
  +}
  +
  +
  +
  +bool
  +XObject::equals(const XObject&       theRHS) const
  +{
  +     if (this == &theRHS)
  +     {
  +             return true;
  +     }
  +     else
  +     {
  +             const eObjectType       theLHSType = getType();
  +
  +             if (theLHSType == eTypeUnknown)
  +             {
  +                     return this == &theRHS ? true : false;
  +             }
  +             else if (theLHSType == eTypeNull)
  +             {
  +                     return theRHS.getType() == eTypeNull ? true : false;
  +             }
  +             else if (theLHSType == eTypeNodeSet)
  +             {
  +                     return equalNodeSet(*this, theRHS, theRHS.getType(), 
m_support);
  +             }
  +             else if (theRHS.getType() == eTypeNodeSet)
  +             {
  +                     return equalNodeSet(theRHS, *this, theLHSType, 
m_support);
  +             }
  +             else
  +             {
  +                     const eObjectType       theRHSType = theRHS.getType();
  +
  +                     if (theLHSType == eTypeBoolean || theLHSType == 
eTypeBoolean)
  +                     {
  +                             return boolean() == theRHS.boolean();
  +                     }
  +                     else if (theLHSType == eTypeNumber || theLHSType == 
eTypeNumber)
  +                     {
  +                             return DoubleSupport::equal(num(), 
theRHS.num());
  +                     }
  +                     else
  +                     {
  +                             return ::equals(str(), theRHS.str());
  +                     }
  +             }
  +     }
  +}
  +
  +
  +
  +bool
  +XObject::notEquals(const XObject&    theRHS) const
  +{
  +     if (this == &theRHS)
  +     {
  +             return false;
  +     }
  +     else
  +     {
  +             const eObjectType       theLHSType = getType();
  +
  +             if (theLHSType == eTypeUnknown)
  +             {
  +                     return this == &theRHS ? false : true;
  +             }
  +             else if (theLHSType == eTypeNull)
  +             {
  +                     return theRHS.getType() == eTypeNull ? false : true;
  +             }
  +             else if (theLHSType == eTypeNodeSet)
  +             {
  +                     return notEqualNodeSet(*this, theRHS, theRHS.getType(), 
m_support);
  +             }
  +             else if (theRHS.getType() == eTypeNodeSet)
  +             {
  +                     return notEqualNodeSet(theRHS, *this, theLHSType, 
m_support);
  +             }
  +             else
  +             {
  +                     const eObjectType       theRHSType = theRHS.getType();
  +
  +                     if (theLHSType == eTypeBoolean || theLHSType == 
eTypeBoolean)
  +                     {
  +                             return boolean() != theRHS.boolean();
  +                     }
  +                     else if (theLHSType == eTypeNumber || theLHSType == 
eTypeNumber)
  +                     {
  +                             return DoubleSupport::notEqual(num(), 
theRHS.num());
  +                     }
  +                     else
  +                     {
  +                             return !::equals(str(), theRHS.str());
  +                     }
  +             }
  +     }
  +}
  +
  +
  +
  +bool
  +XObject::lessThan(const XObject&     theRHS) const
  +{
  +     if (this == &theRHS)
  +     {
  +             return false;
  +     }
  +     else
  +     {
  +             const eObjectType       theLHSType = getType();
  +
  +             if (theLHSType == eTypeNull || theLHSType == eTypeUnknown)
  +             {
  +                     return false;
  +             }
  +             else if (theLHSType == eTypeNodeSet)
  +             {
  +                     return lessThanNodeSet(*this, theRHS, theRHS.getType(), 
m_support);
  +             }
  +             else if (theRHS.getType() == eTypeNodeSet)
  +             {
  +                     return greaterThanOrEqualNodeSet(theRHS, *this, 
theLHSType, theRHS.getSupport());
  +             }
  +             else
  +             {
  +                     return DoubleSupport::lessThan(num(), theRHS.num());
  +             }
  +     }
  +}
  +
  +
  +
  +bool
  +XObject::lessThanOrEqual(const XObject&      theRHS) const
  +{
  +     if (this == &theRHS)
  +     {
  +             return false;
  +     }
  +     else
  +     {
  +             const eObjectType       theLHSType = getType();
  +
  +             if (theLHSType == eTypeNull || theLHSType == eTypeUnknown)
  +             {
  +                     return false;
  +             }
  +             else if (theLHSType == eTypeNodeSet)
  +             {
  +                     return lessThanOrEqualNodeSet(*this, theRHS, 
theRHS.getType(), m_support);
  +             }
  +             else if (theRHS.getType() == eTypeNodeSet)
  +             {
  +                     return greaterThanNodeSet(theRHS, *this, theLHSType, 
theRHS.getSupport());
  +             }
  +             else
  +             {
  +                     return DoubleSupport::lessThanOrEqual(num(), 
theRHS.num());
  +             }
  +     }
  +}
  +
  +
  +
  +bool
  +XObject::greaterThan(const XObject&  theRHS) const
  +{
  +     if (this == &theRHS)
  +     {
  +             return false;
  +     }
  +     else
  +     {
  +             const eObjectType       theLHSType = getType();
  +
  +             if (theLHSType == eTypeNull || theLHSType == eTypeUnknown)
  +             {
  +                     return false;
  +             }
  +             else if (theLHSType == eTypeNodeSet)
  +             {
  +                     return greaterThanNodeSet(*this, theRHS, 
theRHS.getType(), m_support);
  +             }
  +             else if (theRHS.getType() == eTypeNodeSet)
  +             {
  +                     return lessThanOrEqualNodeSet(theRHS, *this, 
theLHSType, theRHS.getSupport());
  +             }
  +             else
  +             {
  +                     return DoubleSupport::greaterThan(num(), theRHS.num());
  +             }
  +     }
  +}
  +
  +
  +
  +bool
  +XObject::greaterThanOrEqual(const XObject&   theRHS) const
  +{
  +     if (this == &theRHS)
  +     {
  +             return false;
  +     }
  +     else
  +     {
  +             const eObjectType       theLHSType = getType();
  +
  +             if (theLHSType == eTypeNull || theLHSType == eTypeUnknown)
  +             {
  +                     return false;
  +             }
  +             else if (theLHSType == eTypeNodeSet)
  +             {
  +                     return greaterThanOrEqualNodeSet(*this, theRHS, 
theRHS.getType(), m_support);
  +             }
  +             else if (theRHS.getType() == eTypeNodeSet)
  +             {
  +                     return lessThanNodeSet(theRHS, *this, theLHSType, 
theRHS.getSupport());
  +             }
  +             else
  +             {
  +                     return DoubleSupport::greaterThanOrEqual(num(), 
theRHS.num());
  +             }
        }
   }
  
  
  
  1.5       +128 -4    xml-xalan/c/src/XPath/XObject.hpp
  
  Index: XObject.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XObject.hpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XObject.hpp       2000/04/11 14:46:14     1.4
  +++ XObject.hpp       2000/05/03 21:21:15     1.5
  @@ -76,6 +76,7 @@
   class NodeRefListBase;
   class ResultTreeFragBase;
   class XObjectTypeCallback;
  +class XPathSupport;
   class XPathEnvSupport;
   
   
  @@ -93,7 +94,9 @@
         * @param envSupport XPath environment support class instance
         */
        explicit
  -     XObject(XPathEnvSupport*        envSupport = 0);
  +     XObject(
  +                     XPathEnvSupport*        envSupport,
  +                     XPathSupport*           support);
   
        XObject(const XObject&  source);
   
  @@ -192,10 +195,57 @@
         * @param theRHS object to compare
         * @return true if they are equal
         */
  -     virtual bool
  -     equals(const XObject&   theRHS) const = 0;
  +     bool
  +     equals(const XObject&   theRHS) const;
  +
  +     /**
  +      * Tell if two objects are functionally not equal.
  +      *
  +      * @param theRHS object to compare
  +      * @return true if they are equal
  +      */
  +     bool
  +     notEquals(const XObject&        theRHS) const;
   
        /**
  +      * Tell if one object is less than the other.
  +      *
  +      * @param theRHS object to compare
  +      * @return true if they are equal
  +      */
  +     bool
  +     lessThan(const XObject&         theRHS) const;
  +
  +     /**
  +      * Tell if one object is less than or equal
  +      * the other.
  +      *
  +      * @param theRHS object to compare
  +      * @return true if they are equal
  +      */
  +     bool
  +     lessThanOrEqual(const XObject&  theRHS) const;
  +
  +     /**
  +      * Tell if one object is greater than the other.
  +      *
  +      * @param theRHS object to compare
  +      * @return true if they are equal
  +      */
  +     bool
  +     greaterThan(const XObject&      theRHS) const;
  +
  +     /**
  +      * Tell if one object is greater than or equal
  +      * the other.
  +      *
  +      * @param theRHS object to compare
  +      * @return true if they are equal
  +      */
  +     bool
  +     greaterThanOrEqual(const XObject&       theRHS) const;
  +
  +     /**
         * Enumeration of possible object types
         */
        enum    eObjectType { eTypeNull = -1,
  @@ -215,6 +265,18 @@
        virtual eObjectType
        getType() const = 0;
   
  +     XPathEnvSupport*
  +     getEnvSupport() const
  +     {
  +             return m_envSupport;
  +     }
  +
  +     XPathSupport*
  +     getSupport() const
  +     {
  +             return m_support;
  +     }
  +
   protected:
   
        virtual
  @@ -227,15 +289,77 @@
        virtual void
        error(const XalanDOMString&             msg) const;
   
  -     // Data member...
  +     // Data members...
        XPathEnvSupport* const  m_envSupport;
   
  +     XPathSupport* const             m_support;
  +
   private:
   
        // Not implemented...
        XObject&
        operator=(const XObject&);
   };
  +
  +
  +
  +inline bool
  +operator==(
  +                     const XObject&  theLHS,
  +                     const XObject&  theRHS)
  +{
  +     return theLHS.equals(theRHS);
  +}
  +
  +
  +
  +inline bool
  +operator!=(
  +                     const XObject&  theLHS,
  +                     const XObject&  theRHS)
  +{
  +     return theLHS.notEquals(theRHS);
  +}
  +
  +
  +
  +inline bool
  +operator<(
  +                     const XObject&  theLHS,
  +                     const XObject&  theRHS)
  +{
  +     return theLHS.lessThan(theRHS);
  +}
  +
  +
  +
  +inline bool
  +operator<=(
  +                     const XObject&  theLHS,
  +                     const XObject&  theRHS)
  +{
  +     return theLHS.lessThanOrEqual(theRHS);
  +}
  +
  +
  +
  +inline bool
  +operator>(
  +                     const XObject&  theLHS,
  +                     const XObject&  theRHS)
  +{
  +     return theLHS.greaterThan(theRHS);
  +}
  +
  +
  +
  +inline bool
  +operator>=(
  +                     const XObject&  theLHS,
  +                     const XObject&  theRHS)
  +{
  +     return theLHS.greaterThanOrEqual(theRHS);
  +}
   
   
   
  
  
  
  1.7       +3 -3      xml-xalan/c/src/XPath/XObjectFactoryDefault.cpp
  
  Index: XObjectFactoryDefault.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XObjectFactoryDefault.cpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- XObjectFactoryDefault.cpp 2000/04/11 14:46:15     1.6
  +++ XObjectFactoryDefault.cpp 2000/05/03 21:21:15     1.7
  @@ -159,7 +159,7 @@
        }
        else
        {
  -             XBoolean* const         theBoolean = new XBoolean(m_envSupport, 
theValue);
  +             XBoolean* const         theBoolean = new XBoolean(m_envSupport, 
m_support, theValue);
   
                m_xobjects.insert(theBoolean);
   
  @@ -254,7 +254,7 @@
                        double  theValue,
                        bool    /* fOptimize */)
   {
  -     XNumber*        theXNumber = new XNumber(m_envSupport, theValue);
  +     XNumber*        theXNumber = new XNumber(m_envSupport, m_support, 
theValue);
   
        m_xobjects.insert(theXNumber);
   
  @@ -290,7 +290,7 @@
                        const XalanDOMString&   theValue,
                        bool                                    /* fOptimize */)
   {
  -     XUnknown* const theXUnknown = new XUnknown(m_envSupport, theValue);
  +     XUnknown* const theXUnknown = new XUnknown(m_envSupport, m_support, 
theValue);
   
        m_xobjects.insert(theXUnknown);
   
  
  
  
  1.15      +18 -86    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.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- XPath.cpp 2000/05/01 15:11:42     1.14
  +++ XPath.cpp 2000/05/03 21:21:16     1.15
  @@ -750,7 +750,7 @@
        XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
        assert(expr2 != 0);
   
  -     return 
executionContext.getXObjectFactory().createBoolean(!expr1->equals(*expr2));
  +     return executionContext.getXObjectFactory().createBoolean(*expr1 != 
*expr2);
   }
   
   
  @@ -771,7 +771,7 @@
        XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
        assert(expr2 != 0);
   
  -     return 
executionContext.getXObjectFactory().createBoolean(expr1->equals(*expr2));
  +     return executionContext.getXObjectFactory().createBoolean(*expr1 == 
*expr2);
   }
   
   
  @@ -782,34 +782,17 @@
                        int                                             opPos,
                        XPathExecutionContext&  executionContext) const
   {
  -     bool    fResult = false;
  -
        opPos += 2;
   
        XObject* const  expr1 = executeMore(context, opPos, executionContext);
        assert(expr1 != 0);
   
  -     const double    expr1Value = expr1->num();
  +     const int               expr2Pos = 
m_expression.getNextOpCodePosition(opPos);
   
  -     if (DoubleSupport::isNaN(expr1Value) == false)
  -     {
  -             const int               expr2Pos = 
m_expression.getNextOpCodePosition(opPos);
  -
  -             XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
  -             assert(expr2 != 0);
  -
  -             const double    expr2Value = expr2->num();
  -
  -             if (DoubleSupport::isNaN(expr2Value) == false)
  -             {
  -                     if (expr1Value <= expr2Value)
  -                     {
  -                             fResult = true;
  -                     }
  -             }
  -     }
  +     XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
  +     assert(expr2 != 0);
   
  -     return executionContext.getXObjectFactory().createBoolean(fResult);
  +     return executionContext.getXObjectFactory().createBoolean(*expr1 <= 
*expr2);
   }
   
   
  @@ -820,34 +803,17 @@
                        int                                             opPos,
                        XPathExecutionContext&  executionContext) const
   {
  -     bool    fResult = false;
  -
        opPos += 2;
   
        XObject* const  expr1 = executeMore(context, opPos, executionContext);
        assert(expr1 != 0);
   
  -     const double    expr1Value = expr1->num();
  +     const int               expr2Pos = 
m_expression.getNextOpCodePosition(opPos);
   
  -     if (DoubleSupport::isNaN(expr1Value) == false)
  -     {
  -             const int               expr2Pos = 
m_expression.getNextOpCodePosition(opPos);
  -
  -             XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
  -             assert(expr2 != 0);
  -
  -             const double    expr2Value = expr2->num();
  -
  -             if (DoubleSupport::isNaN(expr2Value) == false)
  -             {
  -                     if (expr1Value < expr2Value)
  -                     {
  -                             fResult = true;
  -                     }
  -             }
  -     }
  +     XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
  +     assert(expr2 != 0);
   
  -     return executionContext.getXObjectFactory().createBoolean(fResult);
  +     return executionContext.getXObjectFactory().createBoolean(*expr1 < 
*expr2);
   }
   
   
  @@ -858,34 +824,17 @@
                        int                                             opPos,
                        XPathExecutionContext&  executionContext) const
   {
  -     bool    fResult = false;
  -
        opPos += 2;
   
        XObject* const  expr1 = executeMore(context, opPos, executionContext);
        assert(expr1 != 0);
   
  -     const double    expr1Value = expr1->num();
  +     const int               expr2Pos = 
m_expression.getNextOpCodePosition(opPos);
   
  -     if (DoubleSupport::isNaN(expr1Value) == false)
  -     {
  -             const int               expr2Pos = 
m_expression.getNextOpCodePosition(opPos);
  -
  -             XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
  -             assert(expr2 != 0);
  -
  -             const double    expr2Value = expr2->num();
  -
  -             if (DoubleSupport::isNaN(expr2Value) == false)
  -             {
  -                     if (expr1Value >= expr2Value)
  -                     {
  -                             fResult = true;
  -                     }
  -             }
  -     }
  +     XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
  +     assert(expr2 != 0);
   
  -     return executionContext.getXObjectFactory().createBoolean(fResult);
  +     return executionContext.getXObjectFactory().createBoolean(*expr1 >= 
*expr2);
   }
   
   
  @@ -896,34 +845,17 @@
                        int                                             opPos,
                        XPathExecutionContext&  executionContext) const
   {
  -     bool    fResult = false;
  -
        opPos += 2;
   
        XObject* const  expr1 = executeMore(context, opPos, executionContext);
        assert(expr1 != 0);
   
  -     const double    expr1Value = expr1->num();
  +     const int               expr2Pos = 
m_expression.getNextOpCodePosition(opPos);
   
  -     if (DoubleSupport::isNaN(expr1Value) == false)
  -     {
  -             const int               expr2Pos = 
m_expression.getNextOpCodePosition(opPos);
  -
  -             XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
  -             assert(expr2 != 0);
  -
  -             const double    expr2Value = expr2->num();
  -
  -             if (DoubleSupport::isNaN(expr2Value) == false)
  -             {
  -                     if (expr1Value > expr2Value)
  -                     {
  -                             fResult = true;
  -                     }
  -             }
  -     }
  +     XObject* const  expr2 = executeMore(context, expr2Pos, 
executionContext);
  +     assert(expr2 != 0);
   
  -     return executionContext.getXObjectFactory().createBoolean(fResult);
  +     return executionContext.getXObjectFactory().createBoolean(*expr1 > 
*expr2);
   }
   
   
  
  
  
  1.6       +35 -0     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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XPathExpression.cpp       2000/04/20 16:32:14     1.5
  +++ XPathExpression.cpp       2000/05/03 21:21:16     1.6
  @@ -205,6 +205,41 @@
   
   
   
  
+XPathExpression::InvalidRelativeTokenPosition::InvalidRelativeTokenPosition(int
              theOffset) :
  +     XPathExpressionException(FormatErrorMessage(theOffset))
  +{
  +}
  +
  +
  +
  
+XPathExpression::InvalidRelativeTokenPosition::~InvalidRelativeTokenPosition()
  +{
  +}
  +
  +
  +
  +XalanDOMString
  +XPathExpression::InvalidRelativeTokenPosition::FormatErrorMessage(int        
theOffset)
  +{
  +#if !defined(XALAN_NO_NAMESPACES)
  +     using std::ostrstream;
  +#endif
  +
  +     ostrstream      theFormatter;
  +
  +     theFormatter << "An invalid offset of "
  +                              << theOffset
  +                              << " was supplied as a relative token 
position."
  +                              << "."
  +                              << '\0';
  +
  +     theFormatter.freeze(false);
  +
  +     return theFormatter.str();
  +}
  +
  +
  +
   XPathExpression::XPathExpression() :
        m_opMap(),
        m_lastOpCodeIndex(0),
  
  
  
  1.5       +53 -1     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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XPathExpression.hpp       2000/04/20 16:32:14     1.4
  +++ XPathExpression.hpp       2000/05/03 21:21:16     1.5
  @@ -712,7 +712,30 @@
                                int             theValue);
        };
   
  +     /**
  +      * Exception class thrown when an invalid token position is encountered
  +      */
  +     class XALAN_XPATH_EXPORT InvalidRelativeTokenPosition : public 
XPathExpressionException
  +     {
  +     public:
  +
  +             /**
  +              * Construct an InvalidRelativeTokenPosition object.
  +              * 
  +              * @param theOffset the offset that caused the problem.
  +              */
  +             InvalidRelativeTokenPosition(int        theOffset);
  +
  +             virtual~
  +             InvalidRelativeTokenPosition();
  +
  +     private:
  +
  +             static XalanDOMString
  +             FormatErrorMessage(int  theOffset);
  +     };
   
  +
   #if defined(XALAN_NO_NAMESPACES)
   #    define XALAN_STD
   #else
  @@ -962,7 +985,6 @@
   
        /**
         * Update the length of an operation code after a node test code.
  -      * $$$: ??
         * 
         * @param theIndex  index in list
         */
  @@ -1109,6 +1131,36 @@
                assert(theToken != 0);
   
                m_tokenQueue.push_back(theToken);
  +     }
  +
  +     /**
  +      * Replace a token in the token queue.
  +      * 
  +      * @param theOffset the offset at which to replace the token.
  +      * @param theToken pointer to new XObject token
  +      * @return a pointer to the old token
  +      */
  +     XObject*
  +     replaceRelativeToken(
  +                     int                     theOffset,
  +                     XObject*        theToken)
  +     {
  +             assert(theToken != 0);
  +
  +             const int       thePosition =
  +                     static_cast<int>(m_currentPosition) + theOffset;
  +
  +             if (thePosition < 0 ||
  +                     thePosition >= static_cast<int>(tokenQueueSize()))
  +             {
  +                     throw InvalidRelativeTokenPosition(theOffset);
  +             }
  +
  +             XObject* const  theOldToken = m_tokenQueue[thePosition];
  +
  +             m_tokenQueue[thePosition] = theToken;
  +
  +             return theOldToken;
        }
   
        /**
  
  
  
  1.9       +46 -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.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XPathProcessorImpl.cpp    2000/05/01 15:11:42     1.8
  +++ XPathProcessorImpl.cpp    2000/05/03 21:21:16     1.9
  @@ -1813,23 +1813,29 @@
        assert(m_expression != 0);
   
        const int       opPos = m_expression->opCodeMapLength();
  -     
  +
  +     int                     axisType = 0;
  +
        // The next blocks guarantee that a FROM_XXX will be added.
        if(lookahead(XALAN_STATIC_UCODE_STRING("::"), 1) == true)
        {
  -             AxisName();
  +             axisType = AxisName();
   
                nextToken();
                nextToken();
        }
        else if(tokenIs('@') == true)
        {
  +             axisType = XPathExpression::eFROM_ATTRIBUTES;
  +
                m_expression->appendOpCode(XPathExpression::eFROM_ATTRIBUTES);
   
                nextToken();
        }
        else if(tokenIs('/') == true)
        {
  +             axisType = XPathExpression::eFROM_DESCENDANTS_OR_SELF;
  +
                // Have to fix up for patterns such as '//@foo' or 
'//attribute::foo',
                // which translate to 
'descendant-or-self::node()/attribute::foo'.
                // notice I leave the '/' on the queue, so the next will be 
processed 
  @@ -1858,10 +1864,12 @@
        }
        else
        {
  +             axisType = XPathExpression::eFROM_CHILDREN;
  +
                m_expression->appendOpCode(XPathExpression::eFROM_CHILDREN);
        }
   
  -     NodeTest();
  +     NodeTest(axisType);
   
        // Tell how long the step is without the predicate
        m_expression->updateOpCodeLengthAfterNodeTest(opPos);
  @@ -1869,7 +1877,7 @@
   
   
   
  -void
  +int
   XPathProcessorImpl::AxisName()
   {
        assert(m_xpath != 0);
  @@ -1885,14 +1893,16 @@
        }
        else
        {
  -             m_expression->appendOpCode((*i).second);
  +             m_expression->appendOpCode(i->second);
        }
  +
  +     return i->second;
   }
   
   
   
   void
  -XPathProcessorImpl::NodeTest()
  +XPathProcessorImpl::NodeTest(int     axisType)
   {
        assert(m_xpath != 0);
        assert(m_expression != 0);
  @@ -1939,6 +1949,21 @@
                        }
                        else
                        {
  +                             if (axisType == 
XPathExpression::eFROM_NAMESPACE)
  +                             {
  +                                     const XObject* const    theToken =
  +                                             
m_expression->getRelativeToken(-1);
  +
  +                                     const XalanDOMString    theString = 
theToken->str();
  +
  +                                     const XalanDOMString    theNamespace =
  +                                             
m_prefixResolver->getNamespaceForPrefix(theString);
  +
  +                                     m_expression->replaceRelativeToken(
  +                                                                     -1,
  +                                                                     
m_xobjectFactory->createString(theNamespace));
  +                             }
  +
                                m_expression->pushCurrentTokenOnOpCodeMap();
                        }
   
  @@ -2211,23 +2236,33 @@
   
        const int       opPos = m_expression->opCodeMapLength();
   
  +     int                     axisType = 0;
  +
        int                     matchTypePos = -1;
   
        // The next blocks guarantee that a MATCH_XXX will be added.
        if(tokenIs('@') == true)
        {
  +             axisType = XPathExpression::eMATCH_ATTRIBUTE;
  +
                m_expression->appendOpCode(XPathExpression::eMATCH_ATTRIBUTE);
   
                nextToken();
        }
        else if(lookahead(XALAN_STATIC_UCODE_STRING("::"), 1) == true)
        {
  +             // $$$ To Do: Perhaps these strings should be in the
  +             // axis table?
                if(tokenIs(XALAN_STATIC_UCODE_STRING("attribute")) == true)
                {
  +                     axisType = XPathExpression::eMATCH_ATTRIBUTE;
  +
                        
m_expression->appendOpCode(XPathExpression::eMATCH_ATTRIBUTE);
                }
                else if(tokenIs(XALAN_STATIC_UCODE_STRING("child")) == true)
                {
  +                     axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;
  +
                        
m_expression->appendOpCode(XPathExpression::eMATCH_IMMEDIATE_ANCESTOR);
                }
                else
  @@ -2240,6 +2275,8 @@
        }
        else if(tokenIs('/') == true)
        {
  +             axisType = XPathExpression::eMATCH_ANY_ANCESTOR;
  +
                
m_expression->appendOpCode(XPathExpression::eMATCH_ANY_ANCESTOR);
   
                nextToken();
  @@ -2253,6 +2290,8 @@
   
                matchTypePos = m_expression->opCodeMapLength();
   
  +             axisType = XPathExpression::eMATCH_IMMEDIATE_ANCESTOR;
  +
                
m_expression->appendOpCode(XPathExpression::eMATCH_IMMEDIATE_ANCESTOR);
        }
   
  @@ -2260,7 +2299,7 @@
        // This will be replaced by the right value.
        m_expression->appendOpCode(XPathExpression::eENDOP);
   
  -     NodeTest();
  +     NodeTest(axisType);
   
        m_expression->updateOpCodeLengthAfterNodeTest(opPos);
   
  
  
  
  1.5       +2 -2      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.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XPathProcessorImpl.hpp    2000/04/11 14:46:21     1.4
  +++ XPathProcessorImpl.hpp    2000/05/03 21:21:17     1.5
  @@ -615,7 +615,7 @@
         Basis  ::=    AxisName '::' NodeTest   
         | AbbreviatedBasis  
         */
  -     void
  +     int
        AxisName();
     
        /**
  @@ -625,7 +625,7 @@
         | 'processing-instruction' '(' Literal ')' 
         */
        void
  -     NodeTest();
  +     NodeTest(int    axisType);
   
        /**
         * 
--------------------------------------------------------------------------------
  
  
  
  1.4       +5 -7      xml-xalan/c/src/XPath/XResultTreeFrag.cpp
  
  Index: XResultTreeFrag.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XResultTreeFrag.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XResultTreeFrag.cpp       2000/04/20 16:30:20     1.3
  +++ XResultTreeFrag.cpp       2000/05/03 21:21:17     1.4
  @@ -80,9 +80,8 @@
                        XPathSupport&                           support,
                        const ResultTreeFragBase&       val,
                        bool                                            
deepClone) :
  -     XObject(&envSupport),
  +     XObject(&envSupport, &support),
        NodeRefListBase(),
  -     m_support(support),
        m_value(val.clone(deepClone))
   {
   }
  @@ -94,7 +93,6 @@
                        bool                                    deepClone) :
        XObject(source),
        NodeRefListBase(source),
  -     m_support(source.m_support),
        m_value(source.m_value->clone(deepClone))
   {
   }
  @@ -126,7 +124,7 @@
   double
   XResultTreeFrag::num() const
   {
  -     const XalanDOMString    theValue = 
m_support.getNodeData(*m_value.get());
  +     const XalanDOMString    theValue = 
m_support->getNodeData(*m_value.get());
   
        return DOMStringToDouble(theValue);
   }
  @@ -147,7 +145,7 @@
                        const XalanText* const  theTextNode =
                                static_cast<const XalanText*>(theCurrentNode);
   
  -                     if (m_support.isIgnorableWhitespace(*theTextNode) ||
  +                     if (m_support->isIgnorableWhitespace(*theTextNode) ||
                            length(trim(theTextNode->getData())) == 0)
                        {
                                continue;
  @@ -168,7 +166,7 @@
   XalanDOMString
   XResultTreeFrag::str() const
   {
  -     return m_support.getNodeData(*m_value.get());
  +     return m_support->getNodeData(*m_value.get());
   }
   
   
  @@ -313,5 +311,5 @@
   XPathSupport*
   XResultTreeFrag::getSupport() const
   {
  -     return &m_support;
  +     return m_support;
   }
  
  
  
  1.5       +0 -2      xml-xalan/c/src/XPath/XResultTreeFrag.hpp
  
  Index: XResultTreeFrag.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XResultTreeFrag.hpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XResultTreeFrag.hpp       2000/04/20 16:30:20     1.4
  +++ XResultTreeFrag.hpp       2000/05/03 21:21:17     1.5
  @@ -170,8 +170,6 @@
        virtual XPathSupport*
        getSupport() const;
   
  -     XPathSupport&                                           m_support;
  -
   #if defined(XALAN_NO_NAMESPACES)
        auto_ptr<ResultTreeFragBase>            m_value;
   #else
  
  
  
  1.4       +7 -13     xml-xalan/c/src/XPath/XString.cpp
  
  Index: XString.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XString.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XString.cpp       2000/04/20 16:30:20     1.3
  +++ XString.cpp       2000/05/03 21:21:18     1.4
  @@ -78,8 +78,7 @@
                        XPathEnvSupport&                envSupport,
                        XPathSupport&                   support,
                        const XalanDOMString&   val) :
  -     XObject(&envSupport),
  -     m_support(support),
  +     XObject(&envSupport, &support),
        m_value(val),
        m_resultTreeFrag(0)
   {
  @@ -89,7 +88,6 @@
   
   XString::XString(const XString&      source) :
        XObject(source),
  -     m_support(source.m_support),
        m_value(source.m_value),
        m_resultTreeFrag(source.m_resultTreeFrag.get() == 0 ?
                                                0 :
  @@ -148,6 +146,7 @@
   const ResultTreeFragBase&
   XString::rtree() const
   {
  +     assert(m_support != 0);
        assert(m_envSupport != 0);
   
        if (m_resultTreeFrag.get() == 0)
  @@ -158,7 +157,7 @@
   
                ResultTreeFrag* const   theFrag =
                        new ResultTreeFrag(*theFactory,
  -                                                        m_support);
  +                                                        *m_support);
   
                XalanNode* const        textNode =
                        theFactory->createTextNode(str());
  @@ -197,6 +196,9 @@
   ResultTreeFragBase&
   XString::rtree()
   {
  +     assert(m_support != 0);
  +     assert(m_envSupport != 0);
  +
        if (m_resultTreeFrag.get() == 0)
        {
                XalanDocument* const    theFactory =
  @@ -205,7 +207,7 @@
   
                ResultTreeFrag* const   theFrag =
                        new ResultTreeFrag(*theFactory,
  -                                                        m_support);
  +                                                        *m_support);
   
                XalanNode* const        textNode =
                        theFactory->createTextNode(str());
  @@ -291,12 +293,4 @@
   {
        theCallbackObject.String(*this,
                                                         str());
  -}
  -
  -
  -
  -bool
  -XString::equals(const XObject&       theRHS) const
  -{
  -     return ::equals(m_value, theRHS.str());
   }
  
  
  
  1.5       +0 -5      xml-xalan/c/src/XPath/XString.hpp
  
  Index: XString.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XString.hpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XString.hpp       2000/04/20 16:30:20     1.4
  +++ XString.hpp       2000/05/03 21:21:18     1.5
  @@ -143,12 +143,7 @@
        virtual void
        ProcessXObjectTypeCallback(XObjectTypeCallback&         
theCallbackObject) const;
   
  -     virtual bool
  -     equals(const XObject&   theRHS) const;
  -
   private:
  -
  -     XPathSupport&                                                           
m_support;
   
        const XalanDOMString                                            m_value;
   
  
  
  
  1.3       +2 -1      xml-xalan/c/src/XPath/XUnknown.cpp
  
  Index: XUnknown.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XUnknown.cpp,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- XUnknown.cpp      2000/04/11 14:46:24     1.2
  +++ XUnknown.cpp      2000/05/03 21:21:18     1.3
  @@ -69,8 +69,9 @@
   
   XUnknown::XUnknown(
                        XPathEnvSupport&                envSupport,
  +                     XPathSupport&                   support,
                        const XalanDOMString&   name) :
  -     XObject(&envSupport),
  +     XObject(&envSupport, &support),
        m_name(name)
   {
   }
  
  
  
  1.4       +1 -0      xml-xalan/c/src/XPath/XUnknown.hpp
  
  Index: XUnknown.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XPath/XUnknown.hpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- XUnknown.hpp      2000/04/11 14:46:24     1.3
  +++ XUnknown.hpp      2000/05/03 21:21:18     1.4
  @@ -85,6 +85,7 @@
         */
        XUnknown(
                        XPathEnvSupport&                envSupport,
  +                     XPathSupport&                   support,
                        const XalanDOMString&   name);
   
        XUnknown(const XUnknown&        source);
  
  
  

Reply via email to