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) {
|
||||
// set value
|
||||
CParseResult ret = configSetValueSafe(removeBeginEndSpacesTabs(line.substr(0, equalsPos)), removeBeginEndSpacesTabs(line.substr(equalsPos + 1)));
|
||||
if (ret.error) {
|
||||
return ret;
|
||||
// set value or call handler
|
||||
CParseResult ret;
|
||||
const auto LHS = removeBeginEndSpacesTabs(line.substr(0, equalsPos));
|
||||
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()) {
|
||||
// has to be a set
|
||||
if (line.contains("}")) {
|
||||
|
@ -319,3 +336,7 @@ CConfigValue* CConfig::getConfigValuePtr(const char* name) {
|
|||
const auto IT = impl->values.find(std::string{name});
|
||||
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 <vector>
|
||||
|
||||
struct SHandler {
|
||||
std::string name = "";
|
||||
Hyprlang::SHandlerOptions options;
|
||||
Hyprlang::PCONFIGHANDLERFUNC func = nullptr;
|
||||
};
|
||||
|
||||
class CConfigImpl {
|
||||
public:
|
||||
std::string path = "";
|
||||
|
||||
std::unordered_map<std::string, Hyprlang::CConfigValue> values;
|
||||
std::unordered_map<std::string, Hyprlang::CConfigValue> defaultValues;
|
||||
std::vector<SHandler> handlers;
|
||||
|
||||
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;
|
||||
/* Container for a config value */
|
||||
class CConfigValue {
|
||||
|
@ -63,23 +87,6 @@ namespace Hyprlang {
|
|||
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 */
|
||||
class CConfig {
|
||||
public:
|
||||
|
@ -91,6 +98,10 @@ namespace Hyprlang {
|
|||
Value provided becomes default */
|
||||
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
|
||||
no new values may be added or removed. Required for parsing. */
|
||||
void commence();
|
||||
|
|
|
@ -24,7 +24,8 @@ testCategory {
|
|||
testStringQuotes = "Hello World!"
|
||||
#testDefault = 123
|
||||
|
||||
#doABarrelRoll = woohoo, some, params # Funny!
|
||||
doABarrelRoll = woohoo, some, params # Funny!
|
||||
flagsabc = test
|
||||
#doSomethingFunny = 1, 2, 3, 4 # Funnier!
|
||||
#testSpaces = abc , def # many spaces, should be trimmed
|
||||
|
||||
|
|
|
@ -10,6 +10,26 @@
|
|||
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 ret = 0;
|
||||
|
||||
|
@ -33,6 +53,9 @@ int main(int argc, char** argv, char** envp) {
|
|||
config.addConfigValue("testCategory:testColor2", 0L);
|
||||
config.addConfigValue("testCategory:testColor3", 0L);
|
||||
|
||||
config.registerHandler(&handleDoABarrelRoll, "doABarrelRoll", {false});
|
||||
config.registerHandler(&handleFlagsTest, "flags", {true});
|
||||
|
||||
config.commence();
|
||||
|
||||
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:testColor2")), 0xFF000000L);
|
||||
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) {
|
||||
std::cout << "Error: " << e << "\n";
|
||||
return 1;
|
||||
|
|
Loading…
Reference in a new issue