diff options
author | Marius Kintel <marius@kintel.net> | 2012-02-04 00:43:53 (GMT) |
---|---|---|
committer | Marius Kintel <marius@kintel.net> | 2012-02-15 00:32:37 (GMT) |
commit | b9d218e13760f21be5aa94c15631d63b29439e18 (patch) | |
tree | f01d1e16766b5af06939aa531e84b40bcf6f2f31 /src/ModuleCache.cc | |
parent | 44ff85399011ea1bd3eb812ce97d312ccc4f32eb (diff) |
Initial implementation of ModuleCache and dependency tracking of used modules
Diffstat (limited to 'src/ModuleCache.cc')
-rw-r--r-- | src/ModuleCache.cc | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/ModuleCache.cc b/src/ModuleCache.cc new file mode 100644 index 0000000..eaa7d33 --- /dev/null +++ b/src/ModuleCache.cc @@ -0,0 +1,87 @@ +#include "ModuleCache.h" +#include "module.h" +#include "printutils.h" +#include "boosty.h" +#include "openscad.h" + +#include <stdio.h> +#include <sstream> +#include <sys/stat.h> + +ModuleCache *ModuleCache::inst = NULL; + +Module *ModuleCache::evaluate(const std::string &filename) +{ + Module *cached = NULL; + + struct stat st; + memset(&st, 0, sizeof(struct stat)); + stat(filename.c_str(), &st); + + std::stringstream idstream; + idstream << std::hex << st.st_mtime << "." << st.st_size; + std::string cache_id = idstream.str(); + + if (this->entries.find(filename) != this->entries.end() && + this->entries[filename].cache_id == cache_id) { +#ifdef DEBUG + PRINTB("Using cached library: %s (%s)", filename % cache_id); +#endif + PRINTB("%s", this->entries[filename].msg); + cached = &(*this->entries[filename].module); + } + + if (cached) { + cached->handleDependencies(); + return cached; + } + else { + if (this->entries.find(filename) != this->entries.end()) { + PRINTB("Recompiling cached library: %s (%s)", filename % cache_id); + } + else { + PRINTB("Compiling library '%s'.", filename); + } + } + + FILE *fp = fopen(filename.c_str(), "rt"); + if (!fp) { + fprintf(stderr, "WARNING: Can't open library file '%s'\n", filename.c_str()); + return NULL; + } + std::stringstream text; + char buffer[513]; + int ret; + while ((ret = fread(buffer, 1, 512, fp)) > 0) { + buffer[ret] = 0; + text << buffer; + } + fclose(fp); + + print_messages_push(); + + cache_entry e = { NULL, cache_id, std::string("WARNING: Library `") + filename + "' tries to recursively use itself!" }; + if (this->entries.find(filename) != this->entries.end()) + delete this->entries[filename].module; + this->entries[filename] = e; + + std::string pathname = boosty::stringy(fs::path(filename).parent_path()); + Module *lib_mod = dynamic_cast<Module*>(parse(text.str().c_str(), pathname.c_str(), 0)); + + if (lib_mod) { + this->entries[filename].module = lib_mod; + this->entries[filename].msg = print_messages_stack.back(); + } else { + this->entries.erase(filename); + } + + print_messages_pop(); + + return lib_mod; +} + +void ModuleCache::clear() +{ + this->entries.clear(); +} + |