aboutsummaryrefslogtreecommitdiff
path: root/src/zencore/filesystem.cpp
diff options
context:
space:
mode:
authorStefan Boberg <[email protected]>2026-04-27 15:05:16 +0200
committerGitHub Enterprise <[email protected]>2026-04-27 15:05:16 +0200
commit6804dc6ff62c477399183dc85d2ad387298aa49d (patch)
treef4153a901c758b9e385627b43f1606f8c2129a04 /src/zencore/filesystem.cpp
parent5.8.9-pre3 (diff)
downloadarchived-zen-6804dc6ff62c477399183dc85d2ad387298aa49d.tar.xz
archived-zen-6804dc6ff62c477399183dc85d2ad387298aa49d.zip
GetEnvVariable: return std::optional<std::string> (#1017)
- `GetEnvVariable` now returns `std::optional<std::string>` so callers can distinguish an unset variable from one set to an empty value. - Windows path uses `SetLastError(ERROR_SUCCESS)` + `ERROR_ENVVAR_NOT_FOUND` to detect "not found"; POSIX path returns `nullopt` when `getenv` returns `nullptr`. - All call sites migrated. Most use `.value_or("")` to preserve current empty-or-unset behavior. The diagnostic helpers in `zen-test/artifactprovider-tests.cpp` now report `<unset>` vs `<empty>` distinctly. - Added a check in the `ExpandEnvironmentVariables` test confirming `nullopt` for an unset variable; PATH/HOME lookups in that test use `REQUIRE(has_value())` so a missing var fails cleanly instead of throwing `bad_optional_access`.
Diffstat (limited to 'src/zencore/filesystem.cpp')
-rw-r--r--src/zencore/filesystem.cpp44
1 files changed, 30 insertions, 14 deletions
diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp
index 281cb8e2e..e8ceac5c0 100644
--- a/src/zencore/filesystem.cpp
+++ b/src/zencore/filesystem.cpp
@@ -2936,41 +2936,52 @@ GetDirectoryContent(const std::filesystem::path& RootDir,
Visitor.AsyncVisitDirectory(WrapperVisitor.RelativeRoot, std::move(WrapperVisitor.Content));
}
-std::string
+std::optional<std::string>
GetEnvVariable(std::string_view VariableName)
{
ZEN_ASSERT(!VariableName.empty());
#if ZEN_PLATFORM_WINDOWS
-
+ const std::string NameStr(VariableName);
std::vector<CHAR> EnvVariableBuffer(1023 + 1);
- DWORD RESULT = GetEnvironmentVariableA(std::string(VariableName).c_str(), EnvVariableBuffer.data(), (DWORD)EnvVariableBuffer.size());
+ SetLastError(ERROR_SUCCESS);
+ DWORD RESULT = GetEnvironmentVariableA(NameStr.c_str(), EnvVariableBuffer.data(), (DWORD)EnvVariableBuffer.size());
if (RESULT == 0)
{
- return "";
+ if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
+ {
+ return std::nullopt;
+ }
+ return std::string{};
}
if (RESULT <= EnvVariableBuffer.size())
{
return std::string(EnvVariableBuffer.data(), size_t(RESULT));
}
EnvVariableBuffer.resize(size_t(RESULT));
- RESULT = GetEnvironmentVariableA(std::string(VariableName).c_str(), EnvVariableBuffer.data(), (DWORD)EnvVariableBuffer.size());
+ SetLastError(ERROR_SUCCESS);
+ RESULT = GetEnvironmentVariableA(NameStr.c_str(), EnvVariableBuffer.data(), (DWORD)EnvVariableBuffer.size());
if (RESULT == 0)
{
- return "";
+ if (GetLastError() == ERROR_ENVVAR_NOT_FOUND)
+ {
+ return std::nullopt;
+ }
+ return std::string{};
}
if (RESULT <= EnvVariableBuffer.size())
{
return std::string(EnvVariableBuffer.data(), size_t(RESULT));
}
+ return std::nullopt;
#endif
#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC
- char* EnvVariable = getenv(std::string(VariableName).c_str());
+ const char* EnvVariable = getenv(std::string(VariableName).c_str());
if (EnvVariable)
{
return std::string(EnvVariable);
}
+ return std::nullopt;
#endif
- return "";
}
std::string
@@ -2987,7 +2998,7 @@ ExpandEnvironmentVariables(std::string_view Input)
if (End != std::string_view::npos && End > i + 1)
{
std::string_view VarName = Input.substr(i + 1, End - i - 1);
- std::string Value = GetEnvVariable(VarName);
+ std::string Value = GetEnvVariable(VarName).value_or("");
if (!Value.empty())
{
Result += Value;
@@ -4242,12 +4253,16 @@ TEST_CASE("ExpandEnvironmentVariables")
// Known variable
# if ZEN_PLATFORM_WINDOWS
// PATH is always set on Windows
- std::string PathValue = GetEnvVariable("PATH");
+ std::optional<std::string> PathOpt = GetEnvVariable("PATH");
+ REQUIRE(PathOpt.has_value());
+ const std::string& PathValue = *PathOpt;
CHECK(!PathValue.empty());
CHECK_EQ(ExpandEnvironmentVariables("%PATH%"), PathValue);
CHECK_EQ(ExpandEnvironmentVariables("prefix/%PATH%/suffix"), "prefix/" + PathValue + "/suffix");
# else
- std::string HomeValue = GetEnvVariable("HOME");
+ std::optional<std::string> HomeOpt = GetEnvVariable("HOME");
+ REQUIRE(HomeOpt.has_value());
+ const std::string& HomeValue = *HomeOpt;
CHECK(!HomeValue.empty());
CHECK_EQ(ExpandEnvironmentVariables("%HOME%"), HomeValue);
CHECK_EQ(ExpandEnvironmentVariables("prefix/%HOME%/suffix"), "prefix/" + HomeValue + "/suffix");
@@ -4255,13 +4270,14 @@ TEST_CASE("ExpandEnvironmentVariables")
// Unknown variable is left unexpanded
CHECK_EQ(ExpandEnvironmentVariables("%ZEN_UNLIKELY_SET_VAR_12345%"), "%ZEN_UNLIKELY_SET_VAR_12345%");
+ CHECK_FALSE(GetEnvVariable("ZEN_UNLIKELY_SET_VAR_12345").has_value());
// Multiple variables
# if ZEN_PLATFORM_WINDOWS
- std::string OSValue = GetEnvVariable("OS");
- if (!OSValue.empty())
+ std::optional<std::string> OSValue = GetEnvVariable("OS");
+ if (OSValue && !OSValue->empty())
{
- CHECK_EQ(ExpandEnvironmentVariables("%PATH%/%OS%"), PathValue + "/" + OSValue);
+ CHECK_EQ(ExpandEnvironmentVariables("%PATH%/%OS%"), PathValue + "/" + *OSValue);
}
# endif
}