You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by db...@locus.apache.org on 2000/07/21 21:53:05 UTC

cvs commit: xml-xalan/c/src/XSLT ElemVariable.cpp ElemVariable.hpp StackEntry.cpp StackEntry.hpp Stylesheet.cpp Stylesheet.hpp StylesheetExecutionContext.cpp StylesheetExecutionContext.hpp StylesheetExecutionContextDefault.cpp StylesheetExecutionContextDefault.hpp StylesheetRoot.cpp VariablesStack.cpp XSLTEngineImpl.cpp XSLTEngineImpl.hpp XSLTProcessor.hpp XSLTProcessorEnvSupport.hpp XSLTProcessorEnvSupportDefault.cpp XSLTProcessorEnvSupportDefault.hpp XSLTResultTarget.cpp XSLTResultTarget.hpp

dbertoni    00/07/21 12:53:04

  Modified:    c/src/XSLT ElemVariable.cpp ElemVariable.hpp StackEntry.cpp
                        StackEntry.hpp Stylesheet.cpp Stylesheet.hpp
                        StylesheetExecutionContext.cpp
                        StylesheetExecutionContext.hpp
                        StylesheetExecutionContextDefault.cpp
                        StylesheetExecutionContextDefault.hpp
                        StylesheetRoot.cpp VariablesStack.cpp
                        XSLTEngineImpl.cpp XSLTEngineImpl.hpp
                        XSLTProcessor.hpp XSLTProcessorEnvSupport.hpp
                        XSLTProcessorEnvSupportDefault.cpp
                        XSLTProcessorEnvSupportDefault.hpp
                        XSLTResultTarget.cpp XSLTResultTarget.hpp
  Log:
  Performance tuning work.
  
  Revision  Changes    Path
  1.7       +19 -25    xml-xalan/c/src/XSLT/ElemVariable.cpp
  
  Index: ElemVariable.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemVariable.cpp,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- ElemVariable.cpp	2000/05/24 19:38:49	1.6
  +++ ElemVariable.cpp	2000/07/21 19:52:55	1.7
  @@ -155,40 +155,34 @@
   {
   	ElemTemplateElement::execute(executionContext, sourceTree, sourceNode, mode);
   
  -    XObject* const	var = getValue(executionContext, sourceTree, sourceNode);
  -
  -	executionContext.pushVariable(m_qname,
  -								  var,
  -								  getParentNode());
  -}
  -
  -
  -
  -XObject*
  -ElemVariable::getValue(
  -			StylesheetExecutionContext&		executionContext,
  -			XalanNode*						sourceTree, 
  -			XalanNode*						sourceNode) const
  -{
  -	XObject*	var = 0;
  -
   	if(0 != m_selectPattern)
   	{
  -		var = m_selectPattern->execute(sourceNode, *this, executionContext);
  +		executionContext.pushVariable(
  +				m_qname,
  +			    getParentNodeElem(),
  +				*m_selectPattern,
  +				sourceNode,
  +				*this);
   
   		if(0 != executionContext.getTraceListeners())
   		{
   			executionContext.fireSelectEvent(
  -				SelectionEvent(executionContext, sourceNode,
  -					*this, XalanDOMString(XALAN_STATIC_UCODE_STRING("select")), *m_selectPattern, var));
  +				SelectionEvent(
  +					executionContext,
  +					sourceNode,
  +					*this,
  +					XalanDOMString(XALAN_STATIC_UCODE_STRING("select")),
  +					*m_selectPattern,
  +					executionContext.getVariable(m_qname)));
   		}
   	}
   	else
   	{
  -		var = executionContext.createXResultTreeFrag(*this,
  -													 sourceTree,
  -													 sourceNode);
  +		executionContext.pushVariable(
  +				m_qname,
  +			    getParentNodeElem(),
  +				*this,
  +				sourceTree,
  +				sourceNode);
   	}
  -
  -	return var;
   }
  
  
  
  1.5       +6 -6      xml-xalan/c/src/XSLT/ElemVariable.hpp
  
  Index: ElemVariable.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/ElemVariable.hpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- ElemVariable.hpp	2000/04/11 15:09:27	1.4
  +++ ElemVariable.hpp	2000/07/21 19:52:55	1.5
  @@ -58,7 +58,7 @@
   #define XALAN_ELEMVARIABLE_HEADER_GUARD 
   
   /**
  - * $Id: ElemVariable.hpp,v 1.4 2000/04/11 15:09:27 dbertoni Exp $
  + * $Id: ElemVariable.hpp,v 1.5 2000/07/21 19:52:55 dbertoni Exp $
    * 
    * $State: Exp $
    * 
  @@ -119,11 +119,11 @@
   	 * @param sourceTree       input source tree
   	 * @param sourceNode       current context node
   	 */
  -	XObject*
  -	getValue(
  -			StylesheetExecutionContext&		executionContext,
  -			XalanNode*						sourceTree, 
  -			XalanNode*						sourceNode) const;
  +//	XObject*
  +//	getValue(
  +//			StylesheetExecutionContext&		executionContext,
  +//			XalanNode*						sourceTree, 
  +//			XalanNode*						sourceNode) const;
   
   	/**
   	 * Determines if this is a top level variable.
  
  
  
  1.2       +15 -0     xml-xalan/c/src/XSLT/StackEntry.cpp
  
  Index: StackEntry.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/StackEntry.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- StackEntry.cpp	1999/12/18 19:48:04	1.1
  +++ StackEntry.cpp	2000/07/21 19:52:56	1.2
  @@ -58,9 +58,18 @@
   
   
   
  +#if !defined(NDEBUG)
  +unsigned long	StackEntry::s_instanceCount = 0;
  +#endif
  +
  +
  +
   StackEntry::StackEntry(eStackEntryType	theType) :
   	m_type(theType)
   {
  +#if !defined(NDEBUG)
  +	++s_instanceCount;
  +#endif
   }
   
   
  @@ -68,12 +77,18 @@
   StackEntry::StackEntry(const StackEntry&	theSource) :
   	m_type(theSource.m_type)
   {
  +#if !defined(NDEBUG)
  +	++s_instanceCount;
  +#endif
   }
   
   
   
   StackEntry::~StackEntry()
   {
  +#if !defined(NDEBUG)
  +	--s_instanceCount;
  +#endif
   }
   
   
  
  
  
  1.4       +9 -26     xml-xalan/c/src/XSLT/StackEntry.hpp
  
  Index: StackEntry.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/StackEntry.hpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- StackEntry.hpp	2000/05/29 22:46:34	1.3
  +++ StackEntry.hpp	2000/07/21 19:52:56	1.4
  @@ -93,34 +93,13 @@
   		return m_type;
   	}
   
  -	/**
  -	 * Create a copy of this stack entry object.
  -	 * 
  -	 * @return pointer to copy
  -	 */
  -	virtual StackEntry*
  -	clone() const = 0;
  -
  -	/**
  -	 * Compare this stack entry to another
  -	 * 
  -	 * @param rhs the object for comparison
  -	 * @return true if both represent the same value
  -	 */
  -	virtual bool
  -	equals(const StackEntry& rhs) const = 0;
  -
  -	/**
  -	 * Compare this stack entry to another
  -	 * 
  -	 * @param rhs the object for comparison
  -	 * @return true if both represent the same value
  -	 */
  -	bool
  -	operator==(const StackEntry& theRHS) const
  +#if !defined(NDEBUG)
  +	static unsigned long
  +	getInstanceCount()
   	{
  -		return equals(theRHS);
  +		return s_instanceCount;
   	}
  +#endif
   
   
   protected:
  @@ -130,6 +109,10 @@
   	StackEntry(const StackEntry&	theSource);
   
   private:
  +
  +#if !defined(NDEBUG)
  +	static unsigned long	s_instanceCount;
  +#endif
   
   	// Data members...
   	eStackEntryType		m_type;
  
  
  
  1.25      +26 -58    xml-xalan/c/src/XSLT/Stylesheet.cpp
  
  Index: Stylesheet.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/Stylesheet.cpp,v
  retrieving revision 1.24
  retrieving revision 1.25
  diff -u -r1.24 -r1.25
  --- Stylesheet.cpp	2000/07/11 19:54:53	1.24
  +++ Stylesheet.cpp	2000/07/21 19:52:56	1.25
  @@ -119,7 +119,6 @@
   	PrefixResolver(),
   	m_stylesheetRoot(root),
   	m_baseIdent(baseIdentifier),
  -	m_document(),
   	m_key_tables(),
   	m_keyDeclarations(),
   	m_needToBuildKeysTable(false),
  @@ -152,7 +151,7 @@
   	{
   		typedef StylesheetConstructionContext::URLAutoPtrType	URLAutoPtrType;
   
  -		URLAutoPtrType	url = constructionContext.getURLFromString(m_baseIdent);
  +		URLAutoPtrType	url(constructionContext.getURLFromString(m_baseIdent));
   
   		if (url.get() != 0)
   		{
  @@ -584,40 +583,6 @@
   	
   
   
  -XObject*
  -Stylesheet::getTopLevelVariable(
  -			const XalanDOMString&			name,
  -			StylesheetExecutionContext& 	executionContext) const
  -{
  -	XObject*	theResult = executionContext.getTopLevelVariable(name);
  -
  -	if(0 == theResult)
  -	{
  -		const unsigned int	nImports = m_imports.size();
  -
  -		for(unsigned int i = 0; i < nImports; i++)
  -		{
  -			const Stylesheet* const		stylesheet = m_imports[i];
  -			assert(stylesheet != 0);
  -
  -			theResult = stylesheet->getTopLevelVariable(name, executionContext);
  -
  -			if(0 != theResult)
  -			{
  -				break;
  -			}
  -		}
  -	}
  -
  -	if(0 == theResult)
  -	{
  -		executionContext.warn(XalanDOMString("Could not find variable def for: ") + name);
  -	}
  -
  -	return theResult;
  -}
  -
  -
   ElemTemplate*
   Stylesheet::findTemplate(
   			StylesheetExecutionContext& 	executionContext,
  @@ -1120,19 +1085,21 @@
   
   void Stylesheet::pushTopLevelVariables(
   			StylesheetExecutionContext& 	executionContext,
  -			ParamVectorType&				topLevelParams) const
  +			const ParamVectorType&			topLevelParams) const
   {
   //	try
   	{
  -		int i, nImports = m_imports.size();
  -		for(i = 0; i < nImports; i++)
  +		ParamVectorType::size_type			i = 0;
  +		const ParamVectorType::size_type	nImports = m_imports.size();
  +
  +		for(; i < nImports; i++)
   		{
   			const Stylesheet* const stylesheet = m_imports[i];
   
   			stylesheet->pushTopLevelVariables(executionContext, topLevelParams);
   		}
   
  -		const int	nVars = m_topLevelVariables.size();
  +		const ParamVectorType::size_type	nVars = m_topLevelVariables.size();
   
   		for(i = 0; i < nVars; i++)
   		{
  @@ -1145,33 +1112,33 @@
   			{
   				isParam = false;
   
  -				const int	n = topLevelParams.size();
  +				const ParamVectorType::size_type	n = topLevelParams.size();
   
  -				for(int k = 0; k < n; k++)
  +				for(ParamVectorType::size_type k = 0; k < n; k++)
   				{
  -					Arg& a = topLevelParams[k];
  +					const ParamVectorType::value_type&	arg = topLevelParams[k];
   
  -					if(a.getName().equals(var->getName()))
  +					if(arg.getName().equals(var->getName()))
   					{
   						isParam = true;
  -
  -						XObject *pXO = 0;
   
  -						const XalanDOMString& expr = a.getExpression();
  +						XObject* const	theXObject = arg.getXObject();
   
  -						if(length(expr) != 0)
  +						if (theXObject != 0)
   						{
  -							pXO = executionContext.executeXPath(expr,
  -																executionContext.getRootDocument(),
  -																*this);
  -
  -							a.setXObjectPtr(pXO);
  -							a.setExpression(0);
  +							executionContext.pushVariable(arg.getName(),
  +														  theXObject,
  +														  0);
  +						}
  +						else
  +						{
  +							executionContext.pushVariable(arg.getName(),
  +														  0,
  +														  arg.getExpression(),
  +														  executionContext.getRootDocument(),
  +														  *this);
   						}
   
  -						executionContext.pushVariable(a.getName(),
  -													  pXO,
  -													  this);
   						break;
   					}
   				}
  @@ -1179,7 +1146,8 @@
   
   			if (isParam == false)
   			{
  -				XalanDocument* const	doc = executionContext.getRootDocument();
  +				XalanNode* const	doc = executionContext.getRootDocument();
  +				assert(doc != 0);
   
   				var->execute(executionContext,
   							 doc,
  
  
  
  1.17      +21 -38    xml-xalan/c/src/XSLT/Stylesheet.hpp
  
  Index: Stylesheet.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/Stylesheet.hpp,v
  retrieving revision 1.16
  retrieving revision 1.17
  diff -u -r1.16 -r1.17
  --- Stylesheet.hpp	2000/07/11 19:54:53	1.16
  +++ Stylesheet.hpp	2000/07/21 19:52:56	1.17
  @@ -85,8 +85,8 @@
   
   
   
  -#include "Arg.hpp"
  -#include "KeyDeclaration.hpp"
  +#include <XSLT/KeyDeclaration.hpp>
  +#include <XSLT/StylesheetExecutionContext.hpp>
   
   
   
  @@ -103,7 +103,6 @@
   class NodeRefListBase;
   class PrefixResolver;
   class StylesheetConstructionContext;
  -class StylesheetExecutionContext;
   class StylesheetRoot;
   class XMLURL;
   class XObject;
  @@ -127,25 +126,26 @@
   #	define XALAN_STD std::
   #endif
   
  -typedef XALAN_STD map<XalanDOMString, XalanDOMString> PrefixAliasesMapType;
  -typedef XALAN_STD map<XalanDOMString, ExtensionNSHandler*> ExtensionNamespacesMapType;
  -typedef XALAN_STD map<QName, ElemTemplateElement*>	  ElemTemplateElementMapType;
  -typedef XALAN_STD vector<Arg>						  ParamVectorType;
  -typedef XALAN_STD vector<ElemAttributeSet*> 		  AttributeSetMapType;
  -typedef XALAN_STD vector<ElemVariable*> 			  ElemVariableVectorType;
  -typedef XALAN_STD vector<KeyDeclaration>			  KeyDeclarationVectorType;
  -typedef XALAN_STD vector<KeyTable*> 				  KeyTableVectorType;
  -typedef XALAN_STD map<const XalanNode*, KeyTable*>		KeyTablesTableType;
  -typedef XALAN_STD vector<NameSpace> 				  NamespaceVectorType;
  -typedef XALAN_STD vector<NamespaceVectorType>		  NamespacesStackType;
  -typedef XALAN_STD vector<QName> 					  QNameVectorType;
  -typedef XALAN_STD vector<const Stylesheet*>				StylesheetVectorType;
  -typedef XALAN_STD vector<const XMLURL*> 			  URLStackType;
  -typedef XALAN_STD vector<const XPath*>				  XPathVectorType;
  -typedef XALAN_STD vector<ElemDecimalFormat*>			ElemDecimalFormatVectorType;
  +typedef XALAN_STD map<XalanDOMString, XalanDOMString>		PrefixAliasesMapType;
  +typedef XALAN_STD map<XalanDOMString, ExtensionNSHandler*>	ExtensionNamespacesMapType;
  +typedef XALAN_STD map<QName, ElemTemplateElement*>			ElemTemplateElementMapType;
  +typedef XALAN_STD vector<ElemAttributeSet*> 				AttributeSetMapType;
  +typedef XALAN_STD vector<ElemVariable*> 					ElemVariableVectorType;
  +typedef XALAN_STD vector<KeyDeclaration>					KeyDeclarationVectorType;
  +typedef XALAN_STD vector<KeyTable*> 						KeyTableVectorType;
  +typedef XALAN_STD map<const XalanNode*, KeyTable*>			KeyTablesTableType;
  +typedef XALAN_STD vector<NameSpace> 						NamespaceVectorType;
  +typedef XALAN_STD vector<NamespaceVectorType>				NamespacesStackType;
  +typedef XALAN_STD vector<QName> 							QNameVectorType;
  +typedef XALAN_STD vector<const Stylesheet*>					StylesheetVectorType;
  +typedef XALAN_STD vector<const XMLURL*> 					URLStackType;
  +typedef XALAN_STD vector<const XPath*>						XPathVectorType;
  +typedef XALAN_STD vector<ElemDecimalFormat*>				ElemDecimalFormatVectorType;
   
   #undef XALAN_STD
   
  +	typedef StylesheetExecutionContext::ParamVectorType	ParamVectorType;
  +
   	/**
   	 * Constructor for a Stylesheet needs a Document.
   	 * @exception XSLProcessorException thrown if the active ProblemListener and XMLParserLiaison decide 
  @@ -634,18 +634,6 @@
   			StylesheetExecutionContext& 	executionContext) const;
   
   	/**
  -	 * Given the name of a variable, return its corresponding XObject
  -	 *
  -	 * @param name				 name of variable
  -	 * @param executionContext	 current execution context
  -	 * @return pointer to object
  -	 */
  -	virtual XObject*
  -	getTopLevelVariable(
  -			const XalanDOMString&			name,
  -			StylesheetExecutionContext& 	executionContext) const;
  -
  -	/**
   	 * Given a target element, find the template that best matches in the given
   	 * XSL document, according to the rules specified in the xsl draft. 
   	 *
  @@ -935,7 +923,7 @@
   	void
   	pushTopLevelVariables(
   			StylesheetExecutionContext& 	executionContext,
  -			ParamVectorType&				topLevelParams) const;
  +			const ParamVectorType&			topLevelParams) const;
   
   	const XPathVectorType&
   	getWhitespacePreservingElements() const
  @@ -1164,14 +1152,9 @@
   	XPathVectorType 					m_whitespaceStrippingElements;
   
   	/**
  -	 * The root XSL stylesheet.
  -	 */
  -	XalanDocument*						m_document;
  -
  -	/**
   	 * Table of tables of element keys. See KeyTable.
   	 */
  -	mutable KeyTableVectorType			m_key_tables;
  +	KeyTableVectorType					m_key_tables;
   
   	/**
   	 * Table of KeyDeclaration objects, which are set by the 
  
  
  
  1.4       +4 -6      xml-xalan/c/src/XSLT/StylesheetExecutionContext.cpp
  
  Index: StylesheetExecutionContext.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/StylesheetExecutionContext.cpp,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- StylesheetExecutionContext.cpp	2000/05/15 15:57:45	1.3
  +++ StylesheetExecutionContext.cpp	2000/07/21 19:52:56	1.4
  @@ -78,18 +78,16 @@
   
   StylesheetExecutionContext::ParamsPushPop::ParamsPushPop(
   			StylesheetExecutionContext&		executionContext,
  -			const ElemTemplateElement*		contextElement,
  +			const ElemTemplateElement*		/* contextElement */,
   			const ElemTemplateElement&		xslCallTemplateElement,
   			XalanNode*						sourceTree, 
   			XalanNode*						sourceNode,
   			const QName&					mode,
  -			const XalanNode*				targetTemplate) :
  +			const ElemTemplateElement*		targetTemplate) :
   	m_executionContext(executionContext),
   	m_savedStackFrameIndex(executionContext.getCurrentStackFrameIndex())
   {
  -	executionContext.pushContextMarker(
  -			contextElement,
  -			sourceNode);
  +	executionContext.pushContextMarker();
   
   	executionContext.setCurrentStackFrameIndex(m_savedStackFrameIndex);
   
  @@ -107,7 +105,7 @@
   
   StylesheetExecutionContext::ParamsPushPop::~ParamsPushPop()
   {
  -	m_executionContext.popCurrentContext();
  +	m_executionContext.popContextMarker();
   
   	m_executionContext.setCurrentStackFrameIndex(m_savedStackFrameIndex);
   }
  
  
  
  1.23      +142 -42   xml-xalan/c/src/XSLT/StylesheetExecutionContext.hpp
  
  Index: StylesheetExecutionContext.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/StylesheetExecutionContext.hpp,v
  retrieving revision 1.22
  retrieving revision 1.23
  diff -u -r1.22 -r1.23
  --- StylesheetExecutionContext.hpp	2000/07/14 16:57:42	1.22
  +++ StylesheetExecutionContext.hpp	2000/07/21 19:52:56	1.23
  @@ -94,6 +94,11 @@
   
   
   
  +#include <XSLT/TopLevelArg.hpp>
  +
  +
  +
  +
   class ElemTemplateElement;
   class FormatterListener;
   class FormatterToDOM;
  @@ -144,15 +149,6 @@
   	reset() = 0;
   
   	/**
  -	 * Retrieve a top level variable corresponding to name.
  -	 * 
  -	 * @param name name of variable
  -	 * @return pointer to XObject for variable
  -	 */
  -	virtual XObject*
  -	getTopLevelVariable(const XalanDOMString&	theName) const = 0;
  -
  -	/**
   	 * Determine whether conflicts should be reported.
   	 * 
   	 * @return true if conflicts should not be warned
  @@ -161,20 +157,24 @@
   	getQuietConflictWarnings() const = 0;
   
   	/**
  -	 * Retrieve root document for stylesheet.
  +	 * Retrieve root document for stylesheet.  Note that
  +	 * this does not have to be a XalanDocument -- it can
  +	 * be any node in a document.
   	 * 
   	 * @return root document
   	 */
  -	virtual XalanDocument*
  +	virtual XalanNode*
   	getRootDocument() const = 0;
   
   	/**
  -	 * Set root document for stylesheet.
  +	 * Set root document for stylesheet.  Note that
  +	 * this does not have to be a XalanDocument -- it can
  +	 * be any node in a document.
   	 * 
   	 * @param theDocument root document
   	 */
   	virtual void
  -	setRootDocument(XalanDocument*	theDocument) = 0;
  +	setRootDocument(XalanNode*	theDocument) = 0;
   
   	/**
   	 * Create a new empty document.
  @@ -592,6 +592,7 @@
   	virtual int
   	getIndent() const = 0;
   
  +	// $$$ ToDo: Remove this one!!!!
   	/**
   	 * Execute an XPath and return the resulting XObject. The lifetime of this
   	 * XObject is not necessarily that of the Stylesheet.
  @@ -605,21 +606,6 @@
   	executeXPath(
   			const XalanDOMString&	str,
   			XalanNode*				contextNode,
  -			const PrefixResolver&	resolver) = 0;
  -
  -	/**
  -	 * Execute an XPath and return the resulting XObject. The lifetime of this
  -	 * XObject is not necessarily that of the Stylesheet.
  -	 *
  -	 * @param str         string expression for XPath evaluation
  -	 * @param contextNode current node in the source tree
  -	 * @param resolver    resolver for namespace resolution
  -	 * @return pointer to resulting XObject
  -	 */
  -	virtual XObject*
  -	executeXPath(
  -			const XalanDOMString&	str,
  -			XalanNode*				contextNode,
   			const XalanElement&		resolver) = 0;
   
   	/**
  @@ -712,7 +698,115 @@
   			const PrefixResolver&	namespaceContext,
   			const XalanDOMString&	stringedValue) = 0;
   
  +#if defined(XALAN_NO_NAMESPACES)
  +	typedef vector<TopLevelArg>			ParamVectorType;
  +#else
  +	typedef std::vector<TopLevelArg>	ParamVectorType;
  +#endif
  +
  +	/**
  +	 * Set a list of top level variables in the specified execution context
  +	 * stylesheet.
  +	 *
  +	 * @param topLevelParams   list of top level parameters
  +	 */
  +	virtual void
  +	pushTopLevelVariables(const ParamVectorType&	topLevelParams) = 0;
  +
   	/**
  +	 * Execute the supplied XPath and and create a
  +	 * variable in the current context.
  +	 *
  +	 * @param element	  element marker for variable
  +	 * @param str         string expression for XPath evaluation
  +	 * @param contextNode current node in the source tree
  +	 * @param resolver    resolver for namespace resolution
  +	 * @return a pointer to the XObject result
  +	 */
  +	virtual XObject*
  +	createVariable(
  +			const ElemTemplateElement*	element,
  +			const XPath&				xpath,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver) = 0;
  +
  +	/**
  +	 * Create an ResultTreeFragment as a variable and push it
  +	 * on to the stack with the current context.
  +	 *
  +	 * @param name    name of variable
  +	 * @param element element marker for variable
  +	 * @param templateChild result tree fragment to use.
  +	 * @param sourceTree node for source tree
  +	 * @param sourceNode source node
  +	 * @return a pointer to the XObject result
  +	 */
  +	virtual XObject*
  +	createVariable(
  +			const ElemTemplateElement*	element,
  +			const ElemTemplateElement&	templateChild,
  +			XalanNode*					sourceTree,
  +			XalanNode*					sourceNode,
  +			const QName&				mode) = 0;
  +
  +	/**
  +	 * Execute an XPath using the provided expression, 
  +	 * and push the result as a variable in the context of
  +	 * the supplied element.
  +	 *
  +	 * @param name		  name of variable
  +	 * @param element	  element marker for variable
  +	 * @param str         string expression for XPath evaluation
  +	 * @param contextNode current node in the source tree
  +	 * @param resolver    resolver for namespace resolution
  +	 * @return nothing
  +	 */
  +	virtual void
  +	pushVariable(
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const XalanDOMString&		str,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver) = 0;
  +
  +	/**
  +	 * Execute the supplied XPath and push the result as a
  +	 * variable in the current context.
  +	 *
  +	 * @param name		  name of variable
  +	 * @param element	  element marker for variable
  +	 * @param str         string expression for XPath evaluation
  +	 * @param contextNode current node in the source tree
  +	 * @param resolver    resolver for namespace resolution
  +	 * @return nothing
  +	 */
  +	virtual void
  +	pushVariable(
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const XPath&				xpath,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver) = 0;
  +
  +	/**
  +	 * Create an ResultTreeFragment as a variable and push it
  +	 * on to the stack with the current context.
  +	 *
  +	 * @param name    name of variable
  +	 * @param element element marker for variable
  +	 * @param templateChild result tree fragment to use.
  +	 * @param sourceTree node for source tree
  +	 * @param sourceNode source node
  +	 */
  +	virtual void
  +	pushVariable(
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const ElemTemplateElement&	templateChild,
  +			XalanNode*					sourceTree,
  +			XalanNode*					sourceNode) = 0;
  +
  +	/**
   	 * Push a named variable onto the processor variable stack
   	 *
   	 * @param name    name of variable
  @@ -721,27 +815,22 @@
   	 */
   	virtual void
   	pushVariable(
  -			const QName&		name,
  -			XObject*			var,
  -			const XalanNode*	element) = 0;
  +			const QName&				name,
  +			XObject*					var,
  +			const ElemTemplateElement*	element) = 0;
   
   	/**
   	 * Push a context marker onto the stack to let us know when to stop
   	 * searching for a var.
  -	 *
  -	 * @param caller     caller node
  -	 * @param sourceNode source node
   	 */
   	virtual void
  -	pushContextMarker(
  -			const XalanNode*	caller,
  -			const XalanNode*	sourceNode) = 0;
  +	pushContextMarker() = 0;
   
   	/**
   	 * Pop the current context from the current context stack.
   	 */
   	virtual void
  -	popCurrentContext() = 0;
  +	popContextMarker() = 0;
   
   	/**
   	 * Resolve the params that were pushed by the caller.
  @@ -771,7 +860,7 @@
   			XalanNode*					sourceTree, 
   			XalanNode*					sourceNode,
   			const QName&				mode,
  -			const XalanNode*			targetTemplate) = 0;
  +			const ElemTemplateElement*	targetTemplate) = 0;
   
   	/**
   	 * Given a name, return a string representing the value, but don't look in
  @@ -894,7 +983,7 @@
   			XalanNode*						sourceTree, 
   			XalanNode*						sourceNode,
   			const QName&					mode,
  -			const XalanNode*				targetTemplate);
  +			const ElemTemplateElement*		targetTemplate);
   
   		~ParamsPushPop();
   
  @@ -1098,6 +1187,17 @@
   			const QName&				mode) = 0;
   
   	/**
  +	 * Function to destroy an XObject that was returned
  +	 * by executing.  It is safe to call this function
  +	 * with any XObject.
  +	 *
  +	 * @param theXObject pointer to the XObject.
  +	 * @return true if the object was destroyed.
  +	 */
  +	virtual bool
  +	destroyXObject(XObject*		theXObject) const = 0;
  +
  +	/**
   	 * Given a result tree fragment, walk the tree and
   	 * output it to the result stream.
   	 *
  @@ -1260,8 +1360,8 @@
   	virtual FormatterToDOM*
   	createFormatterToDOM(
   			XalanDocument*			doc,
  -			XalanDocumentFragment*	docFrag = 0,
  -			XalanElement*			currentElement = 0) = 0;
  +			XalanDocumentFragment*	docFrag,
  +			XalanElement*			currentElement) = 0;
   
   	/**
   	 * Construct a FormatterToDOM instance.  it will add the DOM nodes 
  
  
  
  1.22      +296 -47   xml-xalan/c/src/XSLT/StylesheetExecutionContextDefault.cpp
  
  Index: StylesheetExecutionContextDefault.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/StylesheetExecutionContextDefault.cpp,v
  retrieving revision 1.21
  retrieving revision 1.22
  diff -u -r1.21 -r1.22
  --- StylesheetExecutionContextDefault.cpp	2000/07/14 16:57:42	1.21
  +++ StylesheetExecutionContextDefault.cpp	2000/07/21 19:52:57	1.22
  @@ -74,7 +74,10 @@
   
   
   #include <XPath/ElementPrefixResolverProxy.hpp>
  +#include <XPath/QName.hpp>
   #include <XPath/ResultTreeFragBase.hpp>
  +#include <XPath/XObjectFactory.hpp>
  +#include <XPath/XPath.hpp>
   #include <XPath/XPathExecutionContext.hpp>
   #include <XPath/QName.hpp>
   
  @@ -95,7 +98,9 @@
   
   
   
  +#include "Constants.hpp"
   #include "ElemTemplateElement.hpp"
  +#include "ElemWithParam.hpp"
   #include "StylesheetRoot.hpp"
   #include "XSLTEngineImpl.hpp"
   #include "XSLTProcessorException.hpp"
  @@ -127,14 +132,18 @@
   								   theContextNodeList,
   								   thePrefixResolver),
   	m_xsltProcessor(xsltProcessor),
  +	m_rootDocument(0),
   	m_elementRecursionStack(),
   	m_prefixResolver(0),
   	m_stylesheetRoot(0),
   	m_formatterListeners(),
   	m_printWriters(),
   	m_textOutputStreams(),
  -	m_collationCompareFunctor(&s_defaultFunctor)
  +	m_collationCompareFunctor(&s_defaultFunctor),
  +	m_liveVariablesStack(),
  +	m_variablesStack()
   {
  +	m_liveVariablesStack.reserve(eDefaultVariablesStackSize);
   }
   
   
  @@ -170,14 +179,10 @@
   			 DeleteFunctor<TextOutputStream>());
   
   	m_textOutputStreams.clear();
  -}
  -
   
  +	clearLiveVariablesStack();
   
  -XObject*
  -StylesheetExecutionContextDefault::getTopLevelVariable(const XalanDOMString&	theName) const
  -{
  -	return m_xsltProcessor.getTopLevelVariable(theName);
  +	m_variablesStack.reset();
   }
   
   
  @@ -190,18 +195,18 @@
   
   
   
  -XalanDocument*
  +XalanNode*
   StylesheetExecutionContextDefault::getRootDocument() const
   {
  -	return m_xsltProcessor.getRootDoc();
  +	return m_rootDocument;
   }
   
   
   
   void
  -StylesheetExecutionContextDefault::setRootDocument(XalanDocument*	theDocument)
  +StylesheetExecutionContextDefault::setRootDocument(XalanNode*	theDocument)
   {
  -	m_xsltProcessor.setRootDoc(theDocument);
  +	m_rootDocument = theDocument;
   }
   
   
  @@ -434,20 +439,6 @@
   StylesheetExecutionContextDefault::executeXPath(
   			const XalanDOMString&	str,
   			XalanNode*				contextNode,
  -			const PrefixResolver&	resolver)
  -{
  -	return m_xsltProcessor.evalXPathStr(str,
  -										contextNode,
  -										resolver,
  -										*this);
  -}
  -
  -
  -
  -XObject*
  -StylesheetExecutionContextDefault::executeXPath(
  -			const XalanDOMString&	str,
  -			XalanNode*				contextNode,
   			const XalanElement&		resolver)
   {
   	return m_xsltProcessor.evalXPathStr(str,
  @@ -491,38 +482,168 @@
   
   
   void
  +StylesheetExecutionContextDefault::pushTopLevelVariables(const ParamVectorType&		topLevelParams)
  +{
  +	assert(m_stylesheetRoot != 0);
  +
  +	m_stylesheetRoot->pushTopLevelVariables(*this, topLevelParams);
  +}
  +
  +
  +
  +XObject*
  +StylesheetExecutionContextDefault::createVariable(
  +			const ElemTemplateElement*	/* element */,
  +			const XPath&				xpath,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver)
  +{
  +	XObject* const	theVariable =
  +		xpath.execute(contextNode, resolver, *this);
  +
  +	assert(m_liveVariablesStack.empty() == false);
  +
  +	// We'll want to return this variable after the current element frame
  +	// has finished executing, so save this off for later...
  +	m_liveVariablesStack.back().push_back(theVariable);
  +
  +	return theVariable;
  +}
  +
  +
  +
  +XObject*
  +StylesheetExecutionContextDefault::createVariable(
  +			const ElemTemplateElement*	/* element */,
  +			const ElemTemplateElement&	templateChild,
  +			XalanNode*					sourceTree,
  +			XalanNode*					sourceNode,
  +			const QName&				mode)
  +{
  +	XObject* const	theVariable =
  +		this->createXResultTreeFrag(templateChild, sourceTree, sourceNode, mode);
  +
  +	// We'll want to return this variable after the current element frame
  +	// has finished executing, so save this off for later...
  +	m_liveVariablesStack.back().push_back(theVariable);
  +
  +	return theVariable;
  +}
  +
  +
  +
  +void
   StylesheetExecutionContextDefault::pushVariable(
  -			const QName&		name,
  -			XObject*			var,
  -			const XalanNode*	element)
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const XalanDOMString&		str,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver)
   {
  -	m_xsltProcessor.pushVariable(name, var, element);
  +	XObject*	var = 0;
  +
  +	if (length(str) > 0)
  +	{
  +		var = 	m_xsltProcessor.evalXPathStr(
  +						str,
  +						contextNode,
  +						resolver,
  +						*this);
  +		assert(var != 0);
  +	}
  +
  +	// Call to our own member function, to keep track of the XObject...
  +	pushVariable(name, var, element);
   }
   
   
   
   void
  -StylesheetExecutionContextDefault::pushContextMarker(
  -			const XalanNode*	caller,
  -			const XalanNode*	sourceNode)
  +StylesheetExecutionContextDefault::pushVariable(
  +			const QName&				name,
  +			XObject*					var,
  +			const ElemTemplateElement*	element)
   {
  -	m_xsltProcessor.pushContextMarker(caller, sourceNode);
  +	m_variablesStack.pushVariable(name, var, element);
  +
  +	if (m_liveVariablesStack.empty() == false)
  +	{
  +		// We'll want to return this variable after the current element frame
  +		// has finished executing, so save this off for later...
  +		m_liveVariablesStack.back().push_back(var);
  +	}
   }
   
   
   
   void
  -StylesheetExecutionContextDefault::popCurrentContext()
  +StylesheetExecutionContextDefault::pushVariable(
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const XPath&				xpath,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver)
  +{
  +	XObjectGuard	theXObject(
  +				m_xpathExecutionContextDefault.getXObjectFactory(),
  +				xpath.execute(contextNode, resolver, *this));
  +
  +	pushVariable(name, theXObject.get(), element);
  +
  +	theXObject.release();
  +}
  +
  +
  +
  +void
  +StylesheetExecutionContextDefault::pushVariable(
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const ElemTemplateElement&	templateChild,
  +			XalanNode*					sourceTree,
  +			XalanNode*					sourceNode)
   {
  -	m_xsltProcessor.popCurrentContext();
  +	XObjectGuard	theXObject(
  +				m_xpathExecutionContextDefault.getXObjectFactory(),
  +				createXResultTreeFrag(templateChild, sourceTree, sourceNode));
  +
  +	pushVariable(name, theXObject.get(), element);
  +
  +	theXObject.release();
   }
   
   
   
   void
  +StylesheetExecutionContextDefault::pushContextMarker()
  +{
  +	m_variablesStack.pushContextMarker();
  +
  +	m_liveVariablesStack.push_back(LiveVariablesStackType::value_type());
  +
  +	m_liveVariablesStack.back().reserve(eDefaultVariablesCollectionSize);
  +}
  +
  +
  +
  +void
  +StylesheetExecutionContextDefault::popContextMarker()
  +{
  +	m_variablesStack.popContextMarker();
  +
  +	popLiveVariablesStack();
  +}
  +
  +
  +
  +void
   StylesheetExecutionContextDefault::resolveTopLevelParams()
   {
  +	pushContextMarker();
  +
   	m_xsltProcessor.resolveTopLevelParams(*this);
  +
  +	m_variablesStack.markGlobalStackFrame();
   }
   
   
  @@ -535,19 +656,93 @@
   
   
   
  +class PopPushContextMarker
  +{
  +public:
  +
  +	PopPushContextMarker(StylesheetExecutionContext&	theExecutionContext) :
  +		m_executionContext(theExecutionContext)
  +	{
  +		m_executionContext.popContextMarker();
  +	}
  +
  +	~PopPushContextMarker()
  +	{
  +		m_executionContext.pushContextMarker();
  +	}
  +
  +private:
  +
  +	StylesheetExecutionContext&		m_executionContext;
  +};
  +
  +
  +
   void
   StylesheetExecutionContextDefault::pushParams(
   			const ElemTemplateElement&	xslCallTemplateElement,
   			XalanNode*					sourceTree, 
   			XalanNode*					sourceNode,
   			const QName&				mode,
  -			const XalanNode*			targetTemplate)
  +			const ElemTemplateElement*	targetTemplate)
   {
  -	m_xsltProcessor.pushParams(*this,
  -							   xslCallTemplateElement,
  -							   sourceTree,
  -							   sourceNode,
  -							   mode,
  +	typedef VariablesStack::ParamsVectorType	ParamsVectorType;
  +	
  +	ParamsVectorType	theParams;
  +
  +	const ElemTemplateElement*	child =
  +			xslCallTemplateElement.getFirstChildElem();
  +
  +	if (0 != child)
  +	{
  +		// This object will take care of popping, then
  +		// pushing the context marker at the top of the
  +		// stack, even if an exception is thrown...
  +		PopPushContextMarker	thePopPush(*this);
  +
  +		while(0 != child)
  +		{
  +			if(Constants::ELEMNAME_WITHPARAM == child->getXSLToken())
  +			{
  +				const ElemWithParam* const	xslParamElement =
  +#if defined(XALAN_OLD_STYLE_CASTS)
  +							(ElemWithParam*)child;
  +#else
  +				static_cast<const ElemWithParam*>(child);
  +#endif
  +
  +				const XPath* const	pxpath = xslParamElement->getSelectPattern();
  +
  +				XObject*			theXObject = 0;
  +
  +				if(0 != pxpath)
  +				{
  +					theXObject =
  +						createVariable(
  +							&xslCallTemplateElement,
  +							*pxpath,
  +							sourceNode,
  +							*xslParamElement);
  +				}
  +				else
  +				{
  +					theXObject =
  +						createVariable(
  +							&xslCallTemplateElement,
  +							*xslParamElement,
  +							sourceTree,
  +							sourceNode,
  +							mode);
  +				}
  +
  +				theParams.push_back(ParamsVectorType::value_type(xslParamElement->getQName(), theXObject));
  +			}
  +
  +			child = child->getNextSiblingElem();
  +		}
  +	}
  +
  +	m_variablesStack.pushParams(theParams,
   							   targetTemplate);
   }
   
  @@ -556,7 +751,7 @@
   XObject*
   StylesheetExecutionContextDefault::getParamVariable(const QName&	theName) const
   {
  -	return m_xsltProcessor.getParamVariable(theName);
  +	return m_variablesStack.getParamVariable(theName);
   }
   
   
  @@ -564,7 +759,9 @@
   void
   StylesheetExecutionContextDefault::pushElementFrame(const ElemTemplateElement*	elem)
   {
  -	m_xsltProcessor.getVariableStacks().pushElementFrame(elem);
  +	m_variablesStack.pushElementFrame(elem);
  +
  +	m_liveVariablesStack.push_back(LiveVariablesStackType::value_type());
   }
   
   
  @@ -572,7 +769,9 @@
   void
   StylesheetExecutionContextDefault::popElementFrame(const ElemTemplateElement*	elem)
   {
  -	m_xsltProcessor.getVariableStacks().popElementFrame(elem);
  +	m_variablesStack.popElementFrame(elem);
  +
  +	popLiveVariablesStack();
   }
   
   
  @@ -580,7 +779,7 @@
   int
   StylesheetExecutionContextDefault::getCurrentStackFrameIndex() const
   {
  -	return m_xsltProcessor.getVariableStacks().getCurrentStackFrameIndex();
  +	return m_variablesStack.getCurrentStackFrameIndex();
   }
   
   
  @@ -588,7 +787,7 @@
   void
   StylesheetExecutionContextDefault::setCurrentStackFrameIndex(int	currentStackFrameIndex)
   {
  -	m_xsltProcessor.getVariableStacks().setCurrentStackFrameIndex(currentStackFrameIndex);
  +	m_variablesStack.setCurrentStackFrameIndex(currentStackFrameIndex);
   }
   
   
  @@ -605,6 +804,10 @@
   StylesheetExecutionContextDefault::endDocument()
   {
   	m_xsltProcessor.endDocument();
  +
  +	// This matches the pushContextMarker in
  +	// resolveTopLevelParams().
  +	popContextMarker();
   }
   
   
  @@ -725,6 +928,15 @@
   
   
   
  +bool
  +StylesheetExecutionContextDefault::destroyXObject(XObject*	theXObject) const
  +{
  +
  +	return m_xsltProcessor.destroyXObject(theXObject);
  +}
  +
  +
  +
   void
   StylesheetExecutionContextDefault::outputResultTreeFragment(const XObject&	theTree)
   {
  @@ -1290,7 +1502,10 @@
   XObject*
   StylesheetExecutionContextDefault::getVariable(const QName&		name) const
   {
  -	return m_xpathExecutionContextDefault.getVariable(name);
  +	XObject* const	theVariable =
  +		m_variablesStack.getVariable(name);
  +
  +	return m_xpathExecutionContextDefault.getXObjectFactory().clone(*theVariable);
   }
   
   
  @@ -1525,3 +1740,37 @@
   {
   	m_xsltProcessor.message(msg, sourceNode, styleNode);
   }
  +
  +
  +
  +void
  +StylesheetExecutionContextDefault::popLiveVariablesStack()
  +{
  +#if !defined(XALAN_NO_NAMESPACES)
  +	using std::for_each;
  +#endif
  +
  +	assert(m_liveVariablesStack.empty() == false);
  +
  +	// Clean up any XObjects we created...
  +	for_each(
  +			m_liveVariablesStack.back().begin(),
  +			m_liveVariablesStack.back().end(),
  +			XObjectFactory::DeleteXObjectFunctor(getXObjectFactory()));
  +
  +	// Pop the stack...
  +	m_liveVariablesStack.pop_back();
  +}
  +
  +
  +
  +void
  +StylesheetExecutionContextDefault::clearLiveVariablesStack()
  +{
  +	// Clean up the entire stack.
  +	while(m_liveVariablesStack.empty() == false)
  +	{
  +		popLiveVariablesStack();
  +	}
  +}
  +
  
  
  
  1.20      +84 -23    xml-xalan/c/src/XSLT/StylesheetExecutionContextDefault.hpp
  
  Index: StylesheetExecutionContextDefault.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/StylesheetExecutionContextDefault.hpp,v
  retrieving revision 1.19
  retrieving revision 1.20
  diff -u -r1.19 -r1.20
  --- StylesheetExecutionContextDefault.hpp	2000/07/14 16:57:42	1.19
  +++ StylesheetExecutionContextDefault.hpp	2000/07/21 19:52:57	1.20
  @@ -66,6 +66,7 @@
   
   
   
  +#include <deque>
   #include <memory>
   #include <set>
   #include <vector>
  @@ -76,6 +77,10 @@
   
   
   
  +#include <XSLT/VariablesStack.hpp>
  +
  +
  +
   class TextOutputStream;
   class XPathProcessor;
   class XPathSupport;
  @@ -108,17 +113,14 @@
   	virtual void
   	reset();
   
  -	virtual XObject*
  -	getTopLevelVariable(const XalanDOMString&	theName) const;
  -
   	virtual bool
   	getQuietConflictWarnings() const;
   
  -	virtual XalanDocument*
  +	virtual XalanNode*
   	getRootDocument() const;
   
   	virtual void
  -	setRootDocument(XalanDocument*	theDocument);
  +	setRootDocument(XalanNode*	theDocument);
   
   	virtual XalanDocument*
   	createDocument() const;
  @@ -203,16 +205,11 @@
   	virtual int
   	getIndent() const;
   
  +	// $$$ ToDo: Get rid of this!!!!
   	virtual XObject*
   	executeXPath(
   			const XalanDOMString&	str,
   			XalanNode*				contextNode,
  -			const PrefixResolver&	resolver);
  -
  -	virtual XObject*
  -	executeXPath(
  -			const XalanDOMString&	str,
  -			XalanNode*				contextNode,
   			const XalanElement&		resolver);
   
   	virtual XPath*
  @@ -230,18 +227,58 @@
   			const XalanDOMString&	stringedValue);
   
   	virtual void
  +	pushTopLevelVariables(const ParamVectorType&	topLevelParams);
  +
  +	virtual XObject*
  +	createVariable(
  +			const ElemTemplateElement*	element,
  +			const XPath&				xpath,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver);
  +
  +	virtual XObject*
  +	createVariable(
  +			const ElemTemplateElement*	element,
  +			const ElemTemplateElement&	templateChild,
  +			XalanNode*					sourceTree,
  +			XalanNode*					sourceNode,
  +			const QName&				mode);
  +
  +	virtual void
   	pushVariable(
  -			const QName&		name,
  -			XObject*			var,
  -			const XalanNode*	element);
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const XalanDOMString&		str,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver);
   
   	virtual void
  -	pushContextMarker(
  -			const XalanNode*	caller,
  -			const XalanNode*	sourceNode);
  +	pushVariable(
  +			const QName&				name,
  +			XObject*					var,
  +			const ElemTemplateElement*	element);
  +
  +	virtual void
  +	pushVariable(
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const XPath&				xpath,
  +			XalanNode*					contextNode,
  +			const PrefixResolver&		resolver);
  +
  +	virtual void
  +	pushVariable(
  +			const QName&				name,
  +			const ElemTemplateElement*	element,
  +			const ElemTemplateElement&	templateChild,
  +			XalanNode*					sourceTree,
  +			XalanNode*					sourceNode);
  +
  +	virtual void
  +	pushContextMarker();
   
   	virtual void
  -	popCurrentContext();
  +	popContextMarker();
   
   	virtual void
   	resolveTopLevelParams();
  @@ -255,7 +292,7 @@
   			XalanNode*					sourceTree, 
   			XalanNode*					sourceNode,
   			const QName&				mode,
  -			const XalanNode*			targetTemplate);
  +			const ElemTemplateElement*	targetTemplate);
   
   	virtual XObject*
   	getParamVariable(const QName&	theName) const;
  @@ -327,6 +364,9 @@
   			XalanNode*					sourceNode,
   			const QName&				mode);
   
  +	virtual bool
  +	destroyXObject(XObject*		theXObject) const;
  +
   	virtual void
   	outputResultTreeFragment(const XObject&		theTree);
   
  @@ -374,8 +414,8 @@
   	virtual FormatterToDOM*
   	createFormatterToDOM(
   			XalanDocument*			doc,
  -			XalanDocumentFragment*	docFrag = 0,
  -			XalanElement*			currentElement = 0);
  +			XalanDocumentFragment*	docFrag,
  +			XalanElement*			currentElement);
   
   	virtual FormatterToDOM*
   	createFormatterToDOM(
  @@ -673,23 +713,37 @@
   
   private:
   
  +	void
  +	popLiveVariablesStack();
  +
  +	void
  +	clearLiveVariablesStack();
  +
   	XPathExecutionContextDefault	m_xpathExecutionContextDefault;
   
   	// $$ ToDo: Try to remove this dependency, and rely only on XSLTProcessor...
   	XSLTEngineImpl&					m_xsltProcessor;
   
  +	XalanNode*						m_rootDocument;
  +
   #if defined(XALAN_NO_NAMESPACES)
  -	typedef vector<const ElemTemplateElement*>			ElementRecursionStackType;
  +	typedef deque<const ElemTemplateElement*>			ElementRecursionStackType;
   	typedef set<FormatterListener*>						FormatterListenerSetType;
   	typedef set<PrintWriter*>							PrintWriterSetType;
   	typedef set<TextOutputStream*>						TextOutputStreamSetType;
  +	typedef vector<const XObject*>						VariablesCollectionType;
  +	typedef vector<VariablesCollectionType>				LiveVariablesStackType;
   #else
  -	typedef std::vector<const ElemTemplateElement*>		ElementRecursionStackType;
  +	typedef std::deque<const ElemTemplateElement*>		ElementRecursionStackType;
   	typedef std::set<FormatterListener*>				FormatterListenerSetType;
   	typedef std::set<PrintWriter*>						PrintWriterSetType;
   	typedef std::set<TextOutputStream*>					TextOutputStreamSetType;
  +	typedef std::vector<const XObject*>					VariablesCollectionType;
  +	typedef std::vector<VariablesCollectionType>		LiveVariablesStackType;
   #endif
   
  +	enum { eDefaultVariablesCollectionSize = 10, eDefaultVariablesStackSize = 200 };
  +
   	ElementRecursionStackType			m_elementRecursionStack;
   
   	const PrefixResolver*				m_prefixResolver;
  @@ -703,6 +757,13 @@
   	TextOutputStreamSetType				m_textOutputStreams;
   
   	const CollationCompareFunctor*		m_collationCompareFunctor;
  +
  +	LiveVariablesStackType				m_liveVariablesStack;
  +
  +	/**
  +	 * Holds all information about variables during execution.
  +	 */
  +	VariablesStack						m_variablesStack;
   
   	static XalanNumberFormatFactory		s_defaultXalanNumberFormatFactory;
   
  
  
  
  1.19      +31 -28    xml-xalan/c/src/XSLT/StylesheetRoot.cpp
  
  Index: StylesheetRoot.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/StylesheetRoot.cpp,v
  retrieving revision 1.18
  retrieving revision 1.19
  diff -u -r1.18 -r1.19
  --- StylesheetRoot.cpp	2000/07/11 19:54:53	1.18
  +++ StylesheetRoot.cpp	2000/07/21 19:52:57	1.19
  @@ -315,46 +315,52 @@
   	/*
   	 * Output target has a node
   	 */
  -	else if(0 != outputTarget.getNode())
  +	else if(outputTarget.hasDOMTarget() == true)
   	{
  -		switch(outputTarget.getNode()->getNodeType())
  +		if (outputTarget.getDocument() != 0)
   		{
  -		case XalanNode::DOCUMENT_NODE:
  -			flistener =
  -					executionContext.createFormatterToDOM(static_cast<XalanDocument*>(outputTarget.getNode()));
  -			break;
  -
  -		case XalanNode::DOCUMENT_FRAGMENT_NODE:
  -			flistener =
  -					executionContext.createFormatterToDOM(executionContext.createDocument(),
  -						static_cast<XalanDocumentFragment*>(outputTarget.getNode()));
  -			break;
  -
  -		case XalanNode::ELEMENT_NODE:
  -			flistener =
  -					executionContext.createFormatterToDOM(executionContext.createDocument(),
  -						static_cast<XalanElement*>(outputTarget.getNode()));
  -			break;
  +				flistener = executionContext.createFormatterToDOM(outputTarget.getDocument(), 0);
  +		}
  +		else if (outputTarget.getDocumentFragment() != 0)
  +		{
  +			XalanDocumentFragment* const	theFragment =
  +					outputTarget.getDocumentFragment();
  +
  +			flistener = executionContext.createFormatterToDOM(
  +								theFragment->getOwnerDocument(),
  +								theFragment,
  +								0);
  +		}
  +		else if (outputTarget.getElement() != 0)
  +		{
  +			XalanElement* const		theElement =
  +					outputTarget.getElement();
   
  -		default:
  -			executionContext.error("Can only output to an Element, DocumentFragment, Document, or PrintWriter.");
  +				flistener = executionContext.createFormatterToDOM(
  +								theElement->getOwnerDocument(),
  +								theElement);
   		}
  +		else
  +		{
  +			assert(0);
  +		}
   	}
   	/*
   	 * Create an empty document and set the output target node to this
   	 */
   	else
   	{
  -		outputTarget.setNode(executionContext.createDocument());
  +		XalanDocument* const	theDocument = executionContext.createDocument();
  +
  +		outputTarget.setDocument(theDocument);
   
  -		flistener =
  -				executionContext.createFormatterToDOM(static_cast<XalanDocument*>(outputTarget.getNode()));
  +		flistener = executionContext.createFormatterToDOM(theDocument, 0);
   	}
   
   	executionContext.setFormatterListener(flistener);
   	executionContext.resetCurrentState(sourceTree, sourceTree);
   
  -	executionContext.setRootDocument(static_cast<XalanDocument*>(sourceTree));
  +	executionContext.setRootDocument(sourceTree);
   		
   	if(executionContext.doDiagnosticsOutput())
   	{
  @@ -362,8 +368,6 @@
   		executionContext.diag(XALAN_STATIC_UCODE_STRING("Transforming..."));
   		executionContext.pushTime(&sourceTree);
   	}
  -		
  -	executionContext.pushContextMarker(0, 0);
   
   	try
   	{
  @@ -379,11 +383,10 @@
   
   	// Output the action of the found root rule.	All processing
   	// occurs from here.	buildResultFromTemplate is highly recursive.
  -	// java: rootRule->execute(*m_processor, sourceTree, sourceTree, 0);
   	rootRule->execute(executionContext, sourceTree, sourceTree, QName());
   
   	executionContext.endDocument();
  -		
  +
   	// Reset the top-level params for the next round.
   	executionContext.clearTopLevelParams();
   
  
  
  
  1.2       +2 -2      xml-xalan/c/src/XSLT/VariablesStack.cpp
  
  Index: VariablesStack.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/VariablesStack.cpp,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- VariablesStack.cpp	2000/07/21 19:46:11	1.1
  +++ VariablesStack.cpp	2000/07/21 19:52:57	1.2
  @@ -132,9 +132,9 @@
   void
   VariablesStack::popContextMarker()
   {
  -	const unsigned int	nElems = m_stack.size();
  +	const int	nElems = m_stack.size();
   
  -	for(unsigned int i = (nElems - 1); i > 0 && m_stack.empty() == false; --i)
  +	for(int i = (nElems - 1); i >= 0 && m_stack.empty() == false; --i)
   	{
   		const StackEntry&	theEntry = m_stack[i];
   		assert(theEntry == back());
  
  
  
  1.50      +20 -752   xml-xalan/c/src/XSLT/XSLTEngineImpl.cpp
  
  Index: XSLTEngineImpl.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTEngineImpl.cpp,v
  retrieving revision 1.49
  retrieving revision 1.50
  diff -u -r1.49 -r1.50
  --- XSLTEngineImpl.cpp	2000/07/19 20:52:31	1.49
  +++ XSLTEngineImpl.cpp	2000/07/21 19:52:57	1.50
  @@ -121,12 +121,8 @@
   
   
   
  -#include "Arg.hpp"
   #include "Constants.hpp"
  -#include "ContextMarker.hpp"
   #include "ElemWithParam.hpp"
  -#include "ElementFrameMarker.hpp"
  -#include "ElementMarker.hpp"
   #include "FunctionCurrent.hpp"
   #include "FunctionDocument.hpp"
   #include "FunctionElementAvailable.hpp"
  @@ -190,7 +186,6 @@
   			XPathFactory&		xpathFactory) :
   	XSLTProcessor(),
   	DocumentHandler(),
  -	m_rootDoc(),
   	m_outputCarriageReturns(false),
   	m_outputLinefeeds(false),
   	m_resultTreeFactory(0),
  @@ -208,8 +203,8 @@
   	m_xpathProcessor(new XPathProcessorImpl),
   	m_cdataStack(),
   	m_stylesheetLocatorStack(),
  -	m_variableStacks(*this),
  -	m_problemListener(new ProblemListenerDefault()),
  +	m_defaultProblemListener(),
  +	m_problemListener(&m_defaultProblemListener),
   	m_stylesheetRoot(0),
   	m_XSLDirectiveLookup(),
   	m_traceSelects(false),
  @@ -224,12 +219,7 @@
   	m_xpathSupport(xpathSupport),
   	m_xpathEnvSupport(xpathEnvSupport),
   	m_flistener(0),
  -	m_contextNodeList(&xpathSupport),
  -	m_topLevelVariables(),
  -	m_executionContext(0),
  -	m_needToCheckForInfiniteLoops(false),
  -	m_stackGuard(*this),
  -	m_attrSetStack()
  +	m_executionContext(0)
   {
   }
   
  @@ -247,6 +237,16 @@
   
   
   
  +void
  +XSLTEngineImpl::Terminate()
  +{
  +	s_XSLT4JElementKeys.clear();
  +	s_elementKeys.clear();
  +	s_attributeKeys.clear();
  +}
  +
  +
  +
   /**
    * Reset the state.  This needs to be called after a process() call 
    * is invoked, if the processor is to be used again.
  @@ -254,8 +254,6 @@
   void
   XSLTEngineImpl::reset()
   {
  -	m_rootDoc = 0;
  -
   	m_topLevelParams.clear();
   	m_durationsTable.clear();
   	m_stylesheetLocatorStack.clear();
  @@ -263,14 +261,11 @@
   	m_pendingAttributes.clear();
   	m_cdataStack.clear();
   	m_resultTreeFactory = 0;
  -	m_contextNodeList.clear();
   	m_currentNode = 0;
  -	m_needToCheckForInfiniteLoops = false;
  -	m_variableStacks.reset();
  +
   	m_hasPendingStartDocument = false;
   	m_mustFlushStartDocument = false;
   
  -	m_stackGuard.clear();
   	m_xpathSupport.reset();
   	m_xpathEnvSupport.reset();
   	m_xpathFactory.reset();
  @@ -281,8 +276,6 @@
   
   XSLTEngineImpl::~XSLTEngineImpl()
   {
  -	delete m_problemListener;
  -
   	reset();
   }
   
  @@ -294,22 +287,6 @@
   
   
   
  -XalanDocument*
  -XSLTEngineImpl::getRootDoc() const
  -{
  -	return m_rootDoc;
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::setRootDoc(XalanDocument*	doc)
  -{
  -	m_rootDoc = doc;
  -}
  -
  -
  -
   AttributeListImpl& 
   XSLTEngineImpl::getPendingAttributes()
   {
  @@ -1477,8 +1454,6 @@
   
   		fireGenerateEvent(ge);
   	}
  -
  -	m_variableStacks.popCurrentContext();
   }
   
   
  @@ -3143,37 +3118,6 @@
   
   
   /**
  - * Given a name, locate a variable in the current context, and return 
  - * the Object.
  - */
  -XObject*
  -XSLTEngineImpl::getVariable(const QName& qname) const
  -{
  -	return m_variableStacks.getXObjectVariable(qname);
  -}
  -
  -
  -
  -XObject*
  -XSLTEngineImpl::getParamVariable(const QName&	theName) const
  -{
  -	return m_variableStacks.getXObjectParamVariable(theName);
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::pushVariable(
  -				const QName&		name,
  -				XObject*			val,
  -				const XalanNode*	e)
  -{
  -	m_variableStacks.pushVariable(name, val, e);
  -}
  -
  -
  -
  -/**
    * Create a document fragment.  This function may return null.
    */
   ResultTreeFragBase* XSLTEngineImpl::createDocFrag() const
  @@ -3183,25 +3127,6 @@
     
   
   
  -XObject*
  -XSLTEngineImpl::getXObjectVariable(
  -			StylesheetExecutionContext&		executionContext,
  -			const XalanDOMString&			name) const
  -{
  -	assert(m_stylesheetRoot != 0);
  -
  -	XObject*	theResult = m_variableStacks.getXObjectVariable(name);
  -
  -    if(0 == theResult)
  -    {
  -		theResult = m_stylesheetRoot->getTopLevelVariable(name, executionContext);
  -    }
  -
  -    return theResult;
  -}
  -
  -
  -
   XLocator*
   XSLTEngineImpl::getXLocatorFromNode(const XalanNode*	node) const
   {
  @@ -3220,26 +3145,6 @@
   
   
   
  -XObject*
  -XSLTEngineImpl::getTopLevelVariable(const XalanDOMString&	theName) const
  -{
  -	TopLevelVariablesMapType::const_iterator	i =
  -		m_topLevelVariables.find(theName);
  -
  -	if (i == m_topLevelVariables.end())
  -	{
  -		return 0;
  -	}
  -	else
  -	{
  -		assert((*i).second != 0);
  -
  -		return (*i).second;
  -	}
  -}
  -
  -
  -
   ResultTreeFragBase*
   XSLTEngineImpl::createResultTreeFrag() const
   {
  @@ -3255,7 +3160,7 @@
   {
   	const QName		qname(theName, 0, m_xpathEnvSupport, m_xpathSupport);
   
  -	m_topLevelParams.push_back(Arg(qname, expression, true));
  +	m_topLevelParams.push_back(ParamVectorType::value_type(qname, expression));
   }
   
   
  @@ -3267,7 +3172,7 @@
   {
   	const QName		qname(theName, 0, m_xpathEnvSupport, m_xpathSupport);
   
  -	m_topLevelParams.push_back(Arg(qname, theValue, true));
  +	m_topLevelParams.push_back(ParamVectorType::value_type(qname, theValue));
   }
   
   
  @@ -3275,9 +3180,7 @@
   void
   XSLTEngineImpl::resolveTopLevelParams(StylesheetExecutionContext&	executionContext)
   {
  -	m_stylesheetRoot->pushTopLevelVariables(executionContext, m_topLevelParams);
  -
  -	getVariableStacks().markGlobalStackFrame();
  +	executionContext.pushTopLevelVariables(m_topLevelParams);
   }
   
   
  @@ -3477,647 +3380,12 @@
   
   
   
  -//@@ JMD: NOTE: java implementation of these classes does not pass reference
  -//to processor
  -
  -//////////////////////////////////////////////////////////////////////////////
  -// CLASS XSLTEngineImpl::StackGuard
  -//////////////////////////////////////////////////////////////////////////////
  -
  -XSLTEngineImpl::StackGuard::StackGuard(
  -			XSLTEngineImpl&			processor,
  -			const XalanElement*		xslTemplate,
  -			const XalanNode*		sourceXML) :
  -	m_processor(&processor),
  -	m_xslRule(xslTemplate),
  -	m_sourceXML(sourceXML),
  -	m_stack()
  -{
  -}
  -
  -
  -
  -XSLTEngineImpl::StackGuard::~StackGuard()
  -{
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::StackGuard::print(PrintWriter&	pw) const
  -{
  -	// for the moment, these diagnostics are really bad...
  -	const XalanNode::NodeType	theType = m_sourceXML->getNodeType();
  -
  -	if(theType == XalanNode::TEXT_NODE)
  -	{
  -#if defined(XALAN_OLD_STYLE_CASTS)
  -		const XalanText* const	tx =
  -			(const XalanText*)m_sourceXML;
  -#else
  -		const XalanText* const	tx =
  -			static_cast<const XalanText*>(m_sourceXML);
  -#endif
  -		pw.println(tx->getData());
  -	}
  -	else if(theType == XalanNode::ELEMENT_NODE)
  -	{
  -		pw.println(m_sourceXML->getNodeName());
  -	}
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::StackGuard::checkForInfiniteLoop(const StackGuard&	guard) const
  -{
  -	const int	nRules = m_stack.size();
  -
  -	int			loopCount = 0;
  -
  -	for(int i = (nRules - 1); i >= 0; --i)
  -	{
  -		if(m_stack[i] == guard)
  -		{
  -			loopCount++;
  -		}
  -
  -		if(loopCount >= 4)
  -		{
  -			DOMStringPrintWriter	pw;
  -
  -			pw.println(XalanDOMString("Infinite loop diagnosed!  Stack trace:"));
  -
  -			int		k = 0;
  -
  -			for(; k < nRules; k++)
  -			{
  -				pw.println(XalanDOMString("Source Elem #") +
  -								LongToDOMString(k) +
  -								XalanDOMString(" "));
  -
  -				m_stack[i].print(pw);
  -			}
  -
  -			pw.println(XalanDOMString("Source Elem #") +
  -							LongToDOMString(k) +
  -							XalanDOMString(" "));
  -
  -			guard.print(pw);
  -
  -			pw.println(XalanDOMString("End of infinite loop diagnosis."));
  -
  -			m_processor->diag(pw.getString());
  -
  -			throw XSLTEngineImpl::XSLInfiniteLoopException();
  -		}
  -	}
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::StackGuard::push(
  -				const XalanElement*		xslTemplate,
  -				const XalanNode*		sourceXML)
  -{
  -	const StackGuard	guard(*m_processor, xslTemplate, sourceXML);
  -
  -	checkForInfiniteLoop(guard);
  -
  -	m_stack.push_back(guard);
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::StackGuard::pop()
  -{
  -	m_stack.pop_back();
  -}
  -
  -
  -
  -
  -XSLTEngineImpl::XSLInfiniteLoopException::XSLInfiniteLoopException() :
  -	XSLTProcessorException("XSLT infinite loop occurred!")
  -{
  -}
  -
  -
  -
  -XSLTEngineImpl::XSLInfiniteLoopException::~XSLInfiniteLoopException()
  -{
  -}
  -
  -
  -
  -//////////////////////////////////////////////////////////////////////////////
  -// CLASS XSLTEngineImpl::VariableStack
  -//////////////////////////////////////////////////////////////////////////////
  -
  -
  -XSLTEngineImpl::VariableStack::VariableStack(XSLTEngineImpl&	theProcessor) :
  -	m_caller(),
  -	m_stack(),
  -	m_stackEntries(),
  -	m_processor(theProcessor),
  -	m_globalStackFrameIndex(-1),
  -	m_currentStackFrameIndex(0)
  -{
  -	m_stack.reserve(eDefaultVectorSize);
  -
  -	pushContextMarker(0, 0);	
  -}
  -
  -
  -
  -XSLTEngineImpl::VariableStack::~VariableStack()
  -{
  -	reset();
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::reset()
  -{
  -#if !defined(XALAN_NO_NAMESPACES)
  -	using std::for_each;
  -#endif
  -
  -	m_stack.clear();
  -
  -	// Delete all entries that we created...
  -	for_each(m_stackEntries.begin(),
  -			 m_stackEntries.end(),
  -			 DeleteFunctor<StackEntry>());
  -
  -	m_stackEntries.clear();
  -
  -	// If the stack has grown past the default size,
  -	// shrink it down...
  -	if (m_stack.capacity() > eDefaultVectorSize)
  -	{
  -		VariableStackStackType	temp;
  -
  -		temp.reserve(eDefaultVectorSize);
  -
  -		m_stack.swap(temp);
  -	}
  -
  -	pushContextMarker(0, 0);	
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::pushElementMarker(const XalanNode*	elem)
  -{
  -	StackEntry* const	theEntry = new ElementMarker(elem);
  -
  -	m_stackEntries.insert(theEntry);
  -
  -	push(theEntry);
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::popElementMarker(const XalanNode*	elem)
  -{
  -	if(elementMarkerAlreadyPushed(elem) == true)
  -	{
  -		const int	nElems = m_stack.size();
  -
  -		bool		fFound = false;
  -
  -		// Sub 1 extra for the context marker.
  -		for(int i = (nElems - 1); i >= 0 && fFound == false; i--)
  -		{
  -			const StackEntry* const		theEntry = m_stack[i];
  -			assert(theEntry != 0);
  -
  -			if(theEntry->getType() == StackEntry::eElementMarker)
  -			{
  -				pop();
  -				fFound = true;
  -			}
  -			else
  -			{
  -				pop();
  -			}
  -
  -		}
  -	}
  -}
  -
  -
  -
   bool
  -XSLTEngineImpl::VariableStack::elementMarkerAlreadyPushed(const XalanNode*	elem) const
  +XSLTEngineImpl::destroyXObject(XObject*		theXObject) const
   {
  -	const int	nElems = m_stack.size();
  -	// Sub 1 extra for the context marker.
  -	for(int i = (nElems - 1); i >= 0; i--)
  -	{
  -		const StackEntry* const		theEntry = m_stack[i];
  -		assert(theEntry != 0);
  +	assert(theXObject != 0);
   
  -		if(theEntry->getType() == StackEntry::eElementMarker)
  -		{
  -			const ElementMarker* const	theElementMarkerEntry =
  -					static_cast<const ElementMarker*>(theEntry);
  -
  -			if(theElementMarkerEntry->getElement() == elem)
  -			{
  -				return true;
  -			}
  -		}
  -	}
  -
  -	return false;
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::pushContextMarker(
  -			const XalanNode*	caller,
  -			const XalanNode*	sourceNode)
  -{
  -	StackEntry* const	theEntry = new ContextMarker(caller, sourceNode);
  -
  -	m_stackEntries.insert(theEntry);
  -
  -	push(theEntry);
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::popCurrentContext()
  -{
  -	const int	nElems = m_stack.size();
  -	bool		fFound = false;
  -
  -	// Sub 1 extra for the context marker.
  -	for(int i = (nElems - 1); i >= 0 && fFound == false; i--)
  -	{
  -		const StackEntry* const		theEntry = m_stack[i];
  -		assert(theEntry != 0 && theEntry == back());
  -
  -		const StackEntry::eStackEntryType	type = theEntry->getType();
  -		assert(type < StackEntry::eNextValue && type >= 0);
  -
  -		fFound = type == StackEntry::eContextMarker ? true : false;
  -
  -		pop();
  -	}
  -}
  -
  -
  -
  -class PopPushStackEntry
  -{
  -public:
  -
  -	PopPushStackEntry(
  -			XSLTEngineImpl::VariableStack&	theVariableStack) :
  -		m_variableStack(theVariableStack),
  -		m_stackEntry(theVariableStack.back())
  -	{
  -		theVariableStack.pop();
  -	}
  -
  -	~PopPushStackEntry()
  -	{
  -		m_variableStack.push(m_stackEntry);
  -	}
  -
  -private:
  -
  -	XSLTEngineImpl::VariableStack&	m_variableStack;
  -
  -	StackEntry* const				m_stackEntry;
  -};
  -
  -
  -
  -class CommitPushElementMarker
  -{
  -public:
  -
  -	CommitPushElementMarker(
  -			XSLTEngineImpl::VariableStack&	theVariableStack,
  -			const XalanNode*				targetTemplate) :
  -		m_variableStack(&theVariableStack),
  -		m_targetTemplate(targetTemplate)
  -	{
  -		theVariableStack.pushElementMarker(targetTemplate);
  -	}
  -
  -	~CommitPushElementMarker()
  -	{
  -		if (m_variableStack != 0)
  -		{
  -			m_variableStack->popElementMarker(m_targetTemplate);
  -		}
  -	}
  -
  -	void
  -	commit()
  -	{
  -		m_variableStack = 0;
  -	}
  -
  -private:
  -
  -	XSLTEngineImpl::VariableStack*	m_variableStack;
  -
  -	const XalanNode* const			m_targetTemplate;
  -};
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::pushParams(
  -				StylesheetExecutionContext&		executionContext,
  -				const ElemTemplateElement&		xslCallTemplateElement,
  -				XalanNode*						sourceTree, 
  -				XalanNode*						sourceNode,
  -				const QName&					mode,
  -				const XalanNode*				targetTemplate)
  -{
  -	StackEntry* const		theStackEntry = m_stack.back();
  -
  -	if (theStackEntry->getType() != StackEntry::eContextMarker)
  -	{
  -		throw InvalidStackContextException();
  -	}
  -
  -	VariableStackStackType		tempStack;
  -
  -	const ElemTemplateElement*	child =
  -			xslCallTemplateElement.getFirstChildElem();
  -
  -	if (0 != child)
  -	{
  -		// This object will take care of popping, then
  -		// pushing the context marker at the top of the
  -		// stack, even if an exception is thrown...
  -		PopPushStackEntry	thePopPush(*this);
  -
  -		while(0 != child)
  -		{
  -			if(Constants::ELEMNAME_WITHPARAM == child->getXSLToken())
  -			{
  -				const ElemWithParam* const	xslParamElement =
  -#if defined(XALAN_OLD_STYLE_CASTS)
  -							(ElemWithParam*)child;
  -#else
  -				static_cast<const ElemWithParam*>(child);
  -#endif
  -
  -				Arg*	theArg = 0;
  -
  -				const XPath* const	pxpath = xslParamElement->getSelectPattern();
  -
  -				if(0 != pxpath)
  -				{
  -					XObject* const	theXObject =
  -								pxpath->execute(sourceNode,
  -										*xslParamElement,
  -										executionContext);
  -
  -					theArg = new Arg(xslParamElement->getQName(), theXObject, true);
  -				}
  -				else
  -				{
  -					ResultTreeFragBase* const	theDocFragment =
  -								m_processor.createResultTreeFrag(executionContext,
  -										*xslParamElement,
  -										sourceTree,
  -										sourceNode,
  -										mode);
  -					assert(theDocFragment != 0);
  -
  -#if !defined(XALAN_NO_NAMESPACES)
  -					using std::auto_ptr;
  -#endif
  -
  -					// Make sure this sucker gets cleaned up...
  -					auto_ptr<ResultTreeFragBase>	theGuard(theDocFragment);
  -
  -					XObject* const	var = m_processor.createXResultTreeFrag(*theDocFragment);
  -
  -					theArg = new Arg(xslParamElement->getQName(), var, true);
  -				}
  -				assert(theArg != 0);
  -
  -				m_stackEntries.insert(theArg);
  -
  -				tempStack.push_back(theArg);
  -			}
  -
  -			child = child->getNextSiblingElem();
  -		}
  -	}
  -
  -	// This object will push an element marker, and pop it
  -	// if we don't call it's commit() member function.  So
  -	// if an exception is thrown will transferring the
  -	// parameters, the element marker will be popped.
  -	// This keeps the stack in a consistent state.
  -	CommitPushElementMarker		thePusher(*this,
  -										  targetTemplate);
  -
  -	const VariableStackStackType::size_type		nParams = tempStack.size();
  -
  -	for(VariableStackStackType::size_type i = 0; i < nParams; ++i)
  -	{
  -		push(tempStack[i]);
  -	}
  -
  -	thePusher.commit();
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::pushVariable(
  -			const QName&		name,
  -			XObject*			val,
  -			const XalanNode*	e)
  -{
  -	if(elementMarkerAlreadyPushed(e) == false)
  -	{
  -		pushElementMarker(e);
  -	}
  -
  -	StackEntry* const	theEntry = new Arg(name, val, false);
  -
  -	m_stackEntries.insert(theEntry);
  -
  -	push(theEntry);
  -}
  -
  -
  -
  -
  -XObject*
  -XSLTEngineImpl::VariableStack::findXObject(
  -			const QName&	name,
  -			bool			fSearchGlobalSpace) const
  -{
  -	XObject*		theXObject = 0;
  -
  -	const Arg* const	theArg = findArg(name, fSearchGlobalSpace);
  -
  -	if (theArg != 0)
  -	{
  -		if (theArg->getArgType() == Arg::eXObject)
  -		{
  -			theXObject = theArg->getXObjectPtr();
  -		}
  -	}
  -
  -	return theXObject;
  -}
  -
  -
  -
  -
  -
  -const Arg*
  -XSLTEngineImpl::VariableStack::findArg(
  -			const QName&	qname,
  -			bool			fSearchGlobalSpace) const
  -{
  -	const Arg*	theResult = 0;
  -
  -	const int	nElems = getCurrentStackFrameIndex();
  -
  -	// Sub 1 extra for the context marker.
  -	for(int i = nElems - 1; i >= 0; --i)
  -	{
  -		const StackEntry* const		theEntry =
  -			m_stack[i];
  -		assert(theEntry != 0);
  -
  -		if(theEntry->getType() == StackEntry::eArgument)
  -		{
  -			const Arg* const	theArg =
  -				static_cast<const Arg*>(theEntry);
  -
  -			if(theArg->getName().equals(qname))
  -			{
  -				theResult = theArg;
  -				break;
  -			}
  -		}
  -		else if(theEntry->getType() == StackEntry::eContextMarker)
  -		{
  -			break;
  -		}
  -	}
  -
  -	if(0 == theResult && true == fSearchGlobalSpace)
  -	{
  -		// Look in the global space
  -		for(int i = m_globalStackFrameIndex - 1; i >= 2; i--)
  -		{
  -			const StackEntry* const		theEntry = m_stack[i];
  -			assert(theEntry != 0);
  -
  -			if(theEntry->getType() == StackEntry::eArgument)
  -			{
  -				const Arg* const	theArg =
  -					static_cast<const Arg*>(theEntry);
  -
  -				if(theArg->getName().equals(qname))
  -				{
  -					theResult = theArg;
  -					break;
  -				}
  -			}
  -			else if(theEntry->getType() == StackEntry::eContextMarker)
  -			{
  -				break;
  -			}
  -		}
  -	}
  -
  -	return theResult;
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::pushElementFrame(const ElemTemplateElement*	elem)
  -{
  -	StackEntry* const	theEntry = new ElementFrameMarker(elem);
  -
  -	m_stackEntries.insert(theEntry);
  -
  -	push(theEntry);
  -}
  -
  -
  -
  -void
  -XSLTEngineImpl::VariableStack::popElementFrame(const ElemTemplateElement*	elem)
  -{
  -	const int	nElems = getCurrentStackFrameIndex();
  -
  -	bool		fFound = false;
  -
  -	// Sub 1 extra for the context marker.
  -	for(int i = nElems - 1; i >= 0 && fFound == false; --i)
  -	{
  -		const StackEntry* const		theEntry =
  -			m_stack[i];
  -		assert(theEntry != 0 && theEntry == back());
  -
  -		// Pop it off the stack...
  -		pop();
  -
  -		if(theEntry->getType() == StackEntry::eContextMarker)
  -		{
  -			// Didn't really find it, but quit anyway...
  -			// $$$ ToDo: Isn't this really a bad stack context???
  -			fFound = true;
  -		}
  -		else if (theEntry->getType() == StackEntry::eElementFrameMarker)
  -		{
  -			const ElementFrameMarker* const		theMarker =
  -					static_cast<const ElementFrameMarker*>(theEntry);
  -
  -			const ElemTemplateElement* const	theElement =
  -				theMarker->getElement();
  -
  -			fFound = true;
  -
  -			if (theElement != elem)
  -			{
  -				throw InvalidStackContextException();
  -			}
  -		}
  -    }
  -}
  -
  -
  -
  -XSLTEngineImpl::VariableStack::InvalidStackContextException::InvalidStackContextException() :
  -	XSLTProcessorException(XALAN_STATIC_UCODE_STRING("Invalid stack context"),
  -						   XALAN_STATIC_UCODE_STRING("InvalidStackContextException"))
  -{
  -}
  -
  -
  -
  -XSLTEngineImpl::VariableStack::InvalidStackContextException::~InvalidStackContextException()
  -{
  +	return m_xobjectFactory.returnObject(theXObject);
   }
   
   
  
  
  
  1.38      +37 -542   xml-xalan/c/src/XSLT/XSLTEngineImpl.hpp
  
  Index: XSLTEngineImpl.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTEngineImpl.hpp,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -r1.37 -r1.38
  --- XSLTEngineImpl.hpp	2000/07/06 20:19:25	1.37
  +++ XSLTEngineImpl.hpp	2000/07/21 19:52:58	1.38
  @@ -93,14 +93,14 @@
   
   
   #include <XPath/Function.hpp>
  -#include <XPath/MutableNodeRefList.hpp>
  +//#include <XPath/MutableNodeRefList.hpp>
   #include <XPath/NameSpace.hpp>
   
   
   
  -#include "Arg.hpp"
   #include "KeyDeclaration.hpp"
  -#include "ProblemListener.hpp"
  +#include "ProblemListenerDefault.hpp"
  +#include "StylesheetExecutionContext.hpp"
   #include "XSLTProcessorException.hpp"
   
   
  @@ -113,8 +113,6 @@
   class InputSource;
   class PrintWriter;
   class ResultTreeFragBase;
  -class StackEntry;
  -class Stylesheet;
   class StylesheetConstructionContext;
   class StylesheetExecutionContext;
   class StylesheetRoot;
  @@ -124,7 +122,6 @@
   class XMLParserLiaison;
   class XMLURL;
   class XObject;
  -class XObjectObject;
   class XPathEnvSupport;
   class XPathFactory;
   class XPathProcessor;
  @@ -154,26 +151,20 @@
   #	define XALAN_STD std::
   #endif
   
  -	typedef XALAN_STD auto_ptr<XPathProcessor>	  XPathProcessorPtrType;
  -	typedef XALAN_STD map<XalanDOMString, XObject*>    TopLevelVariablesMapType;
  -	typedef XALAN_STD map<XalanDOMString, int>		   AttributeKeysMapType;
  -	typedef XALAN_STD map<XalanDOMString, int>		   ElementKeysMapType;
  -	typedef XALAN_STD map<const void*, clock_t>   DurationsTableMapType;
  -	typedef XALAN_STD set<XalanDOMString>			   TranslateCSSSetType;
  -	typedef XALAN_STD vector<Arg>				  ParamVectorType;
  -	typedef XALAN_STD vector<ElemAttributeSet*>   AttrStackType;
  -	typedef XALAN_STD vector<KeyDeclaration>	  KeyDeclarationVectorType;
  -	typedef XALAN_STD vector<const Locator*>	  LocatorStack;
  -	typedef XALAN_STD vector<NameSpace> 		  NamespaceVectorType;
  -	typedef XALAN_STD vector<NamespaceVectorType> NamespacesStackType;
  -	typedef XALAN_STD vector<TraceListener*>	  TraceListenerVectorType;
  -	typedef XALAN_STD vector<bool>				  BoolVectorType;
  -
  -
  -	typedef XALAN_STD map<const XalanNode*, int>	XSLDirectiveMapType;
  +	typedef XALAN_STD auto_ptr<XPathProcessor>			XPathProcessorPtrType;
  +	typedef XALAN_STD map<XalanDOMString, int>			AttributeKeysMapType;
  +	typedef XALAN_STD map<XalanDOMString, int>			ElementKeysMapType;
  +	typedef XALAN_STD map<const void*, clock_t>			DurationsTableMapType;
  +	typedef XALAN_STD vector<const Locator*>			LocatorStack;
  +	typedef XALAN_STD vector<NameSpace> 				NamespaceVectorType;
  +	typedef XALAN_STD vector<NamespaceVectorType>		NamespacesStackType;
  +	typedef XALAN_STD vector<TraceListener*>			TraceListenerVectorType;
  +	typedef XALAN_STD vector<bool>						BoolVectorType;
  +	typedef XALAN_STD map<const XalanNode*, int>		XSLDirectiveMapType;
   #undef XALAN_STD
   
  -	typedef Function::XObjectArgVectorType	XObjectArgVectorType;
  +	typedef Function::XObjectArgVectorType				XObjectArgVectorType;
  +	typedef StylesheetExecutionContext::ParamVectorType	ParamVectorType;
   
   	// Public members
   	//---------------------------------------------------------------------
  @@ -240,6 +231,13 @@
   	static void
   	Initialize();
   
  +	/**
  +	 * Perform termination of statics -- can be called to make memory
  +	 * leak detection easier.
  +	 */
  +	static void
  +	Terminate();
  +
   	// These methods are inherited from XSLTProcessor ...
   	
   	virtual void
  @@ -272,20 +270,11 @@
   	virtual void
   	outputToResultTree(const XObject&	xobj);
   
  -	virtual XObject*
  -	getTopLevelVariable(const XalanDOMString&	theName) const;
  -
   	virtual void
   	resetCurrentState(
   			XalanNode*	sourceTree,
   			XalanNode*	xmlNode);
   
  -	virtual XalanDocument*
  -	getRootDoc() const;
  -
  -	virtual void
  -	setRootDoc(XalanDocument*	doc);
  -
   	virtual XalanDOMString
   	evaluateAttrVal(
   			XalanNode*				contextNode,
  @@ -315,23 +304,23 @@
   	
   	virtual XObject*
   	createXResultTreeFrag(const ResultTreeFragBase&		r) const;
  -
  -	virtual XObject*
  -	getVariable(const QName&	qname) const;
   
  -	virtual XObject*
  -	getParamVariable(const QName&	theName) const;
  +	/**
  +	 * Function to destroy an XObject that was returned
  +	 * by executing.  It is safe to call this function
  +	 * with any XObject.
  +	 *
  +	 * @param theXObject pointer to the XObject.
  +	 * @return true if the object was destroyed.
  +	 */
  +	virtual bool
  +	destroyXObject(XObject*		theXObject) const;
   
   	virtual void
  -	pushVariable(
  -			const QName&		name,
  -			XObject*			var,
  -			const XalanNode*	element);
  -
  -	virtual void setStylesheetParam(	
  +	setStylesheetParam(	
   					const XalanDOMString&	key,
   					const XalanDOMString&	expression);
  -	
  +
   	virtual void
   	setStylesheetParam(
   			const XalanDOMString&	key,
  @@ -974,59 +963,6 @@
   			const XalanDocument& 	doc) const;
   
   	/**
  -	 * Push a context marker onto the stack to let us know when to stop
  -	 * searching for a var.
  -	 *
  -	 * @param caller	 caller node
  -	 * @param sourceNode source node
  -	 */
  -	void
  -	pushContextMarker(
  -			const XalanNode*	caller,
  -			const XalanNode*	sourceNode)
  -	{
  -		m_variableStacks.pushContextMarker(caller, sourceNode);
  -	}
  -
  -	/**
  -	 * Pop the current context from the current context stack.
  -	 */
  -	void
  -	popCurrentContext()
  -	{
  -		m_variableStacks.popCurrentContext();
  -	}
  -
  -	/**
  -	 * Given a template, search for the arguments and push them on the stack.
  -	 * Also, push default arguments on the stack. You <em>must</em> call
  -	 * popContext() when you are done with the arguments.
  -	 *
  -	 * @param executionContext		 execution context
  -	 * @param xslCallTemplateElement "call-template" element
  -	 * @param sourceTree			 source tree
  -	 * @param sourceNode			 source node
  -	 * @param mode					 mode under which the template is operating
  -	 * @param targetTemplate		 target template
  -	 */
  -	void
  -	pushParams(
  -			StylesheetExecutionContext& 	executionContext,
  -			const ElemTemplateElement&		xslCallTemplateElement,
  -			XalanNode* 						sourceTree, 
  -			XalanNode* 						sourceNode,
  -			const QName&					mode,
  -			const XalanNode* 				targetTemplate)
  -	{
  -		m_variableStacks.pushParams(executionContext,
  -									xslCallTemplateElement,
  -									sourceTree,
  -									sourceNode,
  -									mode,
  -									targetTemplate);
  -	}
  -
  -	/**
   	 * Given an element, return an attribute value in the form of a string.
   	 *
   	 * @param el		  element from where to get the attribute
  @@ -1220,26 +1156,7 @@
   		return m_xpathEnvSupport;
   	}
   
  -	// $$$ ToDo: why isn't this just a NodeRefListBase?
  -	const MutableNodeRefList&
  -	getContextNodeList() const
  -	{
  -		return m_contextNodeList;
  -	}
  -
   	/**
  -	 * Set node list for current context.
  -	 * 
  -	 * @param ref new node list
  -	 */
  -	// $$$ ToDo: why isn't this just a NodeRefListBase?
  -	void
  -	setContextNodeList(const MutableNodeRefList&	ref)
  -	{
  -		m_contextNodeList = ref;		
  -	}
  -
  -	/**
   	 * Set the problem listener property. The XSL class can have a single
   	 * listener that can be informed of errors and warnings, and can normally
   	 * control if an exception is thrown or not (or the problem listeners can
  @@ -1308,331 +1225,6 @@
   	}
   
   	/**
  -	 * An class for  exceptions that occur when a given stylesheet goes into an
  -	 * infinite loop.
  -	 */
  -	class XSLInfiniteLoopException : public XSLTProcessorException
  -	{
  -	public:
  -		XSLInfiniteLoopException();
  -
  -		virtual
  -		~XSLInfiniteLoopException();
  -	};
  -
  -	/**
  -	 * Defines a class to keep track of a stack for macro arguments.
  -	 */
  -	class VariableStack
  -	{
  -	public:
  -
  -		/**
  -		 * Constructor for a variable stack.
  -		 * 
  -		 * @param theProcessor XSL processor
  -		 */
  -		VariableStack(XSLTEngineImpl&		theProcessor);
  -
  -		~VariableStack();
  -
  -	
  -		/**
  -		 * Reset the stack.
  -		 */
  -		virtual void
  -		reset();
  -
  -		/**
  -		 * Push a context marker onto the stack to let us know when 
  -		 * to stop searching for a var.
  -		 * 
  -		 * @param elem element for context
  -		 */
  -		void
  -		pushElementMarker(const XalanNode*	elem);
  -
  -		/**
  -		 * Pop the current context from the current context stack.
  -		 * 
  -		 * @param elem element for context
  -		 */
  -		void
  -		popElementMarker(const XalanNode*	elem);
  -
  -		/**
  -		 * Check to see if an element marker for the particular node has already
  -		 * been pushed.
  -		 * 
  -		 * @param elem node in question
  -		 * @return true if it has been pushed already
  -		 */
  -		bool
  -		elementMarkerAlreadyPushed(const XalanNode*		elem) const;
  -
  -		/**
  -		 * Push a context marker onto the stack to let us know when to stop
  -		 * searching for a var.
  -		 *
  -		 * @param caller	 caller node
  -		 * @param sourceNode source node
  -		 */
  -		void
  -		pushContextMarker(
  -				const XalanNode*	caller,
  -				const XalanNode*	sourceNode);
  -
  -		/**
  -		 * Pop the current context from the current context stack.
  -		 */
  -		void
  -		popCurrentContext();
  -
  -		/**
  -		 * Given a template, search for the arguments and push them on the stack.
  -		 * Also, push default arguments on the stack. You <em>must</em> call
  -		 * popContext() when you are done with the arguments.
  -		 *
  -		 * @param executionContext		 execution context
  -		 * @param xslCallTemplateElement "call-template" element
  -		 * @param sourceTree			 source tree
  -		 * @param sourceNode			 source node
  -		 * @param mode					 mode under which the template is operating
  -		 * @param targetTemplate		 target template
  -		 */
  -		void
  -		pushParams(
  -				StylesheetExecutionContext& 	executionContext,
  -				const ElemTemplateElement&		xslCallTemplateElement,
  -				XalanNode*						sourceTree, 
  -				XalanNode*						sourceNode,
  -				const QName&					mode,
  -				const XalanNode*				targetTemplate);
  -
  -		/**
  -		 * Given a name, return a string representing the value, but don't look
  -		 * in the global space.
  -		 *
  -		 * @param theName name of variable
  -		 * @return pointer to XObject for variable
  -		 */
  -		XObject*
  -		getXObjectParamVariable(const QName& qname) const
  -		{
  -			return findXObject(qname, false);
  -		}
  -
  -		/**
  -		 * Given a name, find the corresponding XObject.
  -		 *
  -		 * @param qname name of variable
  -		 * @return pointer to the corresponding XObject
  -		 */
  -		XObject*
  -		getXObjectVariable(const QName& 	name) const
  -		{
  -			return findXObject(name, true);
  -		}
  -
  -		/**
  -		 * Push a named variable onto the processor variable stack. Don't forget
  -		 * to call startContext before pushing a series of arguments for a given
  -		 * macro call.
  -		 *
  -		 * @param name	  name of variable
  -		 * @param val	  pointer to XObject value
  -		 * @param e 	  element marker for variable
  -		 */
  -		void
  -		pushVariable(
  -				const QName&		name,
  -				XObject*			val,
  -				const XalanNode*	e);
  -
  -		/**
  -		 * Mark the top of the global stack frame.
  -		 */
  -		void
  -		markGlobalStackFrame()
  -		{
  -			m_globalStackFrameIndex = m_stack.size();
  -
  -			pushContextMarker(0, 0);
  -		}
  -
  -		/**
  -		 * Set the top of the stack frame from where a search for a variable or
  -		 * param should take place.  Calling with no parameter will cause the
  -		 * index to be set to the size of the stack.
  -		 *
  -		 * @param currentStackFrameIndex new value of index
  -		 */
  -		void
  -		setCurrentStackFrameIndex(int	currentStackFrameIndex = -1)
  -		{
  -			if (currentStackFrameIndex == -1)
  -				m_currentStackFrameIndex = m_stack.size();
  -			else
  -				m_currentStackFrameIndex = currentStackFrameIndex;
  -		}
  -
  -		/**
  -		 * Get the top of the stack frame from where a search 
  -		 * for a variable or param should take place.
  -		 *
  -		 * @return current value of index
  -		 */
  -		int
  -		getCurrentStackFrameIndex() const
  -		{
  -			return m_currentStackFrameIndex;
  -		}
  -
  -		/**
  -		 * Push an entry onto the stack.
  -		 *
  -		 * @param stack entry to push
  -		 */
  -		void
  -		push(StackEntry*	theEntry)
  -		{
  -			assert(theEntry != 0);
  -			assert(theEntry->getType() < StackEntry::eNextValue && theEntry->getType() >= 0);
  -
  -			if(m_currentStackFrameIndex == m_stack.size())
  -			{
  -				++m_currentStackFrameIndex;
  -			}
  -
  -			m_stack.push_back(theEntry);
  -		}
  -
  -		/**
  -		 * Override the pop in order to track the 
  -		 * m_currentStackFrameIndex correctly.
  -		 *
  -		 * @return stack entry popped
  -		 */
  -		void
  -		pop()
  -		{
  -			assert(m_stack.empty() == false);
  -
  -			if(m_currentStackFrameIndex == m_stack.size())
  -			{
  -				--m_currentStackFrameIndex;
  -			}
  -
  -			// We can't really delete anything here, since
  -			// the caller may still be referring to the
  -			// stack entry...
  -			m_stack.pop_back();
  -		}
  -
  -		StackEntry*
  -		back() const
  -		{
  -			assert(m_stack.empty() == false);
  -
  -			return m_stack.back();
  -		}
  -
  -		/**
  -		 * Push a frame marker for an element.
  -		 *
  -		 * @param elem the element
  -		 */
  -		void
  -		pushElementFrame(const ElemTemplateElement*		elem);
  -
  -		/**
  -		 * Pop a frame marker for an element.
  -		 *
  -		 * @param elem the element
  -		 */
  -		void
  -		popElementFrame(const ElemTemplateElement*	elem);
  -
  -
  -		class InvalidStackContextException : public XSLTProcessorException
  -		{
  -		public:
  -
  -			InvalidStackContextException();
  -
  -			virtual
  -			~InvalidStackContextException();
  -
  -		private:
  -
  -		};
  -
  -	private:
  -
  -		// Default stack vector allocation size.
  -		enum
  -		{
  -			eDefaultVectorSize = 200
  -		};
  -
  -		XObject*
  -		findXObject(
  -				const QName&	name,
  -				bool			fSearchGlobalSpace) const;
  -
  -		const Arg*
  -		findArg(
  -				const QName&	name,
  -				bool			fSearchGlobalSpace) const;
  -
  -		// $$$ ToDo:  Is this really used?
  -		/**
  -		 * Holds caller, so that it may be searched for 
  -		 * xsl:params, in order to resolve xsl:param-arg.
  -		 */
  -		const XalanElement* 			m_caller;
  -
  -
  -#if defined(XALAN_NO_NAMESPACES)
  -		typedef vector<StackEntry*>			VariableStackStackType;
  -		typedef set<StackEntry*>			StackEntrySetType;
  -#else
  -		typedef std::vector<StackEntry*>	VariableStackStackType;
  -		typedef std::set<StackEntry*>		StackEntrySetType;
  -#endif
  -
  -		VariableStackStackType			m_stack;
  -
  -		StackEntrySetType				m_stackEntries;
  -
  -		XSLTEngineImpl&					m_processor;
  -
  -		int								m_globalStackFrameIndex;
  -
  -		/**
  -		 * This is the top of the stack frame from where a search 
  -		 * for a variable or param should take place.  It may not 
  -		 * be the real stack top.
  -		 */
  -		unsigned int					m_currentStackFrameIndex;
  -	
  -	}; // end VariableStack
  -
  -	// Give VariableStack access to stuff.
  -	friend class VariableStack;
  -
  -	/**
  -	 * Accessor method for variable stack.
  -	 * 
  -	 * @return variable stack
  -	 */
  -	VariableStack&
  -	getVariableStacks()
  -	{
  -		return m_variableStacks;
  -	}
  -
  -	/**
   	 * Create a document fragment.	This function may return null.
   	 *
   	 * @return pointer to new document fragment
  @@ -1673,17 +1265,6 @@
   	setPendingElementName(const XalanDOMString&		elementName);
   
   	/**
  -	 * Accessor method for stack that keeps track of the attribute elements.
  -	 *
  -	 * @return attribute stack
  -	 */
  -	AttrStackType&
  -	getAttrSetStack()
  -	{ 
  -		return m_attrSetStack; 
  -	}
  -
  -	/**
   	 * Get the locator from the top of the locator stack.
   	 *
   	 * @return A pointer to the Locator, or 0 if there is nothing on the stack.
  @@ -1878,17 +1459,13 @@
   	LocatorStack  m_stylesheetLocatorStack;
   
   	/**
  -	 * The stack of Variable stacks.  A VariableStack will be 
  -	 * pushed onto this stack for each template invocation.
  -	 */
  -	VariableStack	m_variableStacks;
  -
  -	/**
   	 * The XSL class can have a single listener that can be informed 
   	 * of errors and warnings, and can normally control if an exception
   	 * is thrown or not (or the problem listeners can throw their 
   	 * own RuntimeExceptions).
   	 */
  +	ProblemListenerDefault	m_defaultProblemListener;
  +
   	ProblemListener*	m_problemListener;
   
     /**
  @@ -2003,19 +1580,6 @@
   	translateCSSAttrsToStyleAttr(AttributeListImpl&		attList);
   
   	/**
  -	 * Given a name, locate a variable in the current context, and return 
  -	 * the XObject.
  -	 *
  -	 * @param executionContext The current execution context.
  -	 * @param name The name of the variable
  -	 * @return a pointer to an XObject that represents the variable.
  -	 */
  -	XObject*
  -	getXObjectVariable(
  -			StylesheetExecutionContext&		executionContext,
  -			const XalanDOMString&			name) const;
  -
  -	/**
   	 * Get an XLocator provider keyed by node.	This gets the association
   	 * based on the root of the tree that is the node's parent.
   	 *
  @@ -2143,79 +1707,10 @@
   	MutableNodeRefList	m_contextNodeList;
   
   	/**
  -	 * Table for defined constants, keyed on the names.
  +	 * Current execution context...
   	 */
  -	TopLevelVariablesMapType		m_topLevelVariables;
  -
   	StylesheetExecutionContext*		m_executionContext;
   
  -	/**
  -	 * The StackGuard class guard against infinite loops.
  -	 */
  -	class StackGuard
  -	{
  -	public:
  -
  -#if defined(XALAN_NO_NAMESPACES)
  -		typedef vector<StackGuard>			StackGuardStackType;
  -#else
  -		typedef std::vector<StackGuard>		StackGuardStackType;
  -#endif
  -
  -		StackGuard(
  -				XSLTEngineImpl& 		processor,
  -				const XalanElement*		xslTemplate = 0,
  -				const XalanNode* 		sourceXML = 0);
  -
  -		~StackGuard();
  -
  -		bool operator==(const StackGuard&	theRHS) const
  -		{
  -			return m_xslRule == theRHS.m_xslRule &&
  -				   m_sourceXML == theRHS.m_sourceXML;
  -		}
  -
  -		void print(PrintWriter& pw) const;
  -
  -		void push(
  -				const XalanElement*		xslTemplate,
  -				const XalanNode* 		sourceXML);
  -
  -		void pop();
  -
  -		void clear()
  -		{
  -			m_stack.clear();
  -		}
  -
  -		void
  -		checkForInfiniteLoop(const StackGuard&	guard) const;
  -
  -	private:
  -
  -		XSLTEngineImpl*			m_processor;
  -		const XalanElement* 	m_xslRule;
  -		const XalanNode*		m_sourceXML;
  -
  -		StackGuardStackType 	m_stack;
  -	};
  -
  -
  -	// This is set to true when the "ancestor" attribute of 
  -	// the select element is encountered.
  -	bool		m_needToCheckForInfiniteLoops;
  -
  -	/**
  -	 * Object to guard agains infinite recursion when 
  -	 * doing queries.
  -	 */
  -	StackGuard	m_stackGuard;
  -
  -	/**
  -	 * Stack for the purposes of flagging infinite recursion with 
  -	 * attribute sets.
  -	 */
  -	AttrStackType	m_attrSetStack;
   
   	static void
   	InstallFunctions();
  
  
  
  1.12      +8 -55     xml-xalan/c/src/XSLT/XSLTProcessor.hpp
  
  Index: XSLTProcessor.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTProcessor.hpp,v
  retrieving revision 1.11
  retrieving revision 1.12
  diff -u -r1.11 -r1.12
  --- XSLTProcessor.hpp	2000/06/01 16:28:37	1.11
  +++ XSLTProcessor.hpp	2000/07/21 19:52:58	1.12
  @@ -227,15 +227,6 @@
   	outputToResultTree(const XObject&	xobj) = 0;
   
   	/**
  -	 * Retrieve a top level variable corresponding to name.
  -	 * 
  -	 * @param theName name of variable
  -	 * @return pointer to XObject for variable
  -	 */
  -	virtual XObject*
  -	getTopLevelVariable(const XalanDOMString&	theName) const = 0;
  -
  -	/**
   	 * Reset the state of execution to node 'xmlNode' in source tree
   	 * 'sourceTree.'
   	 * 
  @@ -248,22 +239,6 @@
   			XalanNode*	xmlNode) = 0;
   
   	/**
  -	 * Retrieve root document for stylesheet.
  -	 * 
  -	 * @return root document
  -	 */
  -	virtual XalanDocument*
  -	getRootDoc() const = 0;
  -
  -	/**
  -	 * Set root document for stylesheet.
  -	 * 
  -	 * @param doc root document
  -	 */
  -	virtual void
  -	setRootDoc(XalanDocument*	doc) = 0;
  -
  -	/**
   	 * Retrieve the root stylesheet.
   	 * 
   	 * @return pointer to root stylesheet
  @@ -358,7 +333,7 @@
      getUniqueNSValue() const = 0;
   
   	/**
  -	 * Convenience function to create an XObject that represents a Result tree
  +	 * Function to create an XObject that represents a Result tree
   	 * fragment.
   	 *
   	 * @param r result tree fragment to use
  @@ -367,38 +342,16 @@
      virtual XObject*
      createXResultTreeFrag(const ResultTreeFragBase&	r) const = 0;
   
  -	/**
  -	 * Given a name, locate a variable in the current context, and return 
  -	 * a pointer to the object.
  -	 *
  -	 * @param theName name of variable
  -	 * @return pointer to an XObject if the variable was found, 0 if it was not
  -	 */
  -   virtual XObject*
  -   getVariable(const QName& qname) const = 0;
  -
   	/**
  -	 * Given a name, return a string representing the value, but don't look in
  -	 * the global space.
  +	 * Function to destroy an XObject that was returned
  +	 * by executing.  It is safe to call this function
  +	 * with any XObject.
   	 *
  -	 * @param theName name of variable
  -	 * @return pointer to XObject for variable
  +	 * @param theXObject pointer to the XObject.
  +	 * @return true if the object was destroyed.
   	 */
  -	virtual XObject*
  -	getParamVariable(const QName&	theName) const = 0;
  -
  -	/**
  -	 * Push a named variable onto the processor variable stack
  -	 *
  -	 * @param name	  name of variable
  -	 * @param var	  pointer to XObject value
  -	 * @param element element marker for variable
  -	 */
  -	virtual void
  -	pushVariable(
  -			const QName&		name,
  -			XObject*			var,
  -			const XalanNode*	element) = 0;
  +   virtual bool
  +   destroyXObject(XObject*	theXObject) const = 0;
   
     /**
   	* Push a top-level stylesheet parameter.  This value can be evaluated via
  
  
  
  1.6       +0 -5      xml-xalan/c/src/XSLT/XSLTProcessorEnvSupport.hpp
  
  Index: XSLTProcessorEnvSupport.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTProcessorEnvSupport.hpp,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- XSLTProcessorEnvSupport.hpp	2000/05/24 19:38:50	1.5
  +++ XSLTProcessorEnvSupport.hpp	2000/07/21 19:52:58	1.6
  @@ -106,11 +106,6 @@
   			const PrefixResolver&	resolver,
   			XPathExecutionContext&	executionContext) const = 0;
   
  -	virtual XObject*
  -	getVariable(
  -			XObjectFactory&		factory,
  -			const QName&		name) const = 0;
  -
   	virtual XalanDocument*
   	parseXML(
   			const XalanDOMString&	urlString,
  
  
  
  1.14      +0 -18     xml-xalan/c/src/XSLT/XSLTProcessorEnvSupportDefault.cpp
  
  Index: XSLTProcessorEnvSupportDefault.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTProcessorEnvSupportDefault.cpp,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- XSLTProcessorEnvSupportDefault.cpp	2000/05/29 22:43:47	1.13
  +++ XSLTProcessorEnvSupportDefault.cpp	2000/07/21 19:52:58	1.14
  @@ -251,24 +251,6 @@
   
   
   
  -XObject*
  -XSLTProcessorEnvSupportDefault::getVariable(
  -			XObjectFactory&		factory,
  -			const QName&		name) const
  -{
  -	if (m_processor == 0)
  -	{
  -		return m_defaultSupport.getVariable(factory,
  -											name);
  -	}
  -	else
  -	{
  -		return m_processor->getVariable(name);
  -	}
  -}
  -
  -
  -
   XalanDocument*
   XSLTProcessorEnvSupportDefault::parseXML(
   		const XalanDOMString&	urlString,
  
  
  
  1.11      +0 -5      xml-xalan/c/src/XSLT/XSLTProcessorEnvSupportDefault.hpp
  
  Index: XSLTProcessorEnvSupportDefault.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTProcessorEnvSupportDefault.hpp,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- XSLTProcessorEnvSupportDefault.hpp	2000/05/24 19:38:50	1.10
  +++ XSLTProcessorEnvSupportDefault.hpp	2000/07/21 19:52:58	1.11
  @@ -177,11 +177,6 @@
   			const PrefixResolver&	resolver,
   			XPathExecutionContext&	executionContext) const;
   
  -	virtual XObject*
  -	getVariable(
  -			XObjectFactory&		factory,
  -			const QName&		name) const;
  -
   	virtual XalanDocument*
   	parseXML(
   			const XalanDOMString&	urlString,
  
  
  
  1.5       +49 -7     xml-xalan/c/src/XSLT/XSLTResultTarget.cpp
  
  Index: XSLTResultTarget.cpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTResultTarget.cpp,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -r1.4 -r1.5
  --- XSLTResultTarget.cpp	2000/04/25 19:54:20	1.4
  +++ XSLTResultTarget.cpp	2000/07/21 19:52:58	1.5
  @@ -72,7 +72,9 @@
   	m_byteStream(0),
   	m_encoding(),
   	m_characterStream(0),
  -	m_node(),
  +	m_document(0),
  +	m_documentFragment(0),
  +	m_element(0),
   	m_formatterListener(0)
   {
   }
  @@ -84,7 +86,9 @@
   	m_byteStream(0),
   	m_encoding(),
   	m_characterStream(0),
  -	m_node(),
  +	m_document(0),
  +	m_documentFragment(0),
  +	m_element(0),
   	m_formatterListener(0)
   {
   }
  @@ -100,7 +104,9 @@
   	m_byteStream(theStream),
   	m_encoding(),
   	m_characterStream(0),
  -	m_node(),
  +	m_document(0),
  +	m_documentFragment(0),
  +	m_element(0),
   	m_formatterListener(0)
   {
   	assert(theStream != 0);
  @@ -113,7 +119,9 @@
   	m_byteStream(0),
   	m_encoding(),
   	m_characterStream(characterStream),
  -	m_node(),
  +	m_document(0),
  +	m_documentFragment(0),
  +	m_element(0),
   	m_formatterListener(0)
   {
   	assert(characterStream != 0);
  @@ -121,13 +129,47 @@
   
   
   
  -XSLTResultTarget::XSLTResultTarget(XalanNode*	n) :
  +XSLTResultTarget::XSLTResultTarget(XalanDocument*	document) :
   	m_fileName(),
   	m_byteStream(0),
   	m_encoding(),
   	m_characterStream(0),
  -	m_node(n),
  +	m_document(document),
  +	m_documentFragment(0),
  +	m_element(0),
   	m_formatterListener(0)
   {
  -	assert(n != 0);
  +	assert(document != 0);
   }
  +
  +
  +
  +XSLTResultTarget::XSLTResultTarget(XalanDocumentFragment*	documentFragment) :
  +	m_fileName(),
  +	m_byteStream(0),
  +	m_encoding(),
  +	m_characterStream(0),
  +	m_document(0),
  +	m_documentFragment(documentFragment),
  +	m_element(0),
  +	m_formatterListener(0)
  +{
  +	assert(documentFragment != 0);
  +}
  +
  +
  +
  +XSLTResultTarget::XSLTResultTarget(XalanElement*	element) :
  +	m_fileName(),
  +	m_byteStream(0),
  +	m_encoding(),
  +	m_characterStream(0),
  +	m_document(0),
  +	m_documentFragment(0),
  +	m_element(element),
  +	m_formatterListener(0)
  +{
  +	assert(element != 0);
  +}
  +
  +
  
  
  
  1.9       +98 -19    xml-xalan/c/src/XSLT/XSLTResultTarget.hpp
  
  Index: XSLTResultTarget.hpp
  ===================================================================
  RCS file: /home/cvs/xml-xalan/c/src/XSLT/XSLTResultTarget.hpp,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- XSLTResultTarget.hpp	2000/05/31 17:01:19	1.8
  +++ XSLTResultTarget.hpp	2000/07/21 19:52:59	1.9
  @@ -82,7 +82,9 @@
   
   
   
  -class XalanNode;
  +class XalanDocument;
  +class XalanDocumentFragment;
  +class XalanElement;
   class Writer;
   
   
  @@ -121,13 +123,27 @@
   	XSLTResultTarget(Writer*	characterStream);
   
   	/**
  -	 * Create a new output target with a DOM node.
  +	 * Create a new output target with a DOM document.
   	 *
   	 * @param n root of DOM node tree that holds results
   	 */
  -	XSLTResultTarget(XalanNode*	n);
  +	XSLTResultTarget(XalanDocument*		document);
   
   	/**
  +	 * Create a new output target with a DOM document fragment.
  +	 *
  +	 * @param n root of DOM node tree that holds results
  +	 */
  +	XSLTResultTarget(XalanDocumentFragment*		documentFragment);
  +
  +	/**
  +	 * Create a new output target with a DOM element.
  +	 *
  +	 * @param n root of DOM node tree that holds results
  +	 */
  +	XSLTResultTarget(XalanElement*	element);
  +
  +	/**
   	 * Set the file name where the results will be written.
   	 *
   	 * @param fileName system identifier as a string
  @@ -225,29 +241,88 @@
   		return m_characterStream;
   	}
   
  +	bool
  +	hasDOMTarget() const
  +	{
  +		return m_document != 0 || m_documentFragment != 0 || m_element != 0;
  +	}
  +
   	/**
  -	 * Set the node that will contain the result nodes.
  +	 * Set the document node that will contain the result nodes.
   	 *
   	 * @param node DOM node to contain results
   	 */
   	void
  -	setNode(XalanNode*	node)
  +	setDocument(XalanDocument*		document)
  +	{
  +		m_document = document;
  +
  +		m_documentFragment = 0;
  +		m_element = 0;
  +	}
  +
  +	/**
  +	 * Get the document node that will contain the result nodes.
  +	 *
  +	 * @return a pointer to the document node
  +	 */
  +	XalanDocument*
  +	getDocument() const
   	{
  -		m_node = node;
  +		return m_document;
   	}
   
   	/**
  -	 * Get the node that will contain the result nodes.
  +	 * Set the document fragment node that will contain the result nodes.
   	 *
  -	 * @return DOM node containing results
  +	 * @param node DOM node to contain results
   	 */
  -	XalanNode*
  -	getNode() const
  +	void
  +	setDocumentFragment(XalanDocumentFragment*	documentFragment)
   	{
  -		return m_node;
  +		m_documentFragment = documentFragment;
  +
  +		m_document = 0;
  +		m_element = 0;
   	}
  -	
  +
   	/**
  +	 * Get the document node that will contain the result nodes.
  +	 *
  +	 * @return a pointer to the document node
  +	 */
  +	XalanDocumentFragment*
  +	getDocumentFragment() const
  +	{
  +		return m_documentFragment;
  +	}
  +
  +	/**
  +	 * Set the element node that will contain the result nodes.
  +	 *
  +	 * @param node DOM node to contain results
  +	 */
  +	void
  +	setElement(XalanElement*	element)
  +	{
  +		m_element = element;
  +
  +		m_documentFragment = 0;
  +		m_document = 0;
  +	}
  +
  +	/**
  +	 * Get the document node that will contain the result nodes.
  +	 *
  +	 * @return a pointer to the document node
  +	 */
  +	XalanElement*
  +	getElement() const
  +	{
  +		return m_element;
  +	}
  +
  +	/**
   	 * Set a SAX DocumentHandler to process the result tree events.
   	 *
   	 * @param handler pointer to new handler
  @@ -293,21 +368,25 @@
   
   private:
   
  -	XalanDOMString		m_fileName;
  +	XalanDOMString			m_fileName;
   
   #if defined(XALAN_NO_NAMESPACES)
  -	ostream*			m_byteStream;
  +	ostream*				m_byteStream;
   #else
  -	std::ostream*		m_byteStream;
  +	std::ostream*			m_byteStream;
   #endif
  +
  +	XalanDOMString			m_encoding;
  +
  +	Writer*					m_characterStream;
   
  -	XalanDOMString		m_encoding;
  +	XalanDocument*			m_document;
   
  -	Writer*				m_characterStream;
  +	XalanDocumentFragment*	m_documentFragment;
   
  -	XalanNode*			m_node;
  +	XalanElement*			m_element;
   
  -	FormatterListener*	m_formatterListener;
  +	FormatterListener*		m_formatterListener;
   };