diff --git a/src/config.cpp b/src/config.cpp index 94c908a..c6492ee 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -301,7 +301,37 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std:: const auto VALUEONLYNAME = command.starts_with(catPrefix) ? command.substr(catPrefix.length()) : command; - auto VALUEIT = impl->values.find(valueName); + // FIXME: this will bug with nested. + if (valueName.contains('[') && valueName.contains(']')) { + const auto L = valueName.find_first_of('['); + const auto R = valueName.find_last_of(']'); + + if (L < R) { + const auto CATKEY = valueName.substr(L + 1, R - L - 1); + impl->currentSpecialKey = CATKEY; + + valueName = valueName.substr(0, L) + valueName.substr(R + 1); + + // if it doesn't exist, make it + for (auto& sc : impl->specialCategoryDescriptors) { + if (sc->key.empty() || !valueName.starts_with(sc->name)) + continue; + + // bingo + const auto PCAT = impl->specialCategories.emplace_back(std::make_unique()).get(); + PCAT->descriptor = sc.get(); + PCAT->name = sc->name; + PCAT->key = sc->key; + addSpecialConfigValue(sc->name.c_str(), sc->key.c_str(), CConfigValue(CATKEY.c_str())); + + applyDefaultsToCat(*PCAT); + + PCAT->values[sc->key].setFrom(CATKEY); + } + } + } + + auto VALUEIT = impl->values.find(valueName); if (VALUEIT == impl->values.end()) { // it might be in a special category bool found = false; diff --git a/tests/config/config.conf b/tests/config/config.conf index f08b8b7..f3b018f 100644 --- a/tests/config/config.conf +++ b/tests/config/config.conf @@ -40,8 +40,7 @@ special { value = $SPECIALVAL1 } -special { - key = b +special[b] { value = 2 } diff --git a/tests/parse/main.cpp b/tests/parse/main.cpp index ae2c4f8..359757a 100644 --- a/tests/parse/main.cpp +++ b/tests/parse/main.cpp @@ -199,6 +199,8 @@ int main(int argc, char** argv, char** envp) { EXPECT(std::any_cast(config.getSpecialConfigValue("special", "value", "b")), 2); EXPECT(std::any_cast(config.getSpecialConfigValue("specialGeneric:one", "value")), 1); EXPECT(std::any_cast(config.getSpecialConfigValue("specialGeneric:two", "value")), 2); + EXPECT(config.parseDynamic("special[b]:value = 3").error, false); + EXPECT(std::any_cast(config.getSpecialConfigValue("special", "value", "b")), 3); // test dynamic special variable EXPECT(config.parseDynamic("$SPECIALVAL1 = 2").error, false);