diff --git a/DynareMain1.cc b/DynareMain1.cc index fe87ba83b4cf0c60aae726883dbc991b7af6e759..83812284648bd88f413eb459717122a0216642c8 100644 --- a/DynareMain1.cc +++ b/DynareMain1.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015 Dynare Team + * Copyright (C) 2015-2017 Dynare Team * * This file is part of Dynare. * @@ -29,7 +29,7 @@ main1(string &modfile, string &basename, string &modfiletxt, bool debug, bool sa // Do macro processing MacroDriver m; - m.parse(modfile, modfiletxt, macro_output, debug, no_line_macro, defines, path); + m.parse(modfile, basename, modfiletxt, macro_output, debug, no_line_macro, defines, path); if (save_macro) { if (save_macro_file.empty()) diff --git a/macro/MacroBison.yy b/macro/MacroBison.yy index 27c0e4b28c11dc61735eee686730545d698b054e..a2523356c9b7c482b6f5a10ed9422a28e10efc4f 100644 --- a/macro/MacroBison.yy +++ b/macro/MacroBison.yy @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008-2016 Dynare Team + * Copyright (C) 2008-2017 Dynare Team * * This file is part of Dynare. * @@ -74,7 +74,7 @@ class MacroDriver; } %token DEFINE LINE FOR IN IF ELSE ENDIF ECHO_DIR ERROR IFDEF IFNDEF -%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH +%token LPAREN RPAREN LBRACKET RBRACKET EQUAL EOL LENGTH ECHOMACROVARS SAVE %token <int_val> INTEGER %token <string_val> NAME STRING @@ -121,6 +121,10 @@ statement : expr { TYPERR_CATCH(driver.error(@$, $2), @$); } | LINE STRING INTEGER /* Ignore @#line declarations */ + | ECHOMACROVARS + { driver.printvars(@$, true); } + | ECHOMACROVARS LPAREN SAVE RPAREN + { out << driver.printvars(@$, false); } ; expr : INTEGER diff --git a/macro/MacroDriver.cc b/macro/MacroDriver.cc index 1375e3e46d0a8bf365b25888055455da9e682e3a..1633b8132e1ee91a2636bf1c61cbf8a6563e9857 100644 --- a/macro/MacroDriver.cc +++ b/macro/MacroDriver.cc @@ -37,10 +37,13 @@ MacroDriver::~MacroDriver() } void -MacroDriver::parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro, - map<string, string> defines, vector<string> path) +MacroDriver::parse(const string &f, const string &fb, const string &modfiletxt, + ostream &out, bool debug, bool no_line_macro_arg, map<string, string> defines, + vector<string> path) { file = f; + basename = fb; + no_line_macro = no_line_macro_arg; /* Copy the file into a stringstream, and add an extra end-of-line. This is a @@ -206,12 +209,26 @@ MacroDriver::error(const Macro::parser::location_type &l, const MacroValue *valu error(l, sval->value); } -void -MacroDriver::printvars(const Macro::parser::location_type &l) const +string +MacroDriver::printvars(const Macro::parser::location_type &l, const bool tostdout) const { - cout << "Macroprocessor: Printing macro variable values at line " << l << endl; + if (tostdout) + { + cout << "Macroprocessor: Printing macro variable values from " << file + << " at line " << l.begin.line << endl; + for (map<string, const MacroValue *>::const_iterator it = env.begin(); + it != env.end(); it++) + cout << " " << it->first << " = " << it->second->print() << endl; + cout << endl; + return ""; + } + + stringstream intomfile; + if (!no_line_macro) + intomfile << "@#line \"" << file << "\" " << l.begin.line << endl; + for (map<string, const MacroValue *>::const_iterator it = env.begin(); it != env.end(); it++) - cout << "|- " << it->first << " = " << it->second->print() << endl; - cout << endl; + intomfile<< "options_.macrovars." << it->first << " = " << it->second->print() << ";" << endl; + return intomfile.str(); } diff --git a/macro/MacroDriver.hh b/macro/MacroDriver.hh index 08c5d3882ff9a8f813f365eb1c2c09a385b059eb..53b1271d8193131a04c9ff261d0dde463ce2a171 100644 --- a/macro/MacroDriver.hh +++ b/macro/MacroDriver.hh @@ -182,12 +182,18 @@ public: //! Starts parsing a file, returns output in out /*! \param no_line_macro should we omit the @#line statements ? */ - void parse(const string &f, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro, + void parse(const string &f, const string &fb, const string &modfiletxt, ostream &out, bool debug, bool no_line_macro_arg, map<string, string> defines, vector<string> path); //! Name of main file being parsed string file; + //! Basename of main file being parsed + string basename; + + //! Whether or not to print @#line + bool no_line_macro; + //! Reference to the lexer class MacroFlex *lexer; @@ -198,7 +204,7 @@ public: void error(const Macro::parser::location_type &l, const string &m) const; //! Print variables - void printvars(const Macro::parser::location_type &l) const; + string printvars(const Macro::parser::location_type &l, const bool save) const; //! Set a variable void set_variable(const string &name, const MacroValue *value); diff --git a/macro/MacroFlex.ll b/macro/MacroFlex.ll index 503dc7bf367186e9a035e65e7eb36df20dc5066b..5125ffa73906f12668b492ffd99f9b3915f41a72 100644 --- a/macro/MacroFlex.ll +++ b/macro/MacroFlex.ll @@ -236,7 +236,8 @@ CONT \\\\ <STMT>line { return token::LINE; } <STMT>define { return token::DEFINE; } -<STMT>echomacrovars{SPC}*{EOL} { driver.printvars(*yylloc); BEGIN(INITIAL); } +<STMT>echomacrovars { return token::ECHOMACROVARS; } +<STMT>save { return token::SAVE; } <STMT>for { reading_for_statement = true; return token::FOR; } <STMT>endfor { driver.error(*yylloc, "@#endfor is not matched by a @#for statement"); } diff --git a/macro/MacroValue.cc b/macro/MacroValue.cc index 05a331eefda56dae5d10fb8893800a31ced27e4d..db8c8ac293979ecf87a9fdf16c3a4c8d680106d0 100644 --- a/macro/MacroValue.cc +++ b/macro/MacroValue.cc @@ -407,7 +407,7 @@ StringMV::toString() const string StringMV::print() const { - return toString(); + return "'" + value + "'"; } const MacroValue * diff --git a/macro/MacroValue.hh b/macro/MacroValue.hh index 9bcf71bbd66b696379c6c02ce785acdd34e28c89..ced2918958ae30939f4514d81fe1666f401e05b1 100644 --- a/macro/MacroValue.hh +++ b/macro/MacroValue.hh @@ -23,6 +23,7 @@ #include <string> #include <vector> #include <sstream> +#include <boost/lexical_cast.hpp> using namespace std; @@ -344,16 +345,36 @@ template<typename T> string ArrayMV<T>::print() const { + bool printStrArr = false; + try + { + typename vector<T>::const_iterator it = values.begin(); + boost::lexical_cast<int>(*it); + } + catch (boost::bad_lexical_cast &) + { + printStrArr= true; + } ostringstream ss; - ss << "["; + if (printStrArr) + ss << "{"; + else + ss << "["; for (typename vector<T>::const_iterator it = values.begin(); it != values.end(); it++) { if (it != values.begin()) ss << ", "; - ss << *it; + + if (printStrArr) + ss << "'" << *it << "'"; + else + ss << *it; } - ss << "]"; + if (printStrArr) + ss << "}"; + else + ss << "]"; return ss.str(); }