diff --git a/src/config.cpp b/src/config.cpp index f2a2fc7..7c3ea15 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -283,16 +283,12 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std:: CParseResult result; std::string valueName; - std::string catPrefix; for (auto& c : impl->categories) { valueName += c + ':'; - catPrefix += c + ':'; } valueName += command; - const auto VALUEONLYNAME = command.starts_with(catPrefix) ? command.substr(catPrefix.length()) : command; - // FIXME: this will bug with nested. if (valueName.contains('[') && valueName.contains(']')) { const auto L = valueName.find_first_of('['); @@ -306,7 +302,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std:: // if it doesn't exist, make it for (auto& sc : impl->specialCategoryDescriptors) { - if (sc->key.empty() || !valueName.starts_with(sc->name)) + if (sc->key.empty() || !valueName.starts_with(sc->name + ":")) continue; // bingo @@ -358,11 +354,14 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std:: if (!found) { // could be a dynamic category that doesnt exist yet for (auto& sc : impl->specialCategoryDescriptors) { - if (sc->key.empty() || !valueName.starts_with(sc->name)) + if (sc->key.empty() || !valueName.starts_with(sc->name + ":")) continue; - // category does exist, check if value exists - if (!sc->defaultValues.contains(VALUEONLYNAME) && VALUEONLYNAME != sc->key) + // found value root to be a special category, get the trunk + const auto VALUETRUNK = valueName.substr(sc->name.length() + 1); + + // check if trunk is a value within the special category + if (!sc->defaultValues.contains(VALUETRUNK) && VALUETRUNK != sc->key) break; // bingo @@ -835,9 +834,12 @@ CParseResult CConfig::parseLine(std::string line, bool dynamic) { return result; } - impl->currentSpecialKey = ""; - impl->currentSpecialCategory = nullptr; impl->categories.pop_back(); + + if (impl->categories.empty()) { + impl->currentSpecialKey = ""; + impl->currentSpecialCategory = nullptr; + } } else { // open a category. if (!line.ends_with("{")) { diff --git a/tests/config/config.conf b/tests/config/config.conf index 54e71bf..c2c0b87 100644 --- a/tests/config/config.conf +++ b/tests/config/config.conf @@ -127,6 +127,27 @@ specialAnonymous { value = 3 } +specialAnonymousNested { + nested:value1 = 1 + nested:value2 = 2 + nested1:nested2:value1 = 10 + nested1:nested2:value2 = 11 +} + +specialAnonymousNested { + nested { + value1 = 3 + value2 = 4 + } + + nested1 { + nested2 { + value1 = 12 + value2 = 13 + } + } +} + flagsStuff { value = 2 } diff --git a/tests/parse/main.cpp b/tests/parse/main.cpp index dbf5e70..f863d3f 100644 --- a/tests/parse/main.cpp +++ b/tests/parse/main.cpp @@ -154,6 +154,12 @@ int main(int argc, char** argv, char** envp) { config.addSpecialCategory("specialAnonymous", {.key = nullptr, .ignoreMissing = false, .anonymousKeyBased = true}); config.addSpecialConfigValue("specialAnonymous", "value", (Hyprlang::INT)0); + config.addSpecialCategory("specialAnonymousNested", {.key = nullptr, .ignoreMissing = false, .anonymousKeyBased = true}); + config.addSpecialConfigValue("specialAnonymousNested", "nested:value1", (Hyprlang::INT)0); + config.addSpecialConfigValue("specialAnonymousNested", "nested:value2", (Hyprlang::INT)0); + config.addSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value1", (Hyprlang::INT)0); + config.addSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value2", (Hyprlang::INT)0); + config.addConfigValue("multiline", ""); config.commence(); @@ -302,8 +308,21 @@ int main(int argc, char** argv, char** envp) { // test anonymous EXPECT(config.listKeysForSpecialCategory("specialAnonymous").size(), 2); const auto KEYS = config.listKeysForSpecialCategory("specialAnonymous"); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymous", "value", KEYS[0].c_str())), 2); EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymous", "value", KEYS[1].c_str())), 3); + // test anonymous nested + EXPECT(config.listKeysForSpecialCategory("specialAnonymousNested").size(), 2); + const auto KEYS2 = config.listKeysForSpecialCategory("specialAnonymousNested"); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymousNested", "nested:value1", KEYS2[0].c_str())), 1); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymousNested", "nested:value2", KEYS2[0].c_str())), 2); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymousNested", "nested:value1", KEYS2[1].c_str())), 3); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymousNested", "nested:value2", KEYS2[1].c_str())), 4); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value1", KEYS2[0].c_str())), 10); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value2", KEYS2[0].c_str())), 11); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value1", KEYS2[1].c_str())), 12); + EXPECT(std::any_cast(config.getSpecialConfigValue("specialAnonymousNested", "nested1:nested2:value2", KEYS2[1].c_str())), 13); + // test sourcing std::cout << " → Testing sourcing\n"; EXPECT(std::any_cast(config.getConfigValue("myColors:pink")), (Hyprlang::INT)0xFFc800c8);