summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarius Kintel <marius@kintel.net>2012-02-04 00:43:53 (GMT)
committerMarius Kintel <marius@kintel.net>2012-02-15 00:32:37 (GMT)
commitb9d218e13760f21be5aa94c15631d63b29439e18 (patch)
treef01d1e16766b5af06939aa531e84b40bcf6f2f31
parent44ff85399011ea1bd3eb812ce97d312ccc4f32eb (diff)
Initial implementation of ModuleCache and dependency tracking of used modules
-rw-r--r--doc/TODO.txt7
-rw-r--r--openscad.pro2
-rw-r--r--src/MainWindow.h2
-rw-r--r--src/ModuleCache.cc87
-rw-r--r--src/ModuleCache.h22
-rw-r--r--src/context.cc1
-rw-r--r--src/lexer.l3
-rw-r--r--src/mainwin.cc7
-rw-r--r--src/module.cc17
-rw-r--r--src/module.h9
-rw-r--r--src/openscad.cc3
-rw-r--r--src/openscad.h2
-rw-r--r--src/parser.y122
-rw-r--r--tests/CMakeLists.txt7
-rw-r--r--tests/modulecachetest.cc121
-rw-r--r--tests/tests-common.cc7
-rw-r--r--tests/tests-common.h2
17 files changed, 307 insertions, 114 deletions
diff --git a/doc/TODO.txt b/doc/TODO.txt
index 60078e2..5bb66af 100644
--- a/doc/TODO.txt
+++ b/doc/TODO.txt
@@ -256,8 +256,13 @@ o Caching
- Test that caching is actually performed (speedup + same results)
- Test the modifier characters correctly influence the cache (also when
added/removed)
+ - Test the individual caches
+ - PolySetCache
+ - CGALCache
+ - nodecache
+ - ModuleCache
o other tests
- export
- cmd-line tests
- leaf nodes having children, e.g. cube() cylinder();
- - dependency tracking
+ - dependency tracking (use and include)
diff --git a/openscad.pro b/openscad.pro
index 100785b..453ab77 100644
--- a/openscad.pro
+++ b/openscad.pro
@@ -188,6 +188,7 @@ HEADERS += src/parsersettings.h \
src/traverser.h \
src/nodecache.h \
src/nodedumper.h \
+ src/ModuleCache.h \
src/PolySetCache.h \
src/PolySetEvaluator.h \
src/CSGTermEvaluator.h \
@@ -230,6 +231,7 @@ SOURCES += src/mathc99.cc \
src/nodedumper.cc \
src/traverser.cc \
src/PolySetEvaluator.cc \
+ src/ModuleCache.cc \
src/PolySetCache.cc \
src/Tree.cc \
\
diff --git a/src/MainWindow.h b/src/MainWindow.h
index 226689a..a0353a9 100644
--- a/src/MainWindow.h
+++ b/src/MainWindow.h
@@ -30,7 +30,7 @@ public:
QString autoReloadInfo;
Context root_ctx;
- AbstractModule *root_module; // Result of parsing
+ Module *root_module; // Result of parsing
ModuleInstantiation root_inst; // Top level instance
AbstractNode *absolute_root_node; // Result of tree evaluation
AbstractNode *root_node; // Root if the root modifier (!) is used
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();
+}
+
diff --git a/src/ModuleCache.h b/src/ModuleCache.h
new file mode 100644
index 0000000..57ff2e7
--- /dev/null
+++ b/src/ModuleCache.h
@@ -0,0 +1,22 @@
+#include <string>
+#include <boost/unordered_map.hpp>
+
+class ModuleCache
+{
+public:
+ static ModuleCache *instance() { if (!inst) inst = new ModuleCache; return inst; }
+ class Module *evaluate(const std::string &filename);
+ void clear();
+
+private:
+ ModuleCache() {}
+ ~ModuleCache() {}
+
+ static ModuleCache *inst;
+
+ struct cache_entry {
+ class Module *module;
+ std::string cache_id, msg;
+ };
+ boost::unordered_map<std::string, cache_entry> entries;
+};
diff --git a/src/context.cc b/src/context.cc
index b9e685c..f96a45b 100644
--- a/src/context.cc
+++ b/src/context.cc
@@ -162,6 +162,7 @@ AbstractNode *Context::evaluate_module(const ModuleInstantiation &inst) const
}
if (this->usedlibs_p) {
BOOST_FOREACH(const ModuleContainer::value_type &m, *this->usedlibs_p) {
+ assert(m.second);
if (m.second->modules.find(inst.name()) != m.second->modules.end()) {
Context ctx(this->parent, m.second);
return m.second->modules[inst.name()]->evaluate(&ctx, &inst);
diff --git a/src/lexer.l b/src/lexer.l
index 5644ded..11f2aff 100644
--- a/src/lexer.l
+++ b/src/lexer.l
@@ -52,7 +52,7 @@ int lexerget_lineno(void);
static void yyunput(int, char*) __attribute__((unused));
#endif
extern const char *parser_input_buffer;
-extern const char *parser_source_path;
+ extern std::string parser_source_path;
#define YY_INPUT(buf,result,max_size) { \
if (yyin && yyin != stdin) { \
@@ -108,6 +108,7 @@ use[ \t\r\n>]*"<" { BEGIN(cond_use); }
<cond_use>{
[^\t\r\n>]+ { filename = yytext; }
">" {
+ PRINTB("USE: %s", filename);
BEGIN(INITIAL);
fs::path usepath;
if (boosty::is_absolute(fs::path(filename))) {
diff --git a/src/mainwin.cc b/src/mainwin.cc
index 9b24eea..8eebf09 100644
--- a/src/mainwin.cc
+++ b/src/mainwin.cc
@@ -25,6 +25,7 @@
*/
#include "PolySetCache.h"
+#include "ModuleCache.h"
#include "MainWindow.h"
#include "openscad.h" // examplesdir
#include "parsersettings.h"
@@ -695,6 +696,8 @@ void MainWindow::compile(bool procevents)
goto fail;
}
+ this->root_module->handleDependencies();
+
// Evaluate CSG tree
PRINT("Compiling design (CSG Tree generation)...");
if (procevents)
@@ -1449,7 +1452,7 @@ void MainWindow::actionFlushCaches()
#endif
dxf_dim_cache.clear();
dxf_cross_cache.clear();
- Module::clear_library_cache();
+ ModuleCache::instance()->clear();
}
void MainWindow::viewModeActionsUncheck()
@@ -1797,7 +1800,7 @@ void MainWindow::consoleOutput(const std::string &msg, void *userdata)
void MainWindow::setCurrentOutput()
{
- set_output_handler(&MainWindow::consoleOutput, this);
+// set_output_handler(&MainWindow::consoleOutput, this);
}
void MainWindow::clearCurrentOutput()
diff --git a/src/module.cc b/src/module.cc
index 6641ff7..7ad2e33 100644
--- a/src/module.cc
+++ b/src/module.cc
@@ -25,11 +25,13 @@
*/
#include "module.h"
+#include "ModuleCache.h"
#include "node.h"
#include "context.h"
#include "expression.h"
#include "function.h"
#include "printutils.h"
+
#include <boost/foreach.hpp>
#include <sstream>
@@ -201,7 +203,18 @@ std::string Module::dump(const std::string &indent, const std::string &name) con
return dump.str();
}
-void Module::clear_library_cache()
+void Module::handleDependencies()
{
- Module::libs_cache.clear();
+ PRINTB_NOCACHE("Module::handleDependencies(): %p (%d libs %p)", this % this->usedlibs.size() % &this->usedlibs);
+ // Iterating manually since we want to modify the container while iterating
+ Module::ModuleContainer::iterator iter = this->usedlibs.begin();
+ while (iter != this->usedlibs.end()) {
+ Module::ModuleContainer::iterator curr = iter++;
+ curr->second = ModuleCache::instance()->evaluate(curr->first);
+ PRINTB_NOCACHE(" %s: %p", curr->first % curr->second);
+ if (!curr->second) {
+ PRINTB_NOCACHE("WARNING: Failed to compile library '%s'.", curr->first);
+ this->usedlibs.erase(curr);
+ }
+ }
}
diff --git a/src/module.h b/src/module.h
index 6c6529b..a490129 100644
--- a/src/module.h
+++ b/src/module.h
@@ -65,11 +65,9 @@ public:
void addChild(ModuleInstantiation *ch) { this->children.push_back(ch); }
- static Module *compile_library(const std::string &filename);
- static void clear_library_cache();
-
typedef boost::unordered_map<std::string, class Module*> ModuleContainer;
ModuleContainer usedlibs;
+ void handleDependencies();
std::vector<std::string> assignments_var;
std::vector<Expression*> assignments_expr;
@@ -87,11 +85,6 @@ public:
protected:
private:
- struct libs_cache_ent {
- Module *mod;
- std::string cache_id, msg;
- };
- static boost::unordered_map<std::string, libs_cache_ent> libs_cache;
};
#endif
diff --git a/src/openscad.cc b/src/openscad.cc
index 11dad7c..39e3f4c 100644
--- a/src/openscad.cc
+++ b/src/openscad.cc
@@ -255,7 +255,7 @@ int main(int argc, char **argv)
Context root_ctx;
register_builtin(root_ctx);
- AbstractModule *root_module;
+ Module *root_module;
ModuleInstantiation root_inst;
AbstractNode *root_node;
@@ -278,6 +278,7 @@ int main(int argc, char **argv)
std::string fpath = boosty::stringy(abspath.parent_path());
root_module = parse(text.str().c_str(), fpath.c_str(), false);
if (!root_module) exit(1);
+ root_module->handleDependencies();
}
fs::path fpath = boosty::absolute( fs::path(filename) );
diff --git a/src/openscad.h b/src/openscad.h
index dab14cd..8b49ba2 100644
--- a/src/openscad.h
+++ b/src/openscad.h
@@ -27,7 +27,7 @@
#ifndef OPENSCAD_H
#define OPENSCAD_H
-extern class AbstractModule *parse(const char *text, const char *path, int debug);
+extern class Module *parse(const char *text, const char *path, int debug);
extern int get_fragments_from_r(double r, double fn, double fs, double fa);
#include <string>
diff --git a/src/parser.y b/src/parser.y
index 15a754b..85fee48 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -43,7 +43,7 @@
#include <boost/foreach.hpp>
#include <boost/filesystem.hpp>
-using namespace boost::filesystem;
+namespace fs = boost::filesystem;
#include "boosty.h"
int parser_error_pos = -1;
@@ -56,7 +56,7 @@ int lexerlex_destroy(void);
int lexerlex(void);
std::vector<Module*> module_stack;
-Module *module;
+Module *currmodule;
class ArgContainer {
public:
@@ -133,7 +133,7 @@ public:
input:
/* empty */ |
- TOK_USE { module->usedlibs[$1] = NULL; } input |
+ TOK_USE { currmodule->usedlibs[$1] = NULL; } input |
statement input ;
inner_input:
@@ -145,37 +145,38 @@ statement:
'{' inner_input '}' |
module_instantiation {
if ($1) {
- module->addChild($1);
+ currmodule->addChild($1);
} else {
delete $1;
}
} |
TOK_ID '=' expr ';' {
bool add_new_assignment = true;
- for (size_t i = 0; i < module->assignments_var.size(); i++) {
- if (module->assignments_var[i] != $1)
+ for (size_t i = 0; i < currmodule->assignments_var.size(); i++) {
+ if (currmodule->assignments_var[i] != $1)
continue;
- delete module->assignments_expr[i];
- module->assignments_expr[i] = $3;
+ delete currmodule->assignments_expr[i];
+ currmodule->assignments_expr[i] = $3;
add_new_assignment = false;
}
if (add_new_assignment) {
- module->assignments_var.push_back($1);
- module->assignments_expr.push_back($3);
+ currmodule->assignments_var.push_back($1);
+ currmodule->assignments_expr.push_back($3);
free($1);
}
} |
TOK_MODULE TOK_ID '(' arguments_decl optional_commas ')' {
- Module *p = module;
- module_stack.push_back(module);
- module = new Module();
- p->modules[$2] = module;
- module->argnames = $4->argnames;
- module->argexpr = $4->argexpr;
+ Module *p = currmodule;
+ module_stack.push_back(currmodule);
+ currmodule = new Module();
+ PRINTB_NOCACHE("New module: %s %p", $2 % currmodule);
+ p->modules[$2] = currmodule;
+ currmodule->argnames = $4->argnames;
+ currmodule->argexpr = $4->argexpr;
free($2);
delete $4;
} statement {
- module = module_stack.back();
+ currmodule = module_stack.back();
module_stack.pop_back();
} |
TOK_FUNCTION TOK_ID '(' arguments_decl optional_commas ')' '=' expr {
@@ -183,7 +184,7 @@ statement:
func->argnames = $4->argnames;
func->argexpr = $4->argexpr;
func->expr = $8;
- module->functions[$2] = func;
+ currmodule->functions[$2] = func;
free($2);
delete $4;
} ';' ;
@@ -560,101 +561,34 @@ void yyerror (char const *s)
{
// FIXME: We leak memory on parser errors...
PRINTB("Parser error in line %d: %s\n", lexerget_lineno() % s);
- module = NULL;
+ currmodule = NULL;
}
extern void lexerdestroy();
extern FILE *lexerin;
extern const char *parser_input_buffer;
const char *parser_input_buffer;
-const char *parser_source_path;
+std::string parser_source_path;
-AbstractModule *parse(const char *text, const char *path, int debug)
+Module *parse(const char *text, const char *path, int debug)
{
+ PRINT_NOCACHE("New parser");
lexerin = NULL;
parser_error_pos = -1;
parser_input_buffer = text;
- parser_source_path = path;
+ parser_source_path = std::string(path);
module_stack.clear();
- module = new Module();
+ Module *rootmodule = currmodule = new Module();
+ PRINTB_NOCACHE("New module: %s %p", "root" % rootmodule);
parserdebug = debug;
parserparse();
lexerdestroy();
lexerlex_destroy();
- if (!module)
- return NULL;
-
- // Iterating manually since we want to modify the container while iterating
- Module::ModuleContainer::iterator iter = module->usedlibs.begin();
- while (iter != module->usedlibs.end()) {
- Module::ModuleContainer::iterator curr = iter++;
- curr->second = Module::compile_library(curr->first);
- if (!curr->second) {
- PRINTB("WARNING: Failed to compile library '%s'.", curr->first);
- module->usedlibs.erase(curr);
- }
- }
+ if (!rootmodule) return NULL;
parser_error_pos = -1;
- return module;
-}
-
-boost::unordered_map<std::string, Module::libs_cache_ent> Module::libs_cache;
-
-Module *Module::compile_library(const std::string &filename)
-{
- 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 (libs_cache.find(filename) != libs_cache.end() && libs_cache[filename].cache_id == cache_id) {
- PRINTB("%s", libs_cache[filename].msg);
- return &(*libs_cache[filename].mod);
- }
-
- 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();
-
- PRINTB("Compiling library '%s'.", filename);
- libs_cache_ent e = { NULL, cache_id, std::string("WARNING: Library `") + filename + "' tries to recursively use itself!" };
- if (libs_cache.find(filename) != libs_cache.end())
- delete libs_cache[filename].mod;
- libs_cache[filename] = e;
-
- Module *backup_mod = module;
- 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));
- module = backup_mod;
-
- if (lib_mod) {
- libs_cache[filename].mod = lib_mod;
- libs_cache[filename].msg = print_messages_stack.back();
- } else {
- libs_cache.erase(filename);
- }
-
- print_messages_pop();
-
- return lib_mod;
+ return rootmodule;
}
-
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index b81ce8c..fa75776 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -309,6 +309,7 @@ set(CORE_SOURCES
../src/expr.cc
../src/func.cc
../src/module.cc
+ ../src/ModuleCache.cc
../src/node.cc
../src/context.cc
../src/csgterm.cc
@@ -403,6 +404,12 @@ add_executable(dumptest dumptest.cc)
target_link_libraries(dumptest tests-common tests-nocgal ${QT_LIBRARIES} ${OPENGL_LIBRARY} ${Boost_LIBRARIES})
#
+# modulecachetest
+#
+add_executable(modulecachetest modulecachetest.cc)
+target_link_libraries(modulecachetest tests-common tests-nocgal ${QT_LIBRARIES} ${OPENGL_LIBRARY} ${Boost_LIBRARIES})
+
+#
# csgtexttest
#
add_executable(csgtexttest csgtexttest.cc CSGTextRenderer.cc CSGTextCache.cc)
diff --git a/tests/modulecachetest.cc b/tests/modulecachetest.cc
new file mode 100644
index 0000000..ae872e2
--- /dev/null
+++ b/tests/modulecachetest.cc
@@ -0,0 +1,121 @@
+/*
+ * OpenSCAD (www.openscad.org)
+ * Copyright (C) 2009-2011 Clifford Wolf <clifford@clifford.at> and
+ * Marius Kintel <marius@kintel.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * As a special exception, you have permission to link this program
+ * with the CGAL library and distribute executables, as long as you
+ * follow the requirements of the GNU GPL in regard to all of the
+ * software in the executable aside from CGAL.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "tests-common.h"
+#include "openscad.h"
+#include "parsersettings.h"
+#include "node.h"
+#include "module.h"
+#include "context.h"
+#include "value.h"
+#include "export.h"
+#include "builtin.h"
+#include "Tree.h"
+
+#include <QCoreApplication>
+#ifndef _MSC_VER
+#include <getopt.h>
+#endif
+#include <assert.h>
+#include <iostream>
+#include <sstream>
+#include <fstream>
+
+#include <boost/filesystem.hpp>
+namespace fs = boost::filesystem;
+#include "boosty.h"
+
+std::string commandline_commands;
+std::string currentdir;
+QString examplesdir;
+
+using std::string;
+
+int main(int argc, char **argv)
+{
+#ifdef _MSC_VER
+ _set_output_format(_TWO_DIGIT_EXPONENT);
+#endif
+ if (argc != 3) {
+ fprintf(stderr, "Usage: %s <file.scad> <output.txt>\n", argv[0]);
+ exit(1);
+ }
+
+ const char *filename = argv[1];
+ const char *outfilename = argv[2];
+
+ int rc = 0;
+
+ Builtins::instance()->initialize();
+
+ QCoreApplication app(argc, argv);
+ fs::path original_path = fs::current_path();
+
+ currentdir = boosty::stringy( fs::current_path() );
+
+ parser_init(QCoreApplication::instance()->applicationDirPath().toStdString());
+ set_librarydir(boosty::stringy(fs::path(QCoreApplication::instance()->applicationDirPath().toStdString()) / "../libraries"));
+
+ Context root_ctx;
+ register_builtin(root_ctx);
+
+ AbstractModule *root_module;
+ ModuleInstantiation root_inst;
+ AbstractNode *root_node;
+
+ root_module = parsefile(filename);
+ if (!root_module) {
+ fprintf(stderr, "Error: Unable to parse input file\n");
+ exit(1);
+ }
+
+ fs::current_path(fs::path(filename).parent_path());
+
+ AbstractNode::resetIndexCounter();
+ root_node = root_module->evaluate(&root_ctx, &root_inst);
+
+ delete root_node;
+ delete root_module;
+
+ fs::current_path(original_path);
+
+ fprintf(stderr, "Second parse\n");
+ root_module = parsefile(filename);
+ if (!root_module) {
+ fprintf(stderr, "Error: Unable to parse second time\n");
+ exit(1);
+ }
+
+ AbstractNode::resetIndexCounter();
+ root_node = root_module->evaluate(&root_ctx, &root_inst);
+
+ delete root_node;
+ delete root_module;
+
+ Builtins::instance(true);
+
+ return rc;
+}
diff --git a/tests/tests-common.cc b/tests/tests-common.cc
index 1694a74..5b0cc3b 100644
--- a/tests/tests-common.cc
+++ b/tests/tests-common.cc
@@ -7,9 +7,9 @@
#include <QFileInfo>
#include <sstream>
-AbstractModule *parsefile(const char *filename)
+Module *parsefile(const char *filename)
{
- AbstractModule *root_module = NULL;
+ Module *root_module = NULL;
QFileInfo fileInfo(filename);
handle_dep(filename);
@@ -27,6 +27,9 @@ AbstractModule *parsefile(const char *filename)
fclose(fp);
text << "\n" << commandline_commands;
root_module = parse(text.str().c_str(), fileInfo.absolutePath().toLocal8Bit(), false);
+ if (root_module) {
+ root_module->handleDependencies();
+ }
}
return root_module;
}
diff --git a/tests/tests-common.h b/tests/tests-common.h
index 92ebc78..0047562 100644
--- a/tests/tests-common.h
+++ b/tests/tests-common.h
@@ -1,6 +1,6 @@
#ifndef TESTS_COMMON_H_
#define TESTS_COMMON_H_
-class AbstractModule *parsefile(const char *filename);
+class Module *parsefile(const char *filename);
#endif
contact: Jan Huwald // Impressum