RSC  0.12.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Environment.cpp
Go to the documentation of this file.
1 /* ============================================================
2  *
3  * This file is part of the RSC project
4  *
5  * Copyright (C) 2011, 2012, 2013 Jan Moringen
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 "Environment.h"
28 
29 #include <algorithm>
30 #include <iterator>
31 
32 // For dynamic libs the environ variable is not available
33 // on MacOS, hence a workaround is needed. See also:
34 // http://article.gmane.org/gmane.comp.lib.boost.devel/103843
35 #if defined(__APPLE__) && defined(__DYNAMIC__)
36 #include <crt_externs.h>
37 #define environ (*_NSGetEnviron())
38 #endif
39 
40 #include <boost/algorithm/string.hpp>
41 #include <boost/program_options.hpp>
42 #include <boost/program_options/environment_iterator.hpp>
43 
45 
46 using namespace std;
47 
48 using namespace boost;
49 using namespace boost::filesystem;
50 
51 using namespace rsc::logging;
52 
53 namespace rsc {
54 namespace config {
55 
57 #ifndef WIN32
58  return "/etc/";
59 #else
60  return "c:\\";
61 #endif
62 }
63 
64 path prefixConfigDirectory(const path& prefix) {
65 #ifndef WIN32
66  // The "common" rule in the "else" leg would lead to "/usr/etc",
67  // which does not normally exist. Therefore, we treat the "/usr"
68  // prefix specially.
69  if (prefix == "/usr") {
70  return systemConfigDirectory();
71  } else {
72  return prefix / "etc/";
73  }
74 #else
75  return "c:\\";
76 #endif
77 }
78 
80 #ifndef WIN32
81  char* rawHome = getenv("HOME");
82  if (!rawHome) {
83  throw runtime_error("Home directory not defined in HOME variable.");
84  }
85  string home = string(rawHome) + string("/");
86 #else
87  char* rawHomeDrive = getenv("HOMEDRIVE");
88  if (!rawHomeDrive) {
89  throw runtime_error("HOMEDRIVE variable not set.");
90  }
91  char* rawHomePath = getenv("HOMEPATH");
92  if (!rawHomePath) {
93  throw runtime_error("HOMEPATH variable not set.");
94  }
95  string home = string(rawHomeDrive) + string(rawHomePath) + string("\\");
96 #endif
97  return home;
98 }
99 
101  return userHomeDirectory() / ".config";
102 }
103 
104 string transformName(const string& name, const string& prefix,
105  const bool& stripPrefix) {
106  if (starts_with(name, prefix)) {
107  string result;
108  string::const_iterator start = name.begin();
109  if (stripPrefix) {
110  start = start + prefix.size();
111  }
112  transform(start, name.end(), back_inserter(result), &::tolower);
113  return result;
114  } else {
115  return "";
116  }
117 }
118 
119 EnvironmentVariableSource::EnvironmentVariableSource(const string& prefix,
120  const bool& stripPrefix) :
121  logger(Logger::getLogger("rsc.config.EnvironmentVariableSource")), prefix(
122  prefix), stripPrefix(stripPrefix) {
123 }
124 
126  for (environment_iterator it = environment_iterator(environ); it
127  != environment_iterator(); ++it) {
128  string name = transformName(it->first, this->prefix, this->stripPrefix);
129  if (name.empty()) {
130  continue;
131  }
132 
133  vector<string> key;
134  split(key, name, is_any_of("_"));
135  string value = it->second;
136 
137  RSCTRACE(logger, "Option " << key << " -> " << value);
138 
139  handler.handleOption(key, value);
140  }
141 }
142 
143 }
144 }
void provideOptions(OptionHandler &handler)
Implementations should pass all configuration options to handler.
string transformName(const string &name, const string &prefix, const bool &stripPrefix)
virtual void handleOption(const std::vector< std::string > &key, const std::string &value)=0
This method is called once for each individual option available from a given ConfigSource.
path userConfigDirectory()
Return the canonical directory for configuration files of the user associated with the current proces...
Implementations of this interface receive options from ConfigSource objects.
Definition: OptionHandler.h:43
path systemConfigDirectory()
Return the directory in which system-wide configuration files are located.
Definition: Environment.cpp:56
path prefixConfigDirectory(const path &prefix)
Definition: Environment.cpp:64
LoggerPtr getLogger()
#define RSCTRACE(logger, msg)
Definition: Logger.h:210
rsc::logging::LoggerPtr logger
Definition: Environment.h:121
path userHomeDirectory()
Return the home directory of the user associated with the current process.
Definition: Environment.cpp:79
void handler(int signal)
Interface for logging adapters that can be used with RSC.
Definition: Logger.h:54