diff options
-rw-r--r-- | src/ModuleCache.cc | 7 | ||||
-rw-r--r-- | src/lexer.l | 3 | ||||
-rw-r--r-- | src/modcontext.cc | 9 | ||||
-rw-r--r-- | src/module.cc | 20 | ||||
-rw-r--r-- | src/parsersettings.cc | 11 | ||||
-rw-r--r-- | testdata/modulecache-tests/README.txt | 10 |
6 files changed, 50 insertions, 10 deletions
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc index 2d4cbe9..505015e 100644 --- a/src/ModuleCache.cc +++ b/src/ModuleCache.cc @@ -21,6 +21,13 @@ 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) + + If the given filename is relative, it means that the module hasn't been + previously located. +*/ FileModule *ModuleCache::evaluate(const std::string &filename) { FileModule *lib_mod = NULL; diff --git a/src/lexer.l b/src/lexer.l index ae543eb..0b8048f 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -116,11 +116,12 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); } fs::path fullpath = find_valid_path(sourcepath(), fs::path(filename), &openfilenames); if (fullpath.empty()) { PRINTB("WARNING: Can't open library '%s'.", filename); + parserlval.text = strdup(filename.c_str()); } else { handle_dep(fullpath.string()); parserlval.text = strdup(fullpath.string().c_str()); - return TOK_USE; } + return TOK_USE; } } diff --git a/src/modcontext.cc b/src/modcontext.cc index 3879811..3b957fd 100644 --- a/src/modcontext.cc +++ b/src/modcontext.cc @@ -125,7 +125,9 @@ Value FileContext::evaluate_function(const std::string &name, const EvalContext if (foundf) return foundf->evaluate(this, evalctx); BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) { - if (m.second->scope.functions.find(name) != m.second->scope.functions.end()) { + // m.second is NULL if the library wasn't be compiled (error or file-not-found) + if (m.second && + m.second->scope.functions.find(name) != m.second->scope.functions.end()) { FileContext ctx(*m.second, this->parent); ctx.initializeModule(*m.second); // FIXME: Set document path @@ -146,8 +148,9 @@ AbstractNode *FileContext::instantiate_module(const ModuleInstantiation &inst, c if (foundm) return foundm->instantiate(this, &inst, evalctx); BOOST_FOREACH(const FileModule::ModuleContainer::value_type &m, this->usedlibs) { - assert(m.second); - if (m.second->scope.modules.find(inst.name()) != m.second->scope.modules.end()) { + // m.second is NULL if the library wasn't be compiled (error or file-not-found) + if (m.second && + m.second->scope.modules.find(inst.name()) != m.second->scope.modules.end()) { FileContext ctx(*m.second, this->parent); ctx.initializeModule(*m.second); // FIXME: Set document path diff --git a/src/module.cc b/src/module.cc index e910c44..425403b 100644 --- a/src/module.cc +++ b/src/module.cc @@ -218,20 +218,32 @@ bool FileModule::handleDependencies() bool changed = false; // Iterating manually since we want to modify the container while iterating + + + // 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 + // as it will have a relative path. FileModule::ModuleContainer::iterator iter = this->usedlibs.begin(); while (iter != this->usedlibs.end()) { FileModule::ModuleContainer::iterator curr = iter++; FileModule *oldmodule = curr->second; - curr->second = ModuleCache::instance()->evaluate(curr->first); + + // Get an absolute filename for the module + std::string filename = curr->first; + if (!boosty::is_absolute(filename)) { + fs::path fullpath = find_valid_path(this->path, filename); + if (!fullpath.empty()) filename = boosty::stringy(fullpath); + } + + curr->second = ModuleCache::instance()->evaluate(filename); if (curr->second != oldmodule) { changed = true; #ifdef DEBUG - PRINTB_NOCACHE(" %s: %p", curr->first % curr->second); + PRINTB_NOCACHE(" %s: %p", filename % curr->second); #endif } if (!curr->second) { - PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", curr->first); - this->usedlibs.erase(curr); + PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", filename); } } diff --git a/src/parsersettings.cc b/src/parsersettings.cc index 8924eb4..cb7c93d 100644 --- a/src/parsersettings.cc +++ b/src/parsersettings.cc @@ -64,8 +64,15 @@ static bool check_valid(const fs::path &p, const std::vector<std::string> *openf return true; } -// check if file is valid, search path for valid simple file -// return empty path on failure +/*! + Check if the given filename is valid. + + If the given filename is absolute, do a simple check. + If not, search the applicable paths for a valid file. + + Returns the absolute path to a valid file, or an empty path if no + valid files could be found. +*/ fs::path find_valid_path(const fs::path &sourcepath, const fs::path &localpath, const std::vector<std::string> *openfilenames) diff --git a/testdata/modulecache-tests/README.txt b/testdata/modulecache-tests/README.txt index 4577f70..ce341ca 100644 --- a/testdata/modulecache-tests/README.txt +++ b/testdata/modulecache-tests/README.txt @@ -98,3 +98,13 @@ o Verify that you get: WARNING: Can't open include file 'subdir/missingsub.scad' o echo "module missingsub() { sphere(10); }" > subdir/missingsub.scad o rm subdir/missingsub.scad o Reload and Compile (F4) - verify that the sphere is gone + +Test13: Missing library file appears +------- +o rm missing.scad +o Open usemissing.scad +o Compile (F5) +o Verify that you get: WARNING: Can't open 'use' file 'missing.scad'. +o echo "module missing() { sphere(10); }" > missing.scad +o rm missing.scad +o Compile (F5) - verify that the sphere is gone |