From 310f3936feeb476da043a5f6454ea8e806d5153d Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Wed, 2 Oct 2019 17:08:57 +0200
Subject: [PATCH] macro processor: fix bug: interpret @#includepath at node
 level instead of at the Driver level

---
 src/macro/Directives.cc |  7 +++----
 src/macro/Directives.hh | 14 ++++----------
 src/macro/Driver.cc     |  9 +++------
 src/macro/Driver.hh     |  8 ++++----
 src/macro/Parser.yy     |  2 +-
 5 files changed, 15 insertions(+), 25 deletions(-)

diff --git a/src/macro/Directives.cc b/src/macro/Directives.cc
index e1207a28..13777551 100644
--- a/src/macro/Directives.cc
+++ b/src/macro/Directives.cc
@@ -61,15 +61,15 @@ Include::interpretAndGetName() const
   return "";
 }
 
-string
-IncludePath::interpretAndGetPath() const
+void
+IncludePath::interpret(ostream &output, bool no_line_macro)
 {
   try
     {
       StringPtr msp = dynamic_pointer_cast<String>(expr->eval());
       if (!msp)
         throw StackTrace("File name does not evaluate to a string");
-      return *msp;
+      paths.emplace_back(*msp);
     }
   catch (StackTrace &ex)
     {
@@ -80,7 +80,6 @@ IncludePath::interpretAndGetPath() const
     {
       error(StackTrace("@#includepath", e.what(), location));
     }
-  return "";
 }
 
 void
diff --git a/src/macro/Directives.hh b/src/macro/Directives.hh
index 09f34339..a0bc92e5 100644
--- a/src/macro/Directives.hh
+++ b/src/macro/Directives.hh
@@ -84,17 +84,11 @@ namespace macro
   {
   private:
     const ExpressionPtr expr;
+    vector<string> &paths;
   public:
-    IncludePath(ExpressionPtr expr_arg, Environment &env_arg, Tokenizer::location location_arg) :
-      Directive(env_arg, move(location_arg)), expr{move(expr_arg)} { }
-    // Not interpretable because we want the class to be immutable (for use with shared_ptr)
-    // If it were interpretable, the name would need to be stored in a non-const variable
-    // rendering the class mutable
-    inline void interpret(ostream &output, bool no_line_macro) override
-    {
-      error(StackTrace("@#includepath", "should never be interpreted", location));
-    }
-    string interpretAndGetPath() const;
+    IncludePath(ExpressionPtr expr_arg, Environment &env_arg, vector<string> &paths_arg, Tokenizer::location location_arg) :
+      Directive(env_arg, move(location_arg)), expr{move(expr_arg)}, paths{paths_arg} { }
+    void interpret(ostream &output, bool no_line_macro) override;
   };
 
 
diff --git a/src/macro/Driver.cc b/src/macro/Driver.cc
index 8c1fc5ff..cccdeece 100644
--- a/src/macro/Driver.cc
+++ b/src/macro/Driver.cc
@@ -55,7 +55,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
             else
               command_line_defines_with_endl << "@#define " << define.first << " = \"" << define.second << "\"" << endl;
           }
-      Driver m(env, true);
+      Driver m(env, paths, true);
       istream is(command_line_defines_with_endl.rdbuf());
       m.parse("command_line_defines", "command_line_defines", is, output, debug, vector<pair<string, string>>{}, paths);
     }
@@ -82,10 +82,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
         }
 
       auto ip = dynamic_pointer_cast<Include>(statement);
-      auto ipp = dynamic_pointer_cast<IncludePath>(statement);
-      if (ipp)
-        paths.emplace_back(ipp->interpretAndGetPath());
-      else if (ip)
+      if (ip)
         {
           string filename = ip->interpretAndGetName();
           ifstream incfile(filename, ios::binary);
@@ -111,7 +108,7 @@ Driver::parse(const string &file_arg, const string &basename_arg, istream &modfi
           if (pos != string::npos)
             basename.erase(pos);
 
-          Driver m(env, no_line_macro);
+          Driver m(env, paths, no_line_macro);
           m.parse(filename, basename, incfile, output, debug, vector<pair<string, string>>{}, paths);
         }
       else
diff --git a/src/macro/Driver.hh b/src/macro/Driver.hh
index 41d23506..26d5ea72 100644
--- a/src/macro/Driver.hh
+++ b/src/macro/Driver.hh
@@ -63,15 +63,15 @@ namespace macro
   {
   public:
     Environment &env;
+    //! The paths to search when looking for .mod files
+    vector<string> &paths;
   private:
     bool no_line_macro;
     vector<DirectivePtr> statements;
     stack<vector<DirectivePtr>> directive_stack;
-    //! The paths to search when looking for .mod files
-    vector<string> paths;
   public:
-    Driver(Environment &env_arg, bool no_line_macro_arg) :
-      env{env_arg}, no_line_macro(no_line_macro_arg) { }
+    Driver(Environment &env_arg, vector<string> &paths_arg, bool no_line_macro_arg) :
+      env{env_arg}, paths{paths_arg}, no_line_macro(no_line_macro_arg) { }
     Driver(const Driver &) = delete;
     Driver(Driver &&) = delete;
     Driver & operator=(const Driver &) = delete;
diff --git a/src/macro/Parser.yy b/src/macro/Parser.yy
index b84009af..cbd1dd19 100644
--- a/src/macro/Parser.yy
+++ b/src/macro/Parser.yy
@@ -128,7 +128,7 @@ directive : directive_one_line EOL
 directive_one_line : INCLUDE expr
                      { $$ = make_shared<Include>($2, driver.env, @$); }
                    | INCLUDEPATH expr
-                     { $$ = make_shared<IncludePath>($2, driver.env, @$); }
+                     { $$ = make_shared<IncludePath>($2, driver.env, driver.paths, @$); }
                    | DEFINE symbol EQUAL expr
                      { $$ = make_shared<Define>($2, $4, driver.env, @$); }
                    | DEFINE function EQUAL expr
-- 
GitLab