mirror of
https://github.com/hyprwm/hyprlang.git
synced 2024-11-16 18:25:57 +01:00
internal: various stability improvements
This commit is contained in:
parent
c1f5b0ab48
commit
7c5f672b2f
5 changed files with 102 additions and 36 deletions
|
@ -165,6 +165,7 @@ namespace Hyprlang {
|
||||||
PCONFIGCUSTOMVALUEDESTRUCTOR dtor = nullptr;
|
PCONFIGCUSTOMVALUEDESTRUCTOR dtor = nullptr;
|
||||||
void* data = nullptr;
|
void* data = nullptr;
|
||||||
std::string defaultVal = "";
|
std::string defaultVal = "";
|
||||||
|
std::string lastVal = "";
|
||||||
|
|
||||||
friend class CConfigValue;
|
friend class CConfigValue;
|
||||||
friend class CConfig;
|
friend class CConfig;
|
||||||
|
@ -245,7 +246,8 @@ namespace Hyprlang {
|
||||||
eDataType m_eType = eDataType::CONFIGDATATYPE_EMPTY;
|
eDataType m_eType = eDataType::CONFIGDATATYPE_EMPTY;
|
||||||
void* m_pData = nullptr;
|
void* m_pData = nullptr;
|
||||||
void defaultFrom(SConfigDefaultValue& ref);
|
void defaultFrom(SConfigDefaultValue& ref);
|
||||||
void setFrom(std::any value);
|
void setFrom(std::any ref);
|
||||||
|
void setFrom(const CConfigValue* const ref);
|
||||||
|
|
||||||
friend class CConfig;
|
friend class CConfig;
|
||||||
};
|
};
|
||||||
|
|
126
src/common.cpp
126
src/common.cpp
|
@ -17,46 +17,52 @@ void CParseResult::setError(const char* err) {
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigValue::~CConfigValue() {
|
CConfigValue::~CConfigValue() {
|
||||||
if (m_eType == CONFIGDATATYPE_CUSTOM)
|
if (m_pData) {
|
||||||
reinterpret_cast<CConfigCustomValueType*>(m_pData)->dtor(&reinterpret_cast<CConfigCustomValueType*>(m_pData)->data);
|
switch (m_eType) {
|
||||||
|
case CONFIGDATATYPE_INT: delete (int64_t*)m_pData; break;
|
||||||
|
case CONFIGDATATYPE_FLOAT: delete (float*)m_pData; break;
|
||||||
|
case CONFIGDATATYPE_VEC2: delete (SVector2D*)m_pData; break;
|
||||||
|
case CONFIGDATATYPE_CUSTOM: delete (CConfigCustomValueType*)m_pData; break;
|
||||||
|
case CONFIGDATATYPE_STR: delete[] (char*)m_pData; break;
|
||||||
|
|
||||||
if (m_pData)
|
default: break; // oh no?
|
||||||
free(m_pData);
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigValue::CConfigValue(const int64_t value) {
|
CConfigValue::CConfigValue(const int64_t value) {
|
||||||
m_pData = calloc(1, sizeof(int64_t));
|
m_pData = new int64_t;
|
||||||
*reinterpret_cast<int64_t*>(m_pData) = value;
|
*reinterpret_cast<int64_t*>(m_pData) = value;
|
||||||
m_eType = CONFIGDATATYPE_INT;
|
m_eType = CONFIGDATATYPE_INT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigValue::CConfigValue(const float value) {
|
CConfigValue::CConfigValue(const float value) {
|
||||||
m_pData = calloc(1, sizeof(float));
|
m_pData = new float;
|
||||||
*reinterpret_cast<float*>(m_pData) = value;
|
*reinterpret_cast<float*>(m_pData) = value;
|
||||||
m_eType = CONFIGDATATYPE_FLOAT;
|
m_eType = CONFIGDATATYPE_FLOAT;
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigValue::CConfigValue(const SVector2D value) {
|
CConfigValue::CConfigValue(const SVector2D value) {
|
||||||
m_pData = calloc(1, sizeof(SVector2D));
|
m_pData = new SVector2D;
|
||||||
*reinterpret_cast<SVector2D*>(m_pData) = value;
|
*reinterpret_cast<SVector2D*>(m_pData) = value;
|
||||||
m_eType = CONFIGDATATYPE_VEC2;
|
m_eType = CONFIGDATATYPE_VEC2;
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigValue::CConfigValue(const char* value) {
|
CConfigValue::CConfigValue(const char* value) {
|
||||||
m_pData = calloc(1, strlen(value) + 1);
|
m_pData = new char[strlen(value) + 1];
|
||||||
strncpy((char*)m_pData, value, strlen(value));
|
strncpy((char*)m_pData, value, strlen(value));
|
||||||
m_eType = CONFIGDATATYPE_STR;
|
((char*)m_pData)[strlen(value)] = '\0';
|
||||||
|
m_eType = CONFIGDATATYPE_STR;
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigValue::CConfigValue(CConfigCustomValueType&& value) {
|
CConfigValue::CConfigValue(CConfigCustomValueType&& value) {
|
||||||
m_pData = calloc(1, sizeof(CConfigCustomValueType));
|
m_pData = new CConfigCustomValueType(value);
|
||||||
new (m_pData) CConfigCustomValueType(value);
|
|
||||||
m_eType = CONFIGDATATYPE_CUSTOM;
|
m_eType = CONFIGDATATYPE_CUSTOM;
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigValue::CConfigValue(const CConfigValue& other) {
|
CConfigValue::CConfigValue(const CConfigValue& other) {
|
||||||
m_eType = other.m_eType;
|
m_eType = other.m_eType;
|
||||||
setFrom(other.getValue());
|
setFrom(&other);
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigValue::CConfigValue() {
|
CConfigValue::CConfigValue() {
|
||||||
|
@ -75,6 +81,7 @@ CConfigCustomValueType::CConfigCustomValueType(PCONFIGCUSTOMVALUEHANDLERFUNC han
|
||||||
handler = handler_;
|
handler = handler_;
|
||||||
dtor = dtor_;
|
dtor = dtor_;
|
||||||
defaultVal = def;
|
defaultVal = def;
|
||||||
|
lastVal = def;
|
||||||
}
|
}
|
||||||
|
|
||||||
CConfigCustomValueType::~CConfigCustomValueType() {
|
CConfigCustomValueType::~CConfigCustomValueType() {
|
||||||
|
@ -86,37 +93,37 @@ void CConfigValue::defaultFrom(SConfigDefaultValue& ref) {
|
||||||
switch (m_eType) {
|
switch (m_eType) {
|
||||||
case CONFIGDATATYPE_FLOAT: {
|
case CONFIGDATATYPE_FLOAT: {
|
||||||
if (!m_pData)
|
if (!m_pData)
|
||||||
m_pData = calloc(1, sizeof(float));
|
m_pData = new float;
|
||||||
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(ref.data);
|
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(ref.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONFIGDATATYPE_INT: {
|
case CONFIGDATATYPE_INT: {
|
||||||
if (!m_pData)
|
if (!m_pData)
|
||||||
m_pData = calloc(1, sizeof(int64_t));
|
m_pData = new int64_t;
|
||||||
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(ref.data);
|
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(ref.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONFIGDATATYPE_STR: {
|
case CONFIGDATATYPE_STR: {
|
||||||
if (m_pData)
|
if (m_pData)
|
||||||
free(m_pData);
|
delete[] (char*)m_pData;
|
||||||
std::string str = std::any_cast<std::string>(ref.data);
|
std::string str = std::any_cast<std::string>(ref.data);
|
||||||
m_pData = calloc(1, str.length() + 1);
|
m_pData = new char[str.length() + 1];
|
||||||
strncpy((char*)m_pData, str.c_str(), str.length());
|
strncpy((char*)m_pData, str.c_str(), str.length()); // TODO: please just wrap this
|
||||||
|
((char*)m_pData)[str.length()] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONFIGDATATYPE_VEC2: {
|
case CONFIGDATATYPE_VEC2: {
|
||||||
if (!m_pData)
|
if (!m_pData)
|
||||||
m_pData = calloc(1, sizeof(SVector2D));
|
m_pData = new SVector2D;
|
||||||
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(ref.data);
|
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(ref.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONFIGDATATYPE_CUSTOM: {
|
case CONFIGDATATYPE_CUSTOM: {
|
||||||
if (!m_pData)
|
if (!m_pData)
|
||||||
m_pData = calloc(1, sizeof(CConfigCustomValueType));
|
m_pData = new CConfigCustomValueType(ref.handler, ref.dtor, std::any_cast<std::string>(ref.data).c_str());
|
||||||
CConfigCustomValueType* type = reinterpret_cast<CConfigCustomValueType*>(m_pData);
|
CConfigCustomValueType* type = reinterpret_cast<CConfigCustomValueType*>(m_pData);
|
||||||
type->handler = ref.handler;
|
|
||||||
type->dtor = ref.dtor;
|
|
||||||
type->handler(std::any_cast<std::string>(ref.data).c_str(), &type->data);
|
type->handler(std::any_cast<std::string>(ref.data).c_str(), &type->data);
|
||||||
|
type->lastVal = std::any_cast<std::string>(ref.data);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
@ -127,35 +134,84 @@ void CConfigValue::defaultFrom(SConfigDefaultValue& ref) {
|
||||||
m_bSetByUser = false;
|
m_bSetByUser = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CConfigValue::setFrom(std::any value) {
|
void CConfigValue::setFrom(const CConfigValue* const ref) {
|
||||||
switch (m_eType) {
|
switch (m_eType) {
|
||||||
case CONFIGDATATYPE_FLOAT: {
|
case CONFIGDATATYPE_FLOAT: {
|
||||||
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(value);
|
if (!m_pData)
|
||||||
|
m_pData = new float;
|
||||||
|
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(ref->getValue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONFIGDATATYPE_INT: {
|
case CONFIGDATATYPE_INT: {
|
||||||
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(value);
|
if (!m_pData)
|
||||||
|
m_pData = new int64_t;
|
||||||
|
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(ref->getValue());
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONFIGDATATYPE_STR: {
|
case CONFIGDATATYPE_STR: {
|
||||||
if (m_pData)
|
if (m_pData)
|
||||||
free(m_pData);
|
delete[] (char*)m_pData;
|
||||||
std::string str = std::any_cast<std::string>(value);
|
std::string str = std::any_cast<std::string>(ref->getValue());
|
||||||
m_pData = calloc(1, str.length() + 1);
|
m_pData = new char[str.length() + 1];
|
||||||
strncpy((char*)m_pData, str.c_str(), str.length());
|
strncpy((char*)m_pData, str.c_str(), str.length());
|
||||||
|
((char*)m_pData)[str.length()] = '\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CONFIGDATATYPE_VEC2: {
|
case CONFIGDATATYPE_VEC2: {
|
||||||
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(value);
|
if (!m_pData)
|
||||||
|
m_pData = new SVector2D;
|
||||||
|
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(ref->getValue());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONFIGDATATYPE_CUSTOM: {
|
||||||
|
CConfigCustomValueType* reftype = reinterpret_cast<CConfigCustomValueType*>(ref->m_pData);
|
||||||
|
|
||||||
|
if (!m_pData)
|
||||||
|
m_pData = new CConfigCustomValueType(reftype->handler, reftype->dtor, reftype->defaultVal.c_str());
|
||||||
|
|
||||||
|
CConfigCustomValueType* type = reinterpret_cast<CConfigCustomValueType*>(m_pData);
|
||||||
|
type->handler(reftype->lastVal.c_str(), &type->data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
throw "bad defaultFrom type";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CConfigValue::setFrom(std::any ref) {
|
||||||
|
switch (m_eType) {
|
||||||
|
case CONFIGDATATYPE_FLOAT: {
|
||||||
|
if (!m_pData)
|
||||||
|
m_pData = new float;
|
||||||
|
*reinterpret_cast<float*>(m_pData) = std::any_cast<float>(ref);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONFIGDATATYPE_INT: {
|
||||||
|
if (!m_pData)
|
||||||
|
m_pData = new int64_t;
|
||||||
|
*reinterpret_cast<int64_t*>(m_pData) = std::any_cast<int64_t>(ref);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONFIGDATATYPE_STR: {
|
||||||
|
if (m_pData)
|
||||||
|
delete[] (char*)m_pData;
|
||||||
|
std::string str = std::any_cast<std::string>(ref);
|
||||||
|
m_pData = new char[str.length() + 1];
|
||||||
|
strncpy((char*)m_pData, str.c_str(), str.length());
|
||||||
|
((char*)m_pData)[str.length()] = '\0';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONFIGDATATYPE_VEC2: {
|
||||||
|
if (!m_pData)
|
||||||
|
m_pData = new SVector2D;
|
||||||
|
*reinterpret_cast<SVector2D*>(m_pData) = std::any_cast<SVector2D>(ref);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case CONFIGDATATYPE_CUSTOM: {
|
||||||
|
throw "bad defaultFrom type (cannot custom from std::any)";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// case CONFIGDATATYPE_CUSTOM: {
|
|
||||||
// CConfigCustomValueType* type = reinterpret_cast<CConfigCustomValueType*>(m_pData);
|
|
||||||
// type->handler = ref.handler;
|
|
||||||
// type->dtor = ref.dtor;
|
|
||||||
// type->handler(std::any_cast<std::string>(ref.data).c_str(), &type->data);
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
default: {
|
default: {
|
||||||
throw "bad defaultFrom type";
|
throw "bad defaultFrom type";
|
||||||
}
|
}
|
||||||
|
|
|
@ -351,6 +351,7 @@ CParseResult CConfig::configSetValueSafe(const std::string& command, const std::
|
||||||
}
|
}
|
||||||
case CConfigValue::eDataType::CONFIGDATATYPE_CUSTOM: {
|
case CConfigValue::eDataType::CONFIGDATATYPE_CUSTOM: {
|
||||||
reinterpret_cast<CConfigCustomValueType*>(VALUEIT->second.m_pData)->handler(value.c_str(), &reinterpret_cast<CConfigCustomValueType*>(VALUEIT->second.m_pData)->data);
|
reinterpret_cast<CConfigCustomValueType*>(VALUEIT->second.m_pData)->handler(value.c_str(), &reinterpret_cast<CConfigCustomValueType*>(VALUEIT->second.m_pData)->data);
|
||||||
|
reinterpret_cast<CConfigCustomValueType*>(VALUEIT->second.m_pData)->lastVal = value;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default: {
|
default: {
|
||||||
|
|
|
@ -44,6 +44,7 @@ special {
|
||||||
specialGeneric {
|
specialGeneric {
|
||||||
one {
|
one {
|
||||||
value = 1
|
value = 1
|
||||||
|
copyTest = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
two {
|
two {
|
||||||
|
|
|
@ -115,6 +115,9 @@ int main(int argc, char** argv, char** envp) {
|
||||||
config.addSpecialCategory("specialGeneric:two", {nullptr, true});
|
config.addSpecialCategory("specialGeneric:two", {nullptr, true});
|
||||||
config.addSpecialConfigValue("specialGeneric:two", "value", 0L);
|
config.addSpecialConfigValue("specialGeneric:two", "value", 0L);
|
||||||
|
|
||||||
|
const Hyprlang::CConfigValue copyTest = {1L};
|
||||||
|
config.addSpecialConfigValue("specialGeneric:one", "copyTest", copyTest);
|
||||||
|
|
||||||
const auto PARSERESULT = config.parse();
|
const auto PARSERESULT = config.parse();
|
||||||
if (PARSERESULT.error) {
|
if (PARSERESULT.error) {
|
||||||
std::cout << "Parse error: " << PARSERESULT.getError() << "\n";
|
std::cout << "Parse error: " << PARSERESULT.getError() << "\n";
|
||||||
|
@ -180,6 +183,9 @@ int main(int argc, char** argv, char** envp) {
|
||||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:one", "value")), 1);
|
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:one", "value")), 1);
|
||||||
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:two", "value")), 2);
|
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:two", "value")), 2);
|
||||||
|
|
||||||
|
// test copying
|
||||||
|
EXPECT(std::any_cast<int64_t>(config.getSpecialConfigValue("specialGeneric:one", "copyTest")), 2);
|
||||||
|
|
||||||
// test sourcing
|
// test sourcing
|
||||||
std::cout << " → Testing sourcing\n";
|
std::cout << " → Testing sourcing\n";
|
||||||
EXPECT(std::any_cast<int64_t>(config.getConfigValue("myColors:pink")), 0xFFc800c8L);
|
EXPECT(std::any_cast<int64_t>(config.getConfigValue("myColors:pink")), 0xFFc800c8L);
|
||||||
|
|
Loading…
Reference in a new issue