hrev45702 adds 3 changesets to branch 'master' old head: a8e846d0f4cca1f35e2210b6c2ee3e6276c965b4 new head: e312ed26ef0570a3be4dd3271eebe55dc668929e overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=e312ed2+%5Ea8e846d ---------------------------------------------------------------------------- 570241e: Extend ValueNode interface for ranged containers. Add an IsContainerRangeFixed() hook which specifies whether or not the container in question can only display elements within a fixed lower/upper bound, i.e. B{Object}List. f297d65: Relax range setting constraints for arrays. - VariablesView now detects if a container's range is fixed or not, and uses that to adjust both the prompt it displays and whether or not the parsed ranges are bounds checked. - ArrayValueNode now returns the currently user-set range rather than the dimension constraints, since those might not always be accurate. e312ed2: Add "Cast to array" context option. Implements a simple context shortcut allowing to cast a pointer variable directly to a 10-element array of the type it points to. Resolves #9778. [ Rene Gollent <anevilyak@xxxxxxxxx> ] ---------------------------------------------------------------------------- 10 files changed, 137 insertions(+), 29 deletions(-) src/apps/debugger/MessageCodes.h | 1 + .../gui/team_window/VariablesView.cpp | 80 ++++++++++++++++++-- .../debugger/user_interface/util/UiUtils.cpp | 5 +- src/apps/debugger/user_interface/util/UiUtils.h | 1 + src/apps/debugger/value/ValueNode.cpp | 7 ++ src/apps/debugger/value/ValueNode.h | 4 + .../value/value_nodes/ArrayValueNode.cpp | 57 +++++++++----- .../debugger/value/value_nodes/ArrayValueNode.h | 3 + .../value/value_nodes/BListValueNode.cpp | 7 ++ .../debugger/value/value_nodes/BListValueNode.h | 1 + ############################################################################ Commit: 570241e8b723e20083bf6c2ed64becf3f41ca115 URL: http://cgit.haiku-os.org/haiku/commit/?id=570241e Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Mon May 20 22:18:57 2013 UTC Extend ValueNode interface for ranged containers. Add an IsContainerRangeFixed() hook which specifies whether or not the container in question can only display elements within a fixed lower/upper bound, i.e. B{Object}List. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/value/ValueNode.cpp b/src/apps/debugger/value/ValueNode.cpp index 1166f4c..33bde4f 100644 --- a/src/apps/debugger/value/ValueNode.cpp +++ b/src/apps/debugger/value/ValueNode.cpp @@ -70,6 +70,13 @@ ValueNode::IsRangedContainer() const } +bool +ValueNode::IsContainerRangeFixed() const +{ + return false; +} + + void ValueNode::ClearChildren() { diff --git a/src/apps/debugger/value/ValueNode.h b/src/apps/debugger/value/ValueNode.h index 9b88b77..c61f252 100644 --- a/src/apps/debugger/value/ValueNode.h +++ b/src/apps/debugger/value/ValueNode.h @@ -62,6 +62,10 @@ public: // node types to allow the upper layers to be aware of this, and to be // able to request that only a subset of children be created. virtual bool IsRangedContainer() const; + virtual bool IsContainerRangeFixed() const; + // indicates that the user can't + // arbitrarily go outside of the + // specified/supported range. virtual void ClearChildren(); virtual status_t CreateChildrenInRange(int32 lowIndex, int32 highIndex); diff --git a/src/apps/debugger/value/value_nodes/BListValueNode.cpp b/src/apps/debugger/value/value_nodes/BListValueNode.cpp index 1e949b2..147dccd 100644 --- a/src/apps/debugger/value/value_nodes/BListValueNode.cpp +++ b/src/apps/debugger/value/value_nodes/BListValueNode.cpp @@ -330,6 +330,13 @@ BListValueNode::IsRangedContainer() const } +bool +BListValueNode::IsContainerRangeFixed() const +{ + return true; +} + + void BListValueNode::ClearChildren() { diff --git a/src/apps/debugger/value/value_nodes/BListValueNode.h b/src/apps/debugger/value/value_nodes/BListValueNode.h index e4347b6..ce34e01 100644 --- a/src/apps/debugger/value/value_nodes/BListValueNode.h +++ b/src/apps/debugger/value/value_nodes/BListValueNode.h @@ -37,6 +37,7 @@ public: virtual ValueNodeChild* ChildAt(int32 index) const; virtual bool IsRangedContainer() const; + virtual bool IsContainerRangeFixed() const; virtual void ClearChildren(); virtual status_t CreateChildrenInRange(int32 lowIndex, int32 highIndex); ############################################################################ Commit: f297d6591d97d915526ed09bedc24011369d9d2b URL: http://cgit.haiku-os.org/haiku/commit/?id=f297d65 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Mon May 20 23:01:51 2013 UTC Relax range setting constraints for arrays. - VariablesView now detects if a container's range is fixed or not, and uses that to adjust both the prompt it displays and whether or not the parsed ranges are bounds checked. - ArrayValueNode now returns the currently user-set range rather than the dimension constraints, since those might not always be accurate. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index 2b4b040..ba8cabe 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -1593,11 +1593,17 @@ VariablesView::MessageReceived(BMessage* message) ->SelectionModel()->NodeAt(0); int32 lowerBound, upperBound; ValueNode* valueNode = node->NodeChild()->Node(); - if (!valueNode->IsRangedContainer()) + if (!valueNode->IsRangedContainer()) { valueNode = node->ChildAt(0)->NodeChild()->Node(); + if (!valueNode->IsRangedContainer()) + break; + } - if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK) + bool fixedRange = valueNode->IsContainerRangeFixed(); + if (valueNode->SupportedChildRange(lowerBound, upperBound) + != B_OK) { break; + } BMessage* promptMessage = new(std::nothrow) BMessage( MSG_SET_CONTAINER_RANGE); @@ -1606,9 +1612,16 @@ VariablesView::MessageReceived(BMessage* message) ObjectDeleter<BMessage> messageDeleter(promptMessage); promptMessage->AddPointer("node", node); + promptMessage->AddBool("fixedRange", fixedRange); BString infoText; - infoText.SetToFormat("Allowed range: %" B_PRId32 - "-%" B_PRId32 ".", lowerBound, upperBound); + if (fixedRange) { + infoText.SetToFormat("Allowed range: %" B_PRId32 + "-%" B_PRId32 ".", lowerBound, upperBound); + } else { + infoText.SetToFormat("Current range: %" B_PRId32 + "-%" B_PRId32 ".", lowerBound, upperBound); + } + PromptWindow* promptWindow = new(std::nothrow) PromptWindow( "Set Range", "Range: ", infoText.String(), BMessenger(this), promptMessage); @@ -1631,13 +1644,15 @@ VariablesView::MessageReceived(BMessage* message) if (valueNode->SupportedChildRange(lowerBound, upperBound) != B_OK) break; + bool fixedRange = message->FindBool("fixedRange"); + BString rangeExpression = message->FindString("text"); if (rangeExpression.Length() == 0) break; RangeList ranges; status_t result = UiUtils::ParseRangeExpression( - rangeExpression, lowerBound, upperBound, ranges); + rangeExpression, lowerBound, upperBound, fixedRange, ranges); if (result != B_OK) break; diff --git a/src/apps/debugger/user_interface/util/UiUtils.cpp b/src/apps/debugger/user_interface/util/UiUtils.cpp index 6ed0c58..39eee3f 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.cpp +++ b/src/apps/debugger/user_interface/util/UiUtils.cpp @@ -411,7 +411,7 @@ static status_t ParseRangeString(BString& rangeString, int32& lowerBound, /*static*/ status_t UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound, - int32 upperBound, RangeList& _output) + int32 upperBound, bool fixedRange, RangeList& _output) { if (rangeExpression.IsEmpty()) return B_BAD_DATA; @@ -440,7 +440,8 @@ UiUtils::ParseRangeExpression(const BString& rangeExpression, int32 lowerBound, if (result != B_OK) return result; - if (lowValue < lowerBound || highValue > upperBound) + + if (fixedRange && (lowValue < lowerBound || highValue > upperBound)) return B_BAD_VALUE; result = _output.AddRange(lowValue, highValue); diff --git a/src/apps/debugger/user_interface/util/UiUtils.h b/src/apps/debugger/user_interface/util/UiUtils.h index ccb67d5..7b11be9 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.h +++ b/src/apps/debugger/user_interface/util/UiUtils.h @@ -55,6 +55,7 @@ public: static status_t ParseRangeExpression( const BString& rangeString, int32 lowerBound, int32 upperBound, + bool fixedRange, RangeList& _output); }; diff --git a/src/apps/debugger/value/value_nodes/ArrayValueNode.cpp b/src/apps/debugger/value/value_nodes/ArrayValueNode.cpp index 6752c9b..bc05323 100644 --- a/src/apps/debugger/value/value_nodes/ArrayValueNode.cpp +++ b/src/apps/debugger/value/value_nodes/ArrayValueNode.cpp @@ -31,7 +31,10 @@ AbstractArrayValueNode::AbstractArrayValueNode(ValueNodeChild* nodeChild, : ValueNode(nodeChild), fType(type), - fDimension(dimension) + fDimension(dimension), + fLowerBound(0), + fUpperBound(0), + fBoundsInitialized(false) { fType->AcquireReference(); } @@ -106,6 +109,8 @@ void AbstractArrayValueNode::ClearChildren() { fChildren.MakeEmpty(); + fLowerBound = 0; + fUpperBound = 0; if (fContainer != NULL) fContainer->NotifyValueNodeChildrenDeleted(this); } @@ -121,14 +126,22 @@ AbstractArrayValueNode::CreateChildrenInRange(int32 lowIndex, int32 dimensionCount = fType->CountDimensions(); bool isFinalDimension = fDimension + 1 == dimensionCount; - - int32 lowerBound, upperBound; - if (SupportedChildRange(lowerBound, upperBound) == B_OK) { - // clamp inputs to supported range. - if (lowIndex < lowerBound) - lowIndex = lowerBound; - if (highIndex > upperBound) - highIndex = upperBound; + status_t error = B_OK; + + if (!fBoundsInitialized) { + int32 lowerBound, upperBound; + error = SupportedChildRange(lowerBound, upperBound); + if (error != B_OK) + return error; + + fLowerBound = lowerBound; + fUpperBound = upperBound; + fBoundsInitialized = true; + } else { + if (lowIndex < fLowerBound) + fLowerBound = lowIndex; + if (highIndex > fUpperBound) + fUpperBound = highIndex; } // create children for the array elements @@ -166,19 +179,23 @@ status_t AbstractArrayValueNode::SupportedChildRange(int32& lowIndex, int32& highIndex) const { - ArrayDimension* dimension = fType->DimensionAt(fDimension); - - SubrangeType* dimensionType = dynamic_cast<SubrangeType*>( - dimension->GetType()); - - if (dimensionType != NULL) { - lowIndex = dimensionType->LowerBound().ToInt32(); - highIndex = dimensionType->UpperBound().ToInt32(); - - return B_OK; + if (!fBoundsInitialized) { + ArrayDimension* dimension = fType->DimensionAt(fDimension); + + SubrangeType* dimensionType = dynamic_cast<SubrangeType*>( + dimension->GetType()); + + if (dimensionType != NULL) { + lowIndex = dimensionType->LowerBound().ToInt32(); + highIndex = dimensionType->UpperBound().ToInt32(); + } else + return B_UNSUPPORTED; + } else { + lowIndex = fLowerBound; + highIndex = fUpperBound; } - return B_UNSUPPORTED; + return B_OK; } diff --git a/src/apps/debugger/value/value_nodes/ArrayValueNode.h b/src/apps/debugger/value/value_nodes/ArrayValueNode.h index cc305e7..242954d 100644 --- a/src/apps/debugger/value/value_nodes/ArrayValueNode.h +++ b/src/apps/debugger/value/value_nodes/ArrayValueNode.h @@ -54,6 +54,9 @@ protected: ArrayType* fType; ChildList fChildren; int32 fDimension; + int32 fLowerBound; + int32 fUpperBound; + bool fBoundsInitialized; }; ############################################################################ Revision: hrev45702 Commit: e312ed26ef0570a3be4dd3271eebe55dc668929e URL: http://cgit.haiku-os.org/haiku/commit/?id=e312ed2 Author: Rene Gollent <anevilyak@xxxxxxxxx> Date: Sun May 19 15:50:11 2013 UTC Ticket: https://dev.haiku-os.org/ticket/9778 Add "Cast to array" context option. Implements a simple context shortcut allowing to cast a pointer variable directly to a 10-element array of the type it points to. Resolves #9778. ---------------------------------------------------------------------------- diff --git a/src/apps/debugger/MessageCodes.h b/src/apps/debugger/MessageCodes.h index b5ca5e3..ae81129 100644 --- a/src/apps/debugger/MessageCodes.h +++ b/src/apps/debugger/MessageCodes.h @@ -56,6 +56,7 @@ enum { MSG_INSPECTOR_WINDOW_CLOSED = 'irwc', MSG_INSPECT_ADDRESS = 'isad', MSG_SHOW_TYPECAST_NODE_PROMPT = 'stnp', + MSG_TYPECAST_TO_ARRAY = 'stta', MSG_TYPECAST_NODE = 'tyno', MSG_SHOW_WATCH_VARIABLE_PROMPT = 'swvp', MSG_SHOW_CONTAINER_RANGE_PROMPT = 'scrp', diff --git a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp index ba8cabe..e49cd11 100644 --- a/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp +++ b/src/apps/debugger/user_interface/gui/team_window/VariablesView.cpp @@ -1577,14 +1577,54 @@ VariablesView::MessageReceived(BMessage* message) break; } + BReference<Type> typeRef(type, true); ValueNode* valueNode = NULL; if (TypeHandlerRoster::Default()->CreateValueNode( - node->NodeChild(), type, valueNode) != B_OK) { + node->NodeChild(), type, valueNode) != B_OK) { break; } + typeRef.Detach(); node->NodeChild()->SetNode(valueNode); node->SetCastedType(type); + fVariableTableModel->NotifyNodeChanged(node); + break; + } + case MSG_TYPECAST_TO_ARRAY: + { + ModelNode* node = NULL; + if (message->FindPointer("node", reinterpret_cast<void **>(&node)) + != B_OK) { + break; + } + + Type* baseType = dynamic_cast<AddressType*>(node->NodeChild() + ->Node()->GetType())->BaseType(); + ArrayType* arrayType = NULL; + if (baseType->CreateDerivedArrayType(0, kMaxArrayElementCount, + false, arrayType) != B_OK) { + break; + } + + AddressType* addressType = NULL; + BReference<Type> typeRef(arrayType, true); + if (arrayType->CreateDerivedAddressType(DERIVED_TYPE_POINTER, + addressType) != B_OK) { + break; + } + + typeRef.Detach(); + typeRef.SetTo(addressType, true); + ValueNode* valueNode = NULL; + if (TypeHandlerRoster::Default()->CreateValueNode( + node->NodeChild(), addressType, valueNode) != B_OK) { + break; + } + + typeRef.Detach(); + node->NodeChild()->SetNode(valueNode); + node->SetCastedType(addressType); + fVariableTableModel->NotifyNodeChanged(node); break; } case MSG_SHOW_CONTAINER_RANGE_PROMPT: @@ -2000,6 +2040,18 @@ VariablesView::_GetContextActionsForNode(ModelNode* node, message->AddUInt64("address", location->PieceAt(0).address); } + ValueNode* valueNode = node->NodeChild()->Node(); + + if (valueNode != NULL) { + AddressType* type = dynamic_cast<AddressType*>(valueNode->GetType()); + if (type != NULL && type->BaseType() != NULL) { + result = _AddContextAction("Cast to array", MSG_TYPECAST_TO_ARRAY, + actions, message); + if (result != B_OK) + return result; + message->AddPointer("node", node); + } + } result = _AddContextAction("Cast as" B_UTF8_ELLIPSIS, MSG_SHOW_TYPECAST_NODE_PROMPT, actions, message); @@ -2011,7 +2063,6 @@ VariablesView::_GetContextActionsForNode(ModelNode* node, if (result != B_OK) return result; - ValueNode* valueNode = node->NodeChild()->Node(); if (valueNode == NULL) return B_OK;