reverted work on variables - will come back to it another time

This commit is contained in:
Jez Higgins 2009-12-14 23:55:56 +00:00
parent 5fa42997f4
commit d7c3b7c260
9 changed files with 32 additions and 129 deletions

View file

@ -21,7 +21,8 @@ protected:
public: public:
virtual const std::string& name() const = 0; virtual const std::string& name() const = 0;
virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node, virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node,
ExecutionContext& context) const = 0; ExecutionContext& context,
DOMSink& sink) const = 0;
virtual const Precedence& precedence() const = 0; virtual const Precedence& precedence() const = 0;
private: private:
@ -37,19 +38,20 @@ public:
Sink& output, Sink& output,
std::ostream& error_output) : std::ostream& error_output) :
stylesheet_(stylesheet), stylesheet_(stylesheet),
sink_(&output.asOutput()), sink_(output.asOutput()),
message_sink_(error_output), message_sink_(error_output),
to_msg_(0) to_msg_(0)
{ {
xpathContext_.setVariableResolver(stack_); xpathContext_.setVariableResolver(stack_);
sink_->set_warning_sink(message_sink_.asOutput()); sink_.set_warning_sink(message_sink_.asOutput());
message_sink_.asOutput().set_warning_sink(message_sink_.asOutput()); message_sink_.asOutput().set_warning_sink(message_sink_.asOutput());
} // ExecutionContext } // ExecutionContext
ExecutionContext(ExecutionContext& rhs) : ExecutionContext(Sink& output,
ExecutionContext& rhs) :
stylesheet_(rhs.stylesheet_), stylesheet_(rhs.stylesheet_),
stack_(rhs.stack_), stack_(rhs.stack_),
sink_(rhs.sink_), sink_(output.asOutput()),
message_sink_(rhs.message_sink_), message_sink_(rhs.message_sink_),
to_msg_(false) to_msg_(false)
{ {
@ -63,16 +65,10 @@ public:
Output& sink() Output& sink()
{ {
return !to_msg_ ? *sink_ : message_sink_.asOutput(); return !to_msg_ ? sink_ : message_sink_.asOutput();
} // sink } // sink
void redirectToMessageSink() { ++to_msg_; } void redirectToMessageSink() { ++to_msg_; }
void revertFromMessageSink() { --to_msg_; } void revertFromMessageSink() { --to_msg_; }
Output& redirectToSink(Output& newoutput)
{
Output& current = *sink_;
sink_ = &newoutput;
return current;
} // redirectToSink
const Arabica::XPath::ExecutionContext<std::string>& xpathContext() const { return xpathContext_; } const Arabica::XPath::ExecutionContext<std::string>& xpathContext() const { return xpathContext_; }
@ -107,7 +103,7 @@ private:
const CompiledStylesheet& stylesheet_; const CompiledStylesheet& stylesheet_;
VariableStack stack_; VariableStack stack_;
Arabica::XPath::ExecutionContext<std::string> xpathContext_; Arabica::XPath::ExecutionContext<std::string> xpathContext_;
Output* sink_; Output& sink_;
StreamSink message_sink_; StreamSink message_sink_;
int to_msg_; int to_msg_;
@ -115,54 +111,7 @@ private:
friend class ChainStackFrame; friend class ChainStackFrame;
}; // class ExecutionContext }; // class ExecutionContext
class RedirectOutputFrame
{
public:
RedirectOutputFrame(ExecutionContext& context, Sink& output) :
context_(context),
previous_(context.redirectToSink(output.asOutput())) { }
~RedirectOutputFrame() { context_.redirectToSink(previous_); }
private:
ExecutionContext& context_;
Output& previous_;
RedirectOutputFrame();
RedirectOutputFrame(const RedirectOutputFrame&);
bool operator=(const RedirectOutputFrame&);
}; // RedirectOutputFrame
/////////////////////////// ///////////////////////////
class ResolvedVariable : public Variable_instance
{
public:
ResolvedVariable(const Variable_declaration& var,
const DOM::Node<std::string>& node,
ExecutionContext& context) :
var_(var)
{
value_ = var_.value(node, context);
} // ResolvedVariable
virtual const std::string& name() const { return var_.name(); }
virtual const Precedence& precedence() const { return var_.precedence(); }
virtual Arabica::XPath::XPathValue<std::string> value() const { return value_; }
virtual void injectGlobalScope(const Scope& scope) const
{
;
} // globalScope
private:
const Variable_declaration& var_;
mutable Arabica::XPath::XPathValue<std::string> value_;
ResolvedVariable();
ResolvedVariable(const ResolvedVariable&);
ResolvedVariable& operator=(const ResolvedVariable&);
const ResolvedVariable& operator==(const ResolvedVariable&) const;
}; // class ResolvedVariable
class VariableClosure : public Variable_instance class VariableClosure : public Variable_instance
{ {
public: public:
@ -170,9 +119,6 @@ public:
const DOM::Node<std::string>& node, const DOM::Node<std::string>& node,
ExecutionContext& context) ExecutionContext& context)
{ {
if(var.precedence() == Precedence::FrozenPrecedence()) // we're running, so resolve immediately
return Variable_instance_ptr(new ResolvedVariable(var, node, context));
return Variable_instance_ptr(new VariableClosure(var, node, context)); return Variable_instance_ptr(new VariableClosure(var, node, context));
} // create } // create
@ -182,7 +128,7 @@ public:
virtual Arabica::XPath::XPathValue<std::string> value() const virtual Arabica::XPath::XPathValue<std::string> value() const
{ {
if(!value_) if(!value_)
value_ = var_.value(node_, context_); value_ = var_.value(node_, context_, sink_);
return value_; return value_;
} // value } // value
@ -196,12 +142,14 @@ private:
const DOM::Node<std::string>& node, const DOM::Node<std::string>& node,
ExecutionContext& context) : ExecutionContext& context) :
var_(var), var_(var),
sink_(),
node_(node), node_(node),
context_(context) context_(sink_, context)
{ {
} // VariableClosure } // VariableClosure
const Variable_declaration& var_; const Variable_declaration& var_;
mutable DOMSink sink_;
const DOM::Node<std::string> node_; const DOM::Node<std::string> node_;
mutable ExecutionContext context_; mutable ExecutionContext context_;
mutable Arabica::XPath::XPathValue<std::string> value_; mutable Arabica::XPath::XPathValue<std::string> value_;

View file

@ -20,7 +20,7 @@ public:
virtual void execute(const DOM::Node<std::string>& node, ExecutionContext& context) const virtual void execute(const DOM::Node<std::string>& node, ExecutionContext& context) const
{ {
MessageRedirectionFrame toMessageSink(context); RedirectionFrame toMessageSink(context);
execute_children(node, context); execute_children(node, context);
if(terminate_) if(terminate_)
@ -30,19 +30,19 @@ public:
private: private:
bool terminate_; bool terminate_;
class MessageRedirectionFrame class RedirectionFrame
{ {
public: public:
MessageRedirectionFrame(ExecutionContext& context) : context_(context) { context_.redirectToMessageSink(); } RedirectionFrame(ExecutionContext& context) : context_(context) { context_.redirectToMessageSink(); }
~MessageRedirectionFrame() { context_.revertFromMessageSink(); } ~RedirectionFrame() { context_.revertFromMessageSink(); }
private: private:
ExecutionContext& context_; ExecutionContext& context_;
MessageRedirectionFrame(); RedirectionFrame();
MessageRedirectionFrame(const MessageRedirectionFrame&); RedirectionFrame(const RedirectionFrame&);
bool operator=(const MessageRedirectionFrame&); bool operator=(const RedirectionFrame&);
}; // class MessageRedirectionFrame }; // class RedirectionFrame
}; // class Message }; // class Message
} // namespace XSLT } // namespace XSLT

View file

@ -28,25 +28,6 @@ protected:
}; // Param }; // Param
class GlobalParam : public Variable_impl
{
public:
GlobalParam(const std::string& name,
const Arabica::XPath::XPathExpressionPtr<std::string>& select,
const Precedence& precedence) :
Variable_impl(name, select, precedence)
{
} // GlobalParam
virtual ~GlobalParam() { }
protected:
virtual void execute(const DOM::Node<std::string>& node, ExecutionContext& context) const
{
context.declareParam(node, *this);
} // declare
}; // GlobalParam
} // namespace XSLT } // namespace XSLT
} // namespace Arabica } // namespace Arabica
#endif #endif

View file

@ -328,14 +328,6 @@ public:
virtual Output& asOutput() { return *this; } virtual Output& asOutput() { return *this; }
DOM::Node<std::string> node() const { return documentFrag_; } DOM::Node<std::string> node() const { return documentFrag_; }
void reset()
{
current_ = DOM::Node<std::string>();
documentFrag_ = DOM::DocumentFragment<std::string>();
document_ = DOM::Document<std::string>();
indent_ = -1;
out_again_ = false;
} // reset
protected: protected:
void do_start_document(const Settings& settings) void do_start_document(const Settings& settings)

View file

@ -196,11 +196,11 @@ const ChildElement StylesheetHandler::allowedChildren[] =
{ "key", CreateHandler<KeyHandler>}, { "key", CreateHandler<KeyHandler>},
{ "namespace-alias", CreateHandler<NamespaceAliasHandler>}, { "namespace-alias", CreateHandler<NamespaceAliasHandler>},
{ "output", CreateHandler<OutputHandler>}, { "output", CreateHandler<OutputHandler>},
{ "param", CreateHandler<TopLevelVariableHandler<GlobalParam> >}, { "param", CreateHandler<TopLevelVariableHandler<Param> >},
{ "preserve-space", CreateHandler<NotImplementedYetHandler>}, { "preserve-space", CreateHandler<NotImplementedYetHandler>},
{ "strip-space", CreateHandler<NotImplementedYetHandler>}, { "strip-space", CreateHandler<NotImplementedYetHandler>},
{ "template", CreateHandler<TemplateHandler> }, { "template", CreateHandler<TemplateHandler> },
{ "variable", CreateHandler<TopLevelVariableHandler<GlobalVariable> > }, { "variable", CreateHandler<TopLevelVariableHandler<Variable> > },
{ 0, 0 } { 0, 0 }
}; // StylesheetHandler::allowedChildren }; // StylesheetHandler::allowedChildren

View file

@ -28,7 +28,8 @@ public:
virtual const std::string& namespace_uri() const { return namespace_uri_; } virtual const std::string& namespace_uri() const { return namespace_uri_; }
virtual const std::string& name() const { return name_; } virtual const std::string& name() const { return name_; }
virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node, virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node,
ExecutionContext& context) const ExecutionContext& context,
DOMSink& sink) const
{ {
return value_; return value_;
} // value } // value

View file

@ -26,24 +26,6 @@ public:
} // declare } // declare
}; // Variable }; // Variable
class GlobalVariable : public Variable_impl
{
public:
GlobalVariable(const std::string& name,
const Arabica::XPath::XPathExpressionPtr<std::string>& select,
const Precedence precedence) :
Variable_impl(name, select, precedence)
{
} // Variable
virtual ~GlobalVariable() { }
virtual void execute(const DOM::Node<std::string>& node, ExecutionContext& context) const
{
context.declareVariable(node, *this);
} // declare
}; // class GlobalVariable
} // namespace XSLT } // namespace XSLT
} // namespace Arabica } // namespace Arabica
#endif #endif

