diff --git a/preprocessor/DynareMain.cc b/preprocessor/DynareMain.cc index 0535663c3a6b5893118b744ea614ba9a6fd12461..de52a10848ce4e6a8e84d4ecc90502311b059509 100644 --- a/preprocessor/DynareMain.cc +++ b/preprocessor/DynareMain.cc @@ -49,7 +49,7 @@ usage() { cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [nolinemacro] [notmpterms] [nolog] [warn_uninit]" << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]" - << " [-D<variable>[=<value>]] [nostrict] [fast] [minimal_workspace] [output=dynamic|first|second|third] [language=C|C++]" + << " [-D<variable>[=<value>]] [-I/path] [nostrict] [fast] [minimal_workspace] [output=dynamic|first|second|third] [language=C|C++]" #if defined(_WIN32) || defined(__CYGWIN32__) << " [cygwin] [msvc]" #endif @@ -100,6 +100,7 @@ main(int argc, char **argv) bool check_model_changes = false; bool minimal_workspace = false; map<string, string> defines; + vector<string> path; FileOutputType output_mode = none; LanguageOutputType language = matlab; @@ -205,6 +206,16 @@ main(int argc, char **argv) defines[key] = "1"; } } + else if (strlen(argv[arg]) >= 2 && !strncmp(argv[arg], "-I", 2)) + { + if (strlen(argv[arg]) == 2) + { + cerr << "Incorrect syntax for command line define: the defined variable " + << "must not be separated from -I by whitespace." << endl; + usage(); + } + path.push_back(string(argv[arg]).erase(0,2)); + } else if (strlen(argv[arg]) >= 6 && !strncmp(argv[arg], "output", 6)) { if (strlen(argv[arg]) <= 7 || argv[arg][6] != '=') @@ -271,7 +282,7 @@ main(int argc, char **argv) MacroDriver m; stringstream macro_output; - m.parse(argv[1], macro_output, debug, no_line_macro, defines); + m.parse(argv[1], macro_output, debug, no_line_macro, defines, path); if (save_macro) { if (save_macro_file.empty()) diff --git a/preprocessor/macro/MacroDriver.cc b/preprocessor/macro/MacroDriver.cc index 746fd12e334b6ea14ac9ead4744d9fb14fbabc87..1d13c5cee984fde412b12a3f6c5198044c8cad0c 100644 --- a/preprocessor/macro/MacroDriver.cc +++ b/preprocessor/macro/MacroDriver.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Dynare Team + * Copyright (C) 2008-2015 Dynare Team * * This file is part of Dynare. * @@ -37,7 +37,8 @@ MacroDriver::~MacroDriver() } void -MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro, map<string, string> defines) +MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro, + map<string, string> defines, vector<string> path) { file = f; @@ -67,7 +68,7 @@ MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro } file_with_endl << in.rdbuf() << endl; - lexer = new MacroFlex(&file_with_endl, &out, no_line_macro); + lexer = new MacroFlex(&file_with_endl, &out, no_line_macro, path); lexer->set_debug(debug); Macro::parser parser(*this, out); diff --git a/preprocessor/macro/MacroDriver.hh b/preprocessor/macro/MacroDriver.hh index 0945a32960b4cfe1a8c5f3d03a9db72bc2e24e18..92d90ee408ea82ea3ec97a00182bbefb882ac05a 100644 --- a/preprocessor/macro/MacroDriver.hh +++ b/preprocessor/macro/MacroDriver.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2012 Dynare Team + * Copyright (C) 2008-2015 Dynare Team * * This file is part of Dynare. * @@ -78,7 +78,8 @@ private: //! Should we omit the @#line statements ? const bool no_line_macro; - + //! The paths to search when looking for .mod files + const vector<string> path; //! True iff current context is the body of a loop bool is_for_context; //! If current context is the body of a loop, contains the string of the loop body @@ -136,7 +137,7 @@ private: void new_loop_body_buffer(Macro::parser::location_type *yylloc); public: - MacroFlex(istream *in, ostream *out, bool no_line_macro_arg); + MacroFlex(istream *in, ostream *out, bool no_line_macro_arg, vector<string> path_arg); //! The main lexing function Macro::parser::token_type lex(Macro::parser::semantic_type *yylval, @@ -176,7 +177,8 @@ public: //! Starts parsing a file, returns output in out /*! \param no_line_macro should we omit the @#line statements ? */ - void parse(const string &f, ostream &out, bool debug, bool no_line_macro, map<string,string> defines); + void parse(const string &f, ostream &out, bool debug, bool no_line_macro, + map<string,string> defines, const vector<string> path); //! Name of main file being parsed string file; diff --git a/preprocessor/macro/MacroFlex.ll b/preprocessor/macro/MacroFlex.ll index 0b5ff7a21e5f96c386401b85389ae3519c7f8951..72b4a4b51f961eca1568a71c3f87f7525d09b62f 100644 --- a/preprocessor/macro/MacroFlex.ll +++ b/preprocessor/macro/MacroFlex.ll @@ -347,8 +347,8 @@ CONT \\\\ <*>. { driver.error(*yylloc, "Macro lexer error: '" + string(yytext) + "'"); } %% -MacroFlex::MacroFlex(istream* in, ostream* out, bool no_line_macro_arg) - : MacroFlexLexer(in, out), input(in), no_line_macro(no_line_macro_arg), +MacroFlex::MacroFlex(istream* in, ostream* out, bool no_line_macro_arg, vector<string> path_arg) + : MacroFlexLexer(in, out), input(in), no_line_macro(no_line_macro_arg), path(path_arg), reading_for_statement(false), reading_if_statement(false) { } @@ -387,11 +387,30 @@ void MacroFlex::create_include_context(string *filename, Macro::parser::location_type *yylloc, MacroDriver &driver) { +#ifdef _WIN32 + string FILESEP = "\\"; +#else + string FILESEP = "/"; +#endif save_context(yylloc); // Open new file input = new ifstream(filename->c_str(), ios::binary); if (input->fail()) - driver.error(*yylloc, "Could not open " + *filename); + { + ostringstream dirs; + dirs << "." << FILESEP << endl; + for (vector<string>::const_iterator it = path.begin(); it != path.end(); it++) + { + input = new ifstream(it->c_str() + FILESEP + filename->c_str(), ios::binary); + if (input->good()) + break; + dirs << *it << endl; + } + if (input->fail()) + driver.error(*yylloc, "Could not open " + *filename + + ". The following directories were searched:\n" + dirs.str()); + } + // Reset location yylloc->begin.filename = yylloc->end.filename = filename; yylloc->begin.line = yylloc->end.line = 1;