From 7083a1dc7d395df78d8e208c26ad996c5a6394f5 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Tue, 30 Mar 2021 13:29:46 +0200 Subject: Add notion of thread environment --- libbutl/utility.cxx | 52 +++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) (limited to 'libbutl/utility.cxx') diff --git a/libbutl/utility.cxx b/libbutl/utility.cxx index bbeafd2..0a8ba1e 100644 --- a/libbutl/utility.cxx +++ b/libbutl/utility.cxx @@ -9,13 +9,14 @@ #include #endif -#include // setenv(), unsetenv(), _putenv() +#include // getenv(), setenv(), unsetenv(), _putenv() #ifndef __cpp_lib_modules_ts #include #include #include +#include // strncmp() #include #include // enable_if, is_base_of #include @@ -332,6 +333,55 @@ namespace butl s.resize (d - s.begin ()); } +#ifdef __cpp_thread_local + thread_local +#else + __thread +#endif + const char* const* thread_env_ = nullptr; + +#ifdef _WIN32 + const char* const* + thread_env () {return thread_env_;} + + void + thread_env (const char* const* v) {thread_env_ = v;} +#endif + + optional + getenv (const std::string& name) + { + if (const char* const* vs = thread_env_) + { + size_t n (name.size ()); + + for (; *vs != nullptr; ++vs) + { + const char* v (*vs); + + // Note that on Windows variable names are case-insensitive. + // +#ifdef _WIN32 + if (icasecmp (name.c_str (), v, n) == 0) +#else + if (strncmp (name.c_str (), v, n) == 0) +#endif + { + switch (v[n]) + { + case '=': return string (v + n + 1); + case '\0': return nullopt; + } + } + } + } + + if (const char* r = ::getenv (name.c_str ())) + return std::string (r); + + return nullopt; + } + void setenv (const string& name, const string& value) { -- cgit v1.1