mirror of
https://github.com/hyprwm/hyprlang.git
synced 2025-12-20 03:50:02 +01:00
Compare commits
4 commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0d00dc1189 | |||
|
|
eb5be96aa0 | ||
| 3d66ec7c29 | |||
| a318deec0c |
6 changed files with 77 additions and 13 deletions
2
VERSION
2
VERSION
|
|
@ -1 +1 @@
|
|||
0.6.6
|
||||
0.6.7
|
||||
|
|
|
|||
|
|
@ -441,6 +441,13 @@ namespace Hyprlang {
|
|||
return result;
|
||||
}
|
||||
|
||||
/*!
|
||||
Change the root path of the config
|
||||
|
||||
\since 0.6.7
|
||||
*/
|
||||
void changeRootPath(const char* path);
|
||||
|
||||
private:
|
||||
bool m_bCommenced = false;
|
||||
|
||||
|
|
|
|||
|
|
@ -78,13 +78,7 @@ CConfig::CConfig(const char* path, const Hyprlang::SConfigOptions& options_) : i
|
|||
throw "File does not exist";
|
||||
}
|
||||
|
||||
impl->envVariables.clear();
|
||||
for (char** env = environ; *env; ++env) {
|
||||
const std::string ENVVAR = *env ? *env : "";
|
||||
const auto VARIABLE = ENVVAR.substr(0, ENVVAR.find_first_of('='));
|
||||
const auto VALUE = ENVVAR.substr(ENVVAR.find_first_of('=') + 1);
|
||||
impl->envVariables.push_back({VARIABLE, VALUE});
|
||||
}
|
||||
impl->recheckEnv();
|
||||
|
||||
std::ranges::sort(impl->envVariables, [&](const auto& a, const auto& b) { return a.name.length() > b.name.length(); });
|
||||
|
||||
|
|
@ -358,9 +352,13 @@ std::pair<bool, CParseResult> CConfig::configSetValueSafe(const std::string& com
|
|||
found = true;
|
||||
}
|
||||
|
||||
// probably a handler
|
||||
if (!valueName.contains(":"))
|
||||
return {false, result};
|
||||
|
||||
if (!found) {
|
||||
for (auto& sc : impl->specialCategories) {
|
||||
if (!valueName.starts_with(sc->name))
|
||||
if (!valueName.starts_with(sc->name + ":"))
|
||||
continue;
|
||||
|
||||
if (!sc->isStatic && std::string{std::any_cast<const char*>(sc->values[sc->key].getValue())} != impl->currentSpecialKey)
|
||||
|
|
@ -528,6 +526,16 @@ CParseResult CConfig::parseVariable(const std::string& lhs, const std::string& r
|
|||
return result;
|
||||
}
|
||||
|
||||
void CConfigImpl::recheckEnv() {
|
||||
envVariables.clear();
|
||||
for (char** env = environ; *env; ++env) {
|
||||
const std::string ENVVAR = *env ? *env : "";
|
||||
const auto VARIABLE = ENVVAR.substr(0, ENVVAR.find_first_of('='));
|
||||
const auto VALUE = ENVVAR.substr(ENVVAR.find_first_of('=') + 1);
|
||||
envVariables.push_back({VARIABLE, VALUE});
|
||||
}
|
||||
}
|
||||
|
||||
SVariable* CConfigImpl::getVariable(const std::string& name) {
|
||||
for (auto& v : envVariables) {
|
||||
if (v.name == name)
|
||||
|
|
@ -927,6 +935,10 @@ CParseResult CConfig::parse() {
|
|||
return fileParseResult;
|
||||
}
|
||||
|
||||
void CConfig::changeRootPath(const char* path) {
|
||||
impl->path = path;
|
||||
}
|
||||
|
||||
CParseResult CConfig::parseRawStream(const std::string& stream) {
|
||||
CParseResult result;
|
||||
|
||||
|
|
@ -1030,13 +1042,13 @@ CParseResult CConfig::parseFile(const char* file) {
|
|||
}
|
||||
|
||||
CParseResult CConfig::parseDynamic(const char* line) {
|
||||
auto ret = parseLine(line, true);
|
||||
auto ret = parseLine(line, true);
|
||||
impl->currentSpecialCategory = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
||||
CParseResult CConfig::parseDynamic(const char* command, const char* value) {
|
||||
auto ret = parseLine(std::string{command} + "=" + std::string{value}, true);
|
||||
auto ret = parseLine(std::string{command} + "=" + std::string{value}, true);
|
||||
impl->currentSpecialCategory = nullptr;
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1044,7 +1056,8 @@ CParseResult CConfig::parseDynamic(const char* command, const char* value) {
|
|||
void CConfig::clearState() {
|
||||
impl->categories.clear();
|
||||
impl->parseError = "";
|
||||
impl->variables = impl->envVariables;
|
||||
impl->recheckEnv();
|
||||
impl->variables = impl->envVariables;
|
||||
std::erase_if(impl->specialCategories, [](const auto& e) { return !e->isStatic; });
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -102,6 +102,7 @@ class CConfigImpl {
|
|||
std::optional<std::string> parseComment(const std::string& comment);
|
||||
std::expected<float, std::string> parseExpression(const std::string& s);
|
||||
SVariable* getVariable(const std::string& name);
|
||||
void recheckEnv();
|
||||
|
||||
struct SIfBlockData {
|
||||
bool failed = false;
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ $DYNAMIC_EXPRESSION = moved: {{$MOVING_VAR / 2}} expr: \{{$MOVING_VAR / 2}}
|
|||
testDynamicEscapedExpression = \{{ $DYNAMIC_EXPRESSION }}
|
||||
|
||||
testEnv = $SHELL
|
||||
testEnv2 = $TEST_ENV
|
||||
|
||||
source = ./colors.conf
|
||||
|
||||
|
|
@ -171,3 +172,14 @@ doABarrelRoll = woohoo, some, params # Funny!
|
|||
flagsabc = test
|
||||
#doSomethingFunny = 1, 2, 3, 4 # Funnier!
|
||||
#testSpaces = abc , def # many spaces, should be trimmed
|
||||
|
||||
sameKeywordSpecialCat = pablo
|
||||
|
||||
sameKeywordSpecialCat:two:hola = rose
|
||||
|
||||
sameKeywordSpecialCat {
|
||||
one {
|
||||
some_size = 44
|
||||
some_radius = 7.6
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ Hyprlang::CConfig* pConfig = nullptr;
|
|||
std::string currentPath = "";
|
||||
std::string ignoreKeyword = "";
|
||||
std::string useKeyword = "";
|
||||
std::string sameKeywordSpecialCat = "";
|
||||
bool testHandlerDontOverrideValue = false;
|
||||
static std::vector<std::string> categoryKeywordActualValues;
|
||||
|
||||
|
|
@ -75,6 +76,12 @@ static Hyprlang::CParseResult handleSource(const char* COMMAND, const char* VALU
|
|||
return pConfig->parseFile(PATH.c_str());
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleSameKeywordSpecialCat(const char* COMMAND, const char* VALUE) {
|
||||
sameKeywordSpecialCat = VALUE;
|
||||
|
||||
return Hyprlang::CParseResult();
|
||||
}
|
||||
|
||||
static Hyprlang::CParseResult handleTestHandlerDontOverride(const char* COMMAND, const char* VALUE) {
|
||||
testHandlerDontOverrideValue = true;
|
||||
|
||||
|
|
@ -82,7 +89,6 @@ static Hyprlang::CParseResult handleTestHandlerDontOverride(const char* COMMAND,
|
|||
return result;
|
||||
}
|
||||
|
||||
|
||||
static Hyprlang::CParseResult handleCustomValueSet(const char* VALUE, void** data) {
|
||||
if (!*data)
|
||||
*data = calloc(1, sizeof(int64_t));
|
||||
|
|
@ -108,6 +114,8 @@ int main(int argc, char** argv, char** envp) {
|
|||
if (!getenv("SHELL"))
|
||||
setenv("SHELL", "/bin/sh", true);
|
||||
|
||||
setenv("TEST_ENV", "1", true);
|
||||
|
||||
std::cout << "Starting test\n";
|
||||
|
||||
Hyprlang::CConfig config("./config/config.conf", {});
|
||||
|
|
@ -130,6 +138,7 @@ int main(int argc, char** argv, char** envp) {
|
|||
config.addConfigValue("testString", "");
|
||||
config.addConfigValue("testStringColon", "");
|
||||
config.addConfigValue("testEnv", "");
|
||||
config.addConfigValue("testEnv2", "");
|
||||
config.addConfigValue("testVar", (Hyprlang::INT)0);
|
||||
config.addConfigValue("categoryKeyword", (Hyprlang::STRING) "");
|
||||
config.addConfigValue("testStringQuotes", "");
|
||||
|
|
@ -173,8 +182,17 @@ int main(int argc, char** argv, char** envp) {
|
|||
|
||||
config.addConfigValue("multiline", "");
|
||||
|
||||
config.registerHandler(&handleSameKeywordSpecialCat, "sameKeywordSpecialCat", {.allowFlags = false});
|
||||
config.addSpecialCategory("sameKeywordSpecialCat", {.key = nullptr, .ignoreMissing = true, .anonymousKeyBased = false});
|
||||
|
||||
config.commence();
|
||||
|
||||
config.addSpecialCategory("sameKeywordSpecialCat:one", {.key = nullptr, .ignoreMissing = true});
|
||||
config.addSpecialConfigValue("sameKeywordSpecialCat:one", "some_size", (Hyprlang::INT)10);
|
||||
config.addSpecialConfigValue("sameKeywordSpecialCat:one", "some_radius", (Hyprlang::FLOAT)0.0);
|
||||
config.addSpecialCategory("sameKeywordSpecialCat:two", {.key = nullptr, .ignoreMissing = true});
|
||||
config.addSpecialConfigValue("sameKeywordSpecialCat:two", "hola", "");
|
||||
|
||||
config.addSpecialCategory("specialGeneric:one", {.key = nullptr, .ignoreMissing = true});
|
||||
config.addSpecialConfigValue("specialGeneric:one", "value", (Hyprlang::INT)0);
|
||||
config.addSpecialCategory("specialGeneric:two", {.key = nullptr, .ignoreMissing = true});
|
||||
|
|
@ -213,6 +231,12 @@ int main(int argc, char** argv, char** envp) {
|
|||
EXPECT(ignoreKeyword, "aaa");
|
||||
EXPECT(useKeyword, "yes");
|
||||
|
||||
// test special category with same name as a keyword
|
||||
EXPECT(sameKeywordSpecialCat, std::string_view{"pablo"});
|
||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("sameKeywordSpecialCat:one", "some_size")), (Hyprlang::INT)44);
|
||||
EXPECT(std::any_cast<float>(config.getSpecialConfigValue("sameKeywordSpecialCat:one", "some_radius")), (Hyprlang::FLOAT)7.6);
|
||||
EXPECT(std::any_cast<const char*>(config.getSpecialConfigValue("sameKeywordSpecialCat:two", "hola")), std::string_view{"rose"});
|
||||
|
||||
// Test templated wrapper
|
||||
auto T1 = Hyprlang::CSimpleConfigValue<Hyprlang::INT>(&config, "testInt");
|
||||
auto T2 = Hyprlang::CSimpleConfigValue<Hyprlang::FLOAT>(&config, "testFloat");
|
||||
|
|
@ -297,6 +321,7 @@ int main(int argc, char** argv, char** envp) {
|
|||
// test env variables
|
||||
std::cout << " → Testing env variables\n";
|
||||
EXPECT(std::any_cast<const char*>(config.getConfigValue("testEnv")), std::string{getenv("SHELL")});
|
||||
EXPECT(std::any_cast<const char*>(config.getConfigValue("testEnv2")), std::string{"1"});
|
||||
|
||||
// test special categories
|
||||
std::cout << " → Testing special categories\n";
|
||||
|
|
@ -360,6 +385,12 @@ int main(int argc, char** argv, char** envp) {
|
|||
// test multiline config
|
||||
EXPECT(std::any_cast<const char*>(config.getConfigValue("multiline")), std::string{"very long command"});
|
||||
|
||||
// test dynamic env
|
||||
setenv("TEST_ENV", "2", true);
|
||||
config.parse();
|
||||
std::cout << " → Testing dynamic env variables\n";
|
||||
EXPECT(std::any_cast<const char*>(config.getConfigValue("testEnv2")), std::string{"2"});
|
||||
|
||||
std::cout << " → Testing error.conf\n";
|
||||
Hyprlang::CConfig errorConfig("./config/error.conf", {.verifyOnly = true, .throwAllErrors = true});
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue