diff --git a/include/hyprlang.hpp b/include/hyprlang.hpp index 9264fab..c5d43b3 100644 --- a/include/hyprlang.hpp +++ b/include/hyprlang.hpp @@ -13,6 +13,8 @@ class CConfigImpl; struct SConfigDefaultValue; struct SSpecialCategory; +#define HYPRLANG_END_MAGIC 0x1337BEEF + namespace Hyprlang { struct SVector2D; @@ -94,33 +96,42 @@ namespace Hyprlang { /*! Don't throw errors on missing values. */ - bool verifyOnly = false; + int verifyOnly = false; /*! Return all errors instead of just the first */ - bool throwAllErrors = false; + int throwAllErrors = false; /*! \since 0.2.0 Don't throw on a missing config file. Carry on as if nothing happened. */ - bool allowMissingConfig = false; + int allowMissingConfig = false; /*! \since 0.4.2 Treat configPath as a raw config stream. */ - bool pathIsStream = false; + int pathIsStream = false; + + // INTERNAL: DO NOT MODIFY + int __internal_struct_end = HYPRLANG_END_MAGIC; }; /*! Generic struct for options for handlers */ struct SHandlerOptions { + /*! + Allow flags for this handler + */ bool allowFlags = false; + + // INTERNAL: DO NOT MODIFY + int __internal_struct_end = HYPRLANG_END_MAGIC; }; /*! @@ -137,7 +148,7 @@ namespace Hyprlang { /*! don't pop up an error if the config value is missing */ - bool ignoreMissing = false; + int ignoreMissing = false; /*! Make this category an anonymous special one. @@ -148,7 +159,10 @@ namespace Hyprlang { \since 0.4.0 */ - bool anonymousKeyBased = false; + int anonymousKeyBased = false; + + // INTERNAL: DO NOT MODIFY + int __internal_struct_end = HYPRLANG_END_MAGIC; }; /*! diff --git a/src/config.cpp b/src/config.cpp index e342228..bfdffc1 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -7,6 +7,7 @@ #include #include #include +#include using namespace Hyprlang; extern "C" char** environ; @@ -15,6 +16,15 @@ extern "C" char** environ; inline constexpr const char* ANONYMOUS_KEY = "__hyprlang_internal_anonymous_key"; // +static size_t seekABIStructSize(const void* begin, size_t startOffset, size_t maxSize) { + for (size_t off = startOffset; off < maxSize; off += 4) { + if (*(int*)((unsigned char*)begin + off) == int{HYPRLANG_END_MAGIC}) + return off; + } + + return 0; +} + static std::string removeBeginEndSpacesTabs(std::string str) { if (str.empty()) return str; @@ -34,7 +44,10 @@ static std::string removeBeginEndSpacesTabs(std::string str) { return str; } -CConfig::CConfig(const char* path, const Hyprlang::SConfigOptions& options) { +CConfig::CConfig(const char* path, const Hyprlang::SConfigOptions& options_) { + SConfigOptions options; + std::memcpy(&options, &options_, seekABIStructSize(&options_, 16, sizeof(SConfigOptions))); + impl = new CConfigImpl; if (options.pathIsStream) @@ -110,7 +123,10 @@ void CConfig::removeSpecialConfigValue(const char* cat, const char* name) { std::erase_if(IT->get()->defaultValues, [name](const auto& other) { return other.first == name; }); } -void CConfig::addSpecialCategory(const char* name, SSpecialCategoryOptions options) { +void CConfig::addSpecialCategory(const char* name, SSpecialCategoryOptions options_) { + SSpecialCategoryOptions options; + std::memcpy(&options, &options_, seekABIStructSize(&options_, 8, sizeof(SSpecialCategoryOptions))); + const auto PDESC = impl->specialCategoryDescriptors.emplace_back(std::make_unique()).get(); PDESC->name = name; PDESC->key = options.key ? options.key : ""; @@ -738,7 +754,9 @@ CConfigValue* CConfig::getSpecialConfigValuePtr(const char* category, const char return nullptr; } -void CConfig::registerHandler(PCONFIGHANDLERFUNC func, const char* name, SHandlerOptions options) { +void CConfig::registerHandler(PCONFIGHANDLERFUNC func, const char* name, SHandlerOptions options_) { + SHandlerOptions options; + std::memcpy(&options, &options_, seekABIStructSize(&options_, 0, sizeof(SHandlerOptions))); impl->handlers.push_back(SHandler{name, options, func}); }