From ae49cddd1dc82a74e02e477d9e41b4bcbf8f228b Mon Sep 17 00:00:00 2001 From: Houtan Bastani Date: Fri, 28 Aug 2015 17:58:43 +0200 Subject: [PATCH] preprocessor: allow for [paths] block in dynare config file. closes #1039 --- doc/dynare.texi | 29 ++++++++ preprocessor/ConfigFile.cc | 109 +++++++++++++++++++++++++---- preprocessor/ConfigFile.hh | 19 ++++- preprocessor/DynareMain.cc | 7 ++ tests/parallel/dynare.ini | 3 + tests/parallel/folder/endovars.mod | 1 + tests/parallel/ls2003.mod | 3 +- 7 files changed, 155 insertions(+), 16 deletions(-) create mode 100644 tests/parallel/folder/endovars.mod diff --git a/doc/dynare.texi b/doc/dynare.texi index 3b1519d22..9f6fd2117 100644 --- a/doc/dynare.texi +++ b/doc/dynare.texi @@ -9571,6 +9571,35 @@ GlobalInitFile = /home/usern/dynare/myInitFile.m @end deffn +@deffn {Configuration block} [paths] + +@descriptionhead + +The @code{[paths]} block can be used to specify paths that will be +used when running dynare. + +@optionshead + +@table @code + +@item Include = @var{PATH} +A colon-separated path to use when searching for files to include via +@ref{@@#include}. Paths specified via @ref{-I} take priority over +paths specified here, while these paths take priority over those +specified by @ref{@@#includepath}. + +@end table + +@examplehead + +@example +[paths] +Include = /path/to/folder/containing/modfiles:/path/to/another/folder + +@end example + +@end deffn + @node Parallel Configuration @section Parallel Configuration diff --git a/preprocessor/ConfigFile.cc b/preprocessor/ConfigFile.cc index 0a3ef5eed..7186adc0d 100644 --- a/preprocessor/ConfigFile.cc +++ b/preprocessor/ConfigFile.cc @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2013 Dynare Team + * Copyright (C) 2010-2015 Dynare Team * * This file is part of Dynare. * @@ -40,6 +40,16 @@ Hook::Hook(string &global_init_file_arg) hooks["global_init_file"] = global_init_file_arg; } +Path::Path(vector &includepath_arg) +{ + if (includepath_arg.empty()) + { + cerr << "ERROR: The Path must have an Include argument." << endl; + exit(EXIT_FAILURE); + } + paths["include"] = includepath_arg; +} + SlaveNode::SlaveNode(string &computerName_arg, string port_arg, int minCpuNbr_arg, int maxCpuNbr_arg, string &userName_arg, string &password_arg, string &remoteDrive_arg, string &remoteDirectory_arg, string &dynarePath_arg, string &matlabOctavePath_arg, bool singleCompThread_arg, @@ -151,6 +161,7 @@ ConfigFile::getConfigFileInfo(const string &config_file) string name, computerName, port, userName, password, remoteDrive, remoteDirectory, dynarePath, matlabOctavePath, operatingSystem, global_init_file; + vector includepath; int minCpuNbr = 0, maxCpuNbr = 0; bool singleCompThread = true; member_nodes_t member_nodes; @@ -158,6 +169,7 @@ ConfigFile::getConfigFileInfo(const string &config_file) bool inHooks = false; bool inNode = false; bool inCluster = false; + bool inPaths = false; while (configFile->good()) { string line; @@ -166,11 +178,17 @@ ConfigFile::getConfigFileInfo(const string &config_file) if (line.empty()) continue; - if (!line.compare("[node]") || !line.compare("[cluster]") || !line.compare("[hooks]")) + if (!line.compare("[node]") + || !line.compare("[cluster]") + || !line.compare("[hooks]") + || !line.compare("[paths]")) { if (!global_init_file.empty()) // we were just in [hooks] addHooksConfFileElement(global_init_file); + else if (!includepath.empty()) + // we were just in [paths] + addPathsConfFileElement(includepath); else // we were just in [node] or [cluster] addParallelConfFileElement(inNode, inCluster, member_nodes, name, @@ -185,24 +203,34 @@ ConfigFile::getConfigFileInfo(const string &config_file) inHooks = true; inNode = false; inCluster = false; + inPaths = false; + } + else if (!line.compare("[node]")) + { + inHooks = false; + inNode = true; + inCluster = false; + inPaths = false; + } + else if (!line.compare("[paths]")) + { + inHooks = false; + inNode = false; + inCluster = false; + inPaths = true; } else - if (!line.compare("[node]")) - { - inHooks = false; - inNode = true; - inCluster = false; - } - else - { - inHooks = false; - inNode = false; - inCluster = true; - } + { + inHooks = false; + inNode = false; + inCluster = true; + inPaths = false; + } name = userName = computerName = port = password = remoteDrive = remoteDirectory = dynarePath = matlabOctavePath = operatingSystem = global_init_file = ""; + includepath.clear(); minCpuNbr = maxCpuNbr = 0; singleCompThread = true; member_nodes.clear(); @@ -233,6 +261,30 @@ ConfigFile::getConfigFileInfo(const string &config_file) cerr << "ERROR: Unrecognized option " << tokenizedLine.front() << " in [hooks] block." << endl; exit(EXIT_FAILURE); } + else if (inPaths) + if (!tokenizedLine.front().compare("Include")) + if (includepath.empty()) + { + vector tokenizedPath; + split(tokenizedPath, tokenizedLine.back(), is_any_of(":"), token_compress_on); + for (vector::iterator it = tokenizedPath.begin(); + it != tokenizedPath.end(); it++ ) + if (!it->empty()) + { + trim(*it); + includepath.push_back(*it); + } + } + else + { + cerr << "ERROR: May not have more than one Include option in [paths] block." << endl; + exit(EXIT_FAILURE); + } + else + { + cerr << "ERROR: Unrecognized option " << tokenizedLine.front() << " in [paths] block." << endl; + exit(EXIT_FAILURE); + } else if (!tokenizedLine.front().compare("Name")) name = tokenizedLine.back(); @@ -379,12 +431,15 @@ ConfigFile::getConfigFileInfo(const string &config_file) if (!global_init_file.empty()) addHooksConfFileElement(global_init_file); + else if (!includepath.empty()) + addPathsConfFileElement(includepath); else addParallelConfFileElement(inNode, inCluster, member_nodes, name, computerName, port, minCpuNbr, maxCpuNbr, userName, password, remoteDrive, remoteDirectory, dynarePath, matlabOctavePath, singleCompThread, operatingSystem); + configFile->close(); delete configFile; } @@ -401,6 +456,18 @@ ConfigFile::addHooksConfFileElement(string &global_init_file) hooks.push_back(new Hook(global_init_file)); } +void +ConfigFile::addPathsConfFileElement(vector &includepath) +{ + if (includepath.empty()) + { + cerr << "ERROR: The path to be included must be passed to the Include option." << endl; + exit(EXIT_FAILURE); + } + else + paths.push_back(new Path(includepath)); +} + void ConfigFile::addParallelConfFileElement(bool inNode, bool inCluster, member_nodes_t member_nodes, string &name, string &computerName, string port, int minCpuNbr, int maxCpuNbr, string &userName, @@ -609,6 +676,20 @@ ConfigFile::transformPass() it->second /= weight_denominator; } +vector +ConfigFile::getIncludePaths() const +{ + vector include_paths; + for (vector::const_iterator it = paths.begin() ; it != paths.end(); it++) + { + map > pathmap = (*it)->get_paths(); + for (map >::const_iterator mapit = pathmap.begin() ; mapit != pathmap.end(); mapit++) + for (vector::const_iterator vecit = mapit->second.begin(); vecit != mapit->second.end(); vecit++) + include_paths.push_back(*vecit); + } + return include_paths; +} + void ConfigFile::writeHooks(ostream &output) const { diff --git a/preprocessor/ConfigFile.hh b/preprocessor/ConfigFile.hh index c7dd85ef5..0a6d2e6c0 100644 --- a/preprocessor/ConfigFile.hh +++ b/preprocessor/ConfigFile.hh @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Dynare Team + * Copyright (C) 2010-2015 Dynare Team * * This file is part of Dynare. * @@ -40,6 +40,17 @@ public: inline mapget_hooks() { return hooks; }; }; +class Path +{ +public: + Path(vector &includepath_arg); + ~Path(); +private: + map > paths; +public: + inline map >get_paths() { return paths; }; +}; + class SlaveNode { friend class ConfigFile; @@ -91,12 +102,16 @@ private: string firstClusterName; //! Hooks vector hooks; + //! Paths + vector paths; //! Cluster Table map clusters; //! Node Map map slave_nodes; //! Add Hooks void addHooksConfFileElement(string &global_init_file); + //! Add Paths + void addPathsConfFileElement(vector &includepath); //! Add a SlaveNode or a Cluster object void addParallelConfFileElement(bool inNode, bool inCluster, member_nodes_t member_nodes, string &name, string &computerName, string port, int minCpuNbr, int maxCpuNbr, string &userName, @@ -110,6 +125,8 @@ public: void checkPass(WarningConsolidation &warnings) const; //! Check Pass void transformPass(); + //! Get Path Info + vector getIncludePaths() const; //! Write any hooks void writeHooks(ostream &output) const; //! Create options_.parallel structure, write options diff --git a/preprocessor/DynareMain.cc b/preprocessor/DynareMain.cc index 666e43e96..e1804b334 100644 --- a/preprocessor/DynareMain.cc +++ b/preprocessor/DynareMain.cc @@ -288,6 +288,13 @@ main(int argc, char **argv) config_file.checkPass(warnings); config_file.transformPass(); + // If Include option was passed to the [paths] block of the config file, add + // it to paths before macroprocessing + vector config_include_paths = config_file.getIncludePaths(); + for (vector::const_iterator it = config_include_paths.begin(); + it != config_include_paths.end(); it++) + path.push_back(*it); + // Do macro processing MacroDriver m; diff --git a/tests/parallel/dynare.ini b/tests/parallel/dynare.ini index 2132a28cb..0d400f636 100644 --- a/tests/parallel/dynare.ini +++ b/tests/parallel/dynare.ini @@ -9,3 +9,6 @@ GlobalInitFile = ./init.m Name = n1 ComputerName = localhost CPUnbr = [1:8] + +[paths] +Include = folder \ No newline at end of file diff --git a/tests/parallel/folder/endovars.mod b/tests/parallel/folder/endovars.mod new file mode 100644 index 000000000..2ee76dfb7 --- /dev/null +++ b/tests/parallel/folder/endovars.mod @@ -0,0 +1 @@ +var y y_s R pie dq pie_s de A y_obs pie_obs R_obs; diff --git a/tests/parallel/ls2003.mod b/tests/parallel/ls2003.mod index 20f4d6856..6c8043358 100644 --- a/tests/parallel/ls2003.mod +++ b/tests/parallel/ls2003.mod @@ -1,4 +1,5 @@ -var y y_s R pie dq pie_s de A y_obs pie_obs R_obs; +@#include "endovars.mod" + varexo e_R e_q e_ys e_pies e_A; parameters psi1 psi2 psi3 rho_R tau alpha rr k rho_q rho_A rho_ys rho_pies;