mirror of
https://github.com/jezhiggins/arabica
synced 2025-01-18 22:26:32 +01:00
detects loops in imports as well as includes
This commit is contained in:
parent
8c65657d84
commit
e944732d82
1 changed files with 43 additions and 9 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
#ifndef ARABICA_XSLT_INCLUDE_HANDLER_HPP
|
#ifndef ARABICA_XSLT_INCLUDE_HANDLER_HPP
|
||||||
#define ARABICA_XSLT_INCLUDE_HANDLER_HPP
|
#define ARABICA_XSLT_INCLUDE_HANDLER_HPP
|
||||||
|
|
||||||
|
@ -12,6 +13,8 @@ namespace XSLT
|
||||||
|
|
||||||
class IncludeHandler : public SAX::DefaultHandler<std::string>
|
class IncludeHandler : public SAX::DefaultHandler<std::string>
|
||||||
{
|
{
|
||||||
|
struct ImportHref;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
IncludeHandler() :
|
IncludeHandler() :
|
||||||
context_(0),
|
context_(0),
|
||||||
|
@ -54,7 +57,7 @@ public:
|
||||||
if(localName == "import")
|
if(localName == "import")
|
||||||
{
|
{
|
||||||
std::string href = validate_href(qName, atts);
|
std::string href = validate_href(qName, atts);
|
||||||
import_stack_.push_back(href, context_->next_precedence());
|
import_stack_.push_back(href, context_->next_precedence(), current_includes_);
|
||||||
return;
|
return;
|
||||||
} // if(localName == "import")
|
} // if(localName == "import")
|
||||||
if(localName == "include")
|
if(localName == "include")
|
||||||
|
@ -110,7 +113,7 @@ public:
|
||||||
{
|
{
|
||||||
while(!import_stack_.empty())
|
while(!import_stack_.empty())
|
||||||
{
|
{
|
||||||
include_stylesheet(import_stack_.current().first, import_stack_.current().second);
|
import_stylesheet(import_stack_.current());
|
||||||
import_stack_.pop();
|
import_stack_.pop();
|
||||||
} // while ...
|
} // while ...
|
||||||
} // unwind_imports
|
} // unwind_imports
|
||||||
|
@ -122,6 +125,7 @@ private:
|
||||||
{ 0, false, 0 } };
|
{ 0, false, 0 } };
|
||||||
std::string href = gatherAttributes(qName, atts, rules)["href"];
|
std::string href = gatherAttributes(qName, atts, rules)["href"];
|
||||||
no_content_ = true;
|
no_content_ = true;
|
||||||
|
// std::cout << "Base : " << context_->currentBase() << ", href : " << href << "\n";
|
||||||
return context_->makeAbsolute(href);
|
return context_->makeAbsolute(href);
|
||||||
} // validate_href
|
} // validate_href
|
||||||
|
|
||||||
|
@ -130,12 +134,18 @@ private:
|
||||||
if(std::find(current_includes_.begin(), current_includes_.end(), href) != current_includes_.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 = current_includes_.begin(), ie = current_includes_.end(); i != ie; ++i)
|
for(HrefStack::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 import_stylesheet(const ImportHref& import)
|
||||||
|
{
|
||||||
|
current_includes_ = import.includes;
|
||||||
|
include_stylesheet(import.href, import.precedence);
|
||||||
|
} // import_stylesheet
|
||||||
|
|
||||||
void include_stylesheet(const std::string& href, const Precedence& precedence)
|
void include_stylesheet(const std::string& href, const Precedence& precedence)
|
||||||
{
|
{
|
||||||
check_for_loops(href);
|
check_for_loops(href);
|
||||||
|
@ -165,16 +175,40 @@ private:
|
||||||
CompilationContext* context_;
|
CompilationContext* context_;
|
||||||
bool no_content_;
|
bool no_content_;
|
||||||
|
|
||||||
|
typedef std::vector<std::string> HrefStack;
|
||||||
|
|
||||||
|
struct ImportHref
|
||||||
|
{
|
||||||
|
std::string href;
|
||||||
|
Precedence precedence;
|
||||||
|
HrefStack includes;
|
||||||
|
|
||||||
|
ImportHref() { }
|
||||||
|
|
||||||
|
ImportHref(const std::string& h, const Precedence& p, const HrefStack& i) :
|
||||||
|
href(h),
|
||||||
|
precedence(p),
|
||||||
|
includes(i)
|
||||||
|
{
|
||||||
|
} // ImportHref
|
||||||
|
|
||||||
|
ImportHref& operator=(const ImportHref& rhs)
|
||||||
|
{
|
||||||
|
href = rhs.href;
|
||||||
|
precedence = rhs.precedence;
|
||||||
|
includes = rhs.includes;
|
||||||
|
return *this;
|
||||||
|
} // operator=
|
||||||
|
}; // string ImportHref
|
||||||
|
|
||||||
class ImportStack
|
class ImportStack
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::pair<std::string, Precedence> ImportHref;
|
|
||||||
|
|
||||||
ImportStack() { }
|
ImportStack() { }
|
||||||
|
|
||||||
void push_back(const std::string href, const Precedence& precedence)
|
void push_back(const std::string& href, const Precedence& precedence, const HrefStack& includes)
|
||||||
{
|
{
|
||||||
stack_.push_back(std::make_pair<std::string, Precedence>(href, precedence));
|
stack_.push_back(ImportHref(href, precedence, includes));
|
||||||
} // push_back
|
} // push_back
|
||||||
|
|
||||||
bool empty() const { return stack_.empty(); }
|
bool empty() const { return stack_.empty(); }
|
||||||
|
@ -196,9 +230,9 @@ private:
|
||||||
}; // class ImportStack
|
}; // class ImportStack
|
||||||
|
|
||||||
ImportStack import_stack_;
|
ImportStack import_stack_;
|
||||||
std::vector<std::string> current_includes_;
|
HrefStack current_includes_;
|
||||||
|
|
||||||
std::vector<std::string> href_;
|
HrefStack href_;
|
||||||
}; // class IncludeHandler
|
}; // class IncludeHandler
|
||||||
|
|
||||||
} // namespace XSLT
|
} // namespace XSLT
|
||||||
|
|
Loading…
Reference in a new issue