Elements 6.3.3
A C++ base framework for the Euclid Software.
Loading...
Searching...
No Matches
Environment.cpp
Go to the documentation of this file.
1
21
23
24#include <algorithm> // for find
25#include <map> // for map
26#include <sstream> // for stringstream
27#include <stdexcept> // for out_of_range
28#include <string> // for string
29#include <utility> // for move
30
31#include <boost/format.hpp> // for format
32
33#include "ElementsKernel/System.h" // for getEnv, setEnv, isEnvSet
34
35using std::endl;
36using std::ostream;
37using std::string;
39
40namespace Elements {
41
42using System::getEnv;
44using System::setEnv;
46
47Environment::Variable::Variable(Environment& arg_env, const string& arg_index) : m_env{arg_env}, m_index{arg_index} {}
48
52
56
58 checkCompatibility(other);
59
60 m_env = other.m_env;
61
62 return *this;
63}
64
66 checkCompatibility(other);
67
68 m_env = other.m_env;
69
70 return *this;
71}
72
74
75 set(arg_value);
76
77 return *this;
78}
79
81
82 m_env.get().set(m_index, arg_value);
83
84 return *this;
85}
86
88
89 m_env.get().unSet(m_index);
90
91 return *this;
92}
93
95
96 m_env.get().append(m_index, arg_value);
97
98 return *this;
99}
100
102
103 return append(arg_value);
104}
105
107
108 m_env.get().prepend(m_index, arg_value);
109
110 return *this;
111}
112
114
116
117 result.append(arg_value);
118
119 return result;
120}
121
122const string& Environment::Variable::index() const {
123 return m_index;
124}
125
127 return m_env;
128}
129
131
132 return m_env.get().get(m_index, "");
133}
134
135Environment::Variable::operator std::string() const {
136 return value();
137}
138
140 return value().empty();
141}
142
144 return m_env.get().hasKey(m_index);
145}
146
148
149 if (m_index != other.m_index) {
150 stringstream error_buffer;
151 error_buffer << "The \"" << other.m_index << "\" environment variable" << " cannot be copied to the \"" << m_index
152 << "\" environment variable." << endl;
153 throw std::invalid_argument(error_buffer.str());
154 }
155}
156
157//----------------------------------------------------------------------------
158
160
162 for (const auto& v : m_added_variables) {
163 unSetEnv(v);
164 }
165
166 for (const auto& v : m_old_values) {
167 setEnv(v.first, v.second);
168 }
169
170 m_old_values = {};
171
172 return *this;
173}
174
178
180 return Environment::Variable(*this, index);
181}
182
183const Environment::Variable Environment::operator[](const string& index) const {
184 return Environment::Variable(const_cast<Environment&>(*this), index);
185}
186
187Environment& Environment::set(const string& index, const string& value) {
188
189 if (m_old_values.find(index) == m_old_values.end()) {
190 if (hasKey(index)) {
191 if ((not m_keep_same) || (getEnv(index) != value)) {
192 m_old_values[index] = getEnv(index);
193 }
194 } else {
195 m_added_variables.emplace_back(index);
196 }
197 }
198
199 setEnv(index, value);
200
201 return *this;
202}
203
204Environment& Environment::unSet(const string& index) {
205
206 checkOutOfRange(index);
207
208 if (m_old_values.find(index) == m_old_values.end()) {
209 auto found_index = std::find(m_added_variables.begin(), m_added_variables.end(), index);
210 if (found_index != m_added_variables.end()) {
211 m_added_variables.erase(found_index);
212 } else {
213 m_old_values[index] = getEnv(index);
214 }
215 }
216
217 unSetEnv(index);
218
219 return *this;
220}
221
222Environment& Environment::append(const string& index, const string& value) {
223
224 const string new_value = get(index) + value;
225
226 set(index, new_value);
227
228 return *this;
229}
230
231Environment& Environment::prepend(const string& index, const string& value) {
232
233 const string new_value = value + get(index);
234
235 set(index, new_value);
236
237 return *this;
238}
239
240string Environment::get(const string& index, const string& default_value) const {
241 string value{default_value};
242
243 if (hasKey(index)) {
244 value = getEnv(index);
245 }
246
247 return value;
248}
249
250bool Environment::hasKey(const string& index) {
251
252 return isEnvSet(index);
253}
254
256
257 m_old_values = {};
259}
260
262
263 using boost::format;
264 using std::map;
265
266 stringstream script_text{};
267
268 map<ShellType, string> set_cmd{{ShellType::sh, "export %s=%s"}, {ShellType::csh, "setenv %s %s"}};
269 map<ShellType, string> unset_cmd{{ShellType::sh, "unset %s"}, {ShellType::csh, "unsetenv %s"}};
270
271 for (const auto& v : m_old_values) {
272 if (hasKey(v.first)) {
273 script_text << format(set_cmd[type]) % v.first % get(v.first) << endl;
274 } else {
275 script_text << format(unset_cmd[type]) % v.first << endl;
276 }
277 }
278
279 for (const auto& v : m_added_variables) {
280 script_text << format(set_cmd[type]) % v % get(v) << endl;
281 }
282
283 return script_text.str();
284}
285
286void Environment::checkOutOfRange(const string& index) {
287
288 if (not hasKey(index)) {
289 stringstream error_buffer;
290 error_buffer << "The environment doesn't contain the " << index << " variable." << endl;
291 throw std::out_of_range(error_buffer.str());
292 }
293}
294
296
297 stream << v.value();
298
299 return stream;
300}
301
302Environment::Variable operator+(const string& value, const Environment::Variable& other) {
303
304 Environment::Variable result(other.env(), other.index());
305
306 result.prepend(value);
307
308 return result;
309}
310
311} // namespace Elements
T endl(T... args)
Defines a class to handle the Environment.
This file is intended to iron out all the differences between systems (currently Linux and MacOSX)
proxy class to overload the assignment
Definition Environment.h:88
Variable & operator=(const Variable &other)
Variable & set(const std::string &)
Variable & operator+=(const std::string &)
std::reference_wrapper< Environment > m_env
a copiable and movable reference
Variable & prepend(const std::string &)
std::string m_index
The Name of the variable.
Variable & append(const std::string &)
void checkCompatibility(const Variable &)
Variable operator+(const std::string &)
const std::string & index() const
std::vector< std::string > m_added_variables
variable added to the environment
Definition Environment.h:81
std::string get(const std::string &index, const std::string &default_value="") const
Variable operator[](const std::string &)
Environment(bool keep_same=true)
default constructor
std::map< std::string, std::string > m_old_values
old value for changed variables
Definition Environment.h:76
static bool hasKey(const std::string &)
Environment & set(const std::string &, const std::string &)
Environment & append(const std::string &, const std::string &)
Environment & unSet(const std::string &)
Environment & restore()
Environment & prepend(const std::string &, const std::string &)
std::string generateScript(ShellType) const
STL class.
T endl(T... args)
T find(T... args)
static void checkOutOfRange(const std::string &)
check that the variable is in the environment
ELEMENTS_API bool isEnvSet(const std::string &var)
Check if an environment variable is set or not.
Definition System.cpp:340
ELEMENTS_API int setEnv(const std::string &name, const std::string &value, bool overwrite=true)
set an environment variables.
Definition System.cpp:362
ELEMENTS_API int unSetEnv(const std::string &name)
Simple wrap around unsetenv for strings.
Definition System.cpp:372
ELEMENTS_API std::string getEnv(const std::string &var)
get a particular environment variable
Definition System.cpp:317
ELEMENTS_API bool isEnvSet(const std::string &var)
Check if an environment variable is set or not.
Definition System.cpp:340
ELEMENTS_API int setEnv(const string &name, const string &value, bool overwrite)
set an environment variables.
Definition System.cpp:362
ELEMENTS_API Environment::Variable operator+(const std::string &, const Environment::Variable &)
ELEMENTS_API int unSetEnv(const std::string &name)
Simple wrap around unsetenv for strings.
Definition System.cpp:372
ELEMENTS_API std::string getEnv(const std::string &var)
get a particular environment variable
Definition System.cpp:317
ELEMENTS_API std::ostream & operator<<(std::ostream &, const Environment::Variable &)
T str(T... args)