core: fix dynamic env changes

This commit is contained in:
Vaxry 2025-11-22 13:54:21 +00:00
parent 3d3057837c
commit a318deec0c
Signed by: vaxry
GPG key ID: 665806380871D640
4 changed files with 27 additions and 10 deletions

View file

@ -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; });
}

View file

@ -102,6 +102,7 @@ class CConfigImpl {
std::optional<std::string> parseComment(const std::string& comment);
std::expected<float, std::string> parseExpression(const std::string& s);
SVariable* getVariable(const std::string& name);
void recheckEnv();
struct SIfBlockData {
bool failed = false;

View file

@ -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

View file

@ -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<const char*>(config.getConfigValue("testEnv")), std::string{getenv("SHELL")});
EXPECT(std::any_cast<const char*>(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<const char*>(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<const char*>(config.getConfigValue("testEnv2")), std::string{"2"});
std::cout << " → Testing error.conf\n";
Hyprlang::CConfig errorConfig("./config/error.conf", {.verifyOnly = true, .throwAllErrors = true});