diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lexer.l | 25 | ||||
-rw-r--r-- | src/module.cc | 30 | ||||
-rw-r--r-- | src/module.h | 4 | ||||
-rw-r--r-- | src/parsersettings.cc | 54 | ||||
-rw-r--r-- | src/parsersettings.h | 7 |
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 |