/*
* Copyright 2012-2016, Rene Gollent, rene@gollent.com.
* Distributed under the terms of the MIT License.
*/
#include "WatchPromptWindow.h"
#include <Alert.h>
#include <Button.h>
#include <LayoutBuilder.h>
#include <Menu.h>
#include <MenuField.h>
#include <MenuItem.h>
#include <String.h>
#include <TextControl.h>
#include "AutoLocker.h"
#include "AppMessageCodes.h"
#include "Architecture.h"
#include "CppLanguage.h"
#include "IntegerValue.h"
#include "MessageCodes.h"
#include "SyntheticPrimitiveType.h"
#include "UserInterface.h"
#include "Watchpoint.h"
WatchPromptWindow::WatchPromptWindow(Architecture* architecture,
target_addr_t address, uint32 type, int32 length,
UserInterfaceListener* listener)
:
BWindow(BRect(), "Edit Watchpoint", B_FLOATING_WINDOW,
B_AUTO_UPDATE_SIZE_LIMITS | B_CLOSE_ON_ESCAPE),
fInitialAddress(address),
fInitialType(type),
fInitialLength(length),
fArchitecture(architecture),
fRequestedAddress(0),
fRequestedLength(0),
fAddressInput(NULL),
fLengthInput(NULL),
fAddressExpressionInfo(NULL),
fLengthExpressionInfo(NULL),
fTypeField(NULL),
fListener(listener),
fLanguage(NULL)
{
fArchitecture->AcquireReference();
}
WatchPromptWindow::~WatchPromptWindow()
{
fArchitecture->ReleaseReference();
if (fLanguage != NULL)
fLanguage->ReleaseReference();
if (fAddressExpressionInfo != NULL) {
fAddressExpressionInfo->RemoveListener(this);
fAddressExpressionInfo->ReleaseReference();
}
if (fLengthExpressionInfo != NULL) {
fLengthExpressionInfo->RemoveListener(this);
fLengthExpressionInfo->ReleaseReference();
}
}
WatchPromptWindow*
WatchPromptWindow::Create(Architecture* architecture, target_addr_t address,
uint32 type, int32 length, UserInterfaceListener* listener)
{
WatchPromptWindow* self = new WatchPromptWindow(architecture, address,
type, length, listener);
try {
self->_Init();
} catch (...) {
delete self;
throw;
}
return self;
}
void
WatchPromptWindow::_Init()
{
fLanguage = new CppLanguage();
BString text;
text.SetToFormat("0x%" B_PRIx64, fInitialAddress);
fAddressInput = new BTextControl("Address:", text, NULL);
fAddressExpressionInfo = new ExpressionInfo(text);
fAddressExpressionInfo->AddListener(this);
text.SetToFormat("%" B_PRId32, fInitialLength);
fLengthInput = new BTextControl("Length:", text, NULL);
fLengthExpressionInfo = new ExpressionInfo(text);
fLengthExpressionInfo->AddListener(this);
int32 maxDebugRegisters = 0;
int32 maxBytesPerRegister = 0;
uint8 debugCapabilityFlags = 0;
fArchitecture->GetWatchpointDebugCapabilities(maxDebugRegisters,
maxBytesPerRegister, debugCapabilityFlags);
BMenu* typeMenu = new BMenu("Watch type");
BMenuItem* watchTypeItem = new BMenuItem("Read", NULL);
watchTypeItem->SetEnabled(
(debugCapabilityFlags & WATCHPOINT_CAPABILITY_FLAG_READ) != 0);
typeMenu->AddItem(watchTypeItem);
watchTypeItem = new BMenuItem("Write", NULL);
watchTypeItem->SetEnabled(
(debugCapabilityFlags & WATCHPOINT_CAPABILITY_FLAG_WRITE) != 0);
typeMenu->AddItem(watchTypeItem);
watchTypeItem = new BMenuItem("Read/Write", NULL);
watchTypeItem->SetEnabled(
(debugCapabilityFlags & WATCHPOINT_CAPABILITY_FLAG_READ_WRITE) != 0);
typeMenu->AddItem(watchTypeItem);
fTypeField = new BMenuField("Type:", typeMenu);
BLayoutItem* labelItem = fTypeField->CreateLabelLayoutItem();
labelItem->View()->SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
BLayoutBuilder::Group<>(this, B_VERTICAL)
.SetInsets(B_USE_DEFAULT_SPACING)
.AddGroup(B_HORIZONTAL, 4.0f)
.Add(fAddressInput)
.End()
.AddGroup(B_HORIZONTAL, 4.0f)
.Add(fLengthInput)
.Add(labelItem)
.Add(fTypeField->CreateMenuBarLayoutItem())
.End()
.AddGroup(B_HORIZONTAL, 4.0f)
.AddGlue()
.Add((fWatchButton = new BButton("Set",
new BMessage(MSG_SET_WATCHPOINT))))
.Add((fCancelButton = new BButton("Cancel",
new BMessage(B_QUIT_REQUESTED))))
.End();
fWatchButton->SetTarget(this);
fCancelButton->SetTarget(this);
fTypeField->Menu()->SetLabelFromMarked(true);
fTypeField->Menu()->ItemAt(fInitialType)->SetMarked(true);
}
void
WatchPromptWindow::Show()
{
CenterOnScreen();
BWindow::Show();
}
void
WatchPromptWindow::ExpressionEvaluated(ExpressionInfo* info, status_t result,
ExpressionResult* value)
{
BMessage message(MSG_EXPRESSION_EVALUATED);
message.AddInt32("result", result);
message.AddPointer("info", info);
BReference<ExpressionResult> reference;
if (value != NULL) {
reference.SetTo(value);
message.AddPointer("value", value);
}
if (PostMessage(&message) == B_OK)
reference.Detach();
}
void
WatchPromptWindow::MessageReceived(BMessage* message)
{
switch (message->what) {
case MSG_EXPRESSION_EVALUATED:
{
BString errorMessage;
BReference<ExpressionResult> reference;
ExpressionResult* value = NULL;
ExpressionInfo* info = NULL;
if (message->FindPointer("info",
reinterpret_cast<void**>(&info)) != B_OK) {
break;
}
if (message->FindPointer("value",
reinterpret_cast<void**>(&value)) == B_OK) {
reference.SetTo(value, true);
if (value->Kind() == EXPRESSION_RESULT_KIND_PRIMITIVE) {
Value* primitive = value->PrimitiveValue();
if (dynamic_cast<IntegerValue*>(primitive) != NULL) {
BVariant resultVariant;
primitive->ToVariant(resultVariant);
if (info == fAddressExpressionInfo) {
fRequestedAddress = resultVariant.ToUInt64();
break;
} else
fRequestedLength = resultVariant.ToInt32();
}
else
primitive->ToString(errorMessage);
} else
errorMessage.SetTo("Unsupported expression result.");
} 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()) {
BAlert* alert = new(std::nothrow) BAlert("Edit Watchpoint",
errorMessage.String(), "Close");
if (alert != NULL)
alert->Go();
break;
}
fListener->ClearWatchpointRequested(fInitialAddress);
fListener->SetWatchpointRequested(fRequestedAddress,
fTypeField->Menu()->IndexOf(fTypeField->Menu()->FindMarked()),
fRequestedLength, true);
PostMessage(B_QUIT_REQUESTED);
break;
}
case MSG_SET_WATCHPOINT:
{
fRequestedAddress = 0;
fRequestedLength = 0;
fAddressExpressionInfo->SetTo(fAddressInput->Text());
fListener->ExpressionEvaluationRequested(fLanguage,
fAddressExpressionInfo);
fLengthExpressionInfo->SetTo(fLengthInput->Text());
fListener->ExpressionEvaluationRequested(fLanguage,
fLengthExpressionInfo);
break;
}
default:
BWindow::MessageReceived(message);
break;
}
}
↑ V730 Not all members of a class are initialized inside the constructor. Consider inspecting: fWatchButton, fCancelButton.