mirror of
https://github.com/hyprwm/hyprlang.git
synced 2024-11-16 18:25:57 +01:00
core: add support for handlers
This commit is contained in:
parent
53d955b150
commit
19479c3216
5 changed files with 89 additions and 22 deletions
|
@ -243,11 +243,28 @@ CParseResult CConfig::parseLine(std::string line) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (equalsPos != std::string::npos) {
|
if (equalsPos != std::string::npos) {
|
||||||
// set value
|
// set value or call handler
|
||||||
CParseResult ret = configSetValueSafe(removeBeginEndSpacesTabs(line.substr(0, equalsPos)), removeBeginEndSpacesTabs(line.substr(equalsPos + 1)));
|
CParseResult ret;
|
||||||
if (ret.error) {
|
const auto LHS = removeBeginEndSpacesTabs(line.substr(0, equalsPos));
|
||||||
return ret;
|
const auto RHS = removeBeginEndSpacesTabs(line.substr(equalsPos + 1));
|
||||||
|
|
||||||
|
bool found = false;
|
||||||
|
for (auto& h : impl->handlers) {
|
||||||
|
if (!h.options.allowFlags && h.name != LHS)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (h.options.allowFlags && !LHS.starts_with(h.name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = h.func(LHS.c_str(), RHS.c_str());
|
||||||
|
found = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!found)
|
||||||
|
ret = configSetValueSafe(LHS, RHS);
|
||||||
|
|
||||||
|
if (ret.error)
|
||||||
|
return ret;
|
||||||
} else if (!line.empty()) {
|
} else if (!line.empty()) {
|
||||||
// has to be a set
|
// has to be a set
|
||||||
if (line.contains("}")) {
|
if (line.contains("}")) {
|
||||||
|
@ -319,3 +336,7 @@ CConfigValue* CConfig::getConfigValuePtr(const char* name) {
|
||||||
const auto IT = impl->values.find(std::string{name});
|
const auto IT = impl->values.find(std::string{name});
|
||||||
return IT == impl->values.end() ? nullptr : &IT->second;
|
return IT == impl->values.end() ? nullptr : &IT->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CConfig::registerHandler(PCONFIGHANDLERFUNC func, const char* name, SHandlerOptions options) {
|
||||||
|
impl->handlers.push_back(SHandler{name, options, func});
|
||||||
|
}
|
|
@ -4,12 +4,19 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
struct SHandler {
|
||||||
|
std::string name = "";
|
||||||
|
Hyprlang::SHandlerOptions options;
|
||||||
|
Hyprlang::PCONFIGHANDLERFUNC func = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
class CConfigImpl {
|
class CConfigImpl {
|
||||||
public:
|
public:
|
||||||
std::string path = "";
|
std::string path = "";
|
||||||
|
|
||||||
std::unordered_map<std::string, Hyprlang::CConfigValue> values;
|
std::unordered_map<std::string, Hyprlang::CConfigValue> values;
|
||||||
std::unordered_map<std::string, Hyprlang::CConfigValue> defaultValues;
|
std::unordered_map<std::string, Hyprlang::CConfigValue> defaultValues;
|
||||||
|
std::vector<SHandler> handlers;
|
||||||
|
|
||||||
std::vector<std::string> categories;
|
std::vector<std::string> categories;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,30 @@ namespace Hyprlang {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CParseResult {
|
||||||
|
public:
|
||||||
|
bool error = false;
|
||||||
|
const char* getError() const {
|
||||||
|
return errorString;
|
||||||
|
}
|
||||||
|
void setError(const char* err);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setError(const std::string& err);
|
||||||
|
|
||||||
|
std::string errorStdString = "";
|
||||||
|
const char* errorString = nullptr;
|
||||||
|
|
||||||
|
friend class CConfig;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHandlerOptions {
|
||||||
|
bool allowFlags = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* typedefs */
|
||||||
|
typedef CParseResult (*PCONFIGHANDLERFUNC)(const char* COMMAND, const char* VALUE);
|
||||||
|
|
||||||
struct SConfigValueImpl;
|
struct SConfigValueImpl;
|
||||||
/* Container for a config value */
|
/* Container for a config value */
|
||||||
class CConfigValue {
|
class CConfigValue {
|
||||||
|
@ -63,23 +87,6 @@ namespace Hyprlang {
|
||||||
friend class CConfig;
|
friend class CConfig;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CParseResult {
|
|
||||||
public:
|
|
||||||
bool error = false;
|
|
||||||
const char* getError() const {
|
|
||||||
return errorString;
|
|
||||||
}
|
|
||||||
void setError(const char* err);
|
|
||||||
|
|
||||||
private:
|
|
||||||
void setError(const std::string& err);
|
|
||||||
|
|
||||||
std::string errorStdString = "";
|
|
||||||
const char* errorString = nullptr;
|
|
||||||
|
|
||||||
friend class CConfig;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Base class for a config file */
|
/* Base class for a config file */
|
||||||
class CConfig {
|
class CConfig {
|
||||||
public:
|
public:
|
||||||
|
@ -91,6 +98,10 @@ namespace Hyprlang {
|
||||||
Value provided becomes default */
|
Value provided becomes default */
|
||||||
void addConfigValue(const char* name, const CConfigValue value);
|
void addConfigValue(const char* name, const CConfigValue value);
|
||||||
|
|
||||||
|
/* Register a handler. Can be called anytime, though not recommended
|
||||||
|
to do this dynamically */
|
||||||
|
void registerHandler(PCONFIGHANDLERFUNC func, const char* name, SHandlerOptions options);
|
||||||
|
|
||||||
/* Commence the config state. Config becomes immutable, as in
|
/* Commence the config state. Config becomes immutable, as in
|
||||||
no new values may be added or removed. Required for parsing. */
|
no new values may be added or removed. Required for parsing. */
|
||||||
void commence();
|
void commence();
|
||||||
|
|
|
@ -24,7 +24,8 @@ testCategory {
|
||||||
testStringQuotes = "Hello World!"
|
testStringQuotes = "Hello World!"
|
||||||
#testDefault = 123
|
#testDefault = 123
|
||||||
|
|
||||||
#doABarrelRoll = woohoo, some, params # Funny!
|
doABarrelRoll = woohoo, some, params # Funny!
|
||||||
|
flagsabc = test
|
||||||
#doSomethingFunny = 1, 2, 3, 4 # Funnier!
|
#doSomethingFunny = 1, 2, 3, 4 # Funnier!
|
||||||
#testSpaces = abc , def # many spaces, should be trimmed
|
#testSpaces = abc , def # many spaces, should be trimmed
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,26 @@
|
||||||
std::cout << "Passed " << #expr << ". Got " << val << "\n"; \
|
std::cout << "Passed " << #expr << ". Got " << val << "\n"; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// globals for testing
|
||||||
|
bool barrelRoll = false;
|
||||||
|
std::string flagsFound = "";
|
||||||
|
|
||||||
|
static Hyprlang::CParseResult handleDoABarrelRoll(const char* COMMAND, const char* VALUE) {
|
||||||
|
if (std::string(VALUE) == "woohoo, some, params")
|
||||||
|
barrelRoll = true;
|
||||||
|
|
||||||
|
Hyprlang::CParseResult result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Hyprlang::CParseResult handleFlagsTest(const char* COMMAND, const char* VALUE) {
|
||||||
|
std::string cmd = COMMAND;
|
||||||
|
flagsFound = cmd.substr(5);
|
||||||
|
|
||||||
|
Hyprlang::CParseResult result;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv, char** envp) {
|
int main(int argc, char** argv, char** envp) {
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
@ -33,6 +53,9 @@ int main(int argc, char** argv, char** envp) {
|
||||||
config.addConfigValue("testCategory:testColor2", 0L);
|
config.addConfigValue("testCategory:testColor2", 0L);
|
||||||
config.addConfigValue("testCategory:testColor3", 0L);
|
config.addConfigValue("testCategory:testColor3", 0L);
|
||||||
|
|
||||||
|
config.registerHandler(&handleDoABarrelRoll, "doABarrelRoll", {false});
|
||||||
|
config.registerHandler(&handleFlagsTest, "flags", {true});
|
||||||
|
|
||||||
config.commence();
|
config.commence();
|
||||||
|
|
||||||
const auto PARSERESULT = config.parse();
|
const auto PARSERESULT = config.parse();
|
||||||
|
@ -58,6 +81,10 @@ int main(int argc, char** argv, char** envp) {
|
||||||
EXPECT(std::any_cast<int64_t>(config.getConfigValue("testCategory:testColor1")), 0xFFFFFFFFL);
|
EXPECT(std::any_cast<int64_t>(config.getConfigValue("testCategory:testColor1")), 0xFFFFFFFFL);
|
||||||
EXPECT(std::any_cast<int64_t>(config.getConfigValue("testCategory:testColor2")), 0xFF000000L);
|
EXPECT(std::any_cast<int64_t>(config.getConfigValue("testCategory:testColor2")), 0xFF000000L);
|
||||||
EXPECT(std::any_cast<int64_t>(config.getConfigValue("testCategory:testColor3")), 0x22ffeeffL);
|
EXPECT(std::any_cast<int64_t>(config.getConfigValue("testCategory:testColor3")), 0x22ffeeffL);
|
||||||
|
|
||||||
|
// test handlers
|
||||||
|
EXPECT(barrelRoll, true);
|
||||||
|
EXPECT(flagsFound, std::string{"abc"});
|
||||||
} catch (const char* e) {
|
} catch (const char* e) {
|
||||||
std::cout << "Error: " << e << "\n";
|
std::cout << "Error: " << e << "\n";
|
||||||
return 1;
|
return 1;
|
||||||
|
|
Loading…
Reference in a new issue