core: make option structs forward-ABI compatible

This commit is contained in:
Vaxry 2024-03-08 15:47:21 +00:00
parent 9995f54edd
commit 2e2a1992c8
2 changed files with 41 additions and 9 deletions

View file

@ -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;
};
/*!

View file

@ -7,6 +7,7 @@
#include <cmath>
#include <expected>
#include <sstream>
#include <cstring>
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<SSpecialCategoryDescriptor>()).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});
}