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:46:12 UTC
cvs commit: xml-xalan/c/src/XSLT TopLevelArg.cpp TopLevelArg.hpp VariablesStack.cpp VariablesStack.hpp
dbertoni 00/07/21 12:46:11
Added: c/src/XSLT TopLevelArg.cpp TopLevelArg.hpp
VariablesStack.cpp VariablesStack.hpp
Log:
Initial revision.
Revision Changes Path
1.1 xml-xalan/c/src/XSLT/TopLevelArg.cpp
Index: TopLevelArg.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* $ Id: $
*
*/
#include "TopLevelArg.hpp"
TopLevelArg::TopLevelArg(
const QName& name,
const XalanDOMString& expr) :
m_qname(name),
m_expression(expr),
m_xobject(0)
{
}
TopLevelArg::TopLevelArg(
const QName& name,
XObject* variable) :
m_qname(name),
m_expression(),
m_xobject(variable)
{
}
TopLevelArg::TopLevelArg(const TopLevelArg& theSource) :
m_qname(theSource.m_qname),
m_expression(theSource.m_expression),
m_xobject(theSource.m_xobject)
{
}
TopLevelArg::~TopLevelArg()
{
}
1.1 xml-xalan/c/src/XSLT/TopLevelArg.hpp
Index: TopLevelArg.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*
* $ Id: $
*
*/
#if !defined(XALAN_TOPLEVELARG_HEADER_GUARD)
#define XALAN_TOPLEVELARG_HEADER_GUARD
// Base include file. Must be first.
#include <XSLT/XSLTDefinitions.hpp>
#include <XalanDOM/XalanDOMString.hpp>
#include <XPath/QName.hpp>
class XObject;
/**
* This class holds an instance of an argument on the stack.
*/
class TopLevelArg
{
public:
/**
* Construct an argument object from a string expression
*
* @param name name of argument
* @param expr expression argument represents
*/
TopLevelArg(
const QName& name,
const XalanDOMString& expr);
/**
* Construct an argument object from an XObject instance.
*
* @param name name of argument
* @param variable the XObject instance.
*/
TopLevelArg(
const QName& name,
XObject* variable);
/**
* Copy constructor
*
* @param theSource the TopLevelArg to copy.
*/
TopLevelArg(const TopLevelArg& theSource);
/**
* Destructor
*/
~TopLevelArg();
/**
* Retrieve object name
*
* @return qualified name of object
*/
const QName&
getName() const
{
return m_qname;
}
/**
* Retrieve object's expression
*
* @return string representation of expression
*/
const XalanDOMString&
getExpression() const
{
return m_expression;
};
/**
* Retrieve object's XObject variable.
*
* @return pointer to the XObject instance
*/
XObject*
getXObject() const
{
return m_xobject;
}
/**
* Assignment operator
*/
TopLevelArg&
operator=(const TopLevelArg& theRHS)
{
if (&theRHS != this)
{
m_qname = theRHS.m_qname;
m_expression = theRHS.m_expression;
}
return *this;
}
private:
QName m_qname;
XalanDOMString m_expression;
XObject* m_xobject;
};
#endif // XALAN_TOPLEVELARG_HEADER_GUARD
1.1 xml-xalan/c/src/XSLT/VariablesStack.cpp
Index: VariablesStack.cpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
// Class header file.
#include "VariablesStack.hpp"
#include <algorithm>
VariablesStack::VariablesStack() :
m_stack(),
m_globalStackFrameIndex(-1),
m_currentStackFrameIndex(0)
{
m_stack.reserve(eDefaultStackSize);
}
VariablesStack::~VariablesStack()
{
}
void
VariablesStack::reset()
{
while(m_stack.size() > 0)
{
pop();
}
m_stack.clear();
}
bool
VariablesStack::elementFrameAlreadyPushed(const ElemTemplateElement* elem) const
{
const unsigned int nElems = m_stack.size();
// There is guaranteed to be a context marker at
// the bottom of the stack, so i should stop at
// 1.
for(unsigned int i = nElems - 1; i > 0; --i)
{
const StackEntry& theEntry = m_stack[i];
if(theEntry.getType() == StackEntry::eElementFrameMarker)
{
if(theEntry.getElement() == elem)
{
return true;
}
}
}
return false;
}
void
VariablesStack::pushContextMarker()
{
push(StackEntry());
}
void
VariablesStack::popContextMarker()
{
const unsigned int nElems = m_stack.size();
for(unsigned int i = (nElems - 1); i > 0 && m_stack.empty() == false; --i)
{
const StackEntry& theEntry = m_stack[i];
assert(theEntry == back());
const StackEntry::eStackEntryType type = theEntry.getType();
assert(type < StackEntry::eNextValue && type >= 0);
pop();
if (type == StackEntry::eContextMarker)
{
break;
}
}
}
class PopPushStackEntry
{
public:
PopPushStackEntry(VariablesStack& theVariablesStack) :
m_variablesStack(theVariablesStack),
m_stackEntry(theVariablesStack.back())
{
assert(m_stackEntry.getType() == VariablesStack::StackEntry::eContextMarker);
theVariablesStack.pop();
}
~PopPushStackEntry()
{
m_variablesStack.push(m_stackEntry);
}
private:
VariablesStack& m_variablesStack;
const VariablesStack::StackEntry m_stackEntry;
};
class CommitPushElementFrame
{
public:
CommitPushElementFrame(
VariablesStack& theVariableStack,
const ElemTemplateElement* targetTemplate) :
m_variableStack(&theVariableStack),
m_targetTemplate(targetTemplate)
{
theVariableStack.pushElementFrame(targetTemplate);
}
~CommitPushElementFrame()
{
if (m_variableStack != 0)
{
m_variableStack->popElementFrame(m_targetTemplate);
}
}
void
commit()
{
m_variableStack = 0;
}
private:
VariablesStack* m_variableStack;
const ElemTemplateElement* const m_targetTemplate;
};
void
VariablesStack::push(const StackEntry& theEntry)
{
assert(theEntry.getType() < StackEntry::eNextValue && theEntry.getType() >= 0);
if(m_currentStackFrameIndex == m_stack.size())
{
++m_currentStackFrameIndex;
}
m_stack.push_back(theEntry);
}
void
VariablesStack::pop()
{
assert(m_stack.empty() == false);
if(m_currentStackFrameIndex == m_stack.size())
{
--m_currentStackFrameIndex;
}
m_stack.pop_back();
}
class PushFunctor
{
public:
PushFunctor(VariablesStack& theVariablesStack) :
m_variablesStack(theVariablesStack)
{
}
const void
operator()(const VariablesStack::VariableStackStackType::value_type& theEntry)
{
m_variablesStack.push(theEntry);
}
private:
VariablesStack& m_variablesStack;
};
class PushParamFunctor
{
public:
PushParamFunctor(VariablesStack& theVariablesStack) :
m_variablesStack(theVariablesStack)
{
}
const void
operator()(const VariablesStack::ParamsVectorType::value_type& theEntry)
{
m_variablesStack.push(VariablesStack::StackEntry(theEntry.first, theEntry.second));
}
private:
VariablesStack& m_variablesStack;
};
void
VariablesStack::pushParams(
const ParamsVectorType& theParams,
const ElemTemplateElement* targetTemplate)
{
// 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 while transferring the
// parameters, the element marker will be popped.
// This keeps the stack in a consistent state.
// It will also delete things left in the temp stack
// as well.
CommitPushElementFrame thePusher(*this,
targetTemplate);
#if !defined (XALAN_NO_NAMESPACES)
using std::for_each;
#endif
for_each(theParams.begin(), theParams.end(), PushParamFunctor(*this));
thePusher.commit();
}
void
VariablesStack::pushVariable(
const QName& name,
XObject* val,
const ElemTemplateElement* e)
{
if(elementFrameAlreadyPushed(e) == false)
{
pushElementFrame(e);
}
push(StackEntry(name, val));
}
void
VariablesStack::start()
{
}
void
VariablesStack::markGlobalStackFrame()
{
m_globalStackFrameIndex = m_stack.size();
pushContextMarker();
}
XObject*
VariablesStack::findXObject(
const QName& name,
bool fSearchGlobalSpace) const
{
XObject* theXObject = 0;
const StackEntry* theVariable = findVariable(name, fSearchGlobalSpace);
if (theVariable != 0)
{
assert(theVariable->getType() == StackEntry::eVariable);
theXObject = theVariable->getVariable();
}
return theXObject;
}
const VariablesStack::StackEntry*
VariablesStack::findVariable(
const QName& qname,
bool fSearchGlobalSpace) const
{
const StackEntry* theResult = 0;
const unsigned int nElems = getCurrentStackFrameIndex();
// There is guaranteed to be a context marker at
// the bottom of the stack, so i should stop at
// 1.
for(unsigned int i = nElems - 1; i > 0; --i)
{
const StackEntry& theEntry =
m_stack[i];
if(theEntry.getType() == StackEntry::eVariable)
{
if(theEntry.getName().equals(qname))
{
theResult = &theEntry;
break;
}
}
else if(theEntry.getType() == StackEntry::eContextMarker)
{
break;
}
}
if(0 == theResult && true == fSearchGlobalSpace)
{
// Look in the global space
for(unsigned int i = m_globalStackFrameIndex - 1; i > 0; i--)
{
const StackEntry& theEntry = m_stack[i];
if(theEntry.getType() == StackEntry::eVariable)
{
if(theEntry.getName().equals(qname))
{
theResult = &theEntry;
break;
}
}
else if(theEntry.getType() == StackEntry::eContextMarker)
{
break;
}
}
}
return theResult;
}
void
VariablesStack::pushElementFrame(const ElemTemplateElement* elem)
{
push(StackEntry(elem));
}
class EnsurePop
{
public:
EnsurePop(VariablesStack& theVariablesStack) :
m_variablesStack(theVariablesStack)
{
}
~EnsurePop()
{
m_variablesStack.pop();
}
private:
VariablesStack& m_variablesStack;
};
void
VariablesStack::popElementFrame(const ElemTemplateElement* elem)
{
const unsigned int nElems = getCurrentStackFrameIndex();
// Sub 1 extra for the context marker.
for(unsigned int i = nElems - 1; i > 0; --i)
{
const StackEntry& theEntry = m_stack[i];
// Guarantee that it will be popped when we're done.
EnsurePop theEnsurePop(*this);
if(theEntry.getType() == StackEntry::eContextMarker)
{
throw InvalidStackContextException();
}
else if (theEntry.getType() == StackEntry::eElementFrameMarker)
{
const ElemTemplateElement* const theElement =
theEntry.getElement();
if (theElement != elem)
{
throw InvalidStackContextException();
}
break;
}
}
}
VariablesStack::StackEntry::StackEntry() :
m_type(eContextMarker),
m_qname(),
m_variable(0)
{
}
VariablesStack::StackEntry::StackEntry(
const QName& name,
XObject* val) :
m_type(eVariable),
m_qname(name),
m_variable(val)
{
}
VariablesStack::StackEntry::StackEntry(const ElemTemplateElement* elem) :
m_type(eElementFrameMarker),
m_qname(),
m_element(elem)
{
}
VariablesStack::StackEntry::StackEntry(const StackEntry& theSource) :
m_type(theSource.m_type),
m_qname(theSource.m_qname),
m_variable(0)
{
if (theSource.m_type == eVariable)
{
m_variable = theSource.m_variable;
}
else if (theSource.m_type == eElementFrameMarker)
{
m_element = theSource.m_element;
}
else
{
m_variable = 0;
}
}
VariablesStack::StackEntry::~StackEntry()
{
}
VariablesStack::StackEntry&
VariablesStack::StackEntry::operator=(const StackEntry& theRHS)
{
if (&theRHS != this)
{
m_type = theRHS.m_type;
m_qname = theRHS.m_qname;
if (m_type == eVariable)
{
m_variable = theRHS.m_variable;
}
else if (m_type == eElementFrameMarker)
{
m_element = theRHS.m_element;
}
else
{
m_variable = 0;
}
}
return *this;
}
bool
VariablesStack::StackEntry::operator==(const StackEntry& theRHS) const
{
bool fResult = false;
if (m_type == theRHS.m_type)
{
if (m_type == eContextMarker)
{
if (&theRHS == this)
{
fResult = true;
}
}
else if (m_type == eVariable)
{
if (m_qname == theRHS.m_qname &&
m_variable == theRHS.m_variable)
{
fResult = true;
}
}
else if (m_type == eElementFrameMarker)
{
if (m_element == theRHS.m_element)
{
fResult = true;
}
}
else
{
assert(0);
}
}
return fResult;
}
VariablesStack::InvalidStackContextException::InvalidStackContextException() :
XSLTProcessorException(XALAN_STATIC_UCODE_STRING("Invalid stack context"),
XALAN_STATIC_UCODE_STRING("InvalidStackContextException"))
{
}
VariablesStack::InvalidStackContextException::~InvalidStackContextException()
{
}
1.1 xml-xalan/c/src/XSLT/VariablesStack.hpp
Index: VariablesStack.hpp
===================================================================
/*
* The Apache Software License, Version 1.1
*
*
* Copyright (c) 2000 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The end-user documentation included with the redistribution,
* if any, must include the following acknowledgment:
* "This product includes software developed by the
* Apache Software Foundation (http://www.apache.org/)."
* Alternately, this acknowledgment may appear in the software itself,
* if and wherever such third-party acknowledgments normally appear.
*
* 4. The names "Xalan" and "Apache Software Foundation" must
* not be used to endorse or promote products derived from this
* software without prior written permission. For written
* permission, please contact apache@apache.org.
*
* 5. Products derived from this software may not be called "Apache",
* nor may "Apache" appear in their name, without prior written
* permission of the Apache Software Foundation.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation and was
* originally based on software copyright (c) 1999, International
* Business Machines, Inc., http://www.ibm.com. For more
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
#if !defined(XALAN_VARIABLESSTACK_HEADER_GUARD)
#define XALAN_VARIABLESSTACK_HEADER_GUARD
// Base include file. Must be first.
#include <XSLT/XSLTDefinitions.hpp>
#include <cassert>
#include <vector>
#include <XPath/QName.hpp>
#include <XSLT/XSLTProcessorException.hpp>
class Arg;
class ElemTemplateElement;
class StylesheetExecutionContext;
class XObject;
class XalanNode;
/**
* Defines a class to keep track of a stack for macro arguments.
*/
class XALAN_XSLT_EXPORT VariablesStack
{
public:
/**
* Constructor for a variable stack.
*/
explicit
VariablesStack();
~VariablesStack();
/**
* Reset the stack.
*/
void
reset();
/**
* 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);
/**
* 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();
/**
* Pop the current context from the current context stack.
*/
void
popContextMarker();
#if defined(XALAN_NO_NAMESPACES)
typedef vector<pair<QName, XObject*> > ParamsVectorType;
#else
typedef std::vector<std::pair<QName, XObject*> > ParamsVectorType;
#endif
/**
* Push the provided objects as parameters. You must call
* popContextMarker() when you are done with the arguments.
*
* @param theParam The vector containing the parameters.
* @param targetTemplate target template for the parameters
*/
void
pushParams(
const ParamsVectorType& theParams,
const ElemTemplateElement* 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*
getParamVariable(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*
getVariable(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 ElemTemplateElement* e);
/**
* Mark the top of the stack.
*/
void
start();
/**
* Mark the top of the global stack frame.
*/
void
markGlobalStackFrame();
/**
* 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;
}
class InvalidStackContextException : public XSLTProcessorException
{
public:
InvalidStackContextException();
virtual
~InvalidStackContextException();
private:
};
private:
class StackEntry;
/**
* Check to see if an element frame for the particular element has already
* been pushed.
*
* @param elem element in question
* @return true if it has been pushed already
*/
bool
elementFrameAlreadyPushed(const ElemTemplateElement* elem) const;
/**
* Push an entry onto the stack.
*
* @param stack entry to push
*/
void
push(const StackEntry& theEntry);
/**
* Pop an entry from the top of the stack.
*/
void
pop();
/**
* Get a reference to the entry at the back (top) of the stack.
*
* @return a reference to the back of the stack.
*/
const StackEntry&
back() const
{
assert(m_stack.empty() == false);
return m_stack.back();
}
friend class CommitPushElementFrame;
friend class EnsurePop;
friend class PopPushStackEntry;
friend class PushFunctor;
friend class PushParamFunctor;
class StackEntry
{
public:
/**
* Enumeration for types of stack entries, one of context state, context
* marker, element marker, or argument.
*/
enum eStackEntryType { eContextMarker,
eVariable,
eElementFrameMarker,
eNextValue };
/**
* Construct a context marker.
*/
explicit
StackEntry();
/**
* Construct a variable.
*/
StackEntry(
const QName& name,
XObject* val);
/**
* Construct an element frame marker.
*/
StackEntry(const ElemTemplateElement* elem);
/**
* Copy constructor...
*/
StackEntry(const StackEntry& theSource);
/**
* Destructor...
*/
~StackEntry();
/**
* Determine type of stack entry
*
* @return enumeration value for type
*/
eStackEntryType
getType() const
{
return m_type;
}
/**
* Retrieve object name. Valid only for variables
*
* @return qualified name of object
*/
const QName&
getName() const
{
return m_qname;
}
/**
* Retrieve object's XObject pointer. Valid only for variables
*
* @return pointer to XObject
*/
XObject*
getVariable() const
{
return m_variable;
}
/**
* Retrieve the ElemTemplateElem where frame begins. Valid only for element frame markers
*
* @return ElemTemplateElement corresponding to marker
*/
const ElemTemplateElement*
getElement() const
{
return m_element;
}
StackEntry&
operator=(const StackEntry& theRHS);
bool
operator==(const StackEntry& theRHS) const;
private:
// Data members...
eStackEntryType m_type;
QName m_qname;
union
{
XObject* m_variable;
const ElemTemplateElement* m_element;
};
};
#if defined(XALAN_NO_NAMESPACES)
typedef vector<StackEntry> VariableStackStackType;
#else
typedef std::vector<StackEntry> VariableStackStackType;
#endif
enum { eDefaultStackSize = 100 };
XObject*
findXObject(
const QName& name,
bool fSearchGlobalSpace) const;
const StackEntry*
findVariable(
const QName& name,
bool fSearchGlobalSpace) const;
VariableStackStackType m_stack;
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;
};
#endif // #if !defined(XALAN_VARIABLESSTACK_HEADER_GUARD)