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();
 }