summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ModuleCache.cc22
-rw-r--r--src/func.cc2
-rw-r--r--src/lexer.l84
-rw-r--r--src/mainwin.cc20
-rw-r--r--src/module.cc20
-rw-r--r--src/module.h13
-rw-r--r--src/parsersettings.cc56
-rw-r--r--src/parsersettings.h5
8 files changed, 135 insertions, 87 deletions
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc
index 4944495..030cfa0 100644
--- a/src/ModuleCache.cc
+++ b/src/ModuleCache.cc
@@ -14,32 +14,26 @@
#include <time.h>
#include <sys/stat.h>
+//#include "parsersettings.h"
/*!
FIXME: Implement an LRU scheme to avoid having an ever-growing module cache
*/
ModuleCache *ModuleCache::inst = NULL;
-static bool is_modified(const std::string &filename, const time_t &mtime)
-{
- struct stat st;
- memset(&st, 0, sizeof(struct stat));
- stat(filename.c_str(), &st);
- return (st.st_mtime > mtime);
-}
-
FileModule *ModuleCache::evaluate(const std::string &filename)
{
+ std::cout << "modcache eval" << filename << "\n";
FileModule *lib_mod = NULL;
- // Create cache ID
+ // Create cache ID
struct stat st;
memset(&st, 0, sizeof(struct stat));
stat(filename.c_str(), &st);
std::string cache_id = str(boost::format("%x.%x") % st.st_mtime % st.st_size);
- // Lookup in cache
+ // Lookup in cache
if (this->entries.find(filename) != this->entries.end() &&
this->entries[filename].cache_id == cache_id) {
#ifdef DEBUG
@@ -48,15 +42,15 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
#endif
lib_mod = &(*this->entries[filename].module);
- BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, lib_mod->includes) {
- if (is_modified(item.first, item.second)) {
+ BOOST_FOREACH(const FileModule::IncludeContainer::value_type &include, lib_mod->includes) {
+ if (lib_mod->include_modified(include.second)) {
lib_mod = NULL;
break;
}
}
}
- // If cache lookup failed (non-existing or old timestamp), compile module
+ // If cache lookup failed (non-existing or old timestamp), compile module
if (!lib_mod) {
#ifdef DEBUG
if (this->entries.find(filename) != this->entries.end()) {
@@ -91,7 +85,7 @@ FileModule *ModuleCache::evaluate(const std::string &filename)
if (lib_mod) {
// We defer deletion so we can ensure that the new module won't
- // have the same address as the old
+ // have the same address as the old
delete oldmodule;
this->entries[filename].module = lib_mod;
} else {
diff --git a/src/func.cc b/src/func.cc
index 18884b8..eaaae74 100644
--- a/src/func.cc
+++ b/src/func.cc
@@ -64,6 +64,7 @@ AbstractFunction::~AbstractFunction()
Value AbstractFunction::evaluate(const Context*, const EvalContext *evalctx) const
{
+ (void)evalctx; // unusued parameter
return Value();
}
@@ -500,6 +501,7 @@ Value builtin_search(const Context *, const EvalContext *evalctx)
Value builtin_version(const Context *, const EvalContext *evalctx)
{
+ (void)evalctx; // unusued parameter
Value::VectorType val;
val.push_back(Value(double(OPENSCAD_YEAR)));
val.push_back(Value(double(OPENSCAD_MONTH)));
diff --git a/src/lexer.l b/src/lexer.l
index 6dfe9bc..0084d93 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -113,29 +113,15 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); }
[^\t\r\n>]+ { filename = yytext; }
">" {
BEGIN(INITIAL);
- fs::path usepath;
- if (boosty::is_absolute(fs::path(filename))) {
- usepath = filename;
- }
- else {
- usepath = sourcepath() / filename;
- if (!fs::exists(usepath)) {
- usepath = locate_file(filename);
- }
- }
- /* Only accept regular files which exists */
- if (usepath.has_parent_path() && fs::exists(usepath) && !fs::is_directory(usepath)) {
- handle_dep(usepath.string());
- parserlval.text = strdup(usepath.string().c_str());
- return TOK_USE;
- } else {
+ fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames );
+ if ( fullpath.empty() ) {
PRINTB("WARNING: Can't open 'use' file '%s'.", filename);
- if ( filename.size() == 0 )
- PRINT("WARNING: 'use' filename is blank");
- else if ( fs::is_directory( usepath ) )
- PRINTB("WARNING: 'use' file points to a directory: %s",filename);
- }
- }
+ } else {
+ handle_dep(fullpath.string());
+ parserlval.text = strdup(fullpath.string().c_str());
+ return TOK_USE;
+ }
+ }
}
<<EOF>> {
@@ -206,55 +192,43 @@ fs::path sourcepath()
Rules for include <path/file>
1) include <sourcepath/path/file>
2) include <librarydir/path/file>
+
+ Globals used: filepath, sourcepath, filename
*/
void includefile()
{
- if (filename.empty()) return;
-
- fs::path dirinfo = sourcepath();
- if (!filepath.empty()) {
- if (boosty::is_absolute(fs::path(filepath))) {
- dirinfo = filepath;
- }
- else {
- dirinfo /= filepath;
- }
+ 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 ) {
+ PRINTB("lex includefile openfilename: %s",of);
}
- fs::path finfo = dirinfo / filename;
- if (!exists(finfo)) {
- finfo = locate_file((fs::path(filepath) / filename).string());
- }
+ rootmodule->registerInclude(filename);
- if (!exists(finfo) || finfo.empty()) {
- // deal with some unusual situations with is_absolute() and Wine
- fs::path fnp( fs::path(filepath) / filename );
- if (fs::exists( fnp ) && !fs::is_directory( fnp )) {
- finfo = fnp;
- }
- }
+ fs::path fullpath = find_valid_path( sourcepath(), filename, openfilenames );
+ if ( fullpath.empty() ) {
+ PRINTB("WARNING: Can't open 'include' file '%s'.", filename);
+ if (path_stack.size()>0) path_stack.pop_back();
+ return;
+ };
+ PRINTB("lex fullpath %s",fullpath );
- if (finfo.empty()) {
- PRINTB("WARNING: Can't find 'include' file '%s'.", filename);
- }
-
- std::string fullname = boosty::absolute(finfo).string();
- // Detect circular includes
- BOOST_FOREACH(std::string &s, openfilenames) {
- if (s == fullname) return;
- }
+ std::string fullname = boosty::stringy( fullpath );
+ PRINTB("lex fullname %s",fullname );
filepath.clear();
- path_stack.push_back(finfo.parent_path());
+ path_stack.push_back(fullpath.parent_path());
handle_dep(fullname);
- rootmodule->registerInclude(fullname);
+
yyin = fopen(fullname.c_str(), "r");
if (!yyin) {
- PRINTB("WARNING: Can't open 'include' file '%s'.", filename);
+ PRINTB("WARNING: Can't open 'include' file '%s'.", fullname);
path_stack.pop_back();
return;
}
+
openfiles.push_back(yyin);
openfilenames.push_back(fullname);
filename.clear();
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 1ac96fa..a7b7a30 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -615,7 +615,9 @@ void MainWindow::refreshDocument()
*/
bool MainWindow::compile(bool reload, bool procevents)
{
+ PRINT("compile");
if (!compileTopLevelDocument(reload)) return false;
+ PRINT("init render");
// Invalidate renderers before we kill the CSG tree
this->qglview->setRenderer(NULL);
@@ -1018,22 +1020,18 @@ bool MainWindow::fileChangedOnDisk()
return false;
}
-// FIXME: The following two methods are duplicated in ModuleCache.cc - refactor
-static bool is_modified(const std::string &filename, const time_t &mtime)
-{
- struct stat st;
- memset(&st, 0, sizeof(struct stat));
- stat(filename.c_str(), &st);
- return (st.st_mtime > mtime);
-}
-
bool MainWindow::includesChanged()
{
+ PRINT("includes changed?");
if (this->root_module) {
BOOST_FOREACH(const FileModule::IncludeContainer::value_type &item, this->root_module->includes) {
- if (is_modified(item.first, item.second)) return true;
+ //std::cout<< item.first << "second" << item.second << "\n";
+ //std::cout<< (is_modified(item.first, item.second)) <<"\n";
+ if (this->root_module->include_modified(item.second))
+ return true;
}
}
+ PRINT("includes not changed");
return false;
}
@@ -1046,6 +1044,7 @@ bool MainWindow::includesChanged()
*/
bool MainWindow::compileTopLevelDocument(bool reload)
{
+ PRINT("compile top level");
bool shouldcompiletoplevel = !reload;
if (includesChanged()) shouldcompiletoplevel = true;
@@ -1056,6 +1055,7 @@ bool MainWindow::compileTopLevelDocument(bool reload)
}
if (shouldcompiletoplevel) {
+ PRINT("shouldcompile top level");
console->clear();
updateTemporalVariables();
diff --git a/src/module.cc b/src/module.cc
index e853457..2c7246e 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -46,6 +46,8 @@ AbstractModule::~AbstractModule()
AbstractNode *AbstractModule::instantiate(const Context *ctx, const ModuleInstantiation *inst, const EvalContext *evalctx) const
{
+ (void)ctx; // avoid unusued parameter warning
+
AbstractNode *node = new AbstractNode(inst);
node->children = inst->instantiateChildren(evalctx);
@@ -196,10 +198,12 @@ std::string Module::dump(const std::string &indent, const std::string &name) con
void FileModule::registerInclude(const std::string &filename)
{
+ PRINTB("filemodule reginclude %s", filename);
struct stat st;
memset(&st, 0, sizeof(struct stat));
- stat(filename.c_str(), &st);
- this->includes[filename] = st.st_mtime;
+ bool valid = stat(filename.c_str(), &st);
+ IncludeFile inc = {filename,valid,st.st_mtime};
+ this->includes[filename] = inc;
}
/*!
@@ -250,3 +254,15 @@ AbstractNode *FileModule::instantiate(const Context *ctx, const ModuleInstantiat
return node;
}
+
+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;
+}
+
diff --git a/src/module.h b/src/module.h
index 9f46d37..fa255e1 100644
--- a/src/module.h
+++ b/src/module.h
@@ -5,6 +5,9 @@
#include <vector>
#include <list>
#include <boost/unordered_map.hpp>
+#include <time.h>
+#include <sys/stat.h>
+
#include "value.h"
#include "typedefs.h"
#include "localscope.h"
@@ -74,6 +77,12 @@ public:
LocalScope scope;
};
+struct IncludeFile {
+ std::string filename;
+ bool valid;
+ time_t mtime;
+};
+
// FIXME: A FileModule doesn't have definition arguments, so we shouldn't really
// inherit from a Module
class FileModule : public Module
@@ -90,9 +99,9 @@ public:
typedef boost::unordered_map<std::string, class FileModule*> ModuleContainer;
ModuleContainer usedlibs;
- typedef boost::unordered_map<std::string, time_t> IncludeContainer;
+ typedef boost::unordered_map<std::string, struct IncludeFile> IncludeContainer;
IncludeContainer includes;
-
+ 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 8d82744..799949c 100644
--- a/src/parsersettings.cc
+++ b/src/parsersettings.cc
@@ -20,13 +20,63 @@ 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.
*/
-std::string locate_file(const std::string &filename)
+fs::path search_libs(const std::string &filename)
{
BOOST_FOREACH(const std::string &dir, librarypath) {
fs::path usepath = fs::path(dir) / filename;
- if (fs::exists(usepath) && !fs::is_directory(usepath)) return usepath.string();
+ if (fs::exists(usepath) && !fs::is_directory(usepath)) {
+ PRINTB("found %s in %s", filename % dir );
+ return usepath.string();
+ }
+ }
+ return fs::path();
+}
+
+// files must be 'ordinary' - they mus exist and be non-directories
+bool check_valid( fs::path p, std::vector<std::string> openfilenames )
+{
+ if (p.empty()) {
+ PRINTB("WARNING: %s invalid - file path is blank",p);
+ return false;
+ }
+ if (!p.has_parent_path()) {
+ PRINTB("WARNING: %s invalid - no parent path",p);
+ return false;
+ }
+ if (!fs::exists(p)) {
+ PRINTB("WARNING: %s invalid - file not found",p);
+ // searched ===
+ return false;
+ }
+ if (fs::is_directory(p)) {
+ PRINTB("WARNING: %s invalid - points to a directory",p);
+ return false;
}
- return std::string();
+ std::string fullname = boosty::stringy( p );
+ BOOST_FOREACH(std::string &s, openfilenames) {
+ PRINTB("WARNING: circular include with %s", fullname);
+ if (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 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;
+ return fs::path();
}
void parser_init(const std::string &applicationpath)
diff --git a/src/parsersettings.h b/src/parsersettings.h
index 007aa9c..12b4a61 100644
--- a/src/parsersettings.h
+++ b/src/parsersettings.h
@@ -2,11 +2,14 @@
#define PARSERSETTINGS_H_
#include <string>
+#include "boosty.h"
extern int parser_error_pos;
void parser_init(const std::string &applicationpath);
void add_librarydir(const std::string &libdir);
-std::string locate_file(const std::string &filename);
+fs::path search_libs(const std::string &filename);
+fs::path find_valid_path( fs::path sourcepath, std::string filename,
+ std::vector<std::string> openfilenames );
#endif
contact: Jan Huwald // Impressum