From 5fb6667f869698b5e8b6341bbb5d6c7120a347ac Mon Sep 17 00:00:00 2001
From: Houtan Bastani <houtan@dynare.org>
Date: Wed, 8 Apr 2015 14:04:05 +0200
Subject: [PATCH] preprocessor: take care of extra exos in external functions

---
 DataTree.cc               |  8 ++++++-
 DataTree.hh               |  2 ++
 ExternalFunctionsTable.cc | 44 +++++++++++++++++++++++++++++++++++++--
 ExternalFunctionsTable.hh |  6 +++++-
 ModelTree.cc              |  1 +
 5 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/DataTree.cc b/DataTree.cc
index 3f90a44f..7135c9c6 100644
--- a/DataTree.cc
+++ b/DataTree.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2003-2014 Dynare Team
+ * Copyright (C) 2003-2015 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -50,6 +50,12 @@ DataTree::~DataTree()
     delete *it;
 }
 
+void
+DataTree::reindexExternalFunctions(SymbolTable &orig_symbol_table)
+{
+  external_functions_table.reindex(symbol_table, orig_symbol_table);
+}
+
 expr_t
 DataTree::AddNonNegativeConstant(const string &value)
 {
diff --git a/DataTree.hh b/DataTree.hh
index f81f19e6..87f61726 100644
--- a/DataTree.hh
+++ b/DataTree.hh
@@ -238,6 +238,8 @@ public:
   void writePowerDerivCHeader(ostream &output) const;
   //! Write getPowerDeriv
   void writePowerDeriv(ostream &output, bool use_dll) const;
+  //! reindex external functions
+  void reindexExternalFunctions(SymbolTable &orig_symbol_table);
   //! Thrown when trying to access an unknown variable by deriv_id
   class UnknownDerivIDException
   {
diff --git a/ExternalFunctionsTable.cc b/ExternalFunctionsTable.cc
index 8554d830..2fa1523d 100644
--- a/ExternalFunctionsTable.cc
+++ b/ExternalFunctionsTable.cc
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2011 Dynare Team
+ * Copyright (C) 2010-2015 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -24,7 +24,6 @@
 #include <iostream>
 
 #include "ExternalFunctionsTable.hh"
-#include "SymbolTable.hh"
 
 ExternalFunctionsTable::ExternalFunctionsTable()
 {
@@ -115,3 +114,44 @@ ExternalFunctionsTable::addExternalFunction(int symb_id, const external_function
 
   externalFunctionTable[symb_id] = external_function_options_chng;
 }
+
+void
+ExternalFunctionsTable::reindex(SymbolTable &new_symbol_table, SymbolTable &orig_symbol_table)
+{
+  external_function_table_type orig_externalFunctionTable = externalFunctionTable;
+  externalFunctionTable.clear();
+  for (external_function_table_type::const_iterator it = orig_externalFunctionTable.begin();
+       it != orig_externalFunctionTable.end(); it++)
+    try
+      {
+        external_function_options new_external_function_options;
+        if (it->second.firstDerivSymbID == eExtFunNotSet ||
+            it->second.firstDerivSymbID == eExtFunSetButNoNameProvided)
+          new_external_function_options.firstDerivSymbID = it->second.firstDerivSymbID;
+        else
+          new_external_function_options.firstDerivSymbID =
+            new_symbol_table.getID(orig_symbol_table.getName(it->second.firstDerivSymbID));
+
+        if (it->second.secondDerivSymbID == eExtFunNotSet ||
+            it->second.secondDerivSymbID == eExtFunSetButNoNameProvided)
+          new_external_function_options.secondDerivSymbID = it->second.secondDerivSymbID;
+        else
+          new_external_function_options.secondDerivSymbID =
+            new_symbol_table.getID(orig_symbol_table.getName(it->second.secondDerivSymbID));
+        new_external_function_options.nargs = it->second.nargs;
+        bool new_track_nargs = true;
+        if (it->second.nargs == eExtFunNotSet)
+          {
+            new_track_nargs = false;
+            new_external_function_options.nargs = eExtFunSetDefaultNargs;
+          }
+        addExternalFunction(new_symbol_table.getID(orig_symbol_table.getName(it->first)),
+                            new_external_function_options,
+                            new_track_nargs);
+      }
+    catch (...)
+      {
+        cerr << "Error: problem encountered when reindexing external functions table." << endl;
+        exit(EXIT_FAILURE);
+      }
+}
diff --git a/ExternalFunctionsTable.hh b/ExternalFunctionsTable.hh
index aa4b02cd..b5218bea 100644
--- a/ExternalFunctionsTable.hh
+++ b/ExternalFunctionsTable.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2011 Dynare Team
+ * Copyright (C) 2010-2015 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -27,6 +27,8 @@ using namespace std;
 #include <vector>
 #include <map>
 
+#include "SymbolTable.hh"
+
 enum ExternalFunctionSetOrNot
   {
     eExtFunSetButNoNameProvided = -2, //! Signifies that the derivative is obtained from the top-level function
@@ -76,6 +78,8 @@ public:
   inline int getSecondDerivSymbID(int symb_id) const throw (UnknownExternalFunctionSymbolIDException);
   //! Returns the total number of unique external functions declared or used in the .mod file
   inline int get_total_number_of_unique_model_block_external_functions() const;
+  //! Reindex external function table (after removal of extra exo)
+  void reindex(SymbolTable &new_symbol_table, SymbolTable &orig_symbol_table);
 };
 
 inline bool
diff --git a/ModelTree.cc b/ModelTree.cc
index b95a508e..b252d96d 100644
--- a/ModelTree.cc
+++ b/ModelTree.cc
@@ -1419,6 +1419,7 @@ ModelTree::reindex(SymbolTable &orig_symbol_table)
   reindexEquations(orig_symbol_table);
   reindexTrendSymbolsMap(orig_symbol_table);
   reindexNonstationarySymbolsMap(orig_symbol_table);
+  reindexExternalFunctions(orig_symbol_table);
 }
 
 void
-- 
GitLab