feat: Look for custom inspector entries in imhex/scripts/inspectors

This commit is contained in:
WerWolv
2022-10-02 14:18:40 +02:00
parent 0fd7461266
commit 6a07a2f85d
5 changed files with 64 additions and 60 deletions

View File

@@ -1,5 +1,7 @@
#pragma once
#include <hex.hpp>
#include <optional>
#include <string>
#include <vector>
@@ -84,8 +86,8 @@ namespace hex::fs {
void setFileBrowserErrorCallback(const std::function<void()> &callback);
bool openFileBrowser(DialogMode mode, const std::vector<nfdfilteritem_t> &validExtensions, const std::function<void(std::fs::path)> &callback, const std::string &defaultPath = {});
enum class ImHexPath {
Patterns,
enum class ImHexPath : u32 {
Patterns = 0,
PatternsInclude,
Magic,
Python,
@@ -96,7 +98,11 @@ namespace hex::fs {
Constants,
Encodings,
Logs,
Recent
Recent,
Scripts,
Inspectors,
END
};
std::optional<std::fs::path> getExecutablePath();

View File

@@ -209,6 +209,8 @@ namespace hex::fs {
std::vector<std::fs::path> result;
switch (path) {
case ImHexPath::END:
return { };
case ImHexPath::Constants:
result = appendPath(getDataPaths(), "constants");
break;
@@ -245,6 +247,12 @@ namespace hex::fs {
case ImHexPath::Recent:
result = appendPath(getConfigPaths(), "recent");
break;
case ImHexPath::Scripts:
result = appendPath(getDataPaths(), "scripts");
break;
case ImHexPath::Inspectors:
result = appendPath(getDefaultPaths(ImHexPath::Scripts), "inspectors");
break;
}
if (!listNonExisting) {

View File

@@ -61,20 +61,6 @@ namespace hex::init {
bool result = true;
using enum fs::ImHexPath;
constexpr std::array paths = {
Patterns,
PatternsInclude,
Magic,
Plugins,
Resources,
Config,
Constants,
Yara,
Encodings,
Python,
Logs,
Recent
};
// Check if ImHex is installed in portable mode
{
@@ -87,8 +73,8 @@ namespace hex::init {
}
// Create all folders
for (auto path : paths) {
for (auto &folder : fs::getDefaultPaths(path, true)) {
for (u32 path = 0; path < u32(fs::ImHexPath::END); path++) {
for (auto &folder : fs::getDefaultPaths(static_cast<fs::ImHexPath>(path), true)) {
try {
fs::createDirectories(folder);
} catch (...) {

View File

@@ -7,6 +7,8 @@
#include <cstring>
#include <hex/helpers/logger.hpp>
#include <hex/helpers/file.hpp>
#include <pl/pattern_language.hpp>
#include <pl/core/evaluator.hpp>
#include <pl/patterns/pattern.hpp>
@@ -54,17 +56,20 @@ namespace hex::plugin::builtin {
byte ^= 0xFF;
}
InspectorCacheEntry cacheEntry = {
entry.unlocalizedName,
entry.generatorFunction(buffer, this->m_endian, this->m_numberDisplayStyle),
entry.editingFunction,
false
};
this->m_cachedData.push_back(cacheEntry);
this->m_cachedData.push_back({
entry.unlocalizedName,
entry.generatorFunction(buffer, this->m_endian, this->m_numberDisplayStyle),
entry.editingFunction,
false
});
}
// Decode bytes using custom inspectors defined using the pattern language
const std::map<std::string, pl::core::Token::Literal> inVariables = {
{ "numberDisplayStyle", u128(this->m_numberDisplayStyle) }
};
pl::PatternLanguage runtime;
ContentRegistry::PatternLanguage::configureRuntime(runtime, nullptr);
@@ -81,43 +86,42 @@ namespace hex::plugin::builtin {
runtime.setDefaultEndian(this->m_endian);
runtime.setStartAddress(this->m_startAddress);
std::map<std::string, pl::core::Token::Literal> inVariables = {
{ "numberDisplayStyle", u128(this->m_numberDisplayStyle) }
};
for (const auto &folderPath : fs::getDefaultPaths(fs::ImHexPath::Inspectors)) {
for (const auto &filePath : std::fs::recursive_directory_iterator(folderPath)) {
if (!filePath.exists() || !filePath.is_regular_file() || filePath.path().extension() != ".hexpat")
continue;
bool ranSuccessfully = false;
for (const auto &path : fs::getDefaultPaths(fs::ImHexPath::Config)) {
auto inspectorFilePath = path / "inspectors.hexpat";
fs::File file(filePath, fs::File::Mode::Read);
if (file.isValid()) {
auto inspectorCode = file.readString();
if (fs::exists(inspectorFilePath) && fs::isRegularFile(inspectorFilePath)) {
ranSuccessfully = runtime.executeFile(inspectorFilePath, {}, inVariables, true);
break;
}
}
if (!inspectorCode.empty()) {
if (runtime.executeString(inspectorCode, {}, inVariables, true)) {
const auto &patterns = runtime.getAllPatterns();
if (ranSuccessfully) {
const auto &patterns = runtime.getAllPatterns();
for (const auto &pattern : patterns) {
if (pattern->isHidden())
continue;
for (const auto &pattern : patterns) {
InspectorCacheEntry cacheEntry = {
pattern->getDisplayName(),
[value = pattern->getFormattedValue()]() {
ImGui::TextUnformatted(value.c_str());
return value;
},
std::nullopt,
false
};
this->m_cachedData.push_back({
pattern->getDisplayName(),
[value = pattern->getFormattedValue()]() {
ImGui::TextUnformatted(value.c_str());
return value;
},
std::nullopt,
false
});
}
} else {
const auto& error = runtime.getError();
this->m_cachedData.push_back(cacheEntry);
}
} else {
const auto& error = runtime.getError();
if (error.has_value()) {
log::error("Failed to execute inspectors.hexpat:\n {}", error.value().what());
} else {
log::error("Failed to execute inspectors.hexpat");
log::error("Failed to execute inspectors.hexpat!");
if (error.has_value())
log::error("{}", error.value().what());
}
}
}
}
}
}