preprocessor: allow passing mod file as string. Closes #1509

Usage: ./dynare_m $'<<mod file text>>'

The $’’ expands special characters. This is necessary because our setup for native matlab statements require that they end with a newline. In other words, the rest of the mod file can be sent on one line, but if there is a native matlab statement you must enter a `\n` after it.

NB: In this case, apostrophes must be escaped: ' becomes \'

e.g., to run tests/example1.mod:
./dynare_m  $'//Example 1 from Collard\'s guide to Dynare\nvar y, c, k, a, h, b;varexo e, u;verbatim;% I want these comments included in\n% example1.m 1999q1 1999y\n%\nvar = 1;\nend;parameters beta, rho, alpha, delta, theta, psi, tau;alpha = 0.36;rho   = 0.95;tau   = 0.025;beta  = 0.99;delta = 0.025;psi   = 0;theta = 2.95;phi   = 0.1;\nmodel;c*theta*h^(1+psi)=(1-alpha)*y;k = beta*(((exp(b)*c)/(exp(b(+1))*c(+1)))*(exp(b(+1))*alpha*y(+1)+(1-delta)*k));y = exp(a)*(k(-1)^alpha)*(h^(1-alpha));k = exp(b)*(y-c)+(1-delta)*k(-1);a = rho*a(-1)+tau*b(-1) + e;b = tau*a(-1)+rho*b(-1) + u;end;initval;y = 1.08068253095672;c = 0.80359242014163;h = 0.29175631001732;k = 11.08360443260358;a = 0;b = 0;e = 0;u = 0;end;shocks;var e; stderr 0.009;var u; stderr 0.009;var e, u = phi*0.009*0.009;end; stoch_simul;'
issue#70
Houtan Bastani 2017-09-08 16:18:48 +02:00
parent 44ce31dd2a
commit dff540df4e
4 changed files with 37 additions and 20 deletions

View File

@ -48,9 +48,8 @@ void main2(stringstream &in, string &basename, bool debug, bool clear_all, bool
, JsonOutputPointType json, JsonFileOutputType json_output_mode, bool onlyjson, bool jsonderivsimple
);
void main1(char *modfile, string &basename, bool debug, bool save_macro, string &save_macro_file,
bool no_line_macro,
map<string, string> &defines, vector<string> &path, stringstream &macro_output);
void main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file,
bool no_line_macro, map<string, string> &defines, vector<string> &path, stringstream &macro_output);
void
usage()
@ -339,9 +338,34 @@ main(int argc, char **argv)
// Construct basename (i.e. remove file extension if there is one)
string basename = argv[1];
size_t pos = basename.find_last_of('.');
if (pos != string::npos)
basename.erase(pos);
string modfile, modfiletxt;
size_t fsc = basename.find_first_of(';');
if (fsc != string::npos)
{
// If a semicolon is found in argv[1], treat it as the text of the modfile
modfile = "mod_file_passed_as_string.mod";
basename = "mod_file_passed_as_string";
modfiletxt = argv[1];
}
else
{
// If a semicolon is NOT found in argv[1], treat it as the name of the modfile
modfile = argv[1];
size_t pos = basename.find_last_of('.');
if (pos != string::npos)
basename.erase(pos);
ifstream modfile(argv[1], ios::binary);
if (modfile.fail())
{
cerr << "ERROR: Could not open file: " << argv[1] << endl;
exit(EXIT_FAILURE);
}
stringstream buffer;
buffer << modfile.rdbuf();
modfiletxt = buffer.str();
}
WarningConsolidation warnings(no_warn);
@ -360,7 +384,7 @@ main(int argc, char **argv)
// Do macro processing
stringstream macro_output;
main1(argv[1], basename, debug, save_macro, save_macro_file, no_line_macro, defines, path, macro_output);
main1(modfile, basename, modfiletxt, debug, save_macro, save_macro_file, no_line_macro, defines, path, macro_output);
if (only_macro)
return EXIT_SUCCESS;

View File

@ -23,13 +23,13 @@
#include "macro/MacroDriver.hh"
void
main1(char *modfile, string &basename, bool debug, bool save_macro, string &save_macro_file, bool no_line_macro,
map<string, string> &defines, vector<string> &path, stringstream &macro_output)
main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool save_macro, string &save_macro_file,
bool no_line_macro, map<string, string> &defines, vector<string> &path, stringstream &macro_output)
{
// Do macro processing
MacroDriver m;
m.parse(modfile, macro_output, debug, no_line_macro, defines, path);
m.parse(modfile, modfiletxt, macro_output, debug, no_line_macro, defines, path);
if (save_macro)
{
if (save_macro_file.empty())

View File

@ -37,18 +37,11 @@ MacroDriver::~MacroDriver()
}
void
MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro,
MacroDriver::parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro,
map<string, string> defines, vector<string> path)
{
file = f;
ifstream in(f.c_str(), ios::binary);
if (in.fail())
{
cerr << "ERROR: Could not open file: " << f << endl;
exit(EXIT_FAILURE);
}
/*
Copy the file into a stringstream, and add an extra end-of-line. This is a
workaround for trac ticket #73: with this workaround, MOD files ending with
@ -66,7 +59,7 @@ MacroDriver::parse(const string &f, ostream &out, bool debug, bool no_line_macro
{
file_with_endl << "@#define " << it->first << " = \"" << it->second << "\"" << endl;
}
file_with_endl << in.rdbuf() << endl;
file_with_endl << modfiletxt << endl;
lexer = new MacroFlex(&file_with_endl, &out, no_line_macro, path);
lexer->set_debug(debug);

View File

@ -182,7 +182,7 @@ 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,
void parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro,
map<string, string> defines, vector<string> path);
//! Name of main file being parsed