From 7b7e7cdd0711bd277a95a157f6af3c2386afab15 Mon Sep 17 00:00:00 2001 From: Vaxry Date: Sat, 17 Feb 2024 19:01:35 +0000 Subject: [PATCH] api: add listKeysForSpecialCategory --- include/hyprlang.hpp | 27 +++++++++++++++++++++++++++ src/config.cpp | 34 ++++++++++++++++++++++++++++++++++ tests/parse/main.cpp | 3 +++ 3 files changed, 64 insertions(+) diff --git a/include/hyprlang.hpp b/include/hyprlang.hpp index d3a6498..fcebdce 100644 --- a/include/hyprlang.hpp +++ b/include/hyprlang.hpp @@ -7,6 +7,7 @@ #include #include #include +#include class CConfigImpl; struct SConfigDefaultValue; @@ -381,6 +382,31 @@ namespace Hyprlang { */ bool specialCategoryExistsForKey(const char* category, const char* key); + /*! + Get a vector with all registered keys for a special category + + It's an error to query this for a static or non-existent category + + \since 0.4.0 + */ + std::vector listKeysForSpecialCategory(const char* category) { + const char** cats = nullptr; + size_t len = 0; + retrieveKeysForCat(category, &cats, &len); + + if (len == 0) + return {}; + + std::vector result; + for (size_t i = 0; i < len; ++i) { + result.push_back(cats[i]); + } + + free(cats); + + return result; + } + private: bool m_bCommenced = false; @@ -391,6 +417,7 @@ namespace Hyprlang { CParseResult parseVariable(const std::string& lhs, const std::string& rhs, bool dynamic = false); void clearState(); void applyDefaultsToCat(SSpecialCategory& cat); + void retrieveKeysForCat(const char* category, const char*** out, size_t* len); }; }; #endif \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index 815f43c..b93baf3 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -661,3 +661,37 @@ bool CConfig::specialCategoryExistsForKey(const char* category, const char* key) return false; } + +/* if len != 0, out needs to be freed */ +void CConfig::retrieveKeysForCat(const char* category, const char*** out, size_t* len) { + size_t count = 0; + for (auto& sc : impl->specialCategories) { + if (sc->isStatic) + continue; + + if (sc->name != category) + continue; + + count++; + } + + if (count == 0) { + *len = 0; + return; + } + + *out = (const char**)calloc(1, count * sizeof(const char*)); + size_t counter2 = 0; + for (auto& sc : impl->specialCategories) { + if (sc->isStatic) + continue; + + if (sc->name != category) + continue; + + // EVIL, but the pointers will be almost instantly discarded by the caller + (*out)[counter2++] = (const char*)sc->values[sc->key].m_pData; + } + + *len = count; +} diff --git a/tests/parse/main.cpp b/tests/parse/main.cpp index d1ac526..696ef9a 100644 --- a/tests/parse/main.cpp +++ b/tests/parse/main.cpp @@ -191,6 +191,9 @@ int main(int argc, char** argv, char** envp) { // test copying EXPECT(std::any_cast(config.getSpecialConfigValue("specialGeneric:one", "copyTest")), 2); + // test listing keys + EXPECT(config.listKeysForSpecialCategory("special")[1], "b"); + // test sourcing std::cout << " → Testing sourcing\n"; EXPECT(std::any_cast(config.getConfigValue("myColors:pink")), (Hyprlang::INT)0xFFc800c8);