RSC  0.9.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
Configuration.cpp
Go to the documentation of this file.
1 /* ============================================================
2  *
3  * This file is part of the RSC project
4  *
5  * Copyright (C) 2012, 2013 Jan Moringen <jmoringe@techfak.uni-bielefeld.de>
6  *
7  * This file may be licensed under the terms of the
8  * GNU Lesser General Public License Version 3 (the ``LGPL''),
9  * or (at your option) any later version.
10  *
11  * Software distributed under the License is distributed
12  * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
13  * express or implied. See the LGPL for the specific language
14  * governing rights and limitations.
15  *
16  * You should have received a copy of the LGPL along with this
17  * program. If not, go to http://www.gnu.org/licenses/lgpl.html
18  * or write to the Free Software Foundation, Inc.,
19  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The development of this software was supported by:
22  * CoR-Lab, Research Institute for Cognition and Robotics
23  * Bielefeld University
24  *
25  * ============================================================ */
26 
27 #include "Configuration.h"
28 
29 #include <stdexcept>
30 
31 #include <boost/format.hpp>
32 #include <boost/filesystem/fstream.hpp>
33 
34 #include "../logging/Logger.h"
35 #include "../logging/LoggerFactory.h"
36 
37 #include "Environment.h"
38 #include "ConfigFileSource.h"
40 
41 using namespace std;
42 
43 using namespace rsc::logging;
44 
45 namespace rsc {
46 namespace config {
47 
49  static LoggerPtr logger
50  = logging::LoggerFactory::getInstance().getLogger("rsc.config.configure()");
51  return logger;
52 }
53 
54 void configure(OptionHandler& handler,
55  const string& configFileName,
56  const string& environmentVariablePrefix,
57  int argc,
58  const char** argv,
59  bool stripEnvironmentVariablePrefix,
60  const boost::filesystem::path& prefix) {
61 
62  // 1) Try prefix-wide configuration file
63  // (lowest priority)
64  boost::filesystem::path
65  prefixWideFile(prefixConfigDirectory(prefix) / configFileName);
66  try {
67  boost::filesystem::ifstream stream(prefixWideFile);
68  if (stream) {
69  ConfigFileSource source(stream);
70  source.provideOptions(handler);
71  }
72  } catch (const runtime_error& e) {
74  "Failed to process prefix-wide configuration file `"
75  << prefixWideFile << "': " << e.what());
76  }
77 
78  // 2) Try user configuration file.
79  //
80  // The two instance of userConfigDirectory() / configFileName in
81  // the following code cannot be reduce into a variable assignment
82  // outside the try/catch block since the code can throw an
83  // exception.
84  bool isUserConfigDirOK = false;
85  try {
86  boost::filesystem::ifstream
87  stream(userConfigDirectory() / configFileName);
88  isUserConfigDirOK = true;
89  if (stream) {
90  ConfigFileSource source(stream);
91  source.provideOptions(handler);
92  }
93  } catch (const runtime_error& e) {
95  "Failed to process user-specific configuration file `"
96  << (isUserConfigDirOK
97  ? (userConfigDirectory() / configFileName).string()
98  : "<failed to determine user config dir>")
99  << "': " << e.what());
100  }
101 
102  // 3) Try configuration file in current directory.
103  {
104  boost::filesystem::ifstream stream(configFileName);
105  if (stream) {
106  ConfigFileSource source(stream);
107  source.provideOptions(handler);
108  }
109  }
110 
111  // 4) Add environment Variables
112  {
113  EnvironmentVariableSource source(environmentVariablePrefix,
114  stripEnvironmentVariablePrefix);
115  source.provideOptions(handler);
116  }
117 
118  // 5) Command line
119  // (highest priority)
120  if (argc > 0) {
121  CommandLinePropertySource source(argc, argv);
122  source.provideOptions(handler);
123  }
124 
125 }
126 
127 }
128 }