View file

@ -29,17 +29,13 @@ public:
virtual const std::string& name() const { return name_; } virtual const std::string& name() const { return name_; }
virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node, virtual Arabica::XPath::XPathValue<std::string> value(const DOM::Node<std::string>& node,
ExecutionContext& context) const ExecutionContext& context,
DOMSink& sink) const
{ {
if(select_) if(select_)
return select_->evaluate(node, context.xpathContext()); return select_->evaluate(node, context.xpathContext());
DOMSink sink; execute_children(node, context);
{
RedirectOutputFrame redirect(context, sink);
StackFrame frame(context);
execute_children(node, context);
} //
if(sink.node() == 0) if(sink.node() == 0)
return Arabica::XPath::StringValue<std::string, Arabica::default_string_adaptor<std::string> >::createValue(""); return Arabica::XPath::StringValue<std::string, Arabica::default_string_adaptor<std::string> >::createValue("");

View file

@ -12,7 +12,7 @@ namespace XSLT
{ {
class Variable_instance; class Variable_instance;
typedef Variable_instance* Variable_instance_ptr; typedef boost::shared_ptr<Variable_instance> Variable_instance_ptr;
typedef std::map<std::string, Variable_instance_ptr> Scope; typedef std::map<std::string, Variable_instance_ptr> Scope;
class Variable_instance class Variable_instance
@ -120,6 +120,9 @@ public:
return; return;
} // if ... } // if ...
if(var->precedence() == Precedence::FrozenPrecedence()) // we're running so resolve immediately
var->value();
stack[name] = var; stack[name] = var;
} // declareVariable } // declareVariable