mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-30 13:05:25 -05:00
Completely rewrite highlight and pattern evaluator
This commit is contained in:
248
source/lang/evaluator.cpp
Normal file
248
source/lang/evaluator.cpp
Normal file
@@ -0,0 +1,248 @@
|
||||
#include "lang/evaluator.hpp"
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
namespace hex::lang {
|
||||
|
||||
Evaluator::Evaluator() {
|
||||
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createStructPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
std::vector<PatternData*> members;
|
||||
|
||||
auto structNode = static_cast<ASTNodeStruct*>(this->m_types[varDeclNode->getCustomVariableTypeName()]);
|
||||
|
||||
if (structNode == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
size_t structSize = 0;
|
||||
for (const auto &node : structNode->getNodes()) {
|
||||
const auto &member = static_cast<ASTNodeVariableDecl*>(node);
|
||||
|
||||
const auto typeDeclNode = static_cast<ASTNodeTypeDecl*>(this->m_types[member->getCustomVariableTypeName()]);
|
||||
if (typeDeclNode == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
if (member->getVariableType() == Token::TypeToken::Type::Signed8Bit && member->getArraySize() > 1) {
|
||||
const auto &[pattern, size] = this->createStringPattern(member, offset + structSize);
|
||||
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
members.push_back(pattern);
|
||||
structSize += size;
|
||||
} else if (member->getVariableType() == Token::TypeToken::Type::CustomType
|
||||
&& typeDeclNode->getAssignedType() == Token::TypeToken::Type::Signed8Bit
|
||||
&& member->getArraySize() > 1) {
|
||||
|
||||
const auto &[pattern, size] = this->createStringPattern(member, offset + structSize);
|
||||
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
members.push_back(pattern);
|
||||
structSize += size;
|
||||
}
|
||||
else if (member->getArraySize() > 1) {
|
||||
const auto &[pattern, size] = this->createArrayPattern(member, offset + structSize);
|
||||
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
members.push_back(pattern);
|
||||
structSize += size;
|
||||
}
|
||||
else if (member->getVariableType() != Token::TypeToken::Type::CustomType) {
|
||||
const auto &[pattern, size] = this->createBuiltInTypePattern(member, offset + structSize);
|
||||
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
members.push_back(pattern);
|
||||
structSize += size;
|
||||
}
|
||||
else {
|
||||
const auto &[pattern, size] = this->createCustomTypePattern(member, offset + structSize);
|
||||
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
members.push_back(pattern);
|
||||
structSize += size;
|
||||
}
|
||||
}
|
||||
|
||||
return { new PatternDataStruct(offset, structSize, varDeclNode->getVariableName(), structNode->getName(), members, 0x00FFFFFF), structSize };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createEnumPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
std::vector<std::pair<u64, std::string>> enumValues;
|
||||
|
||||
auto *enumType = static_cast<ASTNodeEnum*>(this->m_types[varDeclNode->getCustomVariableTypeName()]);
|
||||
|
||||
if (enumType == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
size_t size = getTypeSize(enumType->getUnderlyingType());
|
||||
|
||||
return { new PatternDataEnum(offset, size, varDeclNode->getVariableName(), enumType->getName(), enumType->getValues()), size };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createArrayPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
std::vector<PatternData*> entries;
|
||||
|
||||
size_t arraySize = 0;
|
||||
for (u32 i = 0; i < varDeclNode->getArraySize(); i++) {
|
||||
ASTNodeVariableDecl *nonArrayVarDeclNode = new ASTNodeVariableDecl(varDeclNode->getVariableType(), "[" + std::to_string(i) + "]", varDeclNode->getCustomVariableTypeName(), varDeclNode->getOffset(), 1);
|
||||
|
||||
if (varDeclNode->getVariableType() != Token::TypeToken::Type::CustomType) {
|
||||
const auto &[pattern, size] = this->createBuiltInTypePattern(nonArrayVarDeclNode, offset + arraySize);
|
||||
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
entries.push_back(pattern);
|
||||
arraySize += size;
|
||||
} else {
|
||||
const auto &[pattern, size] = this->createCustomTypePattern(nonArrayVarDeclNode, offset + arraySize);
|
||||
|
||||
if (pattern == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
entries.push_back(pattern);
|
||||
arraySize += size;
|
||||
}
|
||||
|
||||
delete nonArrayVarDeclNode;
|
||||
}
|
||||
|
||||
return { new PatternDataArray(offset, arraySize, varDeclNode->getVariableName(), entries, 0x00FFFFFF), arraySize };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createStringPattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
size_t arraySize = varDeclNode->getArraySize();
|
||||
|
||||
return { new PatternDataString(offset, arraySize, varDeclNode->getVariableName()), arraySize };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createCustomTypePattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
auto &currType = this->m_types[varDeclNode->getCustomVariableTypeName()];
|
||||
|
||||
if (currType == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
switch (currType->getType()) {
|
||||
case ASTNode::Type::Struct:
|
||||
return this->createStructPattern(varDeclNode, offset);
|
||||
case ASTNode::Type::Enum:
|
||||
return this->createEnumPattern(varDeclNode, offset);
|
||||
case ASTNode::Type::TypeDecl:
|
||||
return this->createBuiltInTypePattern(varDeclNode, offset);
|
||||
}
|
||||
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
|
||||
std::pair<PatternData*, size_t> Evaluator::createBuiltInTypePattern(ASTNodeVariableDecl *varDeclNode, u64 offset) {
|
||||
auto type = varDeclNode->getVariableType();
|
||||
if (type == Token::TypeToken::Type::CustomType) {
|
||||
const auto &currType = static_cast<ASTNodeTypeDecl*>(this->m_types[varDeclNode->getCustomVariableTypeName()]);
|
||||
if (currType == nullptr)
|
||||
return { nullptr, 0 };
|
||||
|
||||
type = currType->getAssignedType();
|
||||
}
|
||||
|
||||
size_t typeSize = getTypeSize(type);
|
||||
size_t arraySize = varDeclNode->getArraySize();
|
||||
|
||||
if (isSigned(type)) {
|
||||
if (typeSize == 1 && arraySize == 1)
|
||||
return { new PatternDataCharacter(offset, typeSize, varDeclNode->getVariableName()), 1 };
|
||||
else if (arraySize > 1)
|
||||
return createArrayPattern(varDeclNode, offset);
|
||||
else
|
||||
return { new PatternDataSigned(offset, typeSize, varDeclNode->getVariableName()), typeSize * arraySize };
|
||||
} else if (isUnsigned(varDeclNode->getVariableType())) {
|
||||
if (arraySize > 1)
|
||||
return createArrayPattern(varDeclNode, offset);
|
||||
else
|
||||
return { new PatternDataUnsigned(offset, typeSize, varDeclNode->getVariableName()), typeSize * arraySize };
|
||||
} else if (isFloatingPoint(varDeclNode->getVariableType())) {
|
||||
if (arraySize > 1)
|
||||
return createArrayPattern(varDeclNode, offset);
|
||||
else
|
||||
return { new PatternDataFloat(offset, typeSize, varDeclNode->getVariableName()), typeSize * arraySize };
|
||||
}
|
||||
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
|
||||
std::pair<Result, std::vector<PatternData*>> Evaluator::evaluate(const std::vector<ASTNode *> &ast) {
|
||||
|
||||
// Evaluate types
|
||||
for (const auto &node : ast) {
|
||||
|
||||
switch(node->getType()) {
|
||||
case ASTNode::Type::Struct:
|
||||
{
|
||||
auto *structNode = static_cast<ASTNodeStruct*>(node);
|
||||
this->m_types.emplace(structNode->getName(), structNode);
|
||||
}
|
||||
break;
|
||||
case ASTNode::Type::Enum:
|
||||
{
|
||||
auto *enumNode = static_cast<ASTNodeEnum*>(node);
|
||||
this->m_types.emplace(enumNode->getName(), enumNode);
|
||||
}
|
||||
break;
|
||||
case ASTNode::Type::TypeDecl:
|
||||
{
|
||||
auto *typeDeclNode = static_cast<ASTNodeTypeDecl*>(node);
|
||||
|
||||
if (typeDeclNode->getAssignedType() == Token::TypeToken::Type::CustomType)
|
||||
this->m_types.emplace(typeDeclNode->getTypeName(), this->m_types[typeDeclNode->getAssignedCustomTypeName()]);
|
||||
else
|
||||
this->m_types.emplace(typeDeclNode->getTypeName(), typeDeclNode);
|
||||
}
|
||||
break;
|
||||
case ASTNode::Type::VariableDecl: break;
|
||||
case ASTNode::Type::Scope: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Evaluate variable declarations
|
||||
|
||||
std::vector<PatternData*> variables;
|
||||
for (const auto &node : ast) {
|
||||
if (node->getType() != ASTNode::Type::VariableDecl)
|
||||
continue;
|
||||
|
||||
auto *varDeclNode = static_cast<ASTNodeVariableDecl*>(node);
|
||||
|
||||
if (varDeclNode->getVariableType() == Token::TypeToken::Type::Signed8Bit && varDeclNode->getArraySize() > 1) {
|
||||
const auto &[pattern, _] = createStringPattern(varDeclNode, varDeclNode->getOffset().value());
|
||||
variables.push_back(pattern);
|
||||
}
|
||||
else if (varDeclNode->getArraySize() > 1) {
|
||||
const auto &[pattern, _] = this->createArrayPattern(varDeclNode, varDeclNode->getOffset().value());
|
||||
variables.push_back(pattern);
|
||||
|
||||
} else if (varDeclNode->getVariableType() != Token::TypeToken::Type::CustomType) {
|
||||
const auto &[pattern, _] = this->createBuiltInTypePattern(varDeclNode, varDeclNode->getOffset().value());
|
||||
variables.push_back(pattern);
|
||||
} else {
|
||||
const auto &[pattern, _] = this->createCustomTypePattern(varDeclNode, varDeclNode->getOffset().value());
|
||||
variables.push_back(pattern);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &var : variables)
|
||||
if (var == nullptr)
|
||||
return { ResultEvaluatorError, { } };
|
||||
|
||||
return { ResultSuccess, variables };
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "window.hpp"
|
||||
|
||||
#include "views/pattern_data.hpp"
|
||||
#include "lang/pattern_data.hpp"
|
||||
#include "views/view_hexeditor.hpp"
|
||||
#include "views/view_pattern.hpp"
|
||||
#include "views/view_pattern_data.hpp"
|
||||
@@ -18,7 +18,7 @@ int main() {
|
||||
hex::Window window;
|
||||
|
||||
// Shared Data
|
||||
std::vector<hex::PatternData*> patternData;
|
||||
std::vector<hex::lang::PatternData*> patternData;
|
||||
hex::prv::Provider *dataProvider = nullptr;
|
||||
|
||||
// Create views
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewHexEditor::ViewHexEditor(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
||||
ViewHexEditor::ViewHexEditor(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData)
|
||||
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
|
||||
this->m_memoryEditor.ReadFn = [](const ImU8 *data, size_t off) -> ImU8 {
|
||||
@@ -36,12 +36,12 @@ namespace hex {
|
||||
ViewHexEditor *_this = (ViewHexEditor *) data;
|
||||
|
||||
for (auto& pattern : _this->m_patternData) {
|
||||
if (next && off == (pattern->getOffset() + pattern->getSize())) {
|
||||
if (next && pattern->highlightBytes(off - 1) != pattern->highlightBytes(off)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (off >= pattern->getOffset() && off < (pattern->getOffset() + pattern->getSize())) {
|
||||
_this->m_memoryEditor.HighlightColor = pattern->getColor();
|
||||
if (auto color = pattern->highlightBytes(off); color.has_value()) {
|
||||
_this->m_memoryEditor.HighlightColor = color.value();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@
|
||||
#include "lang/parser.hpp"
|
||||
#include "lang/lexer.hpp"
|
||||
#include "lang/validator.hpp"
|
||||
#include "lang/evaluator.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewPattern::ViewPattern(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
||||
ViewPattern::ViewPattern(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData)
|
||||
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
|
||||
this->m_buffer = new char[0xFF'FFFF];
|
||||
@@ -84,16 +85,12 @@ namespace hex {
|
||||
}
|
||||
|
||||
|
||||
void ViewPattern::addPatternData(PatternData *patternData) {
|
||||
this->m_patternData.push_back(patternData);
|
||||
}
|
||||
|
||||
void ViewPattern::clearPatternData() {
|
||||
for (auto &data : this->m_patternData)
|
||||
delete data;
|
||||
|
||||
this->m_patternData.clear();
|
||||
PatternData::resetPalette();
|
||||
lang::PatternData::resetPalette();
|
||||
}
|
||||
|
||||
template<std::derived_from<lang::ASTNode> T>
|
||||
@@ -108,10 +105,11 @@ namespace hex {
|
||||
}
|
||||
|
||||
void ViewPattern::parsePattern(char *buffer) {
|
||||
static hex::lang::Preprocessor preprocessor;
|
||||
static hex::lang::Lexer lexer;
|
||||
static hex::lang::Parser parser;
|
||||
static hex::lang::Validator validator;
|
||||
hex::lang::Preprocessor preprocessor;
|
||||
hex::lang::Lexer lexer;
|
||||
hex::lang::Parser parser;
|
||||
hex::lang::Validator validator;
|
||||
hex::lang::Evaluator evaluator;
|
||||
|
||||
this->clearPatternData();
|
||||
this->postEvent(Events::PatternChanged);
|
||||
@@ -127,275 +125,23 @@ namespace hex {
|
||||
|
||||
auto [parseResult, ast] = parser.parse(tokens);
|
||||
if (parseResult.failed()) {
|
||||
for(auto &node : ast) delete node;
|
||||
return;
|
||||
}
|
||||
|
||||
hex::ScopeExit deleteAst([&ast]{ for(auto &node : ast) delete node; });
|
||||
|
||||
auto validatorResult = validator.validate(ast);
|
||||
if (!validatorResult) {
|
||||
for(auto &node : ast) delete node;
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto &varNode : findNodes<lang::ASTNodeVariableDecl>(lang::ASTNode::Type::VariableDecl, ast)) {
|
||||
if (!varNode->getOffset().has_value())
|
||||
continue;
|
||||
|
||||
u64 offset = varNode->getOffset().value();
|
||||
if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = getTypeSize(varNode->getVariableType()) * varNode->getArraySize();
|
||||
|
||||
if (isUnsigned(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, varNode->getVariableName()));
|
||||
else if (isSigned(varNode->getVariableType())) {
|
||||
if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() == 1)
|
||||
this->addPatternData(new PatternDataCharacter(offset, size, varNode->getVariableName()));
|
||||
else if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() > 1)
|
||||
this->addPatternData(new PatternDataString(offset, size, varNode->getVariableName()));
|
||||
else
|
||||
this->addPatternData(new PatternDataSigned(offset, size, varNode->getVariableName()));
|
||||
}
|
||||
else if (isFloatingPoint(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, varNode->getVariableName()));
|
||||
} else {
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == structNode->getName()) {
|
||||
for (u32 i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string name = varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightStruct(ast, structNode, offset, name); size == -1)
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == enumNode->getName()) {
|
||||
for (u32 i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string name = varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightEnum(ast, enumNode, offset, name); size == -1)
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &usingNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (varNode->getCustomVariableTypeName() == usingNode->getTypeName()) {
|
||||
for (u32 i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string name = varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
name += "[" + std::to_string(varNode->getArraySize()) + "]";
|
||||
|
||||
if (size_t size = this->highlightUsingDecls(ast, usingNode, varNode, offset, name); size == -1)
|
||||
this->clearPatternData();
|
||||
else
|
||||
offset += size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto [evaluateResult, patternData] = evaluator.evaluate(ast);
|
||||
if (evaluateResult.failed()) {
|
||||
return;
|
||||
}
|
||||
this->m_patternData = patternData;
|
||||
|
||||
for(auto &node : ast) delete node;
|
||||
this->postEvent(Events::PatternChanged);
|
||||
}
|
||||
|
||||
s32 ViewPattern::highlightUsingDecls(std::vector<lang::ASTNode*> &ast, lang::ASTNodeTypeDecl* currTypeDeclNode, lang::ASTNodeVariableDecl* currVarDecl, u64 offset, std::string name) {
|
||||
u64 startOffset = offset;
|
||||
|
||||
if (currTypeDeclNode->getAssignedType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = (static_cast<u32>(currTypeDeclNode->getAssignedType()) >> 4);
|
||||
|
||||
if (isUnsigned(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, name));
|
||||
else if (isSigned(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataSigned(offset, size, name));
|
||||
else if (isFloatingPoint(currTypeDeclNode->getAssignedType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, name));
|
||||
|
||||
offset += size;
|
||||
} else {
|
||||
bool foundType = false;
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (structNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
for (size_t i = 0; i < currVarDecl->getArraySize(); i++) {
|
||||
size_t size = this->highlightStruct(ast, structNode, offset, name);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (enumNode->getName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
for (size_t i = 0; i < currVarDecl->getArraySize(); i++) {
|
||||
size_t size = this->highlightEnum(ast, enumNode, offset, name);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (typeDeclNode->getTypeName() == currTypeDeclNode->getAssignedCustomTypeName()) {
|
||||
for (size_t i = 0; i < currVarDecl->getArraySize(); i++) {
|
||||
size_t size = this->highlightUsingDecls(ast, typeDeclNode, currVarDecl, offset, name);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundType)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return offset - startOffset;
|
||||
}
|
||||
|
||||
s32 ViewPattern::highlightStruct(std::vector<lang::ASTNode*> &ast, lang::ASTNodeStruct* currStructNode, u64 offset, std::string name) {
|
||||
u64 startOffset = offset;
|
||||
|
||||
for (auto &node : currStructNode->getNodes()) {
|
||||
auto varNode = static_cast<lang::ASTNodeVariableDecl*>(node);
|
||||
|
||||
if (varNode->getVariableType() != lang::Token::TypeToken::Type::CustomType) {
|
||||
size_t size = (static_cast<u32>(varNode->getVariableType()) >> 4);
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
if (isUnsigned(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataUnsigned(offset, size, memberName));
|
||||
else if (isSigned(varNode->getVariableType())) {
|
||||
if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() == 1)
|
||||
this->addPatternData(new PatternDataCharacter(offset, size, memberName));
|
||||
else if (getTypeSize(varNode->getVariableType()) == 1 && varNode->getArraySize() > 1) {
|
||||
this->addPatternData(new PatternDataString(offset, size * varNode->getArraySize(), name + "." + varNode->getVariableName()));
|
||||
offset += size * varNode->getArraySize();
|
||||
break;
|
||||
}
|
||||
else
|
||||
this->addPatternData(new PatternDataSigned(offset, size, memberName));
|
||||
}
|
||||
else if (isFloatingPoint(varNode->getVariableType()))
|
||||
this->addPatternData(new PatternDataFloat(offset, size, memberName));
|
||||
|
||||
offset += size;
|
||||
}
|
||||
} else {
|
||||
bool foundType = false;
|
||||
for (auto &structNode : findNodes<lang::ASTNodeStruct>(lang::ASTNode::Type::Struct, ast)) {
|
||||
if (structNode->getName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightStruct(ast, structNode, offset, memberName);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &enumNode : findNodes<lang::ASTNodeEnum>(lang::ASTNode::Type::Enum, ast)) {
|
||||
if (enumNode->getName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightEnum(ast, enumNode, offset, memberName);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &typeDeclNode : findNodes<lang::ASTNodeTypeDecl>(lang::ASTNode::Type::TypeDecl, ast)) {
|
||||
if (typeDeclNode->getTypeName() == varNode->getCustomVariableTypeName()) {
|
||||
for (size_t i = 0; i < varNode->getArraySize(); i++) {
|
||||
std::string memberName = name + "." + varNode->getVariableName();
|
||||
if (varNode->getArraySize() > 1)
|
||||
memberName += "[" + std::to_string(i) + "]";
|
||||
|
||||
size_t size = this->highlightUsingDecls(ast, typeDeclNode, varNode, offset, memberName);
|
||||
|
||||
if (size == -1)
|
||||
return -1;
|
||||
|
||||
offset += size;
|
||||
}
|
||||
|
||||
foundType = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!foundType)
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return offset - startOffset;
|
||||
}
|
||||
|
||||
s32 ViewPattern::highlightEnum(std::vector<lang::ASTNode*> &ast, lang::ASTNodeEnum* currEnumNode, u64 offset, std::string name) {
|
||||
if (!isUnsigned(currEnumNode->getUnderlyingType()))
|
||||
return -1;
|
||||
|
||||
s32 size = static_cast<u32>(currEnumNode->getUnderlyingType()) >> 4;
|
||||
|
||||
if (size > 8)
|
||||
return -1;
|
||||
|
||||
this->addPatternData(new PatternDataEnum(offset, size, name, currEnumNode->getName(), currEnumNode->getValues()));
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,10 +1,11 @@
|
||||
#include "views/view_pattern_data.hpp"
|
||||
|
||||
#include "providers/provider.hpp"
|
||||
#include "lang/pattern_data.hpp"
|
||||
|
||||
namespace hex {
|
||||
|
||||
ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector<hex::PatternData*> &patternData)
|
||||
ViewPatternData::ViewPatternData(prv::Provider* &dataProvider, std::vector<lang::PatternData*> &patternData)
|
||||
: View(), m_dataProvider(dataProvider), m_patternData(patternData) {
|
||||
|
||||
this->subscribeEvent(Events::PatternChanged, [this](auto data) {
|
||||
@@ -25,85 +26,10 @@ namespace hex {
|
||||
|
||||
if (this->m_dataProvider != nullptr && this->m_dataProvider->isReadable()) {
|
||||
|
||||
if (ImGui::BeginTable("##patterndatatable", 6, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg)) {
|
||||
ImGui::TableSetupColumn("Color", 0, -1, ImGui::GetID("color"));
|
||||
ImGui::TableSetupColumn("Name", 0, -1, ImGui::GetID("name"));
|
||||
ImGui::TableSetupColumn("Position", 0, -1, ImGui::GetID("position"));
|
||||
ImGui::TableSetupColumn("Size", 0, -1, ImGui::GetID("size"));
|
||||
ImGui::TableSetupColumn("Type", 0, -1, ImGui::GetID("type"));
|
||||
ImGui::TableSetupColumn("Value", 0, -1, ImGui::GetID("value"));
|
||||
|
||||
auto sortSpecs = ImGui::TableGetSortSpecs();
|
||||
|
||||
if (sortSpecs->SpecsDirty || this->m_sortedPatternData.empty()) {
|
||||
this->m_sortedPatternData = this->m_patternData;
|
||||
|
||||
std::sort(this->m_sortedPatternData.begin(), this->m_sortedPatternData.end(), [this, &sortSpecs](PatternData* left, PatternData* right) -> bool {
|
||||
if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("name")) {
|
||||
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
|
||||
return left->getName() > right->getName();
|
||||
else
|
||||
return left->getName() < right->getName();
|
||||
}
|
||||
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("position")) {
|
||||
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
|
||||
return left->getOffset() > right->getOffset();
|
||||
else
|
||||
return left->getOffset() < right->getOffset();
|
||||
}
|
||||
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("size")) {
|
||||
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
|
||||
return left->getSize() > right->getSize();
|
||||
else
|
||||
return left->getSize() < right->getSize();
|
||||
}
|
||||
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("value")) {
|
||||
size_t biggerSize = std::max(left->getSize(), right->getSize());
|
||||
std::vector<u8> leftBuffer(biggerSize, 0x00), rightBuffer(biggerSize, 0x00);
|
||||
|
||||
this->m_dataProvider->read(left->getOffset(), leftBuffer.data(), left->getSize());
|
||||
this->m_dataProvider->read(right->getOffset(), rightBuffer.data(), right->getSize());
|
||||
|
||||
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
|
||||
return leftBuffer > rightBuffer;
|
||||
else
|
||||
return leftBuffer < rightBuffer;
|
||||
}
|
||||
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("type")) {
|
||||
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
|
||||
return left->getTypeName() > right->getTypeName();
|
||||
else
|
||||
return left->getTypeName() < right->getTypeName();
|
||||
}
|
||||
else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("color")) {
|
||||
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
|
||||
return left->getColor() > right->getColor();
|
||||
else
|
||||
return left->getColor() < right->getColor();
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
sortSpecs->SpecsDirty = false;
|
||||
}
|
||||
|
||||
ImGui::TableHeadersRow();
|
||||
if (lang::PatternData::beginPatternDataTable(this->m_dataProvider, this->m_patternData, this->m_sortedPatternData)) {
|
||||
u32 rowCount = 0;
|
||||
for (auto& patternData : this->m_sortedPatternData) {
|
||||
ImGui::TableNextRow(ImGuiTableRowFlags_Headers);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::ColorButton("color", ImColor(patternData->getColor()), ImGuiColorEditFlags_NoTooltip);
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", patternData->getName().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("0x%08lx : 0x%08lx", patternData->getOffset(), patternData->getOffset() + patternData->getSize());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("0x%08lx", patternData->getSize());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", patternData->getTypeName().c_str());
|
||||
ImGui::TableNextColumn();
|
||||
ImGui::Text("%s", patternData->format(this->m_dataProvider).c_str());
|
||||
patternData->createEntry(this->m_dataProvider);
|
||||
ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, ((rowCount % 2) == 0) ? 0xFF101010 : 0xFF303030);
|
||||
rowCount++;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user