mirror of
https://github.com/WerWolv/ImHex.git
synced 2026-03-30 05:05:19 -05:00
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <pl/pattern_language.hpp>
|
||||
#include <pl/core/errors/error.hpp>
|
||||
#include <pl/core/lexer.hpp>
|
||||
|
||||
#include <ui/hex_editor.hpp>
|
||||
#include <ui/pattern_drawer.hpp>
|
||||
@@ -350,26 +351,51 @@ namespace hex::plugin::builtin {
|
||||
}
|
||||
}
|
||||
|
||||
auto createRuntime = [this, provider] {
|
||||
auto runtime = std::make_shared<pl::PatternLanguage>();
|
||||
ContentRegistry::PatternLanguage::configureRuntime(*runtime, provider);
|
||||
|
||||
return runtime;
|
||||
};
|
||||
|
||||
ui::PopupNamedFileChooser::open(
|
||||
basePaths, paths, std::vector<hex::fs::ItemFilter>{ { "Pattern File", "hexpat" } }, false,
|
||||
[this, provider](const std::fs::path &path, const std::fs::path &adjustedPath) mutable -> std::string {
|
||||
auto it = m_patternNames.find(path);
|
||||
if (it != m_patternNames.end()) {
|
||||
[this, provider, runtime = createRuntime()](const std::fs::path &path, const std::fs::path &adjustedPath) mutable -> std::string {
|
||||
if (auto it = m_patternNames.find(path); it != m_patternNames.end()) {
|
||||
return it->second;
|
||||
}
|
||||
|
||||
const auto fileName = wolv::util::toUTF8String(adjustedPath.filename());
|
||||
m_patternNames[path] = fileName;
|
||||
|
||||
pl::PatternLanguage runtime;
|
||||
ContentRegistry::PatternLanguage::configureRuntime(runtime, provider);
|
||||
runtime.addPragma("description", [&](pl::PatternLanguage &, const std::string &value) -> bool {
|
||||
m_patternNames[path] = hex::format("{} ({})", value, fileName);
|
||||
return true;
|
||||
});
|
||||
|
||||
wolv::io::File file(path, wolv::io::File::Mode::Read);
|
||||
std::ignore = runtime.preprocessString(file.readString(), pl::api::Source::DefaultSource);
|
||||
pl::api::Source source(file.readString());
|
||||
|
||||
// Only run the lexer on the source file and manually extract the #pragma description to make this
|
||||
// process as fast as possible. Running the preprocessor directly takes too much time
|
||||
auto result = runtime->getInternals().lexer->lex(&source);
|
||||
if (result.isOk()) {
|
||||
const auto tokens = result.unwrap();
|
||||
for (auto it = tokens.begin(); it != tokens.end(); ++it) {
|
||||
if (it->type == pl::core::Token::Type::Directive && std::get<pl::core::Token::Directive>(it->value) == pl::core::Token::Directive::Pragma) {
|
||||
++it;
|
||||
if (it != tokens.end() && it->type == pl::core::Token::Type::String) {
|
||||
auto literal = std::get<pl::core::Token::Literal>(it->value);
|
||||
auto string = std::get_if<std::string>(&literal);
|
||||
if (string != nullptr && *string == "description") {
|
||||
++it;
|
||||
if (it != tokens.end() && it->type == pl::core::Token::Type::String) {
|
||||
literal = std::get<pl::core::Token::Literal>(it->value);
|
||||
string = std::get_if<std::string>(&literal);
|
||||
if (string != nullptr) {
|
||||
m_patternNames[path] = hex::format("{} ({})", *string, fileName);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return m_patternNames[path];
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user