patterns: Use standalone pattern language library instead of built-in one

This commit is contained in:
WerWolv
2022-04-17 16:57:30 +02:00
parent f5fe49923b
commit 17383083fb
92 changed files with 416 additions and 8336 deletions

View File

@@ -3,11 +3,12 @@
#include <hex/helpers/fmt.hpp>
#include <hex/helpers/net.hpp>
#include <hex/helpers/file.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/pattern_language/token.hpp>
#include <hex/pattern_language/log_console.hpp>
#include <hex/pattern_language/evaluator.hpp>
#include <hex/pattern_language/patterns/pattern.hpp>
#include <pl/token.hpp>
#include <pl/log_console.hpp>
#include <pl/evaluator.hpp>
#include <pl/patterns/pattern.hpp>
#include <vector>
@@ -15,7 +16,7 @@
namespace hex::plugin::builtin {
std::string format(pl::Evaluator *ctx, const auto &params) {
std::string format(const auto &params) {
auto format = pl::Token::literalToString(params[0], true);
std::string message;
@@ -26,7 +27,7 @@ namespace hex::plugin::builtin {
std::visit(overloaded {
[&](pl::Pattern *value) {
formatArgs.push_back(value->toString(ctx->getProvider()));
formatArgs.push_back(value->toString());
},
[&](auto &&value) {
formatArgs.push_back(value);
@@ -37,32 +38,30 @@ namespace hex::plugin::builtin {
try {
return fmt::vformat(format, formatArgs);
} catch (fmt::format_error &error) {
hex::pl::LogConsole::abortEvaluation(hex::format("format error: {}", error.what()));
pl::LogConsole::abortEvaluation(hex::format("format error: {}", error.what()));
}
}
void registerPatternLanguageFunctions() {
using namespace hex::pl;
using ParameterCount = ContentRegistry::PatternLanguage::ParameterCount;
using namespace pl;
using FunctionParameterCount = pl::api::FunctionParameterCount;
ContentRegistry::PatternLanguage::addColorPalette("hex.builtin.palette.pastel", { 0x70B4771F, 0x700E7FFF, 0x702CA02C, 0x702827D6, 0x70BD6794, 0x704B568C, 0x70C277E3, 0x707F7F7F, 0x7022BDBC, 0x70CFBE17 });
ContentRegistry::PatternLanguage::Namespace nsStd = { "builtin", "std" };
pl::api::Namespace nsStd = { "builtin", "std" };
{
/* print(format, args...) */
ContentRegistry::PatternLanguage::addFunction(nsStd, "print", ParameterCount::moreThan(0), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ctx->getConsole().log(LogConsole::Level::Info, format(ctx, params));
ContentRegistry::PatternLanguage::addFunction(nsStd, "print", FunctionParameterCount::moreThan(0), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ctx->getConsole().log(LogConsole::Level::Info, format(params));
return std::nullopt;
});
/* format(format, args...) */
ContentRegistry::PatternLanguage::addFunction(nsStd, "format", ParameterCount::moreThan(0), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
return format(ctx, params);
ContentRegistry::PatternLanguage::addFunction(nsStd, "format", FunctionParameterCount::moreThan(0), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return format(params);
});
/* env(name) */
ContentRegistry::PatternLanguage::addFunction(nsStd, "env", ParameterCount::exactly(1), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStd, "env", FunctionParameterCount::exactly(1), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
auto name = Token::literalToString(params[0], false);
auto env = ctx->getEnvVariable(name);
@@ -75,44 +74,44 @@ namespace hex::plugin::builtin {
});
/* pack_size(...) */
ContentRegistry::PatternLanguage::addFunction(nsStd, "sizeof_pack", ParameterCount::atLeast(0), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStd, "sizeof_pack", FunctionParameterCount::atLeast(0), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return u128(params.size());
});
/* error(message) */
ContentRegistry::PatternLanguage::addFunction(nsStd, "error", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStd, "error", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
LogConsole::abortEvaluation(Token::literalToString(params[0], true));
return std::nullopt;
});
/* warning(message) */
ContentRegistry::PatternLanguage::addFunction(nsStd, "warning", ParameterCount::exactly(1), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStd, "warning", FunctionParameterCount::exactly(1), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ctx->getConsole().log(LogConsole::Level::Warning, Token::literalToString(params[0], true));
return std::nullopt;
});
}
ContentRegistry::PatternLanguage::Namespace nsStdMem = { "builtin", "std", "mem" };
api::Namespace nsStdMem = { "builtin", "std", "mem" };
{
/* base_address() */
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "base_address", ParameterCount::none(), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "base_address", FunctionParameterCount::none(), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
hex::unused(params);
return u128(ctx->getProvider()->getBaseAddress());
return u128(ctx->getDataBaseAddress());
});
/* size() */
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "size", ParameterCount::none(), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "size", FunctionParameterCount::none(), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
hex::unused(params);
return u128(ctx->getProvider()->getActualSize());
return u128(ctx->getDataSize());
});
/* find_sequence_in_range(occurrence_index, start_offset, end_offset, bytes...) */
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "find_sequence_in_range", ParameterCount::moreThan(3), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "find_sequence_in_range", FunctionParameterCount::moreThan(3), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
auto occurrenceIndex = Token::literalToUnsigned(params[0]);
auto offsetFrom = Token::literalToUnsigned(params[1]);
auto offsetTo = Token::literalToUnsigned(params[2]);
@@ -129,10 +128,10 @@ namespace hex::plugin::builtin {
std::vector<u8> bytes(sequence.size(), 0x00);
u32 occurrences = 0;
const u64 bufferSize = ctx->getProvider()->getSize();
const u64 bufferSize = ctx->getDataSize();
const u64 endOffset = offsetTo <= offsetFrom ? bufferSize : std::min(bufferSize, u64(offsetTo));
for (u64 offset = offsetFrom; offset < endOffset - sequence.size(); offset++) {
ctx->getProvider()->read(offset, bytes.data(), bytes.size());
ctx->readData(offset, bytes.data(), bytes.size());
if (bytes == sequence) {
if (occurrences < occurrenceIndex) {
@@ -148,7 +147,7 @@ namespace hex::plugin::builtin {
});
/* read_unsigned(address, size) */
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "read_unsigned", ParameterCount::exactly(2), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "read_unsigned", FunctionParameterCount::exactly(2), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
auto address = Token::literalToUnsigned(params[0]);
auto size = Token::literalToUnsigned(params[1]);
@@ -156,13 +155,13 @@ namespace hex::plugin::builtin {
LogConsole::abortEvaluation("read size out of range");
u128 result = 0;
ctx->getProvider()->read(address, &result, size);
ctx->readData(address, &result, size);
return result;
});
/* read_signed(address, size) */
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "read_signed", ParameterCount::exactly(2), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "read_signed", FunctionParameterCount::exactly(2), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
auto address = Token::literalToUnsigned(params[0]);
auto size = Token::literalToUnsigned(params[1]);
@@ -170,33 +169,33 @@ namespace hex::plugin::builtin {
LogConsole::abortEvaluation("read size out of range");
i128 value;
ctx->getProvider()->read(address, &value, size);
ctx->readData(address, &value, size);
return hex::signExtend(size * 8, value);
});
/* read_string(address, size) */
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "read_string", ParameterCount::exactly(2), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMem, "read_string", FunctionParameterCount::exactly(2), [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
auto address = Token::literalToUnsigned(params[0]);
auto size = Token::literalToUnsigned(params[1]);
std::string result(size, '\x00');
ctx->getProvider()->read(address, result.data(), size);
ctx->readData(address, result.data(), size);
return result;
});
}
ContentRegistry::PatternLanguage::Namespace nsStdString = { "builtin", "std", "string" };
api::Namespace nsStdString = { "builtin", "std", "string" };
{
/* length(string) */
ContentRegistry::PatternLanguage::addFunction(nsStdString, "length", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdString, "length", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
auto string = Token::literalToString(params[0], false);
return u128(string.length());
});
/* at(string, index) */
ContentRegistry::PatternLanguage::addFunction(nsStdString, "at", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdString, "at", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
auto string = Token::literalToString(params[0], false);
auto index = Token::literalToSigned(params[1]);
@@ -217,7 +216,7 @@ namespace hex::plugin::builtin {
});
/* substr(string, pos, count) */
ContentRegistry::PatternLanguage::addFunction(nsStdString, "substr", ParameterCount::exactly(3), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdString, "substr", FunctionParameterCount::exactly(3), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
auto string = Token::literalToString(params[0], false);
auto pos = Token::literalToUnsigned(params[1]);
auto size = Token::literalToUnsigned(params[2]);
@@ -229,7 +228,7 @@ namespace hex::plugin::builtin {
});
/* parse_int(string, base) */
ContentRegistry::PatternLanguage::addFunction(nsStdString, "parse_int", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdString, "parse_int", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
auto string = Token::literalToString(params[0], false);
auto base = Token::literalToUnsigned(params[1]);
@@ -237,17 +236,17 @@ namespace hex::plugin::builtin {
});
/* parse_float(string) */
ContentRegistry::PatternLanguage::addFunction(nsStdString, "parse_float", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdString, "parse_float", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
auto string = Token::literalToString(params[0], false);
return double(std::strtod(string.c_str(), nullptr));
});
}
ContentRegistry::PatternLanguage::Namespace nsStdHttp = { "builtin", "std", "http" };
api::Namespace nsStdHttp = { "builtin", "std", "http" };
{
/* get(url) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdHttp, "get", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdHttp, "get", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto url = Token::literalToString(params[0], false);
hex::Net net;
@@ -256,13 +255,13 @@ namespace hex::plugin::builtin {
}
ContentRegistry::PatternLanguage::Namespace nsStdFile = { "builtin", "std", "file" };
api::Namespace nsStdFile = { "builtin", "std", "file" };
{
static u32 fileCounter = 0;
static std::map<u32, fs::File> openFiles;
/* open(path, mode) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "open", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "open", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto path = Token::literalToString(params[0], false);
const auto modeEnum = Token::literalToUnsigned(params[1]);
@@ -293,7 +292,7 @@ namespace hex::plugin::builtin {
});
/* close(file) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "close", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "close", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto file = Token::literalToUnsigned(params[0]);
if (!openFiles.contains(file))
@@ -305,7 +304,7 @@ namespace hex::plugin::builtin {
});
/* read(file, size) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "read", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "read", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto file = Token::literalToUnsigned(params[0]);
const auto size = Token::literalToUnsigned(params[1]);
@@ -316,7 +315,7 @@ namespace hex::plugin::builtin {
});
/* write(file, data) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "write", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "write", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto file = Token::literalToUnsigned(params[0]);
const auto data = Token::literalToString(params[1], true);
@@ -329,7 +328,7 @@ namespace hex::plugin::builtin {
});
/* seek(file, offset) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "seek", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "seek", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto file = Token::literalToUnsigned(params[0]);
const auto offset = Token::literalToUnsigned(params[1]);
@@ -342,7 +341,7 @@ namespace hex::plugin::builtin {
});
/* size(file) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "size", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "size", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto file = Token::literalToUnsigned(params[0]);
if (!openFiles.contains(file))
@@ -352,7 +351,7 @@ namespace hex::plugin::builtin {
});
/* resize(file, size) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "resize", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "resize", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto file = Token::literalToUnsigned(params[0]);
const auto size = Token::literalToUnsigned(params[1]);
@@ -365,7 +364,7 @@ namespace hex::plugin::builtin {
});
/* flush(file) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "flush", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "flush", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto file = Token::literalToUnsigned(params[0]);
if (!openFiles.contains(file))
@@ -377,7 +376,7 @@ namespace hex::plugin::builtin {
});
/* remove(file) */
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "remove", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addDangerousFunction(nsStdFile, "remove", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
const auto file = Token::literalToUnsigned(params[0]);
if (!openFiles.contains(file))
@@ -390,129 +389,129 @@ namespace hex::plugin::builtin {
}
ContentRegistry::PatternLanguage::Namespace nsStdMath = { "builtin", "std", "math" };
api::Namespace nsStdMath = { "builtin", "std", "math" };
{
/* floor(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "floor", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "floor", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::floor(Token::literalToFloatingPoint(params[0]));
});
/* ceil(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "ceil", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "ceil", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::ceil(Token::literalToFloatingPoint(params[0]));
});
/* round(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "round", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "round", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::round(Token::literalToFloatingPoint(params[0]));
});
/* trunc(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "trunc", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "trunc", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::trunc(Token::literalToFloatingPoint(params[0]));
});
/* log10(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "log10", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "log10", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::log10(Token::literalToFloatingPoint(params[0]));
});
/* log2(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "log2", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "log2", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::log2(Token::literalToFloatingPoint(params[0]));
});
/* ln(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "ln", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "ln", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::log(Token::literalToFloatingPoint(params[0]));
});
/* fmod(x, y) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "fmod", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "fmod", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::fmod(Token::literalToFloatingPoint(params[0]), Token::literalToFloatingPoint(params[1]));
});
/* pow(base, exp) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "pow", ParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "pow", FunctionParameterCount::exactly(2), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::pow(Token::literalToFloatingPoint(params[0]), Token::literalToFloatingPoint(params[1]));
});
/* sqrt(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "sqrt", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "sqrt", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::sqrt(Token::literalToFloatingPoint(params[0]));
});
/* cbrt(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "cbrt", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "cbrt", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::cbrt(Token::literalToFloatingPoint(params[0]));
});
/* sin(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "sin", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "sin", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::sin(Token::literalToFloatingPoint(params[0]));
});
/* cos(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "cos", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "cos", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::cos(Token::literalToFloatingPoint(params[0]));
});
/* tan(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "tan", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "tan", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::tan(Token::literalToFloatingPoint(params[0]));
});
/* asin(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "asin", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "asin", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::asin(Token::literalToFloatingPoint(params[0]));
});
/* acos(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "acos", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "acos", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::acos(Token::literalToFloatingPoint(params[0]));
});
/* atan(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "atan", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "atan", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::atan(Token::literalToFloatingPoint(params[0]));
});
/* atan2(y, x) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "atan", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "atan", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::atan2(Token::literalToFloatingPoint(params[0]), Token::literalToFloatingPoint(params[1]));
});
/* sinh(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "sinh", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "sinh", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::sinh(Token::literalToFloatingPoint(params[0]));
});
/* cosh(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "cosh", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "cosh", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::cosh(Token::literalToFloatingPoint(params[0]));
});
/* tanh(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "tanh", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "tanh", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::tanh(Token::literalToFloatingPoint(params[0]));
});
/* asinh(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "asinh", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "asinh", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::asinh(Token::literalToFloatingPoint(params[0]));
});
/* acosh(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "acosh", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "acosh", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::acosh(Token::literalToFloatingPoint(params[0]));
});
/* atanh(value) */
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "atanh", ParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
ContentRegistry::PatternLanguage::addFunction(nsStdMath, "atanh", FunctionParameterCount::exactly(1), [](Evaluator *, auto params) -> std::optional<Token::Literal> {
return std::atanh(Token::literalToFloatingPoint(params[0]));
});
}

View File

@@ -0,0 +1,85 @@
#include <hex/api/content_registry.hpp>
#include <hex/providers/provider.hpp>
#include <pl/evaluator.hpp>
namespace hex::plugin::builtin {
void registerPatternLanguagePragmas() {
ContentRegistry::PatternLanguage::addPragma("endian", [](pl::PatternLanguage &runtime, const std::string &value) {
if (value == "big") {
runtime.getInternals().evaluator->setDefaultEndian(std::endian::big);
return true;
} else if (value == "little") {
runtime.getInternals().evaluator->setDefaultEndian(std::endian::little);
return true;
} else if (value == "native") {
runtime.getInternals().evaluator->setDefaultEndian(std::endian::native);
return true;
} else
return false;
});
ContentRegistry::PatternLanguage::addPragma("eval_depth", [](pl::PatternLanguage &runtime, const std::string &value) {
auto limit = strtol(value.c_str(), nullptr, 0);
if (limit <= 0)
return false;
runtime.getInternals().evaluator->setEvaluationDepth(limit);
return true;
});
ContentRegistry::PatternLanguage::addPragma("array_limit", [](pl::PatternLanguage &runtime, const std::string &value) {
auto limit = strtol(value.c_str(), nullptr, 0);
if (limit <= 0)
return false;
runtime.getInternals().evaluator->setArrayLimit(limit);
return true;
});
ContentRegistry::PatternLanguage::addPragma("pattern_limit", [](pl::PatternLanguage &runtime, const std::string &value) {
auto limit = strtol(value.c_str(), nullptr, 0);
if (limit <= 0)
return false;
runtime.getInternals().evaluator->setPatternLimit(limit);
return true;
});
ContentRegistry::PatternLanguage::addPragma("loop_limit", [](pl::PatternLanguage &runtime, const std::string &value) {
auto limit = strtol(value.c_str(), nullptr, 0);
if (limit <= 0)
return false;
runtime.getInternals().evaluator->setLoopLimit(limit);
return true;
});
ContentRegistry::PatternLanguage::addPragma("base_address", [](pl::PatternLanguage &runtime, const std::string &value) {
hex::unused(runtime);
auto baseAddress = strtoull(value.c_str(), nullptr, 0);
ImHexApi::Provider::get()->setBaseAddress(baseAddress);
return true;
});
ContentRegistry::PatternLanguage::addPragma("bitfield_order", [](pl::PatternLanguage &runtime, const std::string &value) {
if (value == "left_to_right") {
runtime.getInternals().evaluator->setBitfieldOrder(pl::BitfieldOrder::LeftToRight);
return true;
} else if (value == "right_to_left") {
runtime.getInternals().evaluator->setBitfieldOrder(pl::BitfieldOrder::RightToLeft);
return true;
} else {
return false;
}
});
}
}

View File

@@ -133,6 +133,8 @@ namespace hex::plugin::builtin::prv {
#endif
Provider::resize(this->getActualSize());
return true;
}

View File

@@ -264,6 +264,8 @@ namespace hex::plugin::builtin::prv {
}
#endif
Provider::resize(this->getActualSize());
return true;
}

View File

@@ -278,6 +278,8 @@ namespace hex::plugin::builtin::prv {
}
});
Provider::resize(this->getActualSize());
return true;
} else {
return false;

View File

@@ -6,6 +6,7 @@
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
#include <fonts/codicons_font.h>
#include <hex/helpers/utils.hpp>
#include <nlohmann/json.hpp>

View File

@@ -2,8 +2,8 @@
#include <hex/providers/provider.hpp>
#include <hex/pattern_language/pattern_language.hpp>
#include <hex/pattern_language/patterns/pattern.hpp>
#include <pl/pattern_language.hpp>
#include <pl/patterns/pattern.hpp>
namespace hex::plugin::builtin {
@@ -20,6 +20,53 @@ namespace hex::plugin::builtin {
EventManager::unsubscribe<EventHighlightingChanged>(this);
}
static bool sortPatterns(prv::Provider *provider, const ImGuiTableSortSpecs* sortSpecs, const pl::Pattern * left, const pl::Pattern * right) {
if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("name")) {
if (sortSpecs->Specs->SortDirection == ImGuiSortDirection_Ascending)
return left->getDisplayName() > right->getDisplayName();
else
return left->getDisplayName() < right->getDisplayName();
} else if (sortSpecs->Specs->ColumnUserID == ImGui::GetID("offset")) {
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);
provider->read(left->getOffset(), leftBuffer.data(), left->getSize());
provider->read(right->getOffset(), rightBuffer.data(), right->getSize());
if (left->getEndian() != std::endian::native)
std::reverse(leftBuffer.begin(), leftBuffer.end());
if (right->getEndian() != std::endian::native)
std::reverse(rightBuffer.begin(), rightBuffer.end());
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;
}
static bool beginPatternTable(prv::Provider *&provider, const std::vector<std::shared_ptr<pl::Pattern>> &patterns, std::vector<std::shared_ptr<pl::Pattern>> &sortedPatterns) {
if (ImGui::BeginTable("##Patterntable", 6, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Sortable | ImGuiTableFlags_Hideable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | ImGuiTableFlags_ScrollY)) {
ImGui::TableSetupScrollFreeze(0, 1);
@@ -36,11 +83,13 @@ namespace hex::plugin::builtin {
sortedPatterns = patterns;
std::sort(sortedPatterns.begin(), sortedPatterns.end(), [&sortSpecs, &provider](const std::shared_ptr<pl::Pattern> &left, const std::shared_ptr<pl::Pattern> &right) -> bool {
return pl::Pattern::sortPatternTable(sortSpecs, provider, left.get(), right.get());
return sortPatterns(provider, sortSpecs, left.get(), right.get());
});
for (auto &pattern : sortedPatterns)
pattern->sort(sortSpecs, provider);
pattern->sort([&sortSpecs, &provider](const pl::Pattern *left, const pl::Pattern *right){
return sortPatterns(provider, sortSpecs, left, right);
});
sortSpecs->SpecsDirty = false;
}
@@ -61,9 +110,8 @@ namespace hex::plugin::builtin {
ImGui::TableHeadersRow();
if (!sortedPatterns.empty()) {
m_drawer.setProvider(provider);
for (auto &patterns : sortedPatterns)
patterns->accept(m_drawer);
patterns->accept(this->m_patternDrawer);
}
ImGui::EndTable();

View File

@@ -1,12 +1,12 @@
#include "content/views/view_pattern_editor.hpp"
#include <pl/preprocessor.hpp>
#include <pl/patterns/pattern.hpp>
#include <pl/ast/ast_node_variable_decl.hpp>
#include <pl/ast/ast_node_type_decl.hpp>
#include <pl/ast/ast_node_builtin_type.hpp>
#include <hex/pattern_language/preprocessor.hpp>
#include <hex/pattern_language/patterns/pattern.hpp>
#include <hex/pattern_language/ast/ast_node_variable_decl.hpp>
#include <hex/pattern_language/ast/ast_node_type_decl.hpp>
#include <hex/pattern_language/ast/ast_node_builtin_type.hpp>
#include <hex/api/content_registry.hpp>
#include <hex/helpers/fs.hpp>
#include <hex/helpers/utils.hpp>
#include <hex/helpers/file.hpp>
@@ -105,16 +105,18 @@ namespace hex::plugin::builtin {
if (!ContentRegistry::Settings::read("hex.builtin.setting.general", "hex.builtin.setting.general.auto_load_patterns", 1))
return;
pl::Preprocessor preprocessor;
preprocessor.addDefaultPragmaHandlers();
if (!ImHexApi::Provider::isValid())
return;
std::string mimeType = magic::getMIMEType(ImHexApi::Provider::get());
auto provider = ImHexApi::Provider::get();
auto runtime = provider->getPatternLanguageRuntime();
auto mimeType = magic::getMIMEType(ImHexApi::Provider::get());
bool foundCorrectType = false;
preprocessor.addPragmaHandler("MIME", [&mimeType, &foundCorrectType](std::string value) {
runtime.addPragma("MIME", [&mimeType, &foundCorrectType](pl::PatternLanguage &runtime, const std::string &value) {
hex::unused(runtime);
if (value == mimeType) {
foundCorrectType = true;
return true;
@@ -135,13 +137,14 @@ namespace hex::plugin::builtin {
if (!file.isValid())
continue;
preprocessor.preprocess(file.readString());
runtime.getInternals().preprocessor->preprocess(runtime, file.readString());
if (foundCorrectType)
this->m_possiblePatternFiles.push_back(entry.path());
}
}
runtime.removePragma("MIME");
if (!this->m_possiblePatternFiles.empty()) {
this->m_selectedPatternFile = 0;
@@ -329,7 +332,7 @@ namespace hex::plugin::builtin {
}
}
if (provider->getPatternLanguageRuntime().hasDangerousFunctionBeenCalled() && !ImGui::IsPopupOpen(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str())) {
if (this->m_dangerousFunctionCalled && !ImGui::IsPopupOpen(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str())) {
ImGui::OpenPopup(View::toWindowName("hex.builtin.view.pattern_editor.dangerous_function.name").c_str());
}
@@ -339,11 +342,14 @@ namespace hex::plugin::builtin {
ImGui::NewLine();
View::confirmButtons(
"hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang, [] {
ImHexApi::Provider::get()->getPatternLanguageRuntime().allowDangerousFunctions(true);
ImGui::CloseCurrentPopup(); }, [] {
ImHexApi::Provider::get()->getPatternLanguageRuntime().allowDangerousFunctions(false);
ImGui::CloseCurrentPopup(); });
"hex.builtin.common.yes"_lang, "hex.builtin.common.no"_lang,
[this] {
this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Allow;
ImGui::CloseCurrentPopup();
}, [this] {
this->m_dangerousFunctionsAllowed = DangerousFunctionPerms::Deny;
ImGui::CloseCurrentPopup();
});
ImGui::EndPopup();
}
@@ -616,7 +622,6 @@ namespace hex::plugin::builtin {
if (!ImHexApi::Provider::isValid()) return;
ImHexApi::Provider::get()->getPatternLanguageRuntime().reset();
ContentRegistry::PatternLanguage::resetPalette();
}
@@ -679,7 +684,17 @@ namespace hex::plugin::builtin {
auto provider = ImHexApi::Provider::get();
auto &runtime = provider->getPatternLanguageRuntime();
this->m_lastEvaluationResult = runtime.executeString(provider, code, envVars, inVariables);
runtime.setDangerousFunctionCallHandler([this]{
this->m_dangerousFunctionCalled = true;
while (this->m_dangerousFunctionsAllowed == DangerousFunctionPerms::Ask) {
std::this_thread::yield();
}
return this->m_dangerousFunctionsAllowed == DangerousFunctionPerms::Allow;
});
this->m_lastEvaluationResult = runtime.executeString(code, envVars, inVariables);
if (!this->m_lastEvaluationResult) {
this->m_lastEvaluationError = runtime.getError();
}

View File

@@ -1,24 +1,30 @@
#include "pattern_drawer.hpp"
#include <hex/pattern_language/patterns/pattern_array_dynamic.hpp>
#include <hex/pattern_language/patterns/pattern_array_static.hpp>
#include <hex/pattern_language/patterns/pattern_bitfield.hpp>
#include <hex/pattern_language/patterns/pattern_boolean.hpp>
#include <hex/pattern_language/patterns/pattern_character.hpp>
#include <hex/pattern_language/patterns/pattern_enum.hpp>
#include <hex/pattern_language/patterns/pattern_float.hpp>
#include <hex/pattern_language/patterns/pattern_padding.hpp>
#include <hex/pattern_language/patterns/pattern_pointer.hpp>
#include <hex/pattern_language/patterns/pattern_signed.hpp>
#include <hex/pattern_language/patterns/pattern_string.hpp>
#include <hex/pattern_language/patterns/pattern_struct.hpp>
#include <hex/pattern_language/patterns/pattern_union.hpp>
#include <hex/pattern_language/patterns/pattern_unsigned.hpp>
#include <hex/pattern_language/patterns/pattern_wide_character.hpp>
#include <hex/pattern_language/patterns/pattern_wide_string.hpp>
#include <pl/patterns/pattern_array_dynamic.hpp>
#include <pl/patterns/pattern_array_static.hpp>
#include <pl/patterns/pattern_bitfield.hpp>
#include <pl/patterns/pattern_boolean.hpp>
#include <pl/patterns/pattern_character.hpp>
#include <pl/patterns/pattern_enum.hpp>
#include <pl/patterns/pattern_float.hpp>
#include <pl/patterns/pattern_padding.hpp>
#include <pl/patterns/pattern_pointer.hpp>
#include <pl/patterns/pattern_signed.hpp>
#include <pl/patterns/pattern_string.hpp>
#include <pl/patterns/pattern_struct.hpp>
#include <pl/patterns/pattern_union.hpp>
#include <pl/patterns/pattern_unsigned.hpp>
#include <pl/patterns/pattern_wide_character.hpp>
#include <pl/patterns/pattern_wide_string.hpp>
#include <string>
#include <hex/api/imhex_api.hpp>
#include <hex/helpers/utils.hpp>
#include <imgui.h>
#include <hex/ui/imgui_imhex_extensions.h>
namespace {
constexpr static auto DisplayEndDefault = 50u;
constexpr static auto DisplayEndStep = 50u;
@@ -28,14 +34,6 @@ namespace {
namespace hex {
PatternDrawer::PatternDrawer()
: m_provider{nullptr}
{ }
void PatternDrawer::setProvider(prv::Provider *provider) {
m_provider = provider;
}
void PatternDrawer::visit(pl::PatternArrayDynamic& pattern) {
this->drawArray(pattern);
}
@@ -67,12 +65,12 @@ namespace hex {
ImGui::TextFormattedColored(ImColor(0xFF9BC64D), "bits");
ImGui::TableNextColumn();
u64 extractedValue = pattern.getValue(m_provider);
u64 extractedValue = pattern.getValue();
ImGui::TextFormatted("{}", pattern.formatDisplayValue(hex::format("{0} (0x{1:X})", extractedValue, extractedValue), &pattern));
}
void PatternDrawer::visit(pl::PatternBitfield& pattern) {
std::vector<u8> value = pattern.getValue(m_provider);
std::vector<u8> value = pattern.getValue();
bool open = true;
if (!pattern.isInlined()) {
@@ -108,7 +106,7 @@ namespace hex {
}
void PatternDrawer::visit(pl::PatternBoolean& pattern) {
u8 boolean = pattern.getValue(m_provider);
u8 boolean = pattern.getValue();
if (boolean == 0)
this->createDefaultEntry(pattern, "false", false);
@@ -119,12 +117,12 @@ namespace hex {
}
void PatternDrawer::visit(pl::PatternCharacter& pattern) {
char character = pattern.getValue(m_provider);
char character = pattern.getValue();
this->createDefaultEntry(pattern, hex::format("'{0}'", character), character);
}
void PatternDrawer::visit(pl::PatternEnum& pattern) {
u64 value = pattern.getValue(m_provider);
u64 value = pattern.getValue();
std::string valueString = pattern.getTypeName() + "::";
@@ -168,12 +166,12 @@ namespace hex {
void PatternDrawer::visit(pl::PatternFloat& pattern) {
if (pattern.getSize() == 4) {
float f32 = static_cast<float>(pattern.getValue(m_provider));
float f32 = static_cast<float>(pattern.getValue());
u32 integerResult = 0;
std::memcpy(&integerResult, &f32, sizeof(float));
this->createDefaultEntry(pattern, hex::format("{:e} (0x{:0{}X})", f32, integerResult, pattern.getSize() * 2), f32);
} else if (pattern.getSize() == 8) {
double f64 = pattern.getValue(m_provider);
double f64 = pattern.getValue();
u64 integerResult = 0;
std::memcpy(&integerResult, &f64, sizeof(double));
this->createDefaultEntry(pattern, hex::format("{:e} (0x{:0{}X})", f64, integerResult, pattern.getSize() * 2), f64);
@@ -186,7 +184,7 @@ namespace hex {
}
void PatternDrawer::visit(pl::PatternPointer& pattern) {
u64 data = pattern.getValue(m_provider);
u64 data = pattern.getValue();
bool open = true;
@@ -217,7 +215,7 @@ namespace hex {
}
void PatternDrawer::visit(pl::PatternSigned& pattern) {
i128 data = pattern.getValue(m_provider);
i128 data = pattern.getValue();
this->createDefaultEntry(pattern, hex::format("{:d} (0x{:0{}X})", data, data, 1 * 2), data);
}
@@ -227,7 +225,7 @@ namespace hex {
if (size == 0)
return;
std::string displayString = pattern.getValue(m_provider, size);
std::string displayString = pattern.getValue(size);
this->createDefaultEntry(pattern, hex::format("\"{0}\" {1}", displayString, size > pattern.getSize() ? "(truncated)" : ""), displayString);
}
@@ -290,12 +288,12 @@ namespace hex {
}
void PatternDrawer::visit(pl::PatternUnsigned& pattern) {
u128 data = pattern.getValue(m_provider);
u128 data = pattern.getValue();
this->createDefaultEntry(pattern, hex::format("{:d} (0x{:0{}X})", data, data, pattern.getSize() * 2), data);
}
void PatternDrawer::visit(pl::PatternWideCharacter& pattern) {
char16_t character = pattern.getValue(m_provider);
char16_t character = pattern.getValue();
u128 literal = character;
auto str = std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.to_bytes(character);
this->createDefaultEntry(pattern, hex::format("'{0}'", str), literal);
@@ -307,7 +305,7 @@ namespace hex {
if (size == 0)
return;
std::string utf8String = pattern.getValue(m_provider, size);
std::string utf8String = pattern.getValue(size);
this->createDefaultEntry(pattern, hex::format("\"{0}\" {1}", utf8String, size > pattern.getSize() ? "(truncated)" : ""), utf8String);
}

View File

@@ -1,13 +1,12 @@
#include <hex/plugin.hpp>
#include <hex/api/imhex_api.hpp>
namespace hex::plugin::builtin {
void registerViews();
void registerDataInspectorEntries();
void registerToolEntries();
void registerPatternLanguageFunctions();
void registerPatternLanguagePragmas();
void registerCommandPaletteCommands();
void registerSettings();
void registerDataProcessorNodes();
@@ -42,6 +41,7 @@ IMHEX_PLUGIN_SETUP("Built-in", "WerWolv", "Default ImHex functionality") {
registerDataInspectorEntries();
registerToolEntries();
registerPatternLanguageFunctions();
registerPatternLanguagePragmas();
registerCommandPaletteCommands();
registerSettings();
registerDataProcessorNodes();