patterns: Added std::env and ability to pass parameters to patterns from the UI

This commit is contained in:
WerWolv
2021-12-10 11:55:27 +01:00
parent 6a0ad22774
commit 8f2e382c8a
8 changed files with 133 additions and 8 deletions

View File

@@ -51,7 +51,7 @@ namespace hex::plugin::builtin {
/* assert(condition, message) */
ContentRegistry::PatternLanguageFunctions::add(nsStd, "assert", 2, [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
auto condition = Token::literalToBoolean(params[0]);
auto message = std::get<std::string>(params[1]);
auto message = Token::literalToString(params[1], false);
if (!condition)
LogConsole::abortEvaluation(hex::format("assertion failed \"{0}\"", message));
@@ -62,7 +62,7 @@ namespace hex::plugin::builtin {
/* assert_warn(condition, message) */
ContentRegistry::PatternLanguageFunctions::add(nsStd, "assert_warn", 2, [](auto *ctx, auto params) -> std::optional<Token::Literal> {
auto condition = Token::literalToBoolean(params[0]);
auto message = std::get<std::string>(params[1]);
auto message = Token::literalToString(params[1], false);
if (!condition)
ctx->getConsole().log(LogConsole::Level::Warning, hex::format("assertion failed \"{0}\"", message));
@@ -82,6 +82,13 @@ namespace hex::plugin::builtin {
return format(ctx, params);
});
/* env(name) */
ContentRegistry::PatternLanguageFunctions::add(nsStd, "env", 1, [](Evaluator *ctx, auto params) -> std::optional<Token::Literal> {
auto name = Token::literalToString(params[0], false);
return ctx->getEnvVariable(name);
});
}
ContentRegistry::PatternLanguageFunctions::Namespace nsStdMem = { "std", "mem" };

View File

@@ -88,6 +88,8 @@ namespace hex::plugin::builtin {
this->m_textEditor.SetLanguageDefinition(PatternLanguage());
this->m_textEditor.SetShowWhitespaces(false);
this->m_envVarEntries = { { "", s128(0), EnvVarType::Integer } };
EventManager::subscribe<EventProjectFileStore>(this, [this]() {
ProjectFile::setPattern(this->m_textEditor.GetText());
});
@@ -284,6 +286,71 @@ namespace hex::plugin::builtin {
this->m_patternLanguageRuntime->getMaximumPatternCount()
).c_str()
);
ImGui::SameLine();
if (ImGui::IconButton(ICON_VS_GLOBE, ImGui::GetStyleColorVec4(ImGuiCol_Text)))
ImGui::OpenPopup("env_vars");
if (ImGui::BeginPopup("env_vars")) {
ImGui::TextUnformatted("Environment Variables");
ImGui::SameLine();
if (ImGui::IconButton(ICON_VS_ADD, ImGui::GetStyleColorVec4(ImGuiCol_Text))) this->m_envVarEntries.push_back({ "", s128(0), EnvVarType::Integer });
ImGui::Separator();
int index = 0;
for (auto &[name, value, type] : this->m_envVarEntries) {
ImGui::PushID(index++);
ImGui::PushItemWidth(ImGui::GetTextLineHeightWithSpacing() * 2);
constexpr const char* Types[] = { "I", "F", "S", "B" };
if (ImGui::BeginCombo("", Types[static_cast<int>(type)])) {
for (auto i = 0; i < IM_ARRAYSIZE(Types); i++) {
if (ImGui::Selectable(Types[i]))
type = static_cast<EnvVarType>(i);
}
ImGui::EndCombo();
}
ImGui::PopItemWidth();
ImGui::SameLine();
ImGui::InputText("###name", name.data(), name.capacity(), ImGuiInputTextFlags_CallbackResize, ImGui::UpdateStringSizeCallback, &name);
ImGui::SameLine();
switch (type) {
case EnvVarType::Integer: {
s64 displayValue = hex::get_or<s128>(value, 0);
ImGui::InputScalar("###value", ImGuiDataType_S64, &displayValue);
value = s128(displayValue);
break;
}
case EnvVarType::Float: {
auto displayValue = hex::get_or<double>(value, 0.0);
ImGui::InputDouble("###value", &displayValue);
value = displayValue;
break;
}
case EnvVarType::Bool: {
auto displayValue = hex::get_or<bool>(value, false);
ImGui::Checkbox("###value", &displayValue);
value = displayValue;
break;
}
case EnvVarType::String: {
auto displayValue = hex::get_or<std::string>(value, "");
ImGui::InputText("###value", displayValue.data(), displayValue.capacity(), ImGuiInputTextFlags_CallbackResize, ImGui::UpdateStringSizeCallback, &displayValue);
value = displayValue;
break;
}
}
ImGui::PopID();
}
ImGui::EndPopup();
}
}
if (this->m_textEditor.IsTextChanged()) {
@@ -418,7 +485,11 @@ namespace hex::plugin::builtin {
EventManager::post<EventPatternChanged>();
std::thread([this, buffer = std::string(buffer)] {
auto result = this->m_patternLanguageRuntime->executeString(ImHexApi::Provider::get(), buffer);
std::map<std::string, pl::Token::Literal> envVars;
for (const auto &[name, value, type] : this->m_envVarEntries)
envVars.insert({ name, value });
auto result = this->m_patternLanguageRuntime->executeString(ImHexApi::Provider::get(), buffer, envVars);
auto error = this->m_patternLanguageRuntime->getError();
if (error.has_value()) {