diff --git a/src/DynareMain1.cc b/src/DynareMain1.cc index 28cefbe4254f8be443c2cea1bcceeef1afc142a9..7b44da8c9697bc306ec37d0b94d7abbe4428c53e 100644 --- a/src/DynareMain1.cc +++ b/src/DynareMain1.cc @@ -33,7 +33,8 @@ main1(const string &filename, const string &basename, istream &modfile, bool deb { // Do macro processing macro::Environment env = macro::Environment(); - macro::Driver m(env, no_line_macro_arg); + vector<string> paths; + macro::Driver m(env, paths, no_line_macro_arg); m.parse(filename, basename, modfile, macro_output, debug, defines, path); if (save_macro) { diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc index 13777551137cc7f49f1303a193467fdf06298eef..b7c09e74d8655801049a17d7a3656f4f8745b497 100644 --- a/src/macro/Directives.cc +++ b/src/macro/Directives.cc @@ -18,6 +18,9 @@ */ #include "Directives.hh" +#include "Driver.hh" + +#include <fstream> using namespace macro; @@ -39,15 +42,45 @@ Eval::interpret(ostream &output, bool no_line_macro) } } -string -Include::interpretAndGetName() const +void +Include::interpret(ostream &output, bool no_line_macro) { +#ifdef _WIN32 + string FILESEP = "\\"; +#else + string FILESEP = "/"; +#endif try { StringPtr msp = dynamic_pointer_cast<String>(expr->eval()); if (!msp) throw StackTrace("File name does not evaluate to a string"); - return msp->to_string(); + string filename = msp->to_string(); + ifstream incfile(filename, ios::binary); + if (incfile.fail()) + { + ostringstream dirs; + dirs << "." << FILESEP << endl; + for (const auto & path : paths) + { + string testfile = path + FILESEP + filename; + incfile = ifstream(testfile, ios::binary); + if (incfile.good()) + break; + dirs << path << endl; + } + if (incfile.fail()) + error(StackTrace("@#includepath", "Could not open " + filename + + ". The following directories were searched:\n" + dirs.str(), location)); + } + + string basename = filename; + size_t pos = basename.find_last_of('.'); + if (pos != string::npos) + basename.erase(pos); + + Driver m(env, paths, no_line_macro); + m.parse(filename, basename, incfile, output, false, vector<pair<string, string>>{}, paths); } catch (StackTrace &ex) { @@ -58,7 +91,6 @@ Include::interpretAndGetName() const { error(StackTrace("@#include", e.what(), location)); } - return ""; } void diff --git a/src/macro/Directives.hh b/src/macro/Directives.hh index a0bc92e54a4f4b72aec9c7f2b234175487ba2a73..045caa6a6733e365c2b527901a906460f97cb94c 100644 --- a/src/macro/Directives.hh +++ b/src/macro/Directives.hh @@ -66,17 +66,11 @@ namespace macro { private: const ExpressionPtr expr; + vector<string> &paths; public: - Include(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) : - Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { } - // Not interpretable because we want the class to be immutable (for use with shared_ptr) - // If it were interpretable, the name would need to be stored in a non-const variable - // rendering the class mutable - inline void interpret(ostream &output, bool no_line_macro) override - { - error(StackTrace("@#include", "should never be interpreted", location)); - } - string interpretAndGetName() const; + Include(ExpressionPtr expr_arg, Environment &env_arg, vector<string> &paths_arg, Tokenizer::location location_arg) : + Directive(env_arg, move(location_arg)), expr{move(expr_arg)}, paths{paths_arg} { } + void interpret(ostream &output, bool no_line_macro) override; }; diff --git a/src/macro/Driver.cc b/src/macro/Driver.cc index cccdeece0543080463fd47ea7ee937efca219ecf..49553d1a916ca4b7ee3413c56e2dda458f536334 100644 --- a/src/macro/Driver.cc +++ b/src/macro/Driver.cc @@ -19,8 +19,6 @@ #include "Driver.hh" -#include <fstream> - using namespace macro; void @@ -28,12 +26,6 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi ostream &output, bool debug, const vector<pair<string, string>> &defines, vector<string> paths_arg) { -#ifdef _WIN32 - string FILESEP = "\\"; -#else - string FILESEP = "/"; -#endif - file = file_arg; basename = basename_arg; paths = move(paths_arg); @@ -80,39 +72,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi statement->printLineInfo(output, no_line_macro); printLine = false; } - - auto ip = dynamic_pointer_cast<Include>(statement); - if (ip) - { - string filename = ip->interpretAndGetName(); - ifstream incfile(filename, ios::binary); - if (incfile.fail()) - { - ostringstream dirs; - dirs << "." << FILESEP << endl; - for (const auto & path : paths) - { - string testfile = path + FILESEP + filename; - incfile = ifstream(testfile, ios::binary); - if (incfile.good()) - break; - dirs << path << endl; - } - if (incfile.fail()) - error(statement->getLocation(), "Could not open " + filename + - ". The following directories were searched:\n" + dirs.str()); - } - - string basename = filename; - size_t pos = basename.find_last_of('.'); - if (pos != string::npos) - basename.erase(pos); - - Driver m(env, paths, no_line_macro); - m.parse(filename, basename, incfile, output, debug, vector<pair<string, string>>{}, paths); - } - else - statement->interpret(output, no_line_macro); + statement->interpret(output, no_line_macro); } } diff --git a/src/macro/ForwardDeclarationsAndEnums.hh b/src/macro/ForwardDeclarationsAndEnums.hh index 7180222329fda8c639afc032186f97480e39330b..484ea77ebf10024d992818f0e0428c4659163428 100644 --- a/src/macro/ForwardDeclarationsAndEnums.hh +++ b/src/macro/ForwardDeclarationsAndEnums.hh @@ -56,6 +56,9 @@ namespace macro class Eval; using EvalPtr = shared_ptr<Eval>; + // For Directives.cc + class Driver; + namespace codes { enum class BaseType diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy index cbd1dd1913d35c6a1b078136b27661a7bfe7e77a..51b2524576d30eef6c0c37d5985ee05c2ab5b308 100644 --- a/src/macro/Parser.yy +++ b/src/macro/Parser.yy @@ -126,7 +126,7 @@ directive : directive_one_line EOL ; directive_one_line : INCLUDE expr - { $$ = make_shared<Include>($2, driver.env, @$); } + { $$ = make_shared<Include>($2, driver.env, driver.paths, @$); } | INCLUDEPATH expr { $$ = make_shared<IncludePath>($2, driver.env, driver.paths, @$); } | DEFINE symbol EQUAL expr