preprocessor: macroprocessor: add -I switch. closes #1039

time-shift
Houtan Bastani 2015-08-27 16:49:00 +02:00
parent 9179d331e0
commit 1ba04976aa
4 changed files with 45 additions and 12 deletions

View File

@ -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())

View File

@ -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);

View File

@ -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;

View File

@ -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;