diff --git a/src/config.cpp b/src/config.cpp index 8c2d466..2d56c69 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -78,13 +78,7 @@ CConfig::CConfig(const char* path, const Hyprlang::SConfigOptions& options_) : i throw "File does not exist"; } - impl->envVariables.clear(); - for (char** env = environ; *env; ++env) { - const std::string ENVVAR = *env ? *env : ""; - const auto VARIABLE = ENVVAR.substr(0, ENVVAR.find_first_of('=')); - const auto VALUE = ENVVAR.substr(ENVVAR.find_first_of('=') + 1); - impl->envVariables.push_back({VARIABLE, VALUE}); - } + impl->recheckEnv(); std::ranges::sort(impl->envVariables, [&](const auto& a, const auto& b) { return a.name.length() > b.name.length(); }); @@ -528,6 +522,16 @@ CParseResult CConfig::parseVariable(const std::string& lhs, const std::string& r return result; } +void CConfigImpl::recheckEnv() { + envVariables.clear(); + for (char** env = environ; *env; ++env) { + const std::string ENVVAR = *env ? *env : ""; + const auto VARIABLE = ENVVAR.substr(0, ENVVAR.find_first_of('=')); + const auto VALUE = ENVVAR.substr(ENVVAR.find_first_of('=') + 1); + envVariables.push_back({VARIABLE, VALUE}); + } +} + SVariable* CConfigImpl::getVariable(const std::string& name) { for (auto& v : envVariables) { if (v.name == name) @@ -1030,13 +1034,13 @@ CParseResult CConfig::parseFile(const char* file) { } CParseResult CConfig::parseDynamic(const char* line) { - auto ret = parseLine(line, true); + auto ret = parseLine(line, true); impl->currentSpecialCategory = nullptr; return ret; } CParseResult CConfig::parseDynamic(const char* command, const char* value) { - auto ret = parseLine(std::string{command} + "=" + std::string{value}, true); + auto ret = parseLine(std::string{command} + "=" + std::string{value}, true); impl->currentSpecialCategory = nullptr; return ret; } @@ -1044,7 +1048,8 @@ CParseResult CConfig::parseDynamic(const char* command, const char* value) { void CConfig::clearState() { impl->categories.clear(); impl->parseError = ""; - impl->variables = impl->envVariables; + impl->recheckEnv(); + impl->variables = impl->envVariables; std::erase_if(impl->specialCategories, [](const auto& e) { return !e->isStatic; }); } diff --git a/src/config.hpp b/src/config.hpp index d68482c..838a863 100644 --- a/src/config.hpp +++ b/src/config.hpp @@ -102,6 +102,7 @@ class CConfigImpl { std::optional parseComment(const std::string& comment); std::expected parseExpression(const std::string& s); SVariable* getVariable(const std::string& name); + void recheckEnv(); struct SIfBlockData { bool failed = false; diff --git a/tests/config/config.conf b/tests/config/config.conf index 1906acb..3ff1146 100644 --- a/tests/config/config.conf +++ b/tests/config/config.conf @@ -32,6 +32,7 @@ $DYNAMIC_EXPRESSION = moved: {{$MOVING_VAR / 2}} expr: \{{$MOVING_VAR / 2}} testDynamicEscapedExpression = \{{ $DYNAMIC_EXPRESSION }} testEnv = $SHELL +testEnv2 = $TEST_ENV source = ./colors.conf diff --git a/tests/parse/main.cpp b/tests/parse/main.cpp index d0d7ad5..07265a1 100644 --- a/tests/parse/main.cpp +++ b/tests/parse/main.cpp @@ -108,6 +108,8 @@ int main(int argc, char** argv, char** envp) { if (!getenv("SHELL")) setenv("SHELL", "/bin/sh", true); + setenv("TEST_ENV", "1", true); + std::cout << "Starting test\n"; Hyprlang::CConfig config("./config/config.conf", {}); @@ -130,6 +132,7 @@ int main(int argc, char** argv, char** envp) { config.addConfigValue("testString", ""); config.addConfigValue("testStringColon", ""); config.addConfigValue("testEnv", ""); + config.addConfigValue("testEnv2", ""); config.addConfigValue("testVar", (Hyprlang::INT)0); config.addConfigValue("categoryKeyword", (Hyprlang::STRING) ""); config.addConfigValue("testStringQuotes", ""); @@ -297,6 +300,7 @@ int main(int argc, char** argv, char** envp) { // test env variables std::cout << " → Testing env variables\n"; EXPECT(std::any_cast(config.getConfigValue("testEnv")), std::string{getenv("SHELL")}); + EXPECT(std::any_cast(config.getConfigValue("testEnv2")), std::string{"1"}); // test special categories std::cout << " → Testing special categories\n"; @@ -360,6 +364,12 @@ int main(int argc, char** argv, char** envp) { // test multiline config EXPECT(std::any_cast(config.getConfigValue("multiline")), std::string{"very long command"}); + // test dynamic env + setenv("TEST_ENV", "2", true); + config.parse(); + std::cout << " → Testing dynamic env variables\n"; + EXPECT(std::any_cast(config.getConfigValue("testEnv2")), std::string{"2"}); + std::cout << " → Testing error.conf\n"; Hyprlang::CConfig errorConfig("./config/error.conf", {.verifyOnly = true, .throwAllErrors = true});