diff options
| -rw-r--r-- | project2/xml/xmlScriptParser.cpp | 46 | ||||
| -rw-r--r-- | project2/xml/xmlScriptParser.h | 3 | 
2 files changed, 42 insertions, 7 deletions
| diff --git a/project2/xml/xmlScriptParser.cpp b/project2/xml/xmlScriptParser.cpp index d2ee6e7..5091f31 100644 --- a/project2/xml/xmlScriptParser.cpp +++ b/project2/xml/xmlScriptParser.cpp @@ -3,9 +3,11 @@  #include "scripts.h"  #include "commonObjects.h"  #include "variables-modliteral.h" -#include <libxml/xinclude.h>  #include <boost/filesystem/convenience.hpp> +static const std::string XIncludeNS("http://www.w3.org/2001/XInclude"); +static const std::string XIncludeInclude("include"); +  XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file)  {  	try { @@ -14,13 +16,39 @@ XmlScriptParser::XmlScriptParser(const boost::filesystem::path & file)  	catch (const xmlpp::internal_error &) {  		throw NotReadable(file.string());  	} -	for (int x; (x = xmlXIncludeProcessFlags(get_document()->cobj(), XML_PARSE_NOXINCNODE)); ) { -		if (x < 0) { -			throw IncludesError(file.string()); +	doIncludes(get_document()->get_root_node(), file); +	files.insert(Files::value_type(file, boost::filesystem::last_write_time(file))); +} + +void +XmlScriptParser::doIncludes(xmlpp::Element * e, const boost::filesystem::path & f) +{ +	if (e->get_namespace_uri().raw() == XIncludeNS && e->get_name().raw() == XIncludeInclude) { +		boost::filesystem::path inc = f.parent_path(); +		BOOST_FOREACH(boost::filesystem::path c, boost::filesystem::path(e->get_attribute_value("href").raw())) { +			if (c.string() == "..") { +				inc = inc.parent_path(); +			} +			else { +				inc /= c; +			} +		} +		if (xmlpp::Element * c = dynamic_cast<xmlpp::Element *>(e->import_node( +						xmlpp::DomParser(inc.string()).get_document()->get_root_node()))) { +			doIncludes(c, inc); +		} +		files.insert(Files::value_type(inc, boost::filesystem::last_write_time(inc))); +	} +	else { +		BOOST_FOREACH(xmlpp::Node * n, e->get_children()) { +			if (xmlpp::Element * c = dynamic_cast<xmlpp::Element *>(n)) { +				doIncludes(c, f); +			}  		}  	}  } +  ScriptNodePtr  XmlScriptParser::root() const  { @@ -34,14 +62,18 @@ void  XmlScriptParser::load(const CommonObjects * co, bool childrenOnly) const  {  	ScriptReader::load(co, childrenOnly); -	// call me when isCurrent is false -	_root.reset();  }  bool  XmlScriptParser::isCurrent() const  { -	return false; +	BOOST_FOREACH(const Files::value_type & f, files) { +		if (boost::filesystem::last_write_time(f.first) != f.second) { +			_root.reset(); +			return false; +		} +	} +	return true;  }  class XmlScriptReaderLoader : public ScriptReaderLoader { diff --git a/project2/xml/xmlScriptParser.h b/project2/xml/xmlScriptParser.h index 8fa35c9..2d2d5db 100644 --- a/project2/xml/xmlScriptParser.h +++ b/project2/xml/xmlScriptParser.h @@ -44,6 +44,9 @@ class XmlScriptParser : public xmlpp::DomParser, public ScriptReader {  		bool isCurrent() const;  	private:  		mutable ScriptNodePtr _root; +		void doIncludes(xmlpp::Element * e, const boost::filesystem::path & f); +		typedef std::map<boost::filesystem::path, std::time_t> Files; +		Files files;  }; | 
