mirror of
https://github.com/hyprwm/hyprlang.git
synced 2025-12-20 03:50:02 +01:00
config: try variables before handlers if possible
This commit is contained in:
parent
4dafa28d4f
commit
995db114b8
4 changed files with 82 additions and 62 deletions
|
|
@ -447,7 +447,7 @@ namespace Hyprlang {
|
|||
CConfigImpl* impl;
|
||||
|
||||
CParseResult parseLine(std::string line, bool dynamic = false);
|
||||
CParseResult configSetValueSafe(const std::string& command, const std::string& value);
|
||||
std::pair<bool, CParseResult> configSetValueSafe(const std::string& command, const std::string& value);
|
||||
CParseResult parseVariable(const std::string& lhs, const std::string& rhs, bool dynamic = false);
|
||||
void clearState();
|
||||
void applyDefaultsToCat(SSpecialCategory& cat);
|
||||
|
|
|
|||
|
|
@ -279,7 +279,8 @@ static std::expected<int64_t, std::string> configStringToInt(const std::string&
|
|||
return 0;
|
||||
}
|
||||
|
||||
CParseResult CConfig::configSetValueSafe(const std::string& command, const std::string& value) {
|
||||
// found, result
|
||||
std::pair<bool, CParseResult> CConfig::configSetValueSafe(const std::string& command, const std::string& value) {
|
||||
CParseResult result;
|
||||
|
||||
std::string valueName;
|
||||
|
|
@ -358,7 +359,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
if (VALUEIT != sc->values.end())
|
||||
found = true;
|
||||
else if (sc->descriptor->dontErrorOnMissing)
|
||||
return result; // will return a success, cuz we want to ignore missing
|
||||
return {true, result}; // will return a success, cuz we want to ignore missing
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
@ -407,7 +408,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
} else {
|
||||
if (VALUEIT == PCAT->values.end() || VALUEIT->first != sc->key) {
|
||||
result.setError(std::format("special category's first value must be the key. Key for <{}> is <{}>", PCAT->name, PCAT->key));
|
||||
return result;
|
||||
return {true, result};
|
||||
}
|
||||
impl->currentSpecialKey = value;
|
||||
}
|
||||
|
|
@ -418,7 +419,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
|
||||
if (!found) {
|
||||
result.setError(std::format("config option <{}> does not exist.", valueName));
|
||||
return result;
|
||||
return {false, result};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -428,7 +429,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
const auto INT = configStringToInt(value);
|
||||
if (!INT.has_value()) {
|
||||
result.setError(INT.error());
|
||||
return result;
|
||||
return {true, result};
|
||||
}
|
||||
|
||||
VALUEIT->second.setFrom(INT.value());
|
||||
|
|
@ -440,7 +441,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
VALUEIT->second.setFrom(std::stof(value));
|
||||
} catch (std::exception& e) {
|
||||
result.setError(std::format("failed parsing a float: {}", e.what()));
|
||||
return result;
|
||||
return {true, result};
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -458,7 +459,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
VALUEIT->second.setFrom(SVector2D{.x = std::stof(LHS), .y = std::stof(RHS)});
|
||||
} catch (std::exception& e) {
|
||||
result.setError(std::format("failed parsing a vec2: {}", e.what()));
|
||||
return result;
|
||||
return {true, result};
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
@ -473,19 +474,19 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
|||
|
||||
if (RESULT.error) {
|
||||
result.setError(RESULT.getError());
|
||||
return result;
|
||||
return {true, result};
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
result.setError("internal error: invalid value found (no type?)");
|
||||
return result;
|
||||
return {true, result};
|
||||
}
|
||||
}
|
||||
|
||||
VALUEIT->second.m_bSetByUser = true;
|
||||
|
||||
return result;
|
||||
return {true, result};
|
||||
}
|
||||
|
||||
CParseResult CConfig::parseVariable(const std::string& lhs, const std::string& rhs, bool dynamic) {
|
||||
|
|
@ -791,6 +792,13 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
|||
|
||||
bool found = false;
|
||||
|
||||
if (!impl->configOptions.verifyOnly) {
|
||||
auto [f, rv] = configSetValueSafe(LHS, RHS);
|
||||
found = f;
|
||||
ret = std::move(rv);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
for (auto& h : impl->handlers) {
|
||||
// we want to handle potentially nested keywords and ensure
|
||||
// we only call the handler if they are scoped correctly,
|
||||
|
|
@ -827,9 +835,7 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
|||
ret = h.func(LHS.c_str(), RHS.c_str());
|
||||
found = true;
|
||||
}
|
||||
|
||||
if (!found && !impl->configOptions.verifyOnly)
|
||||
ret = configSetValueSafe(LHS, RHS);
|
||||
}
|
||||
|
||||
if (ret.error)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ specialGeneric {
|
|||
|
||||
specialAnonymous {
|
||||
value = 2
|
||||
testHandlerDontOverride = true
|
||||
}
|
||||
|
||||
specialAnonymous {
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ Hyprlang::CConfig* pConfig = nullptr;
|
|||
std::string currentPath = "";
|
||||
std::string ignoreKeyword = "";
|
||||
std::string useKeyword = "";
|
||||
bool testHandlerDontOverrideValue = false;
|
||||
static std::vector<std::string> categoryKeywordActualValues;
|
||||
|
||||
static Hyprlang::CParseResult handleDoABarrelRoll(const char* COMMAND, const char* VALUE) {
|
||||
|
|
@ -74,6 +75,14 @@ static Hyprlang::CParseResult handleSource(const char* COMMAND, const char* VALU
|
|||
return pConfig->parseFile(PATH.c_str());
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleTestHandlerDontOverride(const char* COMMAND, const char* VALUE) {
|
||||
testHandlerDontOverrideValue = true;
|
||||
|
||||
Hyprlang::CParseResult result;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static Hyprlang::CParseResult handleCustomValueSet(const char* VALUE, void** data) {
|
||||
if (!*data)
|
||||
*data = calloc(1, sizeof(int64_t));
|
||||
|
|
@ -147,12 +156,14 @@ int main(int argc, char** argv, char** envp) {
|
|||
config.registerHandler(&handleTestUseKeyword, ":testUseKeyword", {.allowFlags = false});
|
||||
config.registerHandler(&handleNoop, "testCategory:testUseKeyword", {.allowFlags = false});
|
||||
config.registerHandler(&handleCategoryKeyword, "testCategory:categoryKeyword", {.allowFlags = false});
|
||||
config.registerHandler(&handleTestHandlerDontOverride, "testHandlerDontOverride", {.allowFlags = false});
|
||||
|
||||
config.addSpecialCategory("special", {.key = "key"});
|
||||
config.addSpecialConfigValue("special", "value", (Hyprlang::INT)0);
|
||||
|
||||
config.addSpecialCategory("specialAnonymous", {.key = nullptr, .ignoreMissing = false, .anonymousKeyBased = true});
|
||||
config.addSpecialConfigValue("specialAnonymous", "value", (Hyprlang::INT)0);
|
||||
config.addSpecialConfigValue("specialAnonymous", "testHandlerDontOverride", (Hyprlang::INT)0);
|
||||
|
||||
config.addSpecialCategory("specialAnonymousNested", {.key = nullptr, .ignoreMissing = false, .anonymousKeyBased = true});
|
||||
config.addSpecialConfigValue("specialAnonymousNested", "nested:value1", (Hyprlang::INT)0);
|
||||
|
|
@ -239,6 +250,7 @@ int main(int argc, char** argv, char** envp) {
|
|||
std::cout << " → Testing handlers\n";
|
||||
EXPECT(barrelRoll, true);
|
||||
EXPECT(flagsFound, std::string{"abc"});
|
||||
EXPECT(testHandlerDontOverrideValue, false);
|
||||
|
||||
EXPECT(categoryKeywordActualValues.at(0), "we are having fun");
|
||||
EXPECT(categoryKeywordActualValues.at(1), "so much fun");
|
||||
|
|
@ -315,6 +327,7 @@ int main(int argc, char** argv, char** envp) {
|
|||
EXPECT(config.listKeysForSpecialCategory("specialAnonymous").size(), 2);
|
||||
const auto KEYS = config.listKeysForSpecialCategory("specialAnonymous");
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymous", "value", KEYS[0].c_str())), 2);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymous", "testHandlerDontOverride", KEYS[0].c_str())), 1);
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialAnonymous", "value", KEYS[1].c_str())), 3);
|
||||
|
||||
// test anonymous nested
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue