summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ModuleCache.cc7
-rw-r--r--src/lexer.l3
-rw-r--r--src/modcontext.cc9
-rw-r--r--src/module.cc20
-rw-r--r--src/parsersettings.cc11
-rw-r--r--testdata/modulecache-tests/README.txt10
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
contact: Jan Huwald // Impressum