catch include loops

This commit is contained in:
jez 2008-12-29 21:14:44 +00:00
parent 3ea6fde701
commit 73a90f502d

View file

@ -54,8 +54,7 @@ public:
if(localName == "import") if(localName == "import")
{ {
std::string href = validate_href(qName, atts); std::string href = validate_href(qName, atts);
//check_for_loops(import_stack_, href); import_stack_.push_back(href, context_->next_precedence());
import_stack_.push_back(std::make_pair(href, context_->next_precedence()));
return; return;
} // if(localName == "import") } // if(localName == "import")
if(localName == "include") if(localName == "include")
@ -111,10 +110,8 @@ public:
{ {
while(!import_stack_.empty()) while(!import_stack_.empty())
{ {
ImportStack::iterator import = import_stack_.end()-1; include_stylesheet(import_stack_.current().first, import_stack_.current().second);
size_t index = import_stack_.size() - 1; import_stack_.pop();
include_stylesheet(import_stack_.back().first, import_stack_.back().second);
import_stack_.erase(import_stack_.begin() + index);
} // while ... } // while ...
} // unwind_imports } // unwind_imports
@ -128,20 +125,20 @@ private:
return context_->makeAbsolute(href); return context_->makeAbsolute(href);
} // validate_href } // validate_href
/* void check_for_loops(const ImportStack& stack, const std::string& href) void check_for_loops(const std::string& href)
{ {
if(std::find(stack.begin(), stack.end(), candidate) != stack.end()) if(std::find(current_includes_.begin(), current_includes_.end(), href) != current_includes_.end())
{ {
std::string error = "Stylesheet '" + href + "' includes/imports itself "; std::string error = "Stylesheet '" + href + "' includes/imports itself ";
for(std::vector<std::string>::const_iterator i = stack.begin(), ie = stack.end(); i != ie; ++i) for(std::vector<std::string>::const_iterator i = current_includes_.begin(), ie = current_includes_.end(); i != ie; ++i)
error += "\n " + *i; error += "\n " + *i;
throw std::runtime_error(error); throw std::runtime_error(error);
} // if ... } // if ...
} // check_for_loops } // check_for_loops
*/
void include_stylesheet(const std::string& href, const Precedence& precedence) void include_stylesheet(const std::string& href, const Precedence& precedence)
{ {
//check_for_loops(current_includes_, href); check_for_loops(href);
current_includes_.push_back(href); current_includes_.push_back(href);
std::string prev = context_->setBase(href); std::string prev = context_->setBase(href);
@ -168,7 +165,36 @@ private:
CompilationContext* context_; CompilationContext* context_;
bool no_content_; bool no_content_;
typedef std::vector<std::pair<std::string, Precedence> > ImportStack; class ImportStack
{
public:
typedef std::pair<std::string, Precedence> ImportHref;
ImportStack() { }
void push_back(const std::string href, const Precedence& precedence)
{
stack_.push_back(std::make_pair<std::string, Precedence>(href, precedence));
} // push_back
bool empty() const { return stack_.empty(); }
const ImportHref& current() const
{
most_recent_ = stack_.size() - 1;
return stack_[most_recent_];
} // current
void pop()
{
stack_.erase(stack_.begin() + most_recent_);
} // pop
private:
std::vector<ImportHref> stack_;
mutable size_t most_recent_;
}; // class ImportStack
ImportStack import_stack_; ImportStack import_stack_;
std::vector<std::string> current_includes_; std::vector<std::string> current_includes_;