Skip to content

Commit fce9307

Browse files
authored
refactor: get_environment_variable() function in libutil (#505)
2 parents 957c777 + 61d6d8e commit fce9307

File tree

4 files changed

+109
-6
lines changed

4 files changed

+109
-6
lines changed

ben-bot/CMakeLists.txt

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ target_link_libraries (ben_bot PRIVATE ben_bot::libbenbot)
1818

1919
add_executable (ben_bot::ben_bot ALIAS ben_bot)
2020

21-
if (MSVC)
22-
target_compile_definitions (ben_bot PRIVATE _CRT_SECURE_NO_WARNINGS)
23-
endif ()
24-
2521
#
2622

2723
include (CheckIPOSupported)

ben-bot/main.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include <libbenbot/engine/Engine.hpp>
2424
#include <libchess/uci/Printing.hpp>
2525
#include <libutil/Console.hpp>
26+
#include <libutil/Environment.hpp>
2627
#include <span>
2728
#include <string>
2829
#include <string_view>
@@ -110,8 +111,13 @@ try {
110111

111112
ben_bot::Engine engine;
112113

113-
if (const auto* var = std::getenv("BENBOT_CONFIG"))
114-
engine.read_config_file(std::filesystem::path { var });
114+
util::get_environment_variable("BENBOT_CONFIG")
115+
.transform([&engine](const string_view value) {
116+
if (not value.empty())
117+
engine.read_config_file(std::filesystem::path { value });
118+
119+
return std::monostate { };
120+
});
115121

116122
if (not uciCommand.empty())
117123
engine.handle_command(uciCommand);
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/*
2+
* ======================================================================================
3+
*
4+
* ░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░▒▓████████▓▒░
5+
* ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
6+
* ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
7+
* ░▒▓███████▓▒░░▒▓██████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
8+
* ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
9+
* ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
10+
* ░▒▓███████▓▒░░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░
11+
*
12+
* ======================================================================================
13+
*/
14+
15+
/** @file
16+
This file provides functions for working with environment variables.
17+
@ingroup util
18+
*/
19+
20+
#pragma once
21+
22+
#include <optional>
23+
#include <string>
24+
#include <string_view>
25+
26+
namespace util {
27+
28+
/** Returns the value of the environment variable with the given name.
29+
If the variable is not set, or there is an error querying the
30+
environment, ``nullopt`` is returned. If the variable is set to an
31+
empty string, an optional holding an empty string is returned.
32+
33+
@note This function is needed because all compilers warn about
34+
``std::getenv()`` being deprecated and/or thread-unsafe. This
35+
function abstracts platform-specific thread-safe versions of
36+
``std::getenv()``.
37+
*/
38+
[[nodiscard]] auto get_environment_variable(std::string_view name)
39+
-> std::optional<std::string>;
40+
41+
} // namespace util

libutil/src/Environment.cpp

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
/*
2+
* ======================================================================================
3+
*
4+
* ░▒▓███████▓▒░░▒▓████████▓▒░▒▓███████▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░▒▓████████▓▒░
5+
* ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
6+
* ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
7+
* ░▒▓███████▓▒░░▒▓██████▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
8+
* ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
9+
* ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░░▒▓█▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓█▓▒░
10+
* ░▒▓███████▓▒░░▒▓████████▓▒░▒▓█▓▒░░▒▓█▓▒░ ░▒▓███████▓▒░ ░▒▓██████▓▒░ ░▒▓█▓▒░
11+
*
12+
* ======================================================================================
13+
*/
14+
15+
#include <cstdlib> // IWYU pragma: keep - for std::getenv()
16+
#include <libutil/Environment.hpp>
17+
#include <optional>
18+
#include <string>
19+
#include <string_view>
20+
21+
namespace util {
22+
23+
using std::optional;
24+
using std::string;
25+
using std::string_view;
26+
27+
namespace {
28+
#ifdef _MSC_VER
29+
[[nodiscard]] auto get_env_var_internal(const char* name) -> optional<string>
30+
{
31+
char* value { nullptr };
32+
size_t len { 0uz };
33+
34+
[[maybe_unused]] const auto err = _dupenv_s(&value, &len, name);
35+
36+
if (value != nullptr and len > 0uz)
37+
return string { value, len };
38+
39+
return std::nullopt;
40+
}
41+
#else
42+
[[nodiscard]] auto get_env_var_internal(const char* name) -> optional<string>
43+
{
44+
if (const auto* value = std::getenv(name))
45+
return { value };
46+
47+
return std::nullopt;
48+
}
49+
#endif
50+
} // namespace
51+
52+
auto get_environment_variable(const string_view name) -> optional<string>
53+
{
54+
// This is needed because string_view::data() may not be null-terminated
55+
const string nameStr { name };
56+
57+
return get_env_var_internal(nameStr.c_str());
58+
}
59+
60+
} // namespace util

0 commit comments

Comments
 (0)