diff --git a/src/pymod/unit_tests/pymod_tests.cc b/src/pymod/unit_tests/pymod_tests.cc index d523dd344..7ec39f7af 100644 --- a/src/pymod/unit_tests/pymod_tests.cc +++ b/src/pymod/unit_tests/pymod_tests.cc @@ -32,19 +32,12 @@ #include "tlUnitTest.h" #include "tlStream.h" +#include "tlEnv.h" int run_pymodtest (tl::TestBase *_this, const std::string &fn) { - static std::string pypath; - if (pypath.empty ()) { - pypath = "PYTHONPATH="; - pypath += STRINGIFY (PYTHONPATH); - } -#if defined(_WIN32) - _putenv (const_cast (pypath.c_str ())); -#else - putenv (const_cast (pypath.c_str ())); -#endif + std::string pypath = STRINGIFY (PYTHONPATH); + tl::set_env ("PYTHONPATH", pypath); tl::info << pypath; std::string fp (tl::testdata ()); diff --git a/src/tl/tl/tlEnv.cc b/src/tl/tl/tlEnv.cc index ffd779ddd..47107818c 100644 --- a/src/tl/tl/tlEnv.cc +++ b/src/tl/tl/tlEnv.cc @@ -23,6 +23,7 @@ #include "tlEnv.h" #include "tlString.h" +#include "tlThreads.h" #include @@ -38,8 +39,13 @@ namespace tl { +static tl::Mutex s_env_lock; +static std::map s_env_map; + std::string get_env (const std::string &name, const std::string &def_value) { + tl::MutexLocker env_locker (&s_env_lock); + #ifdef _WIN32 std::wstring wname = tl::to_wstring (name); wchar_t *env = _wgetenv (wname.c_str ()); @@ -58,6 +64,38 @@ std::string get_env (const std::string &name, const std::string &def_value) #endif } +void set_env (const std::string &name, const std::string &value) +{ + tl::MutexLocker env_locker (&s_env_lock); + + s_env_map [name] = name + "=" + value; + const std::string &s = s_env_map [name]; + +#if defined(_WIN32) + _putenv (const_cast (s.c_str ())); +#else + putenv (const_cast (s.c_str ())); +#endif +} + +void unset_env (const std::string &name) +{ + tl::MutexLocker env_locker (&s_env_lock); + +#if defined(_WIN32) + s_env_map [name] = name + "="; +#else + s_env_map [name] = name; +#endif + const std::string &s = s_env_map [name]; + +#if defined(_WIN32) + _putenv (const_cast (s.c_str ())); +#else + putenv (const_cast (s.c_str ())); +#endif +} + bool has_env (const std::string &name) { #ifdef _WIN32 diff --git a/src/tl/tl/tlEnv.h b/src/tl/tl/tlEnv.h index 454b68bd8..ca17fdd30 100644 --- a/src/tl/tl/tlEnv.h +++ b/src/tl/tl/tlEnv.h @@ -38,6 +38,16 @@ namespace tl */ std::string TL_PUBLIC get_env (const std::string &name, const std::string &def_value = std::string ()); +/** + * @brief Sets the value for the given environment variable + */ +void TL_PUBLIC set_env (const std::string &name, const std::string &value); + +/** + * @brief Removes the given environment variable + */ +void TL_PUBLIC unset_env (const std::string &name); + /** * @brief Gets the value if the given environment variable is set */ diff --git a/src/tl/unit_tests/tlEnvTests.cc b/src/tl/unit_tests/tlEnvTests.cc new file mode 100644 index 000000000..46a0f0364 --- /dev/null +++ b/src/tl/unit_tests/tlEnvTests.cc @@ -0,0 +1,45 @@ + +/* + + KLayout Layout Viewer + Copyright (C) 2006-2023 Matthias Koefferlein + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +*/ + +#include "tlEnv.h" +#include "tlUnitTest.h" + +const char *dne_name = "__DOES_NOT_EXIST__"; + +TEST(1) +{ + EXPECT_EQ (tl::has_env (dne_name), false); + + tl::set_env (dne_name, "123"); + EXPECT_EQ (tl::has_env (dne_name), true); + + EXPECT_EQ (tl::get_env (dne_name), "123"); + + tl::set_env (dne_name, "42"); + EXPECT_EQ (tl::has_env (dne_name), true); + + EXPECT_EQ (tl::get_env (dne_name), "42"); + + tl::unset_env (dne_name); + EXPECT_EQ (tl::get_env (dne_name, "bla"), "bla"); + EXPECT_EQ (tl::has_env (dne_name), false); +} diff --git a/src/tl/unit_tests/unit_tests.pro b/src/tl/unit_tests/unit_tests.pro index 2e0bab909..0e4bcc449 100644 --- a/src/tl/unit_tests/unit_tests.pro +++ b/src/tl/unit_tests/unit_tests.pro @@ -16,6 +16,7 @@ SOURCES = \ tlDataMappingTests.cc \ tlDeferredExecutionTests.cc \ tlDeflateTests.cc \ + tlEnvTests.cc \ tlEventsTests.cc \ tlExpressionTests.cc \ tlFileSystemWatcherTests.cc \