Remove dynamic exceptions
[anna.git] / source / core / util / Environment.cpp
1 // ANNA - Anna is Not Nothingness Anymore                                                         //
2 //                                                                                                //
3 // (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo                         //
4 //                                                                                                //
5 // See project site at http://redmine.teslayout.com/projects/anna-suite                           //
6 // See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE //
7
8
9 #include <anna/core/util/Environment.hpp>
10
11 #include <anna/config/defines.hpp>
12 #include <anna/core/tracing/Logger.hpp>
13 #include <anna/core/tracing/TraceMethod.hpp>
14 #include <anna/core/functions.hpp>
15
16 #include <stdlib.h> // getenv / setenv
17 #include <string>
18
19
20
21 using namespace std;
22 using namespace anna;
23
24 extern int errno;
25
26 void Environment::initialize(char **envp) {
27   LOGMETHOD(TraceMethod tm("Environment", "initialize", ANNA_FILE_LOCATION));
28   // clear data
29   a_vars.clear();
30
31   if(!envp) return;
32
33   // register data
34   std::string assignment, var, val;
35
36   while(*envp) {
37     assignment = *envp;
38     std::size_t equalPos = assignment.find("=");
39
40     if(equalPos !=  string::npos) {  // protection
41       var = assignment.substr(0, equalPos - 1);
42       val = assignment.substr(equalPos, assignment.size() - 1);
43       a_vars[var] = val;
44     }
45
46     envp++;
47   }
48 }
49
50 std::string Environment::getValue(const char* variableName, bool exceptionIfMissing) noexcept(false) {
51   if(!variableName)
52     throw RuntimeException("Invalid NULL variable name!", ANNA_FILE_LOCATION);
53
54   std::string var = variableName;
55   return getValue(var, exceptionIfMissing);
56 }
57
58 std::string Environment::getValue(const std::string &variableName, bool exceptionIfMissing) noexcept(false) {
59   std::string result = "";
60   std::map<std::string, std::string>::const_iterator it = a_vars.find(variableName);
61
62   if(it == a_vars.end()) {
63     char *current = getenv(variableName.c_str());
64
65     if(!current) {
66       std::string msg = "The variable '";
67       msg += variableName;
68       msg += "' is not defined in the environment.";
69       LOGDEBUG(Logger::debug(msg, ANNA_FILE_LOCATION));
70
71       if(exceptionIfMissing) throw RuntimeException(msg, ANNA_FILE_LOCATION);
72     } else {
73       // assignment
74       a_vars[variableName] = current;
75       result = current;
76     }
77   } else {
78     result = it->second;
79   }
80
81   return result;
82 }
83
84
85 void Environment::setVariable(const std::string &name, const std::string &value, bool overwrite) noexcept(false) {
86   if(name == "") throw RuntimeException("Must provide non-empty variable name", ANNA_FILE_LOCATION);
87
88   if(setenv(name.c_str(), value.c_str(), overwrite ? 1 : 0) != 0) {
89     std::string msg = "Cannot set the environment variable '";
90     msg += name;
91     msg += "=\"";
92     msg += value;
93     msg += "\"'. The errno is ";
94     msg += anna::functions::asString(errno);
95     throw RuntimeException(msg, ANNA_FILE_LOCATION);
96   }
97
98   // optimization
99   if(overwrite)
100     a_vars[name] = value;
101 }
102
103
104 void Environment::unsetVariable(const std::string &name) noexcept(false) {
105   if(name == "") throw RuntimeException("Must provide non-empty variable name", ANNA_FILE_LOCATION);
106
107   if(unsetenv(name.c_str()) != 0) {
108     std::string msg = "Cannot unset the environment variable named '";
109     msg += name;
110     msg += "'. The errno is ";
111     msg += anna::functions::asString(errno);
112     throw RuntimeException(msg, ANNA_FILE_LOCATION);
113   }
114
115   std::map<std::string, std::string>::iterator it = a_vars.find(name);
116
117   if(it != a_vars.end()) a_vars.erase(it);
118 }
119