1
0
mirror of synced 2024-11-28 09:30:51 +01:00

sys: Improved ScopeGuard syntax a lot

This commit is contained in:
WerWolv 2021-03-31 22:54:43 +02:00
parent a2c80e3fd6
commit 2f19ff768d
8 changed files with 70 additions and 50 deletions

View File

@ -76,6 +76,7 @@ namespace hex {
#define TOKEN_CONCAT_IMPL(x, y) x ## y
#define TOKEN_CONCAT(x, y) TOKEN_CONCAT_IMPL(x, y)
#define ANONYMOUS_VARIABLE(prefix) TOKEN_CONCAT(prefix, __COUNTER__)
namespace hex {
@ -235,20 +236,32 @@ namespace hex {
std::vector<std::string> getPath(ImHexPath path);
#define SCOPE_EXIT(func) ScopeExit TOKEN_CONCAT(scopeGuard, __COUNTER__)([&] { func })
class ScopeExit {
#define SCOPE_GUARD ::hex::ScopeGuardOnExit() + [&]()
#define ON_SCOPE_EXIT auto ANONYMOUS_VARIABLE(SCOPE_EXIT_) = SCOPE_GUARD
template<class F>
class ScopeGuard {
private:
F m_func;
bool m_active;
public:
ScopeExit(const std::function<void()> &func) : m_func(func) {}
~ScopeExit() { if (this->m_func != nullptr) this->m_func(); }
constexpr ScopeGuard(F func) : m_func(std::move(func)), m_active(true) { }
~ScopeGuard() { if (this->m_active) { this->m_func(); } }
void release() { this->m_active = false; }
void release() {
this->m_func = nullptr;
ScopeGuard(ScopeGuard &&other) noexcept : m_func(std::move(other.m_func)), m_active(other.m_active) {
other.cancel();
}
private:
std::function<void()> m_func;
ScopeGuard& operator=(ScopeGuard &&) = delete;
};
enum class ScopeGuardOnExit { };
template <typename F>
constexpr ScopeGuard<F> operator+(ScopeGuardOnExit, F&& f) {
return ScopeGuard<F>(std::forward<F>(f));
}
struct Region {
u64 address;
size_t size;

View File

@ -91,7 +91,10 @@ namespace hex::lang {
std::vector<ASTNode*> parseTillToken(Token::Type endTokenType, const auto value) {
std::vector<ASTNode*> program;
ScopeExit guard([&]{ for (auto &node : program) delete node; });
auto guard = SCOPE_GUARD {
for (auto &node : program)
delete node;
};
while (this->m_curr->type != endTokenType || (*this->m_curr) != value) {
program.push_back(parseStatement());

View File

@ -121,10 +121,10 @@ namespace hex::lang {
ASTNode* Evaluator::evaluateFunctionCall(ASTNodeFunctionCall *node) {
std::vector<ASTNode*> evaluatedParams;
ScopeExit paramCleanup([&] {
ON_SCOPE_EXIT {
for (auto &param : evaluatedParams)
delete param;
});
};
for (auto &param : node->getParams()) {
if (auto numericExpression = dynamic_cast<ASTNodeNumericExpression*>(param); numericExpression != nullptr)
@ -310,7 +310,7 @@ namespace hex::lang {
switch (node->getOperator()) {
case Token::Operator::TernaryConditional: {
auto condition = this->evaluateOperand(node->getFirstOperand());
SCOPE_EXIT( delete condition; );
ON_SCOPE_EXIT { delete condition; };
if (std::visit([](auto &&value){ return value != 0; }, condition->getValue()))
return this->evaluateOperand(node->getSecondOperand());
@ -437,7 +437,7 @@ namespace hex::lang {
std::vector<PatternData*> memberPatterns;
this->m_currMembers.push_back(&memberPatterns);
SCOPE_EXIT( this->m_currMembers.pop_back(); );
ON_SCOPE_EXIT { this->m_currMembers.pop_back(); };
this->m_currRecursionDepth++;
if (this->m_currRecursionDepth > this->m_recursionLimit)
@ -457,7 +457,7 @@ namespace hex::lang {
std::vector<PatternData*> memberPatterns;
this->m_currMembers.push_back(&memberPatterns);
SCOPE_EXIT( this->m_currMembers.pop_back(); );
ON_SCOPE_EXIT { this->m_currMembers.pop_back(); };
auto startOffset = this->m_currOffset;
@ -501,7 +501,7 @@ namespace hex::lang {
this->getConsole().abortEvaluation("invalid expression in enum value");
auto valueNode = evaluateMathematicalExpression(expression);
SCOPE_EXIT( delete valueNode; );
ON_SCOPE_EXIT { delete valueNode; };
entryPatterns.push_back({ Token::castTo(builtinUnderlyingType->getType(), valueNode->getValue()), name });
}
@ -522,7 +522,7 @@ namespace hex::lang {
this->getConsole().abortEvaluation("invalid expression in bitfield field size");
auto valueNode = evaluateMathematicalExpression(expression);
SCOPE_EXIT( delete valueNode; );
ON_SCOPE_EXIT { delete valueNode; };
auto fieldBits = std::visit([this, node, type = valueNode->getType()] (auto &&value) {
if (Token::isFloatingPoint(type))
@ -580,7 +580,7 @@ namespace hex::lang {
if (auto offset = dynamic_cast<ASTNodeNumericExpression*>(node->getPlacementOffset()); offset != nullptr) {
auto valueNode = evaluateMathematicalExpression(offset);
SCOPE_EXIT( delete valueNode; );
ON_SCOPE_EXIT { delete valueNode; };
this->m_currOffset = std::visit([this, node, type = valueNode->getType()] (auto &&value) {
if (Token::isFloatingPoint(type))
@ -608,7 +608,7 @@ namespace hex::lang {
if (auto offset = dynamic_cast<ASTNodeNumericExpression*>(node->getPlacementOffset()); offset != nullptr) {
auto valueNode = evaluateMathematicalExpression(offset);
SCOPE_EXIT( delete valueNode; );
ON_SCOPE_EXIT { delete valueNode; };
this->m_currOffset = std::visit([this, node, type = valueNode->getType()] (auto &&value) {
if (Token::isFloatingPoint(type))
@ -628,7 +628,7 @@ namespace hex::lang {
else
this->getConsole().abortEvaluation("array size not a numeric expression");
SCOPE_EXIT( delete valueNode; );
ON_SCOPE_EXIT { delete valueNode; };
arraySize = std::visit([this, node, type = valueNode->getType()] (auto &&value) {
if (Token::isFloatingPoint(type))
@ -701,7 +701,7 @@ namespace hex::lang {
s128 pointerOffset;
if (auto offset = dynamic_cast<ASTNodeNumericExpression*>(node->getPlacementOffset()); offset != nullptr) {
auto valueNode = evaluateMathematicalExpression(offset);
SCOPE_EXIT( delete valueNode; );
ON_SCOPE_EXIT { delete valueNode; };
pointerOffset = std::visit([this, node, type = valueNode->getType()] (auto &&value) {
if (Token::isFloatingPoint(type))

View File

@ -22,10 +22,10 @@ namespace hex::lang {
ASTNode* Parser::parseFunctionCall() {
auto functionName = getValue<std::string>(-2);
std::vector<ASTNode*> params;
ScopeExit paramCleanup([&]{
auto paramCleanup = SCOPE_GUARD {
for (auto &param : params)
delete param;
});
};
while (!MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE))) {
if (MATCHES(sequence(STRING)))
@ -118,7 +118,7 @@ namespace hex::lang {
ASTNode* Parser::parseMultiplicativeExpression() {
auto node = this->parseUnaryExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(oneOf(OPERATOR_STAR, OPERATOR_SLASH, OPERATOR_PERCENT))) {
auto op = getValue<Token::Operator>(-1);
@ -134,7 +134,7 @@ namespace hex::lang {
ASTNode* Parser::parseAdditiveExpression() {
auto node = this->parseMultiplicativeExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(variant(OPERATOR_PLUS, OPERATOR_MINUS))) {
auto op = getValue<Token::Operator>(-1);
@ -150,7 +150,7 @@ namespace hex::lang {
ASTNode* Parser::parseShiftExpression() {
auto node = this->parseAdditiveExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(variant(OPERATOR_SHIFTLEFT, OPERATOR_SHIFTRIGHT))) {
auto op = getValue<Token::Operator>(-1);
@ -166,7 +166,7 @@ namespace hex::lang {
ASTNode* Parser::parseRelationExpression() {
auto node = this->parseShiftExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD{ delete node; };
while (MATCHES(sequence(OPERATOR_BOOLGREATERTHAN) || sequence(OPERATOR_BOOLLESSTHAN) || sequence(OPERATOR_BOOLGREATERTHANOREQUALS) || sequence(OPERATOR_BOOLLESSTHANOREQUALS))) {
auto op = getValue<Token::Operator>(-1);
@ -182,7 +182,7 @@ namespace hex::lang {
ASTNode* Parser::parseEqualityExpression() {
auto node = this->parseRelationExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(sequence(OPERATOR_BOOLEQUALS) || sequence(OPERATOR_BOOLNOTEQUALS))) {
auto op = getValue<Token::Operator>(-1);
@ -198,7 +198,7 @@ namespace hex::lang {
ASTNode* Parser::parseBinaryAndExpression() {
auto node = this->parseEqualityExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(sequence(OPERATOR_BITAND))) {
node = new ASTNodeNumericExpression(node, this->parseEqualityExpression(), Token::Operator::BitAnd);
@ -213,7 +213,7 @@ namespace hex::lang {
ASTNode* Parser::parseBinaryXorExpression() {
auto node = this->parseBinaryAndExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(sequence(OPERATOR_BITXOR))) {
node = new ASTNodeNumericExpression(node, this->parseBinaryAndExpression(), Token::Operator::BitXor);
@ -228,7 +228,7 @@ namespace hex::lang {
ASTNode* Parser::parseBinaryOrExpression() {
auto node = this->parseBinaryXorExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(sequence(OPERATOR_BITOR))) {
node = new ASTNodeNumericExpression(node, this->parseBinaryXorExpression(), Token::Operator::BitOr);
@ -243,7 +243,7 @@ namespace hex::lang {
ASTNode* Parser::parseBooleanAnd() {
auto node = this->parseBinaryOrExpression();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(sequence(OPERATOR_BOOLAND))) {
node = new ASTNodeNumericExpression(node, this->parseBinaryOrExpression(), Token::Operator::BitOr);
@ -258,7 +258,7 @@ namespace hex::lang {
ASTNode* Parser::parseBooleanXor() {
auto node = this->parseBooleanAnd();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(sequence(OPERATOR_BOOLXOR))) {
node = new ASTNodeNumericExpression(node, this->parseBooleanAnd(), Token::Operator::BitOr);
@ -273,7 +273,7 @@ namespace hex::lang {
ASTNode* Parser::parseBooleanOr() {
auto node = this->parseBooleanXor();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(sequence(OPERATOR_BOOLOR))) {
node = new ASTNodeNumericExpression(node, this->parseBooleanXor(), Token::Operator::BitOr);
@ -288,7 +288,7 @@ namespace hex::lang {
ASTNode* Parser::parseTernaryConditional() {
auto node = this->parseBooleanOr();
ScopeExit nodeCleanup([&]{ delete node; });
auto nodeCleanup = SCOPE_GUARD { delete node; };
while (MATCHES(sequence(OPERATOR_TERNARYCONDITIONAL))) {
auto second = this->parseBooleanOr();
@ -341,13 +341,13 @@ namespace hex::lang {
auto condition = parseMathematicalExpression();
std::vector<ASTNode*> trueBody, falseBody;
ScopeExit cleanup([&]{
auto cleanup = SCOPE_GUARD {
delete condition;
for (auto &statement : trueBody)
delete statement;
for (auto &statement : falseBody)
delete statement;
});
};
if (MATCHES(sequence(SEPARATOR_ROUNDBRACKETCLOSE, SEPARATOR_CURLYBRACKETOPEN))) {
while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) {
@ -432,7 +432,7 @@ namespace hex::lang {
auto name = getValue<std::string>(-2);
ASTNode *size = nullptr;
ScopeExit sizeCleanup([&]{ delete size; });
auto sizeCleanup = SCOPE_GUARD { delete size; };
if (!MATCHES(sequence(SEPARATOR_SQUAREBRACKETCLOSE))) {
size = parseMathematicalExpression();
@ -494,7 +494,7 @@ namespace hex::lang {
ASTNode* Parser::parseStruct() {
const auto structNode = new ASTNodeStruct();
const auto &typeName = getValue<std::string>(-2);
ScopeExit structGuard([&]{ delete structNode; });
auto structGuard = SCOPE_GUARD { delete structNode; };
while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) {
structNode->addMember(parseMember());
@ -509,7 +509,7 @@ namespace hex::lang {
ASTNode* Parser::parseUnion() {
const auto unionNode = new ASTNodeUnion();
const auto &typeName = getValue<std::string>(-2);
ScopeExit unionGuard([&]{ delete unionNode; });
auto unionGuard = SCOPE_GUARD { delete unionNode; };
while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) {
unionNode->addMember(parseMember());
@ -533,7 +533,7 @@ namespace hex::lang {
if (underlyingType->getEndian().has_value()) throwParseError("underlying type may not have an endian specification", -2);
const auto enumNode = new ASTNodeEnum(underlyingType);
ScopeExit enumGuard([&]{ delete enumNode; });
auto enumGuard = SCOPE_GUARD { delete enumNode; };
ASTNode *lastEntry = nullptr;
while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) {
@ -577,7 +577,7 @@ namespace hex::lang {
std::string typeName = getValue<std::string>(-2);
const auto bitfieldNode = new ASTNodeBitfield();
ScopeExit enumGuard([&]{ delete bitfieldNode; });
auto enumGuard = SCOPE_GUARD { delete bitfieldNode; };
while (!MATCHES(sequence(SEPARATOR_CURLYBRACKETCLOSE))) {
if (MATCHES(sequence(IDENTIFIER, OPERATOR_INHERIT))) {
@ -615,7 +615,7 @@ namespace hex::lang {
auto name = getValue<std::string>(-2);
ASTNode *size = nullptr;
ScopeExit sizeCleanup([&]{ delete size; });
auto sizeCleanup = SCOPE_GUARD { delete size; };
if (!MATCHES(sequence(SEPARATOR_SQUAREBRACKETCLOSE))) {
size = parseMathematicalExpression();

View File

@ -81,7 +81,10 @@ namespace hex::lang {
return { };
}
SCOPE_EXIT( for(auto &node : ast.value()) delete node; );
ON_SCOPE_EXIT {
for(auto &node : ast.value())
delete node;
};
auto validatorResult = this->m_validator->validate(ast.value());
if (!validatorResult) {

View File

@ -79,7 +79,7 @@ namespace hex {
return nullptr;
}
SCOPE_EXIT( Py_DECREF(instance); );
ON_SCOPE_EXIT { Py_DECREF(instance); };
if (instance->ob_type->tp_base == nullptr || instance->ob_type->tp_base->tp_name != "ImHexType"s) {
PyErr_SetString(PyExc_TypeError, "class type must extend from ImHexType");
@ -104,7 +104,7 @@ namespace hex {
return nullptr;
}
SCOPE_EXIT( Py_DECREF(list); );
ON_SCOPE_EXIT { Py_DECREF(list); };
std::string code = keyword + " " + instance->ob_type->tp_name + " {\n";

View File

@ -42,11 +42,12 @@ namespace hex::prv {
this->m_writable = false;
}
ScopeExit fileCleanup([this]{
auto fileCleanup = SCOPE_GUARD {
this->m_readable = false;
this->m_file = nullptr;
CloseHandle(this->m_file);
});
};
if (this->m_file == nullptr || this->m_file == INVALID_HANDLE_VALUE) {
return;
}
@ -56,11 +57,11 @@ namespace hex::prv {
return;
}
ScopeExit mappingCleanup([this]{
auto mappingCleanup = SCOPE_GUARD {
this->m_readable = false;
this->m_mapping = nullptr;
CloseHandle(this->m_mapping);
});
};
this->m_mappedFile = MapViewOfFile(this->m_mapping, FILE_MAP_ALL_ACCESS, 0, 0, this->m_fileSize);
if (this->m_mappedFile == nullptr) {

View File

@ -138,7 +138,7 @@ namespace hex {
FILE *file = fopen(this->m_rules[this->m_selectedRule].c_str(), "r");
if (file == nullptr) return;
SCOPE_EXIT( fclose(file); );
ON_SCOPE_EXIT { fclose(file); };
if (yr_compiler_add_file(compiler, file, nullptr, nullptr) != 0) {
this->m_errorMessage.resize(0xFFFF);