mirror of https://github.com/WerWolv/ImHex
Fix segfault when opening recent file with pattern sync; Don't show p… (#2448)
…attern selection popup when pattern is already open This PR does two things. Most importantly, it fixes a segfault that can be caused by opening a recent file with pattern sync enabled. Secondly, it makes it so that the pattern selection popup does not appear if you already have text in the pattern editor for a given provider (due to CLI args, a project file, pattern sync, etc.). If you open a file normally, that text field is empty and the popup will appear so you can select a pre-made pattern like usual.
This commit is contained in:
parent
f08b182bf2
commit
67efea6444
|
|
@ -40,8 +40,12 @@ namespace hex::plugin::builtin {
|
|||
return &m_editorRuntime;
|
||||
}
|
||||
|
||||
ui::TextEditor &getTextEditor() {
|
||||
return m_textEditor;
|
||||
ui::TextEditor *getTextEditor() {
|
||||
auto provider = ImHexApi::Provider::get();
|
||||
if (provider == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return &m_textEditor.get(provider);
|
||||
}
|
||||
|
||||
bool getChangesWereParsed() const {
|
||||
|
|
|
|||
|
|
@ -1252,7 +1252,11 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
}
|
||||
}
|
||||
m_viewPatternEditor->getTextEditor().setErrorMarkers(errorMarkers);
|
||||
ui::TextEditor *editor = m_viewPatternEditor->getTextEditor();
|
||||
if (editor != nullptr)
|
||||
editor->setErrorMarkers(errorMarkers);
|
||||
else
|
||||
log::warn("Text editor not found, provider is null");
|
||||
}
|
||||
|
||||
// creates a map from variable names to a vector of token indices
|
||||
|
|
@ -1590,7 +1594,11 @@ namespace hex::plugin::builtin {
|
|||
lineOfColors[tokenOffset + j] = color;
|
||||
}
|
||||
}
|
||||
m_viewPatternEditor->getTextEditor().setColorizedLine(line, lineOfColors);
|
||||
ui::TextEditor *editor = m_viewPatternEditor->getTextEditor();
|
||||
if (editor != nullptr)
|
||||
editor->setColorizedLine(line, lineOfColors);
|
||||
else
|
||||
log::warn("Text editor not found, provider is null");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1918,8 +1926,13 @@ namespace hex::plugin::builtin {
|
|||
if (!m_lines.empty())
|
||||
m_lines.clear();
|
||||
|
||||
if (m_text.empty())
|
||||
m_text = m_viewPatternEditor->getTextEditor().getText();
|
||||
if (m_text.empty()) {
|
||||
ui::TextEditor *editor = m_viewPatternEditor->getTextEditor();
|
||||
if (editor != nullptr)
|
||||
m_text = editor->getText();
|
||||
else
|
||||
log::warn("Text editor not found, provider is null");
|
||||
}
|
||||
|
||||
m_lines = wolv::util::splitString(m_text, "\n");
|
||||
m_lines.push_back("");
|
||||
|
|
@ -2248,72 +2261,85 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
};
|
||||
try {
|
||||
m_runningColorizers++;
|
||||
auto preprocessor = patternLanguage->get()->getInternals().preprocessor.get();
|
||||
auto parser = patternLanguage->get()->getInternals().parser.get();
|
||||
using Types = std::map<std::string, pl::hlp::safe_shared_ptr<pl::core::ast::ASTNodeTypeDecl>>;
|
||||
Types types = parser->getTypes();
|
||||
m_runningColorizers++;
|
||||
auto preprocessor = patternLanguage->get()->getInternals().preprocessor.get();
|
||||
auto parser = patternLanguage->get()->getInternals().parser.get();
|
||||
using Types = std::map<std::string, pl::hlp::safe_shared_ptr<pl::core::ast::ASTNodeTypeDecl>>;
|
||||
Types types = parser->getTypes();
|
||||
|
||||
if (!m_UDTs.empty())
|
||||
m_UDTs.clear();
|
||||
for (auto &[name, type]: types)
|
||||
m_UDTs.push_back(name);
|
||||
if (!m_UDTs.empty())
|
||||
m_UDTs.clear();
|
||||
for (auto &[name, type]: types)
|
||||
m_UDTs.push_back(name);
|
||||
|
||||
// Namespaces from included files.
|
||||
m_nameSpaces.clear();
|
||||
m_nameSpaces = preprocessor->getNamespaces();
|
||||
clearVariables();
|
||||
// Namespaces from included files.
|
||||
m_nameSpaces.clear();
|
||||
m_nameSpaces = preprocessor->getNamespaces();
|
||||
clearVariables();
|
||||
|
||||
m_parsedImports = preprocessor->getParsedImports();
|
||||
for (auto &[name, tokens]: m_parsedImports) {
|
||||
m_tokens = tokens;
|
||||
m_text = tokens[0].location.source->content;
|
||||
if (m_text.empty() || m_text == "\n")
|
||||
return;
|
||||
loadText();
|
||||
processSource();
|
||||
if (!m_tokenColors.empty())
|
||||
m_tokenColors.clear();
|
||||
}
|
||||
|
||||
m_tokens = preprocessor->getResult();
|
||||
if (m_tokens.empty())
|
||||
return;
|
||||
|
||||
if (!m_globalTokenRange.empty())
|
||||
m_globalTokenRange.clear();
|
||||
m_globalTokenRange.insert(Interval(0, m_tokens.size()-1));
|
||||
|
||||
ui::TextEditor *editor = m_viewPatternEditor->getTextEditor();
|
||||
if (editor != nullptr)
|
||||
m_text = editor->getText();
|
||||
else
|
||||
log::warn("Text editor not found, provider is null");
|
||||
|
||||
m_parsedImports = preprocessor->getParsedImports();
|
||||
for (auto &[name, tokens]: m_parsedImports) {
|
||||
m_tokens = tokens;
|
||||
m_text = tokens[0].location.source->content;
|
||||
if (m_text.empty() || m_text == "\n")
|
||||
return;
|
||||
loadText();
|
||||
processSource();
|
||||
if (!m_tokenColors.empty())
|
||||
m_tokenColors.clear();
|
||||
}
|
||||
|
||||
m_tokens = preprocessor->getResult();
|
||||
if (m_tokens.empty())
|
||||
return;
|
||||
getAllTokenRanges(IdentifierType::NameSpace);
|
||||
getAllTokenRanges(IdentifierType::UDT);
|
||||
getAllTokenRanges(IdentifierType::Function);
|
||||
getGlobalTokenRanges();
|
||||
fixGlobalVariables();
|
||||
setInitialColors();
|
||||
loadInstances();
|
||||
getAllTokenRanges(IdentifierType::Attribute);
|
||||
getDefinitions();
|
||||
fixAutos();
|
||||
fixChains();
|
||||
|
||||
if (!m_globalTokenRange.empty())
|
||||
m_globalTokenRange.clear();
|
||||
m_globalTokenRange.insert(Interval(0, m_tokens.size()-1));
|
||||
m_excludedLocations = preprocessor->getExcludedLocations();
|
||||
|
||||
m_text = m_viewPatternEditor->getTextEditor().getText();
|
||||
colorRemainingIdentifierTokens();
|
||||
setRequestedIdentifierColors();
|
||||
|
||||
if (m_text.empty() || m_text == "\n")
|
||||
return;
|
||||
loadText();
|
||||
editor = m_viewPatternEditor->getTextEditor();
|
||||
if (editor != nullptr)
|
||||
editor->clearErrorMarkers();
|
||||
else
|
||||
log::warn("Text editor not found, provider is null");
|
||||
m_compileErrors = patternLanguage->get()->getCompileErrors();
|
||||
|
||||
getAllTokenRanges(IdentifierType::NameSpace);
|
||||
getAllTokenRanges(IdentifierType::UDT);
|
||||
getAllTokenRanges(IdentifierType::Function);
|
||||
getGlobalTokenRanges();
|
||||
fixGlobalVariables();
|
||||
setInitialColors();
|
||||
loadInstances();
|
||||
getAllTokenRanges(IdentifierType::Attribute);
|
||||
getDefinitions();
|
||||
fixAutos();
|
||||
fixChains();
|
||||
|
||||
m_excludedLocations = preprocessor->getExcludedLocations();
|
||||
|
||||
colorRemainingIdentifierTokens();
|
||||
setRequestedIdentifierColors();
|
||||
|
||||
m_viewPatternEditor->getTextEditor().clearErrorMarkers();
|
||||
m_compileErrors = patternLanguage->get()->getCompileErrors();
|
||||
|
||||
if (!m_compileErrors.empty())
|
||||
renderErrors();
|
||||
else
|
||||
m_viewPatternEditor->getTextEditor().clearErrorMarkers();
|
||||
if (!m_compileErrors.empty())
|
||||
renderErrors();
|
||||
else {
|
||||
editor = m_viewPatternEditor->getTextEditor();
|
||||
if (editor != nullptr)
|
||||
editor->clearErrorMarkers();
|
||||
else
|
||||
log::warn("Text editor not found, provider is null");
|
||||
}
|
||||
} catch (const std::out_of_range &e) {
|
||||
log::debug("TextHighlighter::highlightSourceCode: Out of range error: {}", e.what());
|
||||
m_wasInterrupted = true;
|
||||
|
|
@ -2321,4 +2347,4 @@ namespace hex::plugin::builtin {
|
|||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@
|
|||
#include <fonts/fonts.hpp>
|
||||
#include <hex/api/events/requests_gui.hpp>
|
||||
#include <hex/helpers/menu_items.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
|
||||
namespace hex::plugin::builtin {
|
||||
|
||||
|
|
@ -70,6 +71,16 @@ namespace hex::plugin::builtin {
|
|||
return;
|
||||
}
|
||||
|
||||
ui::TextEditor *editor = m_view->getTextEditor();
|
||||
if (editor != nullptr) {
|
||||
if (!editor->isEmpty()) {
|
||||
this->close();
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
log::warn("Text editor not found, provider is null");
|
||||
}
|
||||
|
||||
ImGuiExt::TextFormattedWrapped("{}", static_cast<const char *>("hex.builtin.view.pattern_editor.accept_pattern.desc"_lang));
|
||||
|
||||
if (ImGui::BeginListBox("##patterns_accept", ImVec2(400_scaled, 0))) {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include <ui/text_editor.hpp>
|
||||
#include <hex/helpers/utils.hpp>
|
||||
#include <hex/helpers/logger.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
namespace hex::ui {
|
||||
|
|
@ -50,8 +51,11 @@ namespace hex::ui {
|
|||
|
||||
std::smatch results;
|
||||
std::string id;
|
||||
if (m_languageDefinition.m_tokenize == nullptr)
|
||||
if (m_languageDefinition.m_tokenize == nullptr) {
|
||||
m_languageDefinition.m_tokenize = [](strConstIter, strConstIter, strConstIter &, strConstIter &, PaletteIndex &) { return false; };
|
||||
log::warn("Syntax highlighting tokenize callback is nullptr");
|
||||
return;
|
||||
}
|
||||
i32 linesSize = m_lines.size();
|
||||
for (i32 i = 0; i < linesSize; ++i) {
|
||||
auto &line = m_lines[i];
|
||||
|
|
@ -74,28 +78,11 @@ namespace hex::ui {
|
|||
PaletteIndex token_color = PaletteIndex::Default;
|
||||
|
||||
bool hasTokenizeResult = m_languageDefinition.m_tokenize(current.m_charsIter, last.m_charsIter, token_begin, token_end, token_color);
|
||||
auto token_offset = token_begin - first.m_charsIter;
|
||||
|
||||
if (!hasTokenizeResult) {
|
||||
// todo : remove
|
||||
// printf("using regex for %.*s\n", first + 10 < last ? 10 : i32(last - first), first);
|
||||
|
||||
for (auto &p: m_regexList) {
|
||||
if (std::regex_search(first.m_charsIter, last.m_charsIter, results, p.first, std::regex_constants::match_continuous)) {
|
||||
hasTokenizeResult = true;
|
||||
|
||||
const auto &v = results.begin();
|
||||
token_begin = v->first;
|
||||
token_end = v->second;
|
||||
token_color = p.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasTokenizeResult)
|
||||
current = current + 1;
|
||||
else {
|
||||
auto token_offset = token_begin - first.m_charsIter;
|
||||
current = first + token_offset;
|
||||
u64 token_length = 0;
|
||||
Line::Flags flags(0);
|
||||
|
|
@ -1181,4 +1168,4 @@ namespace hex::ui {
|
|||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue