mirror of
https://github.com/hyprwm/hyprlang.git
synced 2024-11-16 18:25:57 +01:00
core: properly handle unscoped keywords
for users: prefix your keyword with : to make it only global scope
This commit is contained in:
parent
095f54b910
commit
5df0174fd0
3 changed files with 46 additions and 11 deletions
|
@ -565,15 +565,20 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for (auto& h : impl->handlers) {
|
for (auto& h : impl->handlers) {
|
||||||
if (!h.options.allowFlags) {
|
// we want to handle potentially nested keywords and ensure
|
||||||
// we want to handle potentially nested keywords and ensure
|
// we only call the handler if they are scoped correctly,
|
||||||
// we only call the handler if they are scoped correctly.
|
// unless the keyword is not scoped itself
|
||||||
|
|
||||||
|
const bool UNSCOPED = !h.name.contains(":");
|
||||||
|
const auto HANDLERNAME = !h.name.empty() && h.name.at(0) == ':' ? h.name.substr(1) : h.name;
|
||||||
|
|
||||||
|
if (!h.options.allowFlags && !UNSCOPED) {
|
||||||
size_t colon = 0;
|
size_t colon = 0;
|
||||||
size_t idx = 0;
|
size_t idx = 0;
|
||||||
size_t depth = 0;
|
size_t depth = 0;
|
||||||
|
|
||||||
while ((colon = h.name.find(":", idx)) != std::string::npos && impl->categories.size() > depth) {
|
while ((colon = HANDLERNAME.find(":", idx)) != std::string::npos && impl->categories.size() > depth) {
|
||||||
auto actual = h.name.substr(idx, colon - idx);
|
auto actual = HANDLERNAME.substr(idx, colon - idx);
|
||||||
|
|
||||||
if (actual != impl->categories[depth])
|
if (actual != impl->categories[depth])
|
||||||
break;
|
break;
|
||||||
|
@ -582,11 +587,14 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) {
|
||||||
++depth;
|
++depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth != impl->categories.size() || h.name.substr(idx) != LHS)
|
if (depth != impl->categories.size() || HANDLERNAME.substr(idx) != LHS)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h.options.allowFlags && (!LHS.starts_with(h.name) || LHS.contains(':') /* avoid cases where a category is called the same as a handler */))
|
if (UNSCOPED && HANDLERNAME != LHS && !h.options.allowFlags)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (h.options.allowFlags && (!LHS.starts_with(HANDLERNAME) || LHS.contains(':') /* avoid cases where a category is called the same as a handler */))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ret = h.func(LHS.c_str(), RHS.c_str());
|
ret = h.func(LHS.c_str(), RHS.c_str());
|
||||||
|
|
|
@ -29,6 +29,7 @@ errorVariable = true
|
||||||
# hyprlang noerror false
|
# hyprlang noerror false
|
||||||
|
|
||||||
categoryKeyword = oops, this one shouldn't call the handler, not fun
|
categoryKeyword = oops, this one shouldn't call the handler, not fun
|
||||||
|
testUseKeyword = yes
|
||||||
|
|
||||||
testCategory {
|
testCategory {
|
||||||
testValueInt = 123456
|
testValueInt = 123456
|
||||||
|
@ -38,6 +39,9 @@ testCategory {
|
||||||
testColor2 = rgba(0, 0, 0, 1.0)
|
testColor2 = rgba(0, 0, 0, 1.0)
|
||||||
testColor3 = rgba(ffeeff22)
|
testColor3 = rgba(ffeeff22)
|
||||||
|
|
||||||
|
testIgnoreKeyword = aaa
|
||||||
|
testUseKeyword = no
|
||||||
|
|
||||||
nested1 {
|
nested1 {
|
||||||
testValueNest = 1
|
testValueNest = 1
|
||||||
nested2 {
|
nested2 {
|
||||||
|
|
|
@ -23,10 +23,12 @@ namespace Colors {
|
||||||
}
|
}
|
||||||
|
|
||||||
// globals for testing
|
// globals for testing
|
||||||
bool barrelRoll = false;
|
bool barrelRoll = false;
|
||||||
std::string flagsFound = "";
|
std::string flagsFound = "";
|
||||||
Hyprlang::CConfig* pConfig = nullptr;
|
Hyprlang::CConfig* pConfig = nullptr;
|
||||||
std::string currentPath = "";
|
std::string currentPath = "";
|
||||||
|
std::string ignoreKeyword = "";
|
||||||
|
std::string useKeyword = "";
|
||||||
static std::vector<std::string> categoryKeywordActualValues;
|
static std::vector<std::string> categoryKeywordActualValues;
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleDoABarrelRoll(const char* COMMAND, const char* VALUE) {
|
static Hyprlang::CParseResult handleDoABarrelRoll(const char* COMMAND, const char* VALUE) {
|
||||||
|
@ -51,6 +53,22 @@ static Hyprlang::CParseResult handleCategoryKeyword(const char* COMMAND, const c
|
||||||
return Hyprlang::CParseResult();
|
return Hyprlang::CParseResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Hyprlang::CParseResult handleTestIgnoreKeyword(const char* COMMAND, const char* VALUE) {
|
||||||
|
ignoreKeyword = VALUE;
|
||||||
|
|
||||||
|
return Hyprlang::CParseResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Hyprlang::CParseResult handleTestUseKeyword(const char* COMMAND, const char* VALUE) {
|
||||||
|
useKeyword = VALUE;
|
||||||
|
|
||||||
|
return Hyprlang::CParseResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
static Hyprlang::CParseResult handleNoop(const char* COMMAND, const char* VALUE) {
|
||||||
|
return Hyprlang::CParseResult();
|
||||||
|
}
|
||||||
|
|
||||||
static Hyprlang::CParseResult handleSource(const char* COMMAND, const char* VALUE) {
|
static Hyprlang::CParseResult handleSource(const char* COMMAND, const char* VALUE) {
|
||||||
std::string PATH = std::filesystem::canonical(currentPath + "/" + VALUE);
|
std::string PATH = std::filesystem::canonical(currentPath + "/" + VALUE);
|
||||||
return pConfig->parseFile(PATH.c_str());
|
return pConfig->parseFile(PATH.c_str());
|
||||||
|
@ -116,6 +134,9 @@ int main(int argc, char** argv, char** envp) {
|
||||||
config.registerHandler(&handleDoABarrelRoll, "doABarrelRoll", {false});
|
config.registerHandler(&handleDoABarrelRoll, "doABarrelRoll", {false});
|
||||||
config.registerHandler(&handleFlagsTest, "flags", {true});
|
config.registerHandler(&handleFlagsTest, "flags", {true});
|
||||||
config.registerHandler(&handleSource, "source", {false});
|
config.registerHandler(&handleSource, "source", {false});
|
||||||
|
config.registerHandler(&handleTestIgnoreKeyword, "testIgnoreKeyword", {false});
|
||||||
|
config.registerHandler(&handleTestUseKeyword, ":testUseKeyword", {false});
|
||||||
|
config.registerHandler(&handleNoop, "testCategory:testUseKeyword", {false});
|
||||||
config.registerHandler(&handleCategoryKeyword, "testCategory:categoryKeyword", {false});
|
config.registerHandler(&handleCategoryKeyword, "testCategory:categoryKeyword", {false});
|
||||||
|
|
||||||
config.addSpecialCategory("special", {"key"});
|
config.addSpecialCategory("special", {"key"});
|
||||||
|
@ -161,6 +182,8 @@ int main(int argc, char** argv, char** envp) {
|
||||||
EXPECT(std::any_cast<const char*>(config.getConfigValue("testStringColon")), std::string{"ee:ee:ee"});
|
EXPECT(std::any_cast<const char*>(config.getConfigValue("testStringColon")), std::string{"ee:ee:ee"});
|
||||||
EXPECT(std::any_cast<const char*>(config.getConfigValue("categoryKeyword")), std::string{"oops, this one shouldn't call the handler, not fun"});
|
EXPECT(std::any_cast<const char*>(config.getConfigValue("categoryKeyword")), std::string{"oops, this one shouldn't call the handler, not fun"});
|
||||||
EXPECT(std::any_cast<const char*>(config.getConfigValue("testCategory:nested1:categoryKeyword")), std::string{"this one should not either"});
|
EXPECT(std::any_cast<const char*>(config.getConfigValue("testCategory:nested1:categoryKeyword")), std::string{"this one should not either"});
|
||||||
|
EXPECT(ignoreKeyword, "aaa");
|
||||||
|
EXPECT(useKeyword, "yes");
|
||||||
|
|
||||||
// test static values
|
// test static values
|
||||||
std::cout << " → Testing static values\n";
|
std::cout << " → Testing static values\n";
|
||||||
|
|
Loading…
Reference in a new issue