summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lexer.l25
-rw-r--r--src/module.cc30
-rw-r--r--src/module.h4
-rw-r--r--src/parsersettings.cc54
-rw-r--r--src/parsersettings.h7
5 files changed, 66 insertions, 54 deletions
diff --git a/src/lexer.l b/src/lexer.l
index 0084d93..bb1664e 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -113,8 +113,8 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); }
[^\t\r\n>]+ { filename = yytext; }
">" {
BEGIN(INITIAL);
- fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames );
- if ( fullpath.empty() ) {
+ fs::path fullpath = find_valid_path(sourcepath(), fs::path(filename), &openfilenames);
+ if (fullpath.empty()) {
PRINTB("WARNING: Can't open 'use' file '%s'.", filename);
} else {
handle_dep(fullpath.string());
@@ -200,22 +200,25 @@ void includefile()
PRINTB("lex includefile filename %s",filename.c_str());
PRINTB("lex includefile filepath %s",filepath.c_str());
PRINTB("lex includefile sourcepath %s",sourcepath().c_str());
- BOOST_FOREACH(std::string of, openfilenames ) {
+ BOOST_FOREACH(std::string of, openfilenames) {
PRINTB("lex includefile openfilename: %s",of);
}
- rootmodule->registerInclude(filename);
-
- fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames );
- if ( fullpath.empty() ) {
+ fs::path localpath = fs::path(filepath) / filename;
+ fs::path fullpath = find_valid_path(sourcepath(), localpath, &openfilenames);
+ if (!fullpath.empty()) {
+ rootmodule->registerInclude(boosty::stringy(localpath), boosty::stringy(fullpath));
+ }
+ else {
+ rootmodule->registerInclude(boosty::stringy(localpath), boosty::stringy(localpath));
PRINTB("WARNING: Can't open 'include' file '%s'.", filename);
- if (path_stack.size()>0) path_stack.pop_back();
+ if (path_stack.size() > 0) path_stack.pop_back();
return;
};
- PRINTB("lex fullpath %s",fullpath );
+ PRINTB("lex fullpath %s",fullpath);
- std::string fullname = boosty::stringy( fullpath );
- PRINTB("lex fullname %s",fullname );
+ std::string fullname = boosty::stringy(fullpath);
+ PRINTB("lex fullname %s",fullname);
filepath.clear();
path_stack.push_back(fullpath.parent_path());
diff --git a/src/module.cc b/src/module.cc
index 2c7246e..27e01ff 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -32,6 +32,7 @@
#include "expression.h"
#include "function.h"
#include "printutils.h"
+#include "parsersettings.h"
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
@@ -196,14 +197,15 @@ std::string Module::dump(const std::string &indent, const std::string &name) con
return dump.str();
}
-void FileModule::registerInclude(const std::string &filename)
+void FileModule::registerInclude(const std::string &localpath,
+ const std::string &fullpath)
{
- PRINTB("filemodule reginclude %s", filename);
+ PRINTB("filemodule reginclude %s -> %s", localpath % fullpath);
struct stat st;
memset(&st, 0, sizeof(struct stat));
- bool valid = stat(filename.c_str(), &st);
- IncludeFile inc = {filename,valid,st.st_mtime};
- this->includes[filename] = inc;
+ bool valid = stat(fullpath.c_str(), &st);
+ IncludeFile inc = {fullpath, valid, st.st_mtime};
+ this->includes[localpath] = inc;
}
/*!
@@ -257,12 +259,14 @@ AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiat
bool FileModule::include_modified(IncludeFile inc)
{
- struct stat st;
- memset(&st, 0, sizeof(struct stat));
- // todo - search paths
- bool valid = stat(inc.filename.c_str(), &st);
- if (inc.valid != valid) return true;
- if (st.st_mtime > inc.mtime) return true;
- return false;
+ struct stat st;
+ memset(&st, 0, sizeof(struct stat));
+ // FIXME: Detect removal of previously found files
+ fs::path fullpath = find_valid_path(this->path, inc.filename);
+ if (!fullpath.empty()) {
+ bool valid = stat(inc.filename.c_str(), &st);
+ if (inc.valid != valid) return true;
+ if (st.st_mtime > inc.mtime) return true;
+ }
+ return false;
}
-
diff --git a/src/module.h b/src/module.h
index fa255e1..5dfb8c4 100644
--- a/src/module.h
+++ b/src/module.h
@@ -93,7 +93,7 @@ public:
void setModulePath(const std::string &path) { this->path = path; }
const std::string &modulePath() const { return this->path; }
- void registerInclude(const std::string &filename);
+ void registerInclude(const std::string &localpath, const std::string &fullpath);
bool handleDependencies();
virtual AbstractNode *instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx = NULL) const;
@@ -101,7 +101,7 @@ public:
ModuleContainer usedlibs;
typedef boost::unordered_map<std::string, struct IncludeFile> IncludeContainer;
IncludeContainer includes;
- bool include_modified( struct IncludeFile inc );
+ bool include_modified(struct IncludeFile inc);
private:
bool is_handling_dependencies;
std::string path;
diff --git a/src/parsersettings.cc b/src/parsersettings.cc
index 799949c..1f95719 100644
--- a/src/parsersettings.cc
+++ b/src/parsersettings.cc
@@ -20,12 +20,12 @@ void add_librarydir(const std::string &libdir)
Searces for the given file in library paths and returns the full path if found.
Returns an empty path if file cannot be found or filename is a directory.
*/
-fs::path search_libs(const std::string &filename)
+fs::path search_libs(const fs::path &localpath)
{
BOOST_FOREACH(const std::string &dir, librarypath) {
- fs::path usepath = fs::path(dir) / filename;
+ fs::path usepath = fs::path(dir) / localpath;
if (fs::exists(usepath) && !fs::is_directory(usepath)) {
- PRINTB("found %s in %s", filename % dir );
+ PRINTB("found %s in %s", localpath.string() % dir);
return usepath.string();
}
}
@@ -33,7 +33,7 @@ fs::path search_libs(const std::string &filename)
}
// files must be 'ordinary' - they mus exist and be non-directories
-bool check_valid( fs::path p, std::vector<std::string> openfilenames )
+static bool check_valid(const fs::path &p, const std::vector<std::string> *openfilenames)
{
if (p.empty()) {
PRINTB("WARNING: %s invalid - file path is blank",p);
@@ -52,30 +52,34 @@ bool check_valid( fs::path p, std::vector<std::string> openfilenames )
PRINTB("WARNING: %s invalid - points to a directory",p);
return false;
}
- std::string fullname = boosty::stringy( p );
- BOOST_FOREACH(std::string &s, openfilenames) {
- PRINTB("WARNING: circular include with %s", fullname);
- if (s == fullname) return false;
+ std::string fullname = boosty::stringy(p);
+ // Detect circular includes
+ if (openfilenames) {
+ BOOST_FOREACH(const std::string &s, *openfilenames) {
+ if (s == fullname) {
+ PRINTB("WARNING: circular include with %s", fullname);
+ return false;
+ }
+ }
}
return true;
}
// check if file is valid, search path for valid simple file
// return empty path on failure
-fs::path find_valid_path( fs::path sourcepath, std::string filename,
- std::vector<std::string> openfilenames )
+fs::path find_valid_path(const fs::path &sourcepath,
+ const fs::path &localpath,
+ const std::vector<std::string> *openfilenames)
{
- fs::path fpath = fs::path( filename );
-
- if ( boosty::is_absolute( fpath ) )
- if ( check_valid( fpath, openfilenames ) )
- return boosty::absolute( fpath );
-
-
- fpath = sourcepath / filename;
- if ( check_valid( fpath, openfilenames ) ) return fpath;
- fpath = search_libs( filename );
- if ( check_valid( fpath, openfilenames ) ) return fpath;
+ if (boosty::is_absolute(localpath)) {
+ if (check_valid(localpath, openfilenames)) return boosty::absolute(localpath);
+ }
+ else {
+ fs::path fpath = sourcepath / localpath;
+ if (check_valid(fpath, openfilenames)) return fpath;
+ fpath = search_libs(localpath);
+ if (check_valid(fpath, openfilenames)) return fpath;
+ }
return fs::path();
}
@@ -108,15 +112,15 @@ void parser_init(const std::string &applicationpath)
if (!is_directory(libdir / "libraries")) libdir /= "../../..";
#elif !defined(WIN32)
if (is_directory(tmpdir = libdir / "../share/openscad/libraries")) {
- librarydir = boosty::stringy( tmpdir );
+ librarydir = boosty::stringy(tmpdir);
} else if (is_directory(tmpdir = libdir / "../../share/openscad/libraries")) {
- librarydir = boosty::stringy( tmpdir );
+ librarydir = boosty::stringy(tmpdir);
} else if (is_directory(tmpdir = libdir / "../../libraries")) {
- librarydir = boosty::stringy( tmpdir );
+ librarydir = boosty::stringy(tmpdir);
} else
#endif
if (is_directory(tmpdir = libdir / "libraries")) {
- librarydir = boosty::stringy( tmpdir );
+ librarydir = boosty::stringy(tmpdir);
}
if (!librarydir.empty()) add_librarydir(librarydir);
}
diff --git a/src/parsersettings.h b/src/parsersettings.h
index 12b4a61..52172b6 100644
--- a/src/parsersettings.h
+++ b/src/parsersettings.h
@@ -8,8 +8,9 @@ extern int parser_error_pos;
void parser_init(const std::string &applicationpath);
void add_librarydir(const std::string &libdir);
-fs::path search_libs(const std::string &filename);
-fs::path find_valid_path( fs::path sourcepath, std::string filename,
- std::vector<std::string> openfilenames );
+fs::path search_libs(const fs::path &localpath);
+fs::path find_valid_path(const fs::path &sourcepath,
+ const fs::path &localpath,
+ const std::vector<std::string> *openfilenames = NULL);
#endif
contact: Jan Huwald // Impressum