mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-29 08:36:45 +01:00
Finally! Determining import precedence for templates is properly correct.
This commit is contained in:
parent
fe40d482f5
commit
38d2783be3
4 changed files with 74 additions and 89 deletions
|
@ -54,8 +54,8 @@ public:
|
|||
if(localName == "import")
|
||||
{
|
||||
std::string href = validate_href(qName, atts);
|
||||
check_for_loops(import_stack_, href);
|
||||
import_stack_.push_back(href);
|
||||
//check_for_loops(import_stack_, href);
|
||||
import_stack_.push_back(std::make_pair(href, context_->next_precedence()));
|
||||
return;
|
||||
} // if(localName == "import")
|
||||
if(localName == "include")
|
||||
|
@ -87,7 +87,7 @@ public:
|
|||
no_content_ = false;
|
||||
if(localName == "include")
|
||||
{
|
||||
include_stylesheet(href_.back());
|
||||
include_stylesheet(href_.back(), context_->precedence());
|
||||
href_.pop_back();
|
||||
} // if ...
|
||||
if(href_.empty())
|
||||
|
@ -111,11 +111,9 @@ public:
|
|||
{
|
||||
while(!import_stack_.empty())
|
||||
{
|
||||
std::vector<std::string>::iterator import = import_stack_.end()-1;
|
||||
ImportStack::iterator import = import_stack_.end()-1;
|
||||
size_t index = import_stack_.size() - 1;
|
||||
context_->push_import_precedence();
|
||||
include_stylesheet(import_stack_.back());
|
||||
context_->pop_import_precedence();
|
||||
include_stylesheet(import_stack_.back().first, import_stack_.back().second);
|
||||
import_stack_.erase(import_stack_.begin() + index);
|
||||
} // while ...
|
||||
} // unwind_imports
|
||||
|
@ -130,9 +128,9 @@ private:
|
|||
return context_->makeAbsolute(href);
|
||||
} // validate_href
|
||||
|
||||
void check_for_loops(const std::vector<std::string>& stack, const std::string& href)
|
||||
/* void check_for_loops(const ImportStack& stack, const std::string& href)
|
||||
{
|
||||
if(std::find(stack.begin(), stack.end(), href) != stack.end())
|
||||
if(std::find(stack.begin(), stack.end(), candidate) != stack.end())
|
||||
{
|
||||
std::string error = "Stylesheet '" + href + "' includes/imports itself ";
|
||||
for(std::vector<std::string>::const_iterator i = stack.begin(), ie = stack.end(); i != ie; ++i)
|
||||
|
@ -140,13 +138,14 @@ private:
|
|||
throw std::runtime_error(error);
|
||||
} // if ...
|
||||
} // check_for_loops
|
||||
|
||||
void include_stylesheet(const std::string& href)
|
||||
*/
|
||||
void include_stylesheet(const std::string& href, const Precedence& precedence)
|
||||
{
|
||||
check_for_loops(current_includes_, href);
|
||||
//check_for_loops(current_includes_, href);
|
||||
current_includes_.push_back(href);
|
||||
|
||||
std::string prev = context_->setBase(href);
|
||||
context_->set_precedence(precedence);
|
||||
|
||||
SAX::InputSource<std::string> source(href);
|
||||
SAX::XMLReader<std::string> include_parser;
|
||||
|
@ -168,7 +167,9 @@ private:
|
|||
SAX::DefaultHandler<std::string>* compiler_;
|
||||
CompilationContext* context_;
|
||||
bool no_content_;
|
||||
std::vector<std::string> import_stack_;
|
||||
|
||||
typedef std::vector<std::pair<std::string, Precedence> > ImportStack;
|
||||
ImportStack import_stack_;
|
||||
std::vector<std::string> current_includes_;
|
||||
|
||||
std::vector<std::string> href_;
|
||||
|
|
|
@ -27,7 +27,8 @@ public:
|
|||
parser_(parser),
|
||||
stylesheet_(stylesheet),
|
||||
autoNs_(1),
|
||||
current_allowed_(false)
|
||||
current_allowed_(false),
|
||||
precedence_(Precedence::InitialPrecedence())
|
||||
{
|
||||
xpath_.setNamespaceContext(*this);
|
||||
xpath_.setFunctionResolver(*this);
|
||||
|
@ -139,23 +140,19 @@ public:
|
|||
return ss.str();
|
||||
} // autoNamespacePrefix
|
||||
|
||||
void push_import_precedence()
|
||||
void set_precedence(const Precedence& prec)
|
||||
{
|
||||
precedenceStack_.push();
|
||||
} // push_import_precedence
|
||||
precedence_ = prec;
|
||||
} // set_precedence
|
||||
|
||||
void pop_import_precedence()
|
||||
Precedence next_precedence()
|
||||
{
|
||||
precedenceStack_.pop();
|
||||
} // pop_import_precedence
|
||||
|
||||
// void set_precedence(const Prcedence& prec)
|
||||
|
||||
// const Precedence& next_precedence()
|
||||
return precedence_.next_generation();
|
||||
} // next_precedence
|
||||
|
||||
const Precedence& precedence() const
|
||||
{
|
||||
return precedenceStack_.top();
|
||||
return precedence_;
|
||||
} // precedence
|
||||
|
||||
private:
|
||||
|
@ -203,7 +200,7 @@ private:
|
|||
std::stack<SAX::DefaultHandler<std::string>*> handlerStack_;
|
||||
std::stack<ItemContainer*> parentStack_;
|
||||
std::map<std::string, Namespace> namespaceRemap_;
|
||||
PrecedenceStack precedenceStack_;
|
||||
Precedence precedence_;
|
||||
|
||||
CompilationContext(const CompilationContext&);
|
||||
mutable int autoNs_;
|
||||
|
|
|
@ -195,19 +195,19 @@ private:
|
|||
void doApplyTemplates(const DOM::Node<std::string>& node,
|
||||
ExecutionContext& context,
|
||||
const std::pair<std::string, std::string>& mode,
|
||||
Precedence generation) const
|
||||
const Precedence& generation) const
|
||||
{
|
||||
StackFrame frame(context);
|
||||
|
||||
std::vector<Precedence> higher_precedences;
|
||||
std::vector<Precedence> lower_precedences;
|
||||
for(TemplateStack::const_iterator ts = templates_.begin(), tse = templates_.end(); ts != tse; ++ts)
|
||||
if(ts->first > generation)
|
||||
higher_precedences.push_back(ts->first);
|
||||
std::sort(higher_precedences.begin(), higher_precedences.end());
|
||||
if(generation.is_descendant(ts->first))
|
||||
lower_precedences.push_back(ts->first);
|
||||
std::sort(lower_precedences.rbegin(), lower_precedences.rend());
|
||||
|
||||
current_mode_ = mode;
|
||||
|
||||
for(std::vector<Precedence>::const_iterator p = higher_precedences.begin(), pe = higher_precedences.end(); p != pe; ++p)
|
||||
for(std::vector<Precedence>::const_iterator p = lower_precedences.begin(), pe = lower_precedences.end(); p != pe; ++p)
|
||||
{
|
||||
current_generation_ = *p;
|
||||
ModeTemplates ts = templates_.find(current_generation_)->second;
|
||||
|
|
|
@ -12,29 +12,33 @@ public:
|
|||
|
||||
static const Precedence& FrozenPrecedence()
|
||||
{
|
||||
static Precedence frozen_(-1);
|
||||
static Precedence frozen_;
|
||||
return frozen_;
|
||||
} // Precedence
|
||||
|
||||
Precedence() :
|
||||
precedence_()
|
||||
precedence_(),
|
||||
children_(0)
|
||||
{
|
||||
//precedence_.push_back(0);
|
||||
} // Precedence
|
||||
|
||||
Precedence(const Precedence& rhs) :
|
||||
precedence_(rhs.precedence_)
|
||||
precedence_(rhs.precedence_),
|
||||
children_(rhs.children_)
|
||||
{
|
||||
} // Precedence
|
||||
|
||||
private:
|
||||
Precedence(const std::vector<int> precedence) :
|
||||
precedence_(precedence)
|
||||
precedence_(precedence),
|
||||
children_(0)
|
||||
{
|
||||
} // Precedence
|
||||
|
||||
Precedence(int precedence) :
|
||||
precedence_()
|
||||
precedence_(),
|
||||
children_(0)
|
||||
{
|
||||
precedence_.push_back(precedence);
|
||||
} // Precedence
|
||||
|
@ -47,80 +51,63 @@ public:
|
|||
return precedence_ == rhs.precedence_;
|
||||
} // operator==
|
||||
|
||||
bool operator>(const Precedence& rhs) const
|
||||
{
|
||||
return precedence_ > rhs.precedence_;
|
||||
} // operator>
|
||||
|
||||
Precedence& operator=(const Precedence& rhs)
|
||||
{
|
||||
std::vector<int> other(rhs.precedence_);
|
||||
precedence_.swap(other);
|
||||
children_ = rhs.children_;
|
||||
return *this;
|
||||
} // operator=
|
||||
|
||||
Precedence nextGeneration(int p) const
|
||||
bool is_descendant(const Precedence& other) const
|
||||
{
|
||||
if(other.precedence_.size() <= precedence_.size())
|
||||
return false;
|
||||
|
||||
for(int i = 0, ie = precedence_.size(); i != ie; ++i)
|
||||
if(other.precedence_[i] != precedence_[i])
|
||||
return false;
|
||||
|
||||
return true;
|
||||
} // is_descendant
|
||||
|
||||
|
||||
Precedence next_generation()
|
||||
{
|
||||
Precedence next(precedence_);
|
||||
next.precedence_.push_back(p);
|
||||
next.precedence_.push_back(++children_);
|
||||
return next;
|
||||
} // nextGeneration
|
||||
|
||||
private:
|
||||
std::vector<int> precedence_;
|
||||
int children_;
|
||||
|
||||
friend bool operator<(const Precedence& lhs, const Precedence& rhs);
|
||||
friend std::ostream& operator<<(std::ostream& os, const Precedence& prec);
|
||||
}; // class Precedence
|
||||
|
||||
bool operator<(const Precedence& lhs, const Precedence& rhs)
|
||||
{
|
||||
return lhs.precedence_.back() < rhs.precedence_.back();
|
||||
} // PrecedenceCompare
|
||||
if(lhs.precedence_ == rhs.precedence_)
|
||||
return false;
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const Precedence& prec)
|
||||
{
|
||||
os << "(";
|
||||
for(std::vector<int>::const_iterator p = prec.precedence_.begin(), pe = prec.precedence_.end(); p != pe; ++p)
|
||||
int len = std::min(lhs.precedence_.size(), rhs.precedence_.size());
|
||||
for(int c = 0; c < len; ++c)
|
||||
{
|
||||
if(p != prec.precedence_.begin())
|
||||
os << ",";
|
||||
os << *p;
|
||||
} // for ..
|
||||
os << ")";
|
||||
} // operator<<
|
||||
|
||||
class PrecedenceStack
|
||||
{
|
||||
public:
|
||||
PrecedenceStack() :
|
||||
stack_(),
|
||||
count_(1)
|
||||
{
|
||||
stack_.push(Precedence::InitialPrecedence());
|
||||
} // PrecedenceStack
|
||||
|
||||
PrecedenceStack(const PrecedenceStack& rhs) :
|
||||
stack_(rhs.stack_)
|
||||
{
|
||||
} // PrecedenceStack
|
||||
|
||||
const Precedence& top() const { return stack_.top(); }
|
||||
void push()
|
||||
{
|
||||
stack_.push(top().nextGeneration(count_++));
|
||||
std::cout << "Pushed " << top() << std::endl;
|
||||
if(lhs.precedence_[c] < rhs.precedence_[c])
|
||||
return true;
|
||||
if(lhs.precedence_[c] > rhs.precedence_[c])
|
||||
return false;
|
||||
}
|
||||
void pop() { stack_.pop(); }
|
||||
void freeze()
|
||||
{
|
||||
while(!stack_.empty())
|
||||
stack_.pop();
|
||||
stack_.push(Precedence::FrozenPrecedence());
|
||||
} // freeze
|
||||
if(lhs.precedence_.size() < rhs.precedence_.size())
|
||||
return false;
|
||||
|
||||
private:
|
||||
std::stack<Precedence> stack_;
|
||||
int count_;
|
||||
}; // class PrecedenceStack
|
||||
return true;
|
||||
} // operator>
|
||||
|
||||
bool operator>(const Precedence& lhs, const Precedence& rhs)
|
||||
{
|
||||
return !(lhs == rhs) && !(lhs < rhs);
|
||||
} // operator>
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue