Teuchos - Trilinos Tools Package Version of the Day
Loading...
Searching...
No Matches
Teuchos_EnvVariables.cpp
1// @HEADER
2// *****************************************************************************
3// Teuchos: Common Tools Package
4//
5// Copyright 2004 NTESS and the Teuchos contributors.
6// SPDX-License-Identifier: BSD-3-Clause
7// *****************************************************************************
8// @HEADER
9
10#include "Teuchos_EnvVariables.hpp"
11
12#include <stddef.h>
13#include <string>
14
15#include <cstdlib> // std::getenv
16#include <map>
17#include <sstream>
18#include <stdexcept>
19#include <string>
20#include <vector>
21
22#include "Teuchos_StrUtils.hpp"
24
25namespace Teuchos {
26
27namespace {
28
29enum EnvironmentVariableState {
30 EnvironmentVariableIsSet_ON,
31 EnvironmentVariableIsSet_OFF,
32 EnvironmentVariableIsSet,
33 EnvironmentVariableIsNotSet
34};
35
36EnvironmentVariableState
37environmentVariableState(const std::string &environmentVariableValue) {
38 std::string v = StrUtils::allCaps(environmentVariableValue);
39 if (v == "1" || v == "YES" || v == "TRUE" || v == "ON")
40 // Environment variable is "ON"
41 return EnvironmentVariableIsSet_ON;
42 else if (v == "0" || v == "NO" || v == "FALSE" || v == "OFF")
43 // Environment variable is "OFF"
44 return EnvironmentVariableIsSet_OFF;
45 // Environment has some other non-boolean value
46 return EnvironmentVariableIsSet;
47}
48
49void setEnvironmentVariableMap(
50 const char environmentVariableName[],
51 std::map<std::string, std::map<std::string, bool>> &valsMap,
52 const bool defaultValue) {
53 using std::getenv;
54 using std::map;
55 using std::string;
56 using std::vector;
57
58 // Set the default value for this variable
59 valsMap[environmentVariableName] =
60 map<string, bool>{{"DEFAULT", defaultValue}};
61
62 const char *varVal = getenv(environmentVariableName);
63 if (varVal == nullptr) {
64 // Environment variable is not set, use the default value for any named
65 // variants
66 return;
67 }
68
69 // Variable is not empty.
70 const string varStr(varVal);
71 // vector<string> names;
72 // split(varStr, [&](const string &x) { names.push_back(x); });
73 auto names = StrUtils::splitString(varStr, ',');
74 for (auto const &name : names) {
75 auto state = environmentVariableState(name);
76 if (state == EnvironmentVariableIsSet_ON) {
77 // Environment variable was set as ENVAR_NAME=[1,YES,TRUE,ON]
78 // Global value takes precedence
79 valsMap[environmentVariableName]["DEFAULT"] = true;
80 } else if (state == EnvironmentVariableIsSet_OFF) {
81 // Environment variable was set as ENVAR_NAME=[0,NO,FALSE,OFF]
82 // Global value takes precedence
83 valsMap[environmentVariableName]["DEFAULT"] = false;
84 } else {
85 // Environment variable was set as ENVAR_NAME=...:name:...
86 // So we set the mapping true for this named variant
87 valsMap[environmentVariableName][name] = true;
88 }
89 }
90 return;
91}
92} // namespace
93
94template <typename T>
95T getEnvironmentVariable(const std::string_view environmentVariableName,
96 const T defaultValue) {
97 const char *varVal = std::getenv(environmentVariableName.data());
98 if (varVal == nullptr) {
99 return defaultValue;
100 } else {
101 std::stringstream ss(varVal);
102 T parsed;
103 ss >> parsed;
104
106 !ss, std::out_of_range,
107 "Environment variable \""
108 << environmentVariableName << "\" has a value " << varVal
109 << " that cannot be parsed as a " << typeid(T).name() << ".");
110
111 return parsed;
112 }
113}
114
115// full specialization of bool to preserve historical parsing behavior
116template <>
117bool getEnvironmentVariable<bool>(
118 const std::string_view environmentVariableName, const bool defaultValue) {
119 const char *varVal = std::getenv(environmentVariableName.data());
120 bool retVal = defaultValue;
121 if (varVal != nullptr) {
122 auto state = environmentVariableState(std::string(varVal));
123 if (state == EnvironmentVariableIsSet_ON)
124 retVal = true;
125 else if (state == EnvironmentVariableIsSet_OFF)
126 retVal = false;
127 }
128 return retVal;
129}
130
136template <>
137size_t
139 const size_t defaultValue) {
140 const char *varVal = std::getenv(environmentVariableName.data());
141 if (varVal == nullptr) {
142 return defaultValue;
143 } else {
144 long long val = std::stoll(StrUtils::allCaps(varVal));
145 if (val < static_cast<long long>(0)) {
146 // If negative - user has requested threshold be lifted
147 return std::numeric_limits<size_t>::max();
148 }
149 if (sizeof(long long) > sizeof(size_t)) {
150 // It's hard to test this code, but I want to try writing it
151 // at least, in case we ever have to run on 32-bit machines or
152 // machines with sizeof(long long)=16 and sizeof(size_t)=8.
153 constexpr long long maxSizeT =
154 static_cast<long long>(std::numeric_limits<size_t>::max());
156 val > maxSizeT, std::out_of_range,
157 "Environment variable \""
158 << environmentVariableName << "\" has a value " << val
159 << " larger than the largest size_t value " << maxSizeT << ".");
160 }
161 return static_cast<size_t>(val);
162 }
163}
164
165bool idempotentlyGetNamedEnvironmentVariableAsBool(
166 const char name[], bool &initialized, const char environmentVariableName[],
167 const bool defaultValue) {
168 static std::map<std::string, std::map<std::string, bool>> namedVariableMap_;
169 if (!initialized) {
170 setEnvironmentVariableMap(environmentVariableName, namedVariableMap_,
171 defaultValue);
172 initialized = true;
173 }
174 auto thisEnvironmentVariableMap = namedVariableMap_[environmentVariableName];
175 auto thisEnvironmentVariable = thisEnvironmentVariableMap.find(name);
176 if (thisEnvironmentVariable != thisEnvironmentVariableMap.end())
177 return thisEnvironmentVariable->second;
178 return thisEnvironmentVariableMap["DEFAULT"];
179}
180
181template <typename T>
183 T &value, bool &initialized, const std::string_view environmentVariableName,
184 const T defaultValue) {
185 if (!initialized) {
187 initialized = true;
188 }
189 return value;
190}
191
192
193template std::string idempotentlyGetEnvironmentVariable<std::string>(std::string&, bool&, const std::string_view, const std::string);
194template int idempotentlyGetEnvironmentVariable<int>(int&, bool&, const std::string_view, const int);
195template unsigned long idempotentlyGetEnvironmentVariable<unsigned long>(unsigned long&, bool&, const std::string_view, const unsigned long);
196template bool idempotentlyGetEnvironmentVariable<bool>(bool&, bool&, const std::string_view, const bool);
197template unsigned long long idempotentlyGetEnvironmentVariable<unsigned long long>(unsigned long long&, bool&, const std::string_view, const unsigned long long);
198
199} // namespace Teuchos
A std::string utilities class for Teuchos.
Standard test and throw macros.
Smart reference counting pointer class for automatic garbage collection.
static std::string allCaps(const std::string &str)
Converts a std::string to all upper case.
static Array< std::string > splitString(const std::string_view s, const char sep=',')
Split an input std::string using a seperator char sep.
This class creates a basic std::map object for platforms where the std::map is deficient,...
#define TEUCHOS_TEST_FOR_EXCEPTION(throw_exception_test, Exception, msg)
Macro for throwing an exception with breakpointing to ease debugging.
The Teuchos namespace contains all of the classes, structs and enums used by Teuchos,...
size_t getEnvironmentVariable< size_t >(const std::string_view environmentVariableName, const size_t defaultValue)
T idempotentlyGetEnvironmentVariable(T &value, bool &initialized, const std::string_view environmentVariableName, const T defaultValue)
Read a variable from the environment. Example usage: