summaryrefslogtreecommitdiff
path: root/DevTools/HackStudio
diff options
context:
space:
mode:
authorFalseHonesty <thefalsehonesty@gmail.com>2020-05-31 22:51:12 -0400
committerAndreas Kling <kling@serenityos.org>2020-06-03 08:12:50 +0200
commitf958c693eeefa9a5acd7716099b9814a1aa7a922 (patch)
treed4f4afa5734b7c86d8ba97f2d370e9c455611ecd /DevTools/HackStudio
parenta4f23429aaf88a419d6cf4278f2ef49f1ff75ca1 (diff)
downloadserenity-f958c693eeefa9a5acd7716099b9814a1aa7a922.zip
HackStudio: Support debugging variables with Enum types
Variables with enum types can now be both viewed and modified in the variables view!
Diffstat (limited to 'DevTools/HackStudio')
-rw-r--r--DevTools/HackStudio/Debugger/DebugInfoWidget.cpp2
-rw-r--r--DevTools/HackStudio/Debugger/VariablesModel.cpp43
2 files changed, 35 insertions, 10 deletions
diff --git a/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp b/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp
index 199f8d85cf..7ef5299dac 100644
--- a/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp
+++ b/DevTools/HackStudio/Debugger/DebugInfoWidget.cpp
@@ -71,7 +71,7 @@ DebugInfoWidget::DebugInfoWidget()
auto* variable = static_cast<const DebugInfo::VariableInfo*>(index.internal_data());
if (variable->location_type != DebugInfo::VariableInfo::LocationType::Address)
return false;
- return variable->type.is_one_of("int", "bool");
+ return variable->is_enum_type() || variable->type_name.is_one_of("int", "bool");
};
m_variables_view->on_context_menu_request = [this, is_valid_index](auto& index, auto& event) {
diff --git a/DevTools/HackStudio/Debugger/VariablesModel.cpp b/DevTools/HackStudio/Debugger/VariablesModel.cpp
index 35e382e465..b5351724f5 100644
--- a/DevTools/HackStudio/Debugger/VariablesModel.cpp
+++ b/DevTools/HackStudio/Debugger/VariablesModel.cpp
@@ -75,36 +75,61 @@ String variable_value_as_string(const DebugInfo::VariableInfo& variable)
auto variable_address = variable.location_data.address;
- if (variable.type == "int") {
+ if (variable.is_enum_type()) {
+ auto value = Debugger::the().session()->peek((u32*)variable_address);
+ ASSERT(value.has_value());
+ auto it = variable.type->members.find([enumerator_value = value.value()](auto& enumerator) {
+ return enumerator->constant_data.as_u32 == enumerator_value;
+ });
+ ASSERT(!it.is_end());
+ return String::format("%s::%s", variable.type_name.characters(), (*it)->name.characters());
+ }
+
+ if (variable.type_name == "int") {
auto value = Debugger::the().session()->peek((u32*)variable_address);
ASSERT(value.has_value());
return String::format("%d", static_cast<int>(value.value()));
}
- if (variable.type == "char") {
+ if (variable.type_name == "char") {
auto value = Debugger::the().session()->peek((u32*)variable_address);
ASSERT(value.has_value());
return String::format("'%c' (%d)", static_cast<char>(value.value()), static_cast<char>(value.value()));
}
- if (variable.type == "bool") {
+ if (variable.type_name == "bool") {
auto value = Debugger::the().session()->peek((u32*)variable_address);
ASSERT(value.has_value());
return (value.value() & 1) ? "true" : "false";
}
- return String::format("type: %s @ %08x, ", variable.type.characters(), variable_address);
+ return String::format("type: %s @ %08x, ", variable.type_name.characters(), variable_address);
}
-static Optional<u32> string_to_value_of_type(const StringView& string_value, const StringView& type)
+static Optional<u32> string_to_variable_value(const StringView& string_value, const DebugInfo::VariableInfo& variable)
{
- if (type == "int") {
+ if (variable.is_enum_type()) {
+ auto prefix_string = String::format("%s::", variable.type_name.characters());
+ auto string_to_use = string_value;
+ if (string_value.starts_with(prefix_string))
+ string_to_use = string_value.substring_view(prefix_string.length(), string_value.length() - prefix_string.length());
+
+ auto it = variable.type->members.find([string_to_use](auto& enumerator) {
+ return enumerator->name == string_to_use;
+ });
+
+ if (it.is_end())
+ return {};
+ return (*it)->constant_data.as_u32;
+ }
+
+ if (variable.type_name == "int") {
bool success = false;
auto value = string_value.to_int(success);
return success ? value : Optional<u32>();
}
- if (type == "bool") {
+ if (variable.type_name == "bool") {
if (string_value == "true")
return true;
if (string_value == "false")
@@ -119,7 +144,7 @@ void VariablesModel::set_variable_value(const GUI::ModelIndex& index, const Stri
{
auto variable = static_cast<const DebugInfo::VariableInfo*>(index.internal_data());
- auto value = string_to_value_of_type(string_value, variable->type);
+ auto value = string_to_variable_value(string_value, *variable);
if (value.has_value()) {
auto success = Debugger::the().session()->poke((u32*)variable->location_data.address, value.value());
@@ -128,7 +153,7 @@ void VariablesModel::set_variable_value(const GUI::ModelIndex& index, const Stri
}
GUI::MessageBox::show(
- String::format("String value \"%s\" could not be converted to a value of type %s.", string_value.to_string().characters(), variable->type.characters()),
+ String::format("String value \"%s\" could not be converted to a value of type %s.", string_value.to_string().characters(), variable->type_name.characters()),
"Set value failed",
GUI::MessageBox::Type::Error,
GUI::MessageBox::InputType::OK,