diff --git a/src/apps/debugger/user_interface/util/UiUtils.cpp b/src/apps/debugger/user_interface/util/UiUtils.cpp index 72aa28120c..28fcd89431 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.cpp +++ b/src/apps/debugger/user_interface/util/UiUtils.cpp @@ -11,6 +11,7 @@ #include #include +#include #include #include "FunctionInstance.h" @@ -18,6 +19,9 @@ #include "StackFrame.h" #include "Team.h" #include "Thread.h" +#include "Type.h" +#include "Value.h" +#include "ValueNode.h" /*static*/ const char* @@ -156,3 +160,66 @@ UiUtils::ReportNameForTeam(::Team* team, char* buffer, size_t bufferSize) return buffer; } + + +/*static*/ void +UiUtils::PrintValueNodeGraph(BString& _output, StackFrame* frame, + ValueNodeChild* child, int32 indentLevel, int32 maxDepth) +{ + _output.Append('\t', indentLevel); + _output << child->Name(); + + ValueNode* node = child->Node(); + if (node == NULL) { + _output << ": Unavailable\n"; + return; + } + + if (node->GetType()->Kind() != TYPE_COMPOUND) { + _output << ": "; + status_t resolutionState = node->LocationAndValueResolutionState(); + if (resolutionState == VALUE_NODE_UNRESOLVED) + _output << "Unresolved"; + else if (resolutionState == B_OK) { + Value* value = node->GetValue(); + if (value != NULL) { + BString valueData; + value->ToString(valueData); + _output << valueData; + } else + _output << "Unavailable"; + } else + _output << strerror(resolutionState); + } + + if (maxDepth == 0 || node->CountChildren() == 0) { + _output << "\n"; + return; + } + + _output << " {\n"; + + if (node->CountChildren() == 1 + && node->GetType()->Kind() == TYPE_ADDRESS + && node->ChildAt(0)->GetType()->Kind() == TYPE_COMPOUND) { + // for the case of a pointer to a compound type, + // we want to hide the intervening compound node and print + // the children directly. + node = node->ChildAt(0)->Node(); + } + + for (int32 i = 0; i < node->CountChildren(); i++) { + // don't dump compound nodes if our depth limit won't allow + // us to traverse into their children anyways, and the top + // level node contains no data of intereest. + if (node->ChildAt(i)->GetType()->Kind() != TYPE_COMPOUND + || maxDepth > 1) { + PrintValueNodeGraph(_output, frame, node->ChildAt(i), + indentLevel + 1, maxDepth - 1); + } + } + _output.Append('\t', indentLevel); + _output << "}\n"; + + return; +} diff --git a/src/apps/debugger/user_interface/util/UiUtils.h b/src/apps/debugger/user_interface/util/UiUtils.h index 81ed46df90..3e81de83de 100644 --- a/src/apps/debugger/user_interface/util/UiUtils.h +++ b/src/apps/debugger/user_interface/util/UiUtils.h @@ -10,10 +10,11 @@ #include +class BString; class BVariant; class StackFrame; class Team; - +class ValueNodeChild; class UiUtils { public: @@ -29,6 +30,13 @@ public: static const char* ReportNameForTeam(::Team* team, char* buffer, size_t bufferSize); + + // this function assumes the value nodes have already been resolved + // (if possible). + static void PrintValueNodeGraph(BString& _output, + StackFrame* frame, + ValueNodeChild* child, + int32 indentLevel, int32 maxDepth); };