Elements  6.2
A C++ base framework for the Euclid Software.
Environment.cpp
Go to the documentation of this file.
1 
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 
35 using std::endl;
36 using std::ostream;
37 using std::string;
38 using std::stringstream;
39 
40 namespace Elements {
41 
42 using System::getEnv;
43 using System::isEnvSet;
44 using System::setEnv;
45 using System::unSetEnv;
46 
47 Environment::Variable::Variable(Environment& arg_env, const string& arg_index) : m_env{arg_env}, m_index{arg_index} {}
48 
50  checkCompatibility(other);
51 }
52 
54  checkCompatibility(other);
55 }
56 
58  checkCompatibility(other);
59 
60  m_env = other.m_env;
61 
62  return *this;
63 }
64 
66  checkCompatibility(other);
67 
68  m_env = move(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 
115  Environment::Variable result(m_env, m_index);
116 
117  result.append(arg_value);
118 
119  return result;
120 }
121 
122 const 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 
135 Environment::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"
152  << " cannot be copied to the \"" << m_index << "\" environment variable." << endl;
153  throw std::invalid_argument(error_buffer.str());
154  }
155 }
156 
157 //----------------------------------------------------------------------------
158 
159 Environment::Environment(bool keep_same) : m_old_values{}, m_keep_same{keep_same}, m_added_variables{} {}
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 
176  restore();
177 }
178 
180  return Environment::Variable(*this, index);
181 }
182 
183 const Environment::Variable Environment::operator[](const string& index) const {
184  return Environment::Variable(const_cast<Environment&>(*this), index);
185 }
186 
187 Environment& 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 {
196  }
197  }
198 
199  setEnv(index, value);
200 
201  return *this;
202 }
203 
204 Environment& 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 
222 Environment& 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 
231 Environment& 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 
240 string 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 
250 bool Environment::hasKey(const string& index) {
251 
252  return isEnvSet(index);
253 }
254 
256 
257  m_old_values = {};
258  m_added_variables = {};
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 
286 void 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 
302 Environment::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
Elements::Environment::Variable::m_env
std::reference_wrapper< Environment > m_env
a copiable and movable reference
Definition: Environment.h:116
Elements::Environment::Variable::empty
bool empty() const
Definition: Environment.cpp:139
Elements::Environment::Variable::set
Variable & set(const std::string &)
Definition: Environment.cpp:80
Elements::Environment::unSet
Environment & unSet(const std::string &)
Definition: Environment.cpp:204
System.h
This file is intended to iron out all the differences between systems (currently Linux and MacOSX)
Elements::System::getEnv
ELEMENTS_API std::string getEnv(const std::string &var)
get a particular environment variable
Definition: System.cpp:324
std::string
STL class.
std::move
T move(T... args)
Elements::Environment::prepend
Environment & prepend(const std::string &, const std::string &)
Definition: Environment.cpp:231
Elements::Environment::generateScript
std::string generateScript(ShellType) const
Definition: Environment.cpp:261
Elements::Environment::Variable::append
Variable & append(const std::string &)
Definition: Environment.cpp:94
Elements::Environment::Variable::index
const std::string & index() const
Definition: Environment.cpp:122
std::map::find
T find(T... args)
std::stringstream
STL class.
Elements::Environment::hasKey
static bool hasKey(const std::string &)
Definition: Environment.cpp:250
Elements::Environment::Variable::operator+=
Variable & operator+=(const std::string &)
Definition: Environment.cpp:101
Elements::Environment::Variable
proxy class to overload the assignment
Definition: Environment.h:88
Elements::Environment::~Environment
virtual ~Environment()
Definition: Environment.cpp:175
Elements::Environment::append
Environment & append(const std::string &, const std::string &)
Definition: Environment.cpp:222
Elements::operator+
ELEMENTS_API Environment::Variable operator+(const std::string &, const Environment::Variable &)
Definition: Environment.cpp:302
Elements::System::unSetEnv
ELEMENTS_API int unSetEnv(const std::string &name)
Simple wrap around unsetenv for strings.
Definition: System.cpp:379
Elements::operator<<
ELEMENTS_API std::ostream & operator<<(std::ostream &, const Environment::Variable &)
Definition: Environment.cpp:295
Elements::Environment::Variable::exists
bool exists() const
Definition: Environment.cpp:143
Elements::Environment::operator[]
Variable operator[](const std::string &)
Definition: Environment.cpp:179
Elements::Environment::Environment
Environment(bool keep_same=true)
default constructor
Definition: Environment.cpp:159
Elements::Environment::m_added_variables
std::vector< std::string > m_added_variables
variable added to the environment
Definition: Environment.h:81
Elements::Environment::Variable::m_index
std::string m_index
The Name of the variable.
Definition: Environment.h:119
std::ostream
STL class.
Elements::System::isEnvSet
ELEMENTS_API bool isEnvSet(const std::string &var)
Check if an environment variable is set or not.
Definition: System.cpp:347
Elements::Environment::get
std::string get(const std::string &index, const std::string &default_value="") const
Definition: Environment.cpp:240
std::vector::erase
T erase(T... args)
Elements::Environment::m_old_values
std::map< std::string, std::string > m_old_values
old value for changed variables
Definition: Environment.h:76
std::invalid_argument
STL class.
Elements::Environment::commit
void commit()
Definition: Environment.cpp:255
std::map
STL class.
Elements::Environment::Variable::value
std::string value() const
Definition: Environment.cpp:130
Elements::Environment::m_keep_same
bool m_keep_same
Definition: Environment.h:78
Elements::Environment::Variable::Variable
Variable()=delete
Elements::Environment::restore
Environment & restore()
Definition: Environment.cpp:161
std::vector::emplace_back
T emplace_back(T... args)
std::endl
T endl(T... args)
std::vector::begin
T begin(T... args)
Elements::Environment::Variable::prepend
Variable & prepend(const std::string &)
Definition: Environment.cpp:106
Elements::Environment::ShellType
ShellType
Definition: Environment.h:64
Environment.h
Defines a class to handle the Environment.
std::out_of_range
STL class.
std::stringstream::str
T str(T... args)
Elements::Environment
Python dictionary-like Environment interface.
Definition: Environment.h:44
Elements::Environment::Variable::operator+
Variable operator+(const std::string &)
Definition: Environment.cpp:113
Elements::Environment::Variable::unSet
Variable & unSet()
Definition: Environment.cpp:87
std::map::end
T end(T... args)
Elements::Environment::Variable::env
Environment & env() const
Definition: Environment.cpp:126
Elements::Environment::Variable::operator=
Variable & operator=(const Variable &other)
Definition: Environment.cpp:57
Elements::Environment::checkOutOfRange
static void checkOutOfRange(const std::string &)
check that the variable is in the environment
Definition: Environment.cpp:286
Elements::System::setEnv
ELEMENTS_API int setEnv(const std::string &name, const std::string &value, bool overwrite=true)
set an environment variables.
Definition: System.cpp:369
Elements::Environment::set
Environment & set(const std::string &, const std::string &)
Definition: Environment.cpp:187
Elements
Definition: callBackExample.h:35
Elements::Environment::Variable::checkCompatibility
void checkCompatibility(const Variable &)
Definition: Environment.cpp:147