From 6f4cf3ebecdd720ed31c0257543fd071f41afc17 Mon Sep 17 00:00:00 2001 From: Marius Kintel Date: Mon, 10 Feb 2014 02:19:56 -0500 Subject: [PATCH] Fixed a bug failing to detect changes in underlying libraries. Should improve some of the issues reported in #181 --- src/ModuleCache.cc | 17 +++++++++++------ src/ModuleCache.h | 2 +- src/module.cc | 23 +++++++++++++---------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 595a4631..d79a0261 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -22,12 +22,16 @@ ModuleCache *ModuleCache::inst = NULL; /*! - Reevaluate the given file and recompile if necessary. - Returns NULL on any error (e.g. compile error or file not found) - + Reevaluate the given file and all it's dependencies and recompile anything + needing reevaluation. The given filename must be absolute. + + Sets the module reference to the new modile, or NULL on any error (e.g. compile + error or file not found) + + Returns true if anything was compiled (module or dependencies) and false otherwise. */ -FileModule *ModuleCache::evaluate(const std::string &filename) +bool ModuleCache::evaluate(const std::string &filename, FileModule *&module) { FileModule *lib_mod = NULL; bool found = false; @@ -115,9 +119,10 @@ FileModule *ModuleCache::evaluate(const std::string &filename) print_messages_pop(); } - if (lib_mod) lib_mod->handleDependencies(); + module = lib_mod; + bool depschanged = lib_mod ? lib_mod->handleDependencies() : false; - return lib_mod; + return shouldCompile || depschanged; } void ModuleCache::clear() diff --git a/src/ModuleCache.h b/src/ModuleCache.h index e8a45807..0c15fbda 100644 --- a/src/ModuleCache.h +++ b/src/ModuleCache.h @@ -8,7 +8,7 @@ class ModuleCache { public: static ModuleCache *instance() { if (!inst) inst = new ModuleCache; return inst; } - class FileModule *evaluate(const std::string &filename); + bool evaluate(const std::string &filename, class FileModule *&module); class FileModule *lookup(const std::string &filename); bool isCached(const std::string &filename); size_t size() { return this->entries.size(); } diff --git a/src/module.cc b/src/module.cc index dc89a6f6..ccc475e4 100644 --- a/src/module.cc +++ b/src/module.cc @@ -263,8 +263,8 @@ bool FileModule::handleDependencies() if (this->is_handling_dependencies) return false; this->is_handling_dependencies = true; - bool changed = false; - std::vector updates; + bool somethingchanged = false; + std::vector > updates; // If a lib in usedlibs was previously missing, we need to relocate it // by searching the applicable paths. We can identify a previously missing module @@ -279,9 +279,8 @@ bool FileModule::handleDependencies() wasmissing = true; fs::path fullpath = find_valid_path(this->path, filename); if (!fullpath.empty()) { + updates.push_back(std::make_pair(filename, boosty::stringy(fullpath))); filename = boosty::stringy(fullpath); - updates.push_back(filename); - this->usedlibs.erase(filename); } else { found = false; @@ -291,15 +290,16 @@ bool FileModule::handleDependencies() if (found) { bool wascached = ModuleCache::instance()->isCached(filename); FileModule *oldmodule = ModuleCache::instance()->lookup(filename); - FileModule *newmodule = ModuleCache::instance()->evaluate(filename); + FileModule *newmodule; + bool changed = ModuleCache::instance()->evaluate(filename, newmodule); // Detect appearance but not removal of files, and keep old module // on compile errors (FIXME: Is this correct behavior?) - if (newmodule && oldmodule != newmodule) { - changed = true; + if (changed) { #ifdef DEBUG PRINTB_NOCACHE(" %s: %p -> %p", filename % oldmodule % newmodule); #endif } + somethingchanged |= changed; // Only print warning if we're not part of an automatic reload if (!newmodule && !wascached && !wasmissing) { PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename); @@ -308,10 +308,13 @@ bool FileModule::handleDependencies() } // Relative filenames which were located is reinserted as absolute filenames - BOOST_FOREACH(const std::string &filename, updates) this->usedlibs.insert(filename); - + typedef std::pair stringpair; + BOOST_FOREACH(const stringpair &files, updates) { + this->usedlibs.erase(files.first); + this->usedlibs.insert(files.second); + } this->is_handling_dependencies = false; - return changed; + return somethingchanged; } AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const