From 8e03f17350c1ee7f29afb15f934077c26ac182f6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Villemot?= <sebastien@dynare.org>
Date: Fri, 8 Jan 2021 14:55:15 +0100
Subject: [PATCH] =?UTF-8?q?Cleanup=20the=20=E2=80=9Coutput=E2=80=9D=20opti?=
 =?UTF-8?q?on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

— output Julia files as soon as “language=julia” is passed, independently of
  the value of the “output” option
— drop the “dynamic” and “first” values of the “output” option, since they
  actually do nothing
— obey the “output” option even in the deterministic case

Ref. dynare#1600
---
 src/DynareMain.cc                | 26 ++++++++-----------
 src/ExtendedPreprocessorTypes.hh | 18 +++++++------
 src/ModFile.cc                   | 43 +++++++++++++-------------------
 src/ModFile.hh                   | 16 ++++++------
 4 files changed, 47 insertions(+), 56 deletions(-)

diff --git a/src/DynareMain.cc b/src/DynareMain.cc
index dbdf6460..494808c3 100644
--- a/src/DynareMain.cc
+++ b/src/DynareMain.cc
@@ -54,7 +54,7 @@ usage()
 {
   cerr << "Dynare usage: dynare mod_file [debug] [noclearall] [onlyclearglobals] [savemacro[=macro_file]] [onlymacro] [linemacro] [notmpterms] [nolog] [warn_uninit]"
        << " [console] [nograph] [nointeractive] [parallel[=cluster_name]] [conffile=parallel_config_path_and_filename] [parallel_slave_open_mode] [parallel_test]"
-       << " [-D<variable>[=<value>]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] [compute_xrefs] [output=dynamic|first|second|third] [language=matlab|julia]"
+       << " [-D<variable>[=<value>]] [-I/path] [nostrict] [stochastic] [fast] [minimal_workspace] [compute_xrefs] [output=second|third] [language=matlab|julia]"
        << " [params_derivs_order=0|1|2] [transform_unary_ops] [exclude_eqs=<equation_tag_list_or_file>] [include_eqs=<equation_tag_list_or_file>]"
        << " [json=parse|check|transform|compute] [jsonstdout] [onlyjson] [jsonderivsimple] [nopathchange] [nopreprocessoroutput]"
        << " [mexext=<extension>] [matlabroot=<path>] [onlymodel] [notime] [use_dll]"
@@ -153,7 +153,7 @@ main(int argc, char **argv)
   string exclude_eqs, include_eqs;
   vector<pair<string, string>> defines;
   vector<filesystem::path> paths;
-  FileOutputType output_mode{FileOutputType::none};
+  OutputType output_mode{OutputType::standard};
   JsonOutputPointType json{JsonOutputPointType::nojson};
   JsonFileOutputType json_output_mode{JsonFileOutputType::file};
   bool onlyjson = false;
@@ -297,14 +297,10 @@ main(int argc, char **argv)
 
           s.erase(0, 7);
 
-          if (s == "dynamic")
-            output_mode = FileOutputType::dynamic;
-          else if (s == "first")
-            output_mode = FileOutputType::first;
-          else if (s == "second")
-            output_mode = FileOutputType::second;
+          if (s == "second")
+            output_mode = OutputType::second;
           else if (s == "third")
-            output_mode = FileOutputType::third;
+            output_mode = OutputType::third;
           else
             {
               cerr << "Incorrect syntax for output option" << endl;
@@ -495,13 +491,13 @@ main(int argc, char **argv)
   if (json == JsonOutputPointType::computingpass)
     mod_file->writeJsonOutput(basename, json, json_output_mode, onlyjson, jsonderivsimple);
 
-  // Write outputs
-  if (output_mode != FileOutputType::none)
-    mod_file->writeExternalFiles(basename, language);
+  // Write output files
+  if (language == LanguageOutputType::julia)
+    mod_file->writeJuliaOutput(basename);
   else
-    mod_file->writeOutputFiles(basename, clear_all, clear_global, no_warn, console, nograph,
-                               nointeractive, config_file, check_model_changes, minimal_workspace, compute_xrefs,
-                               mexext, matlabroot, dynareroot, onlymodel, gui, notime);
+    mod_file->writeMOutput(basename, clear_all, clear_global, no_warn, console, nograph,
+                           nointeractive, config_file, check_model_changes, minimal_workspace, compute_xrefs,
+                           mexext, matlabroot, dynareroot, onlymodel, gui, notime);
 
   cout << "Preprocessing completed." << endl;
   return EXIT_SUCCESS;
diff --git a/src/ExtendedPreprocessorTypes.hh b/src/ExtendedPreprocessorTypes.hh
index 68dacb90..732b80dc 100644
--- a/src/ExtendedPreprocessorTypes.hh
+++ b/src/ExtendedPreprocessorTypes.hh
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2014-2019 Dynare Team
+ * Copyright © 2014-2021 Dynare Team
  *
  * This file is part of Dynare.
  *
@@ -20,18 +20,18 @@
 #ifndef _EXTENDED_PREPROCESSOR_TYPES_HH
 #define _EXTENDED_PREPROCESSOR_TYPES_HH
 
-enum class FileOutputType
+// Values for the “output” option
+enum class OutputType
   {
-   none, // outputs files for Matlab/Octave processing
-   dynamic, // outputs <fname>_dynamic.* and related files
-   first, // outputs <fname>_first_derivatives.* and related files
-   second, // outputs <fname>_first_derivatives.*, <fname>_second_derivatives.* and related files
-   third, // outputs <fname>_first_derivatives.*, <fname>_second_derivatives.*, <fname>_third_derivatives.*  and related files
+   standard, // Default value, infer the derivation order from .mod file only
+   second, // Output at least 2nd dynamic derivatives
+   third, // Output at least 3rd dynamic derivatives
   };
 
+// Values for the “language” option
 enum class LanguageOutputType
   {
-   matlab, // outputs files for Matlab/Octave processing
+   matlab, // outputs files for MATLAB/Octave processing
    julia, // outputs files for Julia
   };
 
@@ -41,6 +41,7 @@ enum class JsonFileOutputType
    standardout, // output JSON files to stdout
   };
 
+// Values for the “json” option
 enum class JsonOutputPointType
   {
    nojson, // don't output JSON
@@ -49,4 +50,5 @@ enum class JsonOutputPointType
    transformpass, // output JSON after the transform pass
    computingpass // output JSON after the computing pass
   };
+
 #endif
diff --git a/src/ModFile.cc b/src/ModFile.cc
index b101bd88..239308e7 100644
--- a/src/ModFile.cc
+++ b/src/ModFile.cc
@@ -721,7 +721,7 @@ ModFile::transformPass(bool nostrict, bool stochastic, bool compute_xrefs, bool
 }
 
 void
-ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order)
+ModFile::computingPass(bool no_tmp_terms, OutputType output, int params_derivs_order)
 {
   // Mod file may have no equation (for example in a standalone BVAR estimation)
   if (dynamic_model.equation_number() > 0)
@@ -765,7 +765,14 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
           || mod_file_struct.calib_smoother_present || mod_file_struct.mom_estimation_present)
         {
           if (mod_file_struct.perfect_foresight_solver_present)
-            dynamic_model.computingPass(true, 1, 0, global_eval_context, no_tmp_terms, block, use_dll, bytecode, linear_decomposition);
+            {
+              int derivsOrder = 1;
+              if (output == OutputType::second)
+                derivsOrder = 2;
+              else if  (output == OutputType::third)
+                derivsOrder = 3;
+              dynamic_model.computingPass(true, derivsOrder, 0, global_eval_context, no_tmp_terms, block, use_dll, bytecode, linear_decomposition);
+            }
           else
             {
               if (mod_file_struct.stoch_simul_present
@@ -783,9 +790,9 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
                 derivsOrder = max(mod_file_struct.order_option,
                                     max(mod_file_struct.identification_order,mod_file_struct.mom_order) + 1); // See preprocessor#40
 
-              if (mod_file_struct.sensitivity_present || linear || output == FileOutputType::second)
+              if (mod_file_struct.sensitivity_present || linear || output == OutputType::second)
                 derivsOrder = max(derivsOrder, 2);
-              if (mod_file_struct.estimation_analytic_derivation || output == FileOutputType::third)
+              if (mod_file_struct.estimation_analytic_derivation || output == OutputType::third)
                 derivsOrder = max(derivsOrder, 3);
               int paramsDerivsOrder = 0;
               if (mod_file_struct.identification_present 
@@ -839,12 +846,12 @@ ModFile::computingPass(bool no_tmp_terms, FileOutputType output, int params_deri
 }
 
 void
-ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_warn,
-                          bool console, bool nograph, bool nointeractive, const ConfigFile &config_file,
-                          bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
-                          const string &mexext,
-                          const filesystem::path &matlabroot,
-                          const filesystem::path &dynareroot, bool onlymodel, bool gui, bool notime) const
+ModFile::writeMOutput(const string &basename, bool clear_all, bool clear_global, bool no_warn,
+                      bool console, bool nograph, bool nointeractive, const ConfigFile &config_file,
+                      bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
+                      const string &mexext,
+                      const filesystem::path &matlabroot,
+                      const filesystem::path &dynareroot, bool onlymodel, bool gui, bool notime) const
 {
   bool hasModelChanged = !dynamic_model.isChecksumMatching(basename, block) || !check_model_changes;
   if (hasModelChanged)
@@ -1154,21 +1161,7 @@ ModFile::writeOutputFiles(const string &basename, bool clear_all, bool clear_glo
 }
 
 void
-ModFile::writeExternalFiles(const string &basename, LanguageOutputType language) const
-{
-  switch (language)
-    {
-    case LanguageOutputType::julia:
-      writeExternalFilesJulia(basename);
-      break;
-    case LanguageOutputType::matlab:
-      cerr << "The 'output' option cannot be used when language=matlab" << endl;
-      exit(EXIT_FAILURE);
-    }
-}
-
-void
-ModFile::writeExternalFilesJulia(const string &basename) const
+ModFile::writeJuliaOutput(const string &basename) const
 {
   ofstream jlOutputFile;
   if (basename.size())
diff --git a/src/ModFile.hh b/src/ModFile.hh
index 3a7375fa..b2ba54c7 100644
--- a/src/ModFile.hh
+++ b/src/ModFile.hh
@@ -152,7 +152,7 @@ public:
   //! Execute computations
   /*! \param no_tmp_terms if true, no temporary terms will be computed in the static and dynamic files */
   /*! \param params_derivs_order compute this order of derivs wrt parameters */
-  void computingPass(bool no_tmp_terms, FileOutputType output, int params_derivs_order);
+  void computingPass(bool no_tmp_terms, OutputType output, int params_derivs_order);
   //! Writes Matlab/Octave output files
   /*!
     \param basename The base name used for writing output files. Should be the name of the mod file without its extension
@@ -165,13 +165,13 @@ public:
     \param mingw Should the MEX command of use_dll be adapted for MinGW?
     \param compute_xrefs if true, equation cross references will be computed
   */
-  void writeOutputFiles(const string &basename, bool clear_all, bool clear_global, bool no_warn,
-                        bool console, bool nograph, bool nointeractive, const ConfigFile &config_file,
-                        bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
-                        const string &mexext, const filesystem::path &matlabroot,
-                        const filesystem::path &dynareroot, bool onlymodel, bool gui, bool notime) const;
-  void writeExternalFiles(const string &basename, LanguageOutputType language) const;
-  void writeExternalFilesJulia(const string &basename) const;
+  void writeMOutput(const string &basename, bool clear_all, bool clear_global, bool no_warn,
+                    bool console, bool nograph, bool nointeractive, const ConfigFile &config_file,
+                    bool check_model_changes, bool minimal_workspace, bool compute_xrefs,
+                    const string &mexext, const filesystem::path &matlabroot,
+                    const filesystem::path &dynareroot, bool onlymodel, bool gui, bool notime) const;
+
+  void writeJuliaOutput(const string &basename) const;
 
   void computeChecksum();
   //! Write JSON representation of ModFile object
-- 
GitLab