Debugger: Adapt expression eval users to async interface.
Factor out message constant for expression evaluation completion, as multiple places will be using that. ExpressionEvaluationWindow: - Check for expression match immediately in listener hook, and don't bother dispatching to the message loop in such a case. Simplifies some of the other code. InspectorWindow / WatchPromptWindow: - Rather than attempting to evaluate an expression directly, we now defer to the async interface. Clean up and adjust accordingly. TeamWindow: - Adjust window creation calls due to parameter changes. This leaves only the CLI dump memory command to be adapted.
This commit is contained in:
@@ -69,6 +69,7 @@ enum {
|
|||||||
MSG_EXPRESSION_WINDOW_CLOSED = 'ewwc',
|
MSG_EXPRESSION_WINDOW_CLOSED = 'ewwc',
|
||||||
MSG_INSPECT_ADDRESS = 'isad',
|
MSG_INSPECT_ADDRESS = 'isad',
|
||||||
MSG_EVALUATE_EXPRESSION = 'evex',
|
MSG_EVALUATE_EXPRESSION = 'evex',
|
||||||
|
MSG_EXPRESSION_EVALUATED = 'exev',
|
||||||
MSG_SHOW_TYPECAST_NODE_PROMPT = 'stnp',
|
MSG_SHOW_TYPECAST_NODE_PROMPT = 'stnp',
|
||||||
MSG_TYPECAST_TO_ARRAY = 'stta',
|
MSG_TYPECAST_TO_ARRAY = 'stta',
|
||||||
MSG_TYPECAST_NODE = 'tyno',
|
MSG_TYPECAST_NODE = 'tyno',
|
||||||
|
|||||||
@@ -17,19 +17,20 @@
|
|||||||
#include <TextControl.h>
|
#include <TextControl.h>
|
||||||
|
|
||||||
#include "Architecture.h"
|
#include "Architecture.h"
|
||||||
#include "CLanguageExpressionEvaluator.h"
|
#include "CppLanguage.h"
|
||||||
#include "GuiTeamUiSettings.h"
|
#include "GuiTeamUiSettings.h"
|
||||||
#include "MemoryView.h"
|
#include "MemoryView.h"
|
||||||
#include "MessageCodes.h"
|
#include "MessageCodes.h"
|
||||||
#include "Number.h"
|
#include "Number.h"
|
||||||
#include "Team.h"
|
#include "Team.h"
|
||||||
#include "UserInterface.h"
|
#include "UserInterface.h"
|
||||||
|
#include "Value.h"
|
||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MSG_NAVIGATE_PREVIOUS_BLOCK = 'npbl',
|
MSG_NAVIGATE_PREVIOUS_BLOCK = 'npbl',
|
||||||
MSG_NAVIGATE_NEXT_BLOCK = 'npnl',
|
MSG_NAVIGATE_NEXT_BLOCK = 'npnl',
|
||||||
MSG_MEMORY_BLOCK_RETRIEVED = 'mbre',
|
MSG_MEMORY_BLOCK_RETRIEVED = 'mbre'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -46,8 +47,11 @@ InspectorWindow::InspectorWindow(::Team* team, UserInterfaceListener* listener,
|
|||||||
fCurrentBlock(NULL),
|
fCurrentBlock(NULL),
|
||||||
fCurrentAddress(0LL),
|
fCurrentAddress(0LL),
|
||||||
fTeam(team),
|
fTeam(team),
|
||||||
|
fLanguage(NULL),
|
||||||
fTarget(target)
|
fTarget(target)
|
||||||
{
|
{
|
||||||
|
AutoLocker< ::Team> teamLocker(fTeam);
|
||||||
|
fTeam->AddListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -57,6 +61,12 @@ InspectorWindow::~InspectorWindow()
|
|||||||
fCurrentBlock->RemoveListener(this);
|
fCurrentBlock->RemoveListener(this);
|
||||||
fCurrentBlock->ReleaseReference();
|
fCurrentBlock->ReleaseReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AutoLocker< ::Team> teamLocker(fTeam);
|
||||||
|
fTeam->RemoveListener(this);
|
||||||
|
|
||||||
|
if (fLanguage != NULL)
|
||||||
|
fLanguage->ReleaseReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -80,6 +90,8 @@ InspectorWindow::Create(::Team* team, UserInterfaceListener* listener,
|
|||||||
void
|
void
|
||||||
InspectorWindow::_Init()
|
InspectorWindow::_Init()
|
||||||
{
|
{
|
||||||
|
fLanguage = new CppLanguage();
|
||||||
|
|
||||||
BScrollView* scrollView;
|
BScrollView* scrollView;
|
||||||
|
|
||||||
BMenu* hexMenu = new BMenu("Hex Mode");
|
BMenu* hexMenu = new BMenu("Hex Mode");
|
||||||
@@ -197,45 +209,44 @@ InspectorWindow::MessageReceived(BMessage* message)
|
|||||||
case MSG_INSPECT_ADDRESS:
|
case MSG_INSPECT_ADDRESS:
|
||||||
{
|
{
|
||||||
target_addr_t address = 0;
|
target_addr_t address = 0;
|
||||||
bool addressValid = false;
|
|
||||||
if (message->FindUInt64("address", &address) != B_OK) {
|
if (message->FindUInt64("address", &address) != B_OK) {
|
||||||
CLanguageExpressionEvaluator evaluator;
|
fListener->ExpressionEvaluationRequested(
|
||||||
const char* addressExpression = fAddressInput->Text();
|
fLanguage,
|
||||||
BString errorMessage;
|
fAddressInput->Text(),
|
||||||
try {
|
B_UINT64_TYPE);
|
||||||
Number value;
|
} else
|
||||||
value = evaluator.Evaluate(addressExpression,
|
_SetToAddress(address);
|
||||||
B_INT64_TYPE);
|
|
||||||
address = value.GetValue().ToUInt64();
|
|
||||||
} catch(ParseException parseError) {
|
|
||||||
errorMessage.SetToFormat("Failed to parse address: %s",
|
|
||||||
parseError.message.String());
|
|
||||||
} catch(...) {
|
|
||||||
errorMessage.SetToFormat(
|
|
||||||
"Unknown error while parsing address");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errorMessage.Length() > 0) {
|
|
||||||
BAlert* alert = new(std::nothrow) BAlert("Inspect Address",
|
|
||||||
errorMessage.String(), "Close");
|
|
||||||
if (alert != NULL)
|
|
||||||
alert->Go();
|
|
||||||
} else
|
|
||||||
addressValid = true;
|
|
||||||
} else {
|
|
||||||
addressValid = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addressValid) {
|
|
||||||
fCurrentAddress = address;
|
|
||||||
if (fCurrentBlock == NULL
|
|
||||||
|| !fCurrentBlock->Contains(address)) {
|
|
||||||
fListener->InspectRequested(address, this);
|
|
||||||
} else
|
|
||||||
fMemoryView->SetTargetAddress(fCurrentBlock, address);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MSG_EXPRESSION_EVALUATED:
|
||||||
|
{
|
||||||
|
BString errorMessage;
|
||||||
|
BReference<Value> reference;
|
||||||
|
Value* value = NULL;
|
||||||
|
if (message->FindPointer("value",
|
||||||
|
reinterpret_cast<void**>(&value)) == B_OK) {
|
||||||
|
reference.SetTo(value, true);
|
||||||
|
BVariant variant;
|
||||||
|
value->ToVariant(variant);
|
||||||
|
if (variant.Type() == B_UINT64_TYPE) {
|
||||||
|
_SetToAddress(variant.ToUInt64());
|
||||||
|
break;
|
||||||
|
} else
|
||||||
|
value->ToString(errorMessage);
|
||||||
|
} else {
|
||||||
|
status_t result = message->FindInt32("result");
|
||||||
|
errorMessage.SetToFormat("Failed to evaluate expression: %s",
|
||||||
|
strerror(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
BAlert* alert = new(std::nothrow) BAlert("Inspect Address",
|
||||||
|
errorMessage.String(), "Close");
|
||||||
|
if (alert != NULL)
|
||||||
|
alert->Go();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case MSG_NAVIGATE_PREVIOUS_BLOCK:
|
case MSG_NAVIGATE_PREVIOUS_BLOCK:
|
||||||
case MSG_NAVIGATE_NEXT_BLOCK:
|
case MSG_NAVIGATE_NEXT_BLOCK:
|
||||||
{
|
{
|
||||||
@@ -344,6 +355,32 @@ InspectorWindow::TargetAddressChanged(target_addr_t address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InspectorWindow::ExpressionEvaluated(
|
||||||
|
const Team::ExpressionEvaluationEvent& event)
|
||||||
|
{
|
||||||
|
BMessage message(MSG_EXPRESSION_EVALUATED);
|
||||||
|
AutoLocker<BLooper> lock(this);
|
||||||
|
if (!lock.IsLocked())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event.GetExpression() != fAddressInput->Text())
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock.Unlock();
|
||||||
|
message.AddInt32("result", event.GetResult());
|
||||||
|
Value* value = event.GetValue();
|
||||||
|
BReference<Value> reference;
|
||||||
|
if (value != NULL) {
|
||||||
|
reference.SetTo(value);
|
||||||
|
message.AddPointer("value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PostMessage(&message) == B_OK)
|
||||||
|
reference.Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
InspectorWindow::LoadSettings(const GuiTeamUiSettings& settings)
|
InspectorWindow::LoadSettings(const GuiTeamUiSettings& settings)
|
||||||
{
|
{
|
||||||
@@ -432,3 +469,15 @@ InspectorWindow::_SaveMenuFieldMode(BMenuField* field, const char* name,
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
InspectorWindow::_SetToAddress(target_addr_t address)
|
||||||
|
{
|
||||||
|
fCurrentAddress = address;
|
||||||
|
if (fCurrentBlock == NULL
|
||||||
|
|| !fCurrentBlock->Contains(address)) {
|
||||||
|
fListener->InspectRequested(address, this);
|
||||||
|
} else
|
||||||
|
fMemoryView->SetTargetAddress(fCurrentBlock, address);
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011-2013, Rene Gollent, [email protected]. All rights reserved.
|
* Copyright 2011-2014, Rene Gollent, [email protected]. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef INSPECTOR_WINDOW_H
|
#ifndef INSPECTOR_WINDOW_H
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
#include "MemoryView.h"
|
#include "MemoryView.h"
|
||||||
|
#include "Team.h"
|
||||||
#include "TeamMemoryBlock.h"
|
#include "TeamMemoryBlock.h"
|
||||||
#include "Types.h"
|
#include "Types.h"
|
||||||
|
|
||||||
@@ -18,13 +19,14 @@ class BMenuField;
|
|||||||
class BMessenger;
|
class BMessenger;
|
||||||
class BTextControl;
|
class BTextControl;
|
||||||
class GuiTeamUiSettings;
|
class GuiTeamUiSettings;
|
||||||
class Team;
|
class SourceLanguage;
|
||||||
class UserInterfaceListener;
|
class UserInterfaceListener;
|
||||||
|
|
||||||
|
|
||||||
class InspectorWindow : public BWindow,
|
class InspectorWindow : public BWindow,
|
||||||
public TeamMemoryBlock::Listener,
|
public TeamMemoryBlock::Listener,
|
||||||
public MemoryView::Listener {
|
public MemoryView::Listener,
|
||||||
|
private Team::Listener {
|
||||||
public:
|
public:
|
||||||
InspectorWindow(::Team* team,
|
InspectorWindow(::Team* team,
|
||||||
UserInterfaceListener* listener,
|
UserInterfaceListener* listener,
|
||||||
@@ -47,10 +49,16 @@ public:
|
|||||||
// MemoryView::Listener
|
// MemoryView::Listener
|
||||||
virtual void TargetAddressChanged(target_addr_t address);
|
virtual void TargetAddressChanged(target_addr_t address);
|
||||||
|
|
||||||
|
// Team::Listener
|
||||||
|
virtual void ExpressionEvaluated(
|
||||||
|
const Team::ExpressionEvaluationEvent&
|
||||||
|
event);
|
||||||
|
|
||||||
status_t LoadSettings(
|
status_t LoadSettings(
|
||||||
const GuiTeamUiSettings& settings);
|
const GuiTeamUiSettings& settings);
|
||||||
status_t SaveSettings(
|
status_t SaveSettings(
|
||||||
BMessage& settings);
|
BMessage& settings);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _Init();
|
void _Init();
|
||||||
|
|
||||||
@@ -61,6 +69,8 @@ private:
|
|||||||
const char* name,
|
const char* name,
|
||||||
BMessage& settings);
|
BMessage& settings);
|
||||||
|
|
||||||
|
void _SetToAddress(target_addr_t address);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UserInterfaceListener* fListener;
|
UserInterfaceListener* fListener;
|
||||||
BTextControl* fAddressInput;
|
BTextControl* fAddressInput;
|
||||||
@@ -73,6 +83,7 @@ private:
|
|||||||
TeamMemoryBlock* fCurrentBlock;
|
TeamMemoryBlock* fCurrentBlock;
|
||||||
target_addr_t fCurrentAddress;
|
target_addr_t fCurrentAddress;
|
||||||
::Team* fTeam;
|
::Team* fTeam;
|
||||||
|
SourceLanguage* fLanguage;
|
||||||
BHandler* fTarget;
|
BHandler* fTarget;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -21,8 +21,7 @@
|
|||||||
|
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
MSG_CHANGE_EVALUATION_TYPE = 'chet',
|
MSG_CHANGE_EVALUATION_TYPE = 'chet'
|
||||||
MSG_EXPRESSION_EVALUATED = 'exev'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@@ -164,9 +163,16 @@ ExpressionEvaluationWindow::ExpressionEvaluated(
|
|||||||
const Team::ExpressionEvaluationEvent& event)
|
const Team::ExpressionEvaluationEvent& event)
|
||||||
{
|
{
|
||||||
BMessage message(MSG_EXPRESSION_EVALUATED);
|
BMessage message(MSG_EXPRESSION_EVALUATED);
|
||||||
message.AddString("expression", event.GetExpression());
|
|
||||||
message.AddInt32("result", event.GetResult());
|
|
||||||
|
|
||||||
|
AutoLocker<BLooper> lock(this);
|
||||||
|
if (!lock.IsLocked())
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (event.GetExpression() != fExpressionInput->Text())
|
||||||
|
return;
|
||||||
|
|
||||||
|
lock.Unlock();
|
||||||
|
message.AddInt32("result", event.GetResult());
|
||||||
BReference<Value> reference;
|
BReference<Value> reference;
|
||||||
Value* value = event.GetValue();
|
Value* value = event.GetValue();
|
||||||
if (value != NULL) {
|
if (value != NULL) {
|
||||||
@@ -207,7 +213,7 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
fListener->ExpressionEvaluationRequested(fLanguage,
|
fListener->ExpressionEvaluationRequested(fLanguage,
|
||||||
fExpressionInput->TextView()->Text(), fCurrentEvaluationType);
|
fExpressionInput->Text(), fCurrentEvaluationType);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,13 +225,6 @@ ExpressionEvaluationWindow::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
case MSG_EXPRESSION_EVALUATED:
|
case MSG_EXPRESSION_EVALUATED:
|
||||||
{
|
{
|
||||||
BString expression;
|
|
||||||
if (message->FindString("expression", &expression) != B_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (expression != fExpressionInput->TextView()->Text())
|
|
||||||
break;
|
|
||||||
|
|
||||||
Value* value = NULL;
|
Value* value = NULL;
|
||||||
BReference<Value> reference;
|
BReference<Value> reference;
|
||||||
if (message->FindPointer("value",
|
if (message->FindPointer("value",
|
||||||
|
|||||||
@@ -408,7 +408,7 @@ TeamWindow::MessageReceived(BMessage* message)
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
WatchPromptWindow* window = WatchPromptWindow::Create(
|
WatchPromptWindow* window = WatchPromptWindow::Create(
|
||||||
fTeam->GetArchitecture(), address, type, length,
|
fTeam, address, type, length,
|
||||||
fListener);
|
fListener);
|
||||||
window->Show();
|
window->Show();
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
|
|||||||
@@ -13,45 +13,58 @@
|
|||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <TextControl.h>
|
#include <TextControl.h>
|
||||||
|
|
||||||
|
#include "AutoLocker.h"
|
||||||
|
|
||||||
#include "Architecture.h"
|
#include "Architecture.h"
|
||||||
#include "CLanguageExpressionEvaluator.h"
|
#include "CppLanguage.h"
|
||||||
#include "MessageCodes.h"
|
#include "MessageCodes.h"
|
||||||
#include "Number.h"
|
#include "Number.h"
|
||||||
#include "UserInterface.h"
|
#include "UserInterface.h"
|
||||||
|
#include "Value.h"
|
||||||
#include "Watchpoint.h"
|
#include "Watchpoint.h"
|
||||||
|
|
||||||
|
|
||||||
WatchPromptWindow::WatchPromptWindow(Architecture* architecture,
|
WatchPromptWindow::WatchPromptWindow(::Team* team, target_addr_t address,
|
||||||
target_addr_t address, uint32 type, int32 length,
|
uint32 type, int32 length, UserInterfaceListener* listener)
|
||||||
UserInterfaceListener* listener)
|
|
||||||
:
|
:
|
||||||
BWindow(BRect(), "Edit Watchpoint", B_FLOATING_WINDOW,
|
BWindow(BRect(), "Edit Watchpoint", B_FLOATING_WINDOW,
|
||||||
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
|
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
|
||||||
fInitialAddress(address),
|
fInitialAddress(address),
|
||||||
fInitialType(type),
|
fInitialType(type),
|
||||||
fInitialLength(length),
|
fInitialLength(length),
|
||||||
fArchitecture(architecture),
|
fTeam(team),
|
||||||
|
fRequestedAddress(0),
|
||||||
|
fRequestedLength(0),
|
||||||
fAddressInput(NULL),
|
fAddressInput(NULL),
|
||||||
fLengthInput(NULL),
|
fLengthInput(NULL),
|
||||||
fTypeField(NULL),
|
fTypeField(NULL),
|
||||||
fListener(listener)
|
fListener(listener),
|
||||||
|
fLanguage(NULL)
|
||||||
{
|
{
|
||||||
fArchitecture->AcquireReference();
|
AutoLocker< ::Team> teamLocker(fTeam);
|
||||||
|
fTeam->AddListener(this);
|
||||||
|
fTeam->GetArchitecture()->AcquireReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WatchPromptWindow::~WatchPromptWindow()
|
WatchPromptWindow::~WatchPromptWindow()
|
||||||
{
|
{
|
||||||
fArchitecture->ReleaseReference();
|
fTeam->GetArchitecture()->ReleaseReference();
|
||||||
|
|
||||||
|
AutoLocker< ::Team> teamLocker(fTeam);
|
||||||
|
fTeam->RemoveListener(this);
|
||||||
|
|
||||||
|
if (fLanguage != NULL)
|
||||||
|
fLanguage->ReleaseReference();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
WatchPromptWindow*
|
WatchPromptWindow*
|
||||||
WatchPromptWindow::Create(Architecture* architecture, target_addr_t address,
|
WatchPromptWindow::Create(::Team* team, target_addr_t address, uint32 type,
|
||||||
uint32 type, int32 length, UserInterfaceListener* listener)
|
int32 length, UserInterfaceListener* listener)
|
||||||
{
|
{
|
||||||
WatchPromptWindow* self = new WatchPromptWindow(architecture, address,
|
WatchPromptWindow* self = new WatchPromptWindow(team, address, type,
|
||||||
type, length, listener);
|
length, listener);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
self->_Init();
|
self->_Init();
|
||||||
@@ -68,6 +81,8 @@ WatchPromptWindow::Create(Architecture* architecture, target_addr_t address,
|
|||||||
void
|
void
|
||||||
WatchPromptWindow::_Init()
|
WatchPromptWindow::_Init()
|
||||||
{
|
{
|
||||||
|
fLanguage = new CppLanguage();
|
||||||
|
|
||||||
BString text;
|
BString text;
|
||||||
text.SetToFormat("0x%" B_PRIx64, fInitialAddress);
|
text.SetToFormat("0x%" B_PRIx64, fInitialAddress);
|
||||||
fAddressInput = new BTextControl("Address:", text, NULL);
|
fAddressInput = new BTextControl("Address:", text, NULL);
|
||||||
@@ -78,7 +93,7 @@ WatchPromptWindow::_Init()
|
|||||||
int32 maxDebugRegisters = 0;
|
int32 maxDebugRegisters = 0;
|
||||||
int32 maxBytesPerRegister = 0;
|
int32 maxBytesPerRegister = 0;
|
||||||
uint8 debugCapabilityFlags = 0;
|
uint8 debugCapabilityFlags = 0;
|
||||||
fArchitecture->GetWatchpointDebugCapabilities(maxDebugRegisters,
|
fTeam->GetArchitecture()->GetWatchpointDebugCapabilities(maxDebugRegisters,
|
||||||
maxBytesPerRegister, debugCapabilityFlags);
|
maxBytesPerRegister, debugCapabilityFlags);
|
||||||
|
|
||||||
BMenu* typeMenu = new BMenu("Watch type");
|
BMenu* typeMenu = new BMenu("Watch type");
|
||||||
@@ -135,31 +150,65 @@ WatchPromptWindow::Show()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
WatchPromptWindow::ExpressionEvaluated(
|
||||||
|
const Team::ExpressionEvaluationEvent& event)
|
||||||
|
{
|
||||||
|
BMessage message(MSG_EXPRESSION_EVALUATED);
|
||||||
|
AutoLocker<BLooper> lock(this);
|
||||||
|
if (!lock.IsLocked())
|
||||||
|
return;
|
||||||
|
|
||||||
|
BString expression = event.GetExpression();
|
||||||
|
if (expression != fAddressInput->Text()
|
||||||
|
&& expression != fLengthInput->Text()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.Unlock();
|
||||||
|
message.AddInt32("result", event.GetResult());
|
||||||
|
Value* value = event.GetValue();
|
||||||
|
BReference<Value> reference;
|
||||||
|
if (value != NULL) {
|
||||||
|
reference.SetTo(value);
|
||||||
|
message.AddPointer("value", value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (PostMessage(&message) == B_OK)
|
||||||
|
reference.Detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
WatchPromptWindow::MessageReceived(BMessage* message)
|
WatchPromptWindow::MessageReceived(BMessage* message)
|
||||||
{
|
{
|
||||||
switch (message->what) {
|
switch (message->what) {
|
||||||
case MSG_SET_WATCHPOINT:
|
case MSG_EXPRESSION_EVALUATED:
|
||||||
{
|
{
|
||||||
target_addr_t address = 0;
|
|
||||||
int32 length = 0;
|
|
||||||
CLanguageExpressionEvaluator evaluator;
|
|
||||||
BString errorMessage;
|
BString errorMessage;
|
||||||
try {
|
BReference<Value> reference;
|
||||||
Number value = evaluator.Evaluate(fAddressInput->Text(),
|
Value* value = NULL;
|
||||||
B_UINT64_TYPE);
|
if (message->FindPointer("value",
|
||||||
address = value.GetValue().ToUInt64();
|
reinterpret_cast<void**>(&value)) == B_OK) {
|
||||||
value = evaluator.Evaluate(fLengthInput->Text(),
|
reference.SetTo(value, true);
|
||||||
B_INT32_TYPE);
|
BVariant variant;
|
||||||
length = value.GetValue().ToInt32();
|
value->ToVariant(variant);
|
||||||
} catch(ParseException parseError) {
|
if (variant.Type() == B_UINT64_TYPE) {
|
||||||
errorMessage.SetToFormat("Failed to parse data: %s",
|
fRequestedAddress = variant.ToUInt64();
|
||||||
parseError.message.String());
|
break;
|
||||||
} catch(...) {
|
} else if (variant.Type() == B_INT32_TYPE)
|
||||||
errorMessage.SetToFormat(
|
fRequestedLength = variant.ToInt32();
|
||||||
"Unknown error while parsing address");
|
else
|
||||||
|
value->ToString(errorMessage);
|
||||||
|
} else {
|
||||||
|
status_t result = message->FindInt32("result");
|
||||||
|
errorMessage.SetToFormat("Failed to evaluate expression: %s",
|
||||||
|
strerror(result));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (fRequestedLength <= 0)
|
||||||
|
errorMessage = "Watchpoint length must be at least 1 byte.";
|
||||||
|
|
||||||
if (!errorMessage.IsEmpty()) {
|
if (!errorMessage.IsEmpty()) {
|
||||||
BAlert* alert = new(std::nothrow) BAlert("Edit Watchpoint",
|
BAlert* alert = new(std::nothrow) BAlert("Edit Watchpoint",
|
||||||
errorMessage.String(), "Close");
|
errorMessage.String(), "Close");
|
||||||
@@ -169,13 +218,27 @@ WatchPromptWindow::MessageReceived(BMessage* message)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fListener->ClearWatchpointRequested(fInitialAddress);
|
fListener->ClearWatchpointRequested(fInitialAddress);
|
||||||
fListener->SetWatchpointRequested(address, fTypeField->Menu()
|
fListener->SetWatchpointRequested(fRequestedAddress,
|
||||||
->IndexOf(fTypeField->Menu()->FindMarked()), length, true);
|
fTypeField->Menu()->IndexOf(fTypeField->Menu()->FindMarked()),
|
||||||
|
fRequestedLength, true);
|
||||||
|
|
||||||
PostMessage(B_QUIT_REQUESTED);
|
PostMessage(B_QUIT_REQUESTED);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case MSG_SET_WATCHPOINT:
|
||||||
|
{
|
||||||
|
fRequestedAddress = 0;
|
||||||
|
fRequestedLength = 0;
|
||||||
|
|
||||||
|
fListener->ExpressionEvaluationRequested(fLanguage,
|
||||||
|
fAddressInput->Text(), B_UINT64_TYPE);
|
||||||
|
|
||||||
|
fListener->ExpressionEvaluationRequested(fLanguage,
|
||||||
|
fLengthInput->Text(), B_INT32_TYPE);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
BWindow::MessageReceived(message);
|
BWindow::MessageReceived(message);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2012, Rene Gollent, [email protected].
|
* Copyright 2012-2014, Rene Gollent, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef WATCH_PROMPT_WINDOW_H
|
#ifndef WATCH_PROMPT_WINDOW_H
|
||||||
@@ -8,27 +8,28 @@
|
|||||||
|
|
||||||
#include <Window.h>
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "Team.h"
|
||||||
#include "types/Types.h"
|
#include "types/Types.h"
|
||||||
|
|
||||||
|
|
||||||
class Architecture;
|
|
||||||
class BTextControl;
|
|
||||||
class Watchpoint;
|
|
||||||
class BMenuField;
|
class BMenuField;
|
||||||
|
class BTextControl;
|
||||||
|
class SourceLanguage;
|
||||||
|
class Watchpoint;
|
||||||
class UserInterfaceListener;
|
class UserInterfaceListener;
|
||||||
|
|
||||||
|
|
||||||
class WatchPromptWindow : public BWindow
|
class WatchPromptWindow : public BWindow, private Team::Listener
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
WatchPromptWindow(Architecture* architecture,
|
WatchPromptWindow(::Team* team,
|
||||||
target_addr_t address, uint32 type,
|
target_addr_t address, uint32 type,
|
||||||
int32 length,
|
int32 length,
|
||||||
UserInterfaceListener* listener);
|
UserInterfaceListener* listener);
|
||||||
|
|
||||||
~WatchPromptWindow();
|
~WatchPromptWindow();
|
||||||
|
|
||||||
static WatchPromptWindow* Create(Architecture* architecture,
|
static WatchPromptWindow* Create(::Team* team,
|
||||||
target_addr_t address, uint32 type,
|
target_addr_t address, uint32 type,
|
||||||
int32 length,
|
int32 length,
|
||||||
UserInterfaceListener* listener);
|
UserInterfaceListener* listener);
|
||||||
@@ -39,6 +40,11 @@ public:
|
|||||||
|
|
||||||
virtual void Show();
|
virtual void Show();
|
||||||
|
|
||||||
|
// Team::Listener
|
||||||
|
virtual void ExpressionEvaluated(
|
||||||
|
const Team::ExpressionEvaluationEvent&
|
||||||
|
event);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void _Init();
|
void _Init();
|
||||||
|
|
||||||
@@ -47,13 +53,16 @@ private:
|
|||||||
target_addr_t fInitialAddress;
|
target_addr_t fInitialAddress;
|
||||||
uint32 fInitialType;
|
uint32 fInitialType;
|
||||||
int32 fInitialLength;
|
int32 fInitialLength;
|
||||||
Architecture* fArchitecture;
|
::Team* fTeam;
|
||||||
|
target_addr_t fRequestedAddress;
|
||||||
|
int32 fRequestedLength;
|
||||||
BTextControl* fAddressInput;
|
BTextControl* fAddressInput;
|
||||||
BTextControl* fLengthInput;
|
BTextControl* fLengthInput;
|
||||||
BMenuField* fTypeField;
|
BMenuField* fTypeField;
|
||||||
UserInterfaceListener* fListener;
|
UserInterfaceListener* fListener;
|
||||||
BButton* fWatchButton;
|
BButton* fWatchButton;
|
||||||
BButton* fCancelButton;
|
BButton* fCancelButton;
|
||||||
|
SourceLanguage* fLanguage;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // WATCH_PROMPT_WINDOW_H
|
#endif // WATCH_PROMPT_WINDOW_H
|
||||||
|
|||||||
Reference in New Issue
Block a user