[haiku-commits] haiku: hrev45645 - src/apps/debugger/user_interface/gui/team_window

  • From: anevilyak@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Thu, 9 May 2013 05:26:36 +0200 (CEST)

hrev45645 adds 1 changeset to branch 'master'
old head: 879020baf11d142a48ba1714fcca1c419b93a4c3
new head: a69facf0517bfcea02258dcc0e17a037158938a1
overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=a69facf+%5E879020b

----------------------------------------------------------------------------

a69facf: Implement #9756. ImageFunctionsView now builds...
  
  ...a source path-based tree of all the image's functions, and
  consequently organizes them into a nested hierarchy similar to the
  on-disk directory structure in which they were originally found (or at
  least, as close as we can get from the DWARF info).

                                      [ Rene Gollent <anevilyak@xxxxxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev45645
Commit:      a69facf0517bfcea02258dcc0e17a037158938a1
URL:         http://cgit.haiku-os.org/haiku/commit/?id=a69facf
Author:      Rene Gollent <anevilyak@xxxxxxxxx>
Date:        Thu May  9 03:24:12 2013 UTC

Ticket:      https://dev.haiku-os.org/ticket/9756

----------------------------------------------------------------------------

2 files changed, 300 insertions(+), 113 deletions(-)
.../gui/team_window/ImageFunctionsView.cpp       | 411 ++++++++++++++-----
.../gui/team_window/ImageFunctionsView.h         |   2 +

----------------------------------------------------------------------------

diff --git 
a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp 
b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp
index 3a096fa..06eb89d 100644
--- a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp
+++ b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.cpp
@@ -1,6 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
- * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxx.
+ * Copyright 2011-2013, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 
@@ -23,6 +23,135 @@
 #include "Tracing.h"
 
 
+// #pragma mark - SourcePathComponentNode
+
+
+class ImageFunctionsView::SourcePathComponentNode : public BReferenceable {
+public:
+       SourcePathComponentNode(SourcePathComponentNode* parent,
+               const BString& componentName, LocatableFile* sourceFile,
+               FunctionInstance* function)
+               :
+               fParent(parent),
+               fComponentName(componentName),
+               fSourceFile(sourceFile),
+               fFunction(function)
+       {
+               if (fParent != NULL)
+                       fParent->AcquireReference();
+               if (fSourceFile != NULL)
+                       fSourceFile->AcquireReference();
+               if (fFunction != NULL)
+                       fFunction->AcquireReference();
+       }
+
+       virtual ~SourcePathComponentNode()
+       {
+               for (int32 i = 0; i < fChildPathComponents.CountItems(); i++)
+                       fChildPathComponents.ItemAt(i)->ReleaseReference();
+
+               if (fParent != NULL)
+                       fParent->ReleaseReference();
+
+               if (fSourceFile != NULL)
+                       fSourceFile->ReleaseReference();
+
+               if (fFunction != NULL)
+                       fFunction->AcquireReference();
+       }
+
+       const BString& ComponentName() const
+       {
+               return fComponentName;
+       }
+
+       LocatableFile* SourceFile() const
+       {
+               return fSourceFile;
+       }
+
+       FunctionInstance* Function() const
+       {
+               return fFunction;
+       }
+
+       int32 CountChildren() const
+       {
+               return fChildPathComponents.CountItems();
+       }
+
+       SourcePathComponentNode* ChildAt(int32 index)
+       {
+               return fChildPathComponents.ItemAt(index);
+       }
+
+       SourcePathComponentNode* FindChildByName(const BString& name) const
+       {
+               return fChildPathComponents.BinarySearchByKey(name,
+                       &CompareByComponentName);
+       }
+
+       int32 FindChildIndexByName(const BString& name) const
+       {
+               return fChildPathComponents.BinarySearchIndexByKey(name,
+                       &CompareByComponentName);
+       }
+
+       bool AddChild(SourcePathComponentNode* child)
+       {
+               if (!fChildPathComponents.BinaryInsert(child,
+                               &CompareComponents)) {
+                       return false;
+               }
+
+               child->AcquireReference();
+
+               return true;
+       }
+
+       bool RemoveChild(SourcePathComponentNode* child)
+       {
+               if (!fChildPathComponents.RemoveItem(child))
+                       return false;
+
+               child->ReleaseReference();
+
+               return true;
+       }
+
+       bool RemoveAllChildren()
+       {
+               for (int32 i = 0; i < fChildPathComponents.CountItems(); i++)
+                       RemoveChild(fChildPathComponents.ItemAt(i));
+
+               return true;
+       }
+
+private:
+       static int CompareByComponentName(const BString* name, const
+               SourcePathComponentNode* node)
+       {
+               return name->Compare(node->ComponentName());
+       }
+
+       static int CompareComponents(const SourcePathComponentNode* a,
+               const SourcePathComponentNode* b)
+       {
+               return a->ComponentName().Compare(b->ComponentName());
+       }
+
+private:
+       typedef BObjectList<SourcePathComponentNode> ChildPathComponentList;
+
+private:
+       SourcePathComponentNode* fParent;
+       BString                                 fComponentName;
+       LocatableFile*                  fSourceFile;
+       FunctionInstance*               fFunction;
+       ChildPathComponentList  fChildPathComponents;
+};
+
+
 // #pragma mark - FunctionsTableModel
 
 
@@ -31,10 +160,7 @@ public:
        FunctionsTableModel()
                :
                fImageDebugInfo(NULL),
-               fFunctions(NULL),
-               fFunctionCount(0),
-               fSourceFileIndices(NULL),
-               fSourceFileCount(0)
+               fSourcelessNode(NULL)
        {
        }
 
@@ -46,16 +172,14 @@ public:
        void SetImageDebugInfo(ImageDebugInfo* imageDebugInfo)
        {
                // unset old functions
-               if (fSourceFileIndices != NULL) {
-                       NotifyNodesRemoved(TreeTablePath(), 0, 
fSourceFileCount);
-
-                       delete[] fFunctions;
-                       fFunctions = NULL;
-                       fFunctionCount = 0;
-
-                       delete[] fSourceFileIndices;
-                       fSourceFileIndices = NULL;
-                       fSourceFileCount = 0;
+               if (fImageDebugInfo != NULL) {
+                       NotifyNodesRemoved(TreeTablePath(), 0,
+                               fChildPathComponents.CountItems());
+                       for (int32 i = 0; i < 
fChildPathComponents.CountItems(); i++)
+                               
fChildPathComponents.ItemAt(i)->ReleaseReference();
+
+                       fChildPathComponents.MakeEmpty();
+                       fSourcelessNode = NULL;
                }
 
                fImageDebugInfo = imageDebugInfo;
@@ -95,35 +219,27 @@ public:
                                // The array might now be too large, but we can 
live with that.
                }
 
-               // count the different source files
-               int32 sourceFileCount = 1;
-               for (int32 i = 1; i < functionCount; i++) {
-                       if (_CompareSourceFileNames(functions[i - 
1]->SourceFile(),
-                                       functions[i]->SourceFile()) != 0) {
-                               sourceFileCount++;
-                       }
-               }
+               SourcePathComponentNode* sourcelessNode = new(std::nothrow)
+                       SourcePathComponentNode(NULL, "<no source file>", NULL, 
NULL);
+               ObjectDeleter<SourcePathComponentNode> sourceNodeDeleter(
+                       sourcelessNode);
 
-               // allocate and init the indices for the source files
-               fSourceFileIndices = new(std::nothrow) int32[sourceFileCount];
-               if (fSourceFileIndices == NULL)
-                       return;
-               fSourceFileCount = sourceFileCount;
 
-               fSourceFileIndices[0] = 0;
+               for (int32 i = 0; i < functionCount; i++) {
+                       if (!_BuildFunctionSourcePath(functions[i], 
sourcelessNode))
+                               return;
+               }
 
-               int32 sourceFileIndex = 1;
-               for (int32 i = 1; i < functionCount; i++) {
-                       if (_CompareSourceFileNames(functions[i - 
1]->SourceFile(),
-                                       functions[i]->SourceFile()) != 0) {
-                               fSourceFileIndices[sourceFileIndex++] = i;
+               if (sourcelessNode->CountChildren() != 0) {
+                       if (fChildPathComponents.BinaryInsert(sourcelessNode,
+                                       
&SourcePathComponentNode::CompareComponents)) {
+                               fSourcelessNode = sourcelessNode;
+                               sourceNodeDeleter.Detach();
                        }
                }
 
-               fFunctions = functionsDeleter.Detach();
-               fFunctionCount = functionCount;
-
-               NotifyNodesAdded(TreeTablePath(), 0, fSourceFileCount);
+               NotifyNodesAdded(TreeTablePath(), 0,
+                       fChildPathComponents.CountItems());
        }
 
        virtual int32 CountColumns() const
@@ -139,34 +255,17 @@ public:
        virtual int32 CountChildren(void* parent) const
        {
                if (parent == this)
-                       return fSourceFileCount;
-
-               if (parent >= fSourceFileIndices
-                       && parent < fSourceFileIndices + fSourceFileCount) {
-                       int32 sourceIndex = (int32*)parent - fSourceFileIndices;
-                       return _CountSourceFileFunctions(sourceIndex);
-               }
+                       return fChildPathComponents.CountItems();
 
-               return 0;
+               return ((SourcePathComponentNode*)parent)->CountChildren();
        }
 
        virtual void* ChildAt(void* parent, int32 index) const
        {
-               if (parent == this) {
-                       return index >= 0 && index < fSourceFileCount
-                               ? fSourceFileIndices + index : NULL;
-               }
-
-               if (parent >= fSourceFileIndices
-                       && parent < fSourceFileIndices + fSourceFileCount) {
-                       int32 sourceIndex = (int32*)parent - fSourceFileIndices;
-                       int32 count = _CountSourceFileFunctions(sourceIndex);
-                       int32 firstFunctionIndex = 
fSourceFileIndices[sourceIndex];
-                       return index >= 0 && index < count
-                               ? fFunctions[firstFunctionIndex + index] : NULL;
-               }
+               if (parent == this)
+                       return fChildPathComponents.ItemAt(index);
 
-               return NULL;
+               return ((SourcePathComponentNode*)parent)->ChildAt(index);
        }
 
        virtual bool GetValueAt(void* object, int32 columnIndex, BVariant& 
value)
@@ -177,84 +276,168 @@ public:
                if (object == this)
                        return false;
 
-               if (object >= fSourceFileIndices
-                       && object < fSourceFileIndices + fSourceFileCount) {
-                       int32 index = *(int32*)object;
-                       if (LocatableFile* file = 
fFunctions[index]->SourceFile()) {
-                               BString path;
-                               file->GetPath(path);
-                               value.SetTo(path);
-                       } else
-                               value.SetTo("<no source file>", 
B_VARIANT_DONT_COPY_DATA);
+               SourcePathComponentNode* node = 
(SourcePathComponentNode*)object;
 
-                       return true;
-               }
+               value.SetTo(node->ComponentName(), B_VARIANT_DONT_COPY_DATA);
 
-               FunctionInstance* function = (FunctionInstance*)object;
-               value.SetTo(function->PrettyName(), B_VARIANT_DONT_COPY_DATA);
                return true;
        }
 
        bool GetFunctionPath(FunctionInstance* function, TreeTablePath& _path)
        {
-               int32 index = -1;
-               for (int32 i = 0; i < fFunctionCount; i++) {
-                       if (fFunctions[i] == function) {
-                               index = i;
-                               break;
+               if (function == NULL)
+                       return false;
+
+               LocatableFile* sourceFile = function->SourceFile();
+               SourcePathComponentNode* node = NULL;
+               int32 childIndex = -1;
+               if (sourceFile == NULL) {
+                       node = fSourcelessNode;
+                       _path.AddComponent(fChildPathComponents.IndexOf(node));
+               } else {
+                       BString sourcePath;
+                       sourceFile->GetPath(sourcePath);
+
+                       if (sourcePath.IsEmpty())
+                               return false;
+
+                       BString searchPath;
+                       while (!sourcePath.IsEmpty()) {
+                               if (sourcePath[0] == '/')
+                                       sourcePath.Remove(0, 1);
+                               int32 separatorIndex = 
sourcePath.FindFirst('/');
+                               if (separatorIndex == -1) {
+                                       searchPath = sourcePath;
+                                       sourcePath.Truncate(0);
+                               } else
+                                       sourcePath.MoveInto(searchPath, 0, 
separatorIndex);
+
+                               if (node == NULL) {
+                                       childIndex = 
fChildPathComponents.BinarySearchIndexByKey(
+                                               searchPath,
+                                               
&SourcePathComponentNode::CompareByComponentName);
+                                       node = 
fChildPathComponents.ItemAt(childIndex);
+                               } else {
+                                       childIndex = 
node->FindChildIndexByName(searchPath);
+                                       node = node->ChildAt(childIndex);
+                               }
+
+                               if (childIndex < 0)
+                                       return false;
+
+                               _path.AddComponent(childIndex);
                        }
                }
 
-               if (index < 0)
+               if (node == NULL)
                        return false;
 
-               int32 sourceIndex = fSourceFileCount - 1;
-               while (fSourceFileIndices[sourceIndex] > index)
-                       sourceIndex--;
+               childIndex = node->FindChildIndexByName(function->PrettyName());
+               if (childIndex < 0)
+                       return false;
 
-               _path.Clear();
-               return _path.AddComponent(sourceIndex)
-                       && _path.AddComponent(index - 
fSourceFileIndices[sourceIndex]);
+               _path.AddComponent(childIndex);
+               return true;
        }
 
        bool GetObjectForPath(const TreeTablePath& path,
                LocatableFile*& _sourceFile, FunctionInstance*& _function)
        {
-               int32 componentCount = path.CountComponents();
-               if (componentCount == 0 || componentCount > 2)
-                       return false;
+               SourcePathComponentNode* node = fChildPathComponents.ItemAt(
+                       path.ComponentAt(0));
 
-               int32 sourceIndex = path.ComponentAt(0);
-               if (sourceIndex < 0 || sourceIndex >= fSourceFileCount)
+               if (node == NULL)
                        return false;
 
-               _sourceFile = 
fFunctions[fSourceFileIndices[sourceIndex]]->SourceFile();
+               for (int32 i = 1; i < path.CountComponents(); i++)
+                       node = node->ChildAt(path.ComponentAt(i));
 
-               _function = NULL;
-
-               if (componentCount == 2) {
-                       int32 index = path.ComponentAt(1);
-                       if (index >= 0 && index < 
_CountSourceFileFunctions(sourceIndex))
-                               _function = 
fFunctions[fSourceFileIndices[sourceIndex] + index];
+               if (node != NULL) {
+                       _sourceFile = node->SourceFile();
+                       _function = node->Function();
+                       return true;
                }
 
-               return true;
+               return false;
        }
 
-       int32 CountSourceFiles() const
+private:
+       bool _BuildFunctionSourcePath(FunctionInstance* function,
+               SourcePathComponentNode* sourcelessNode)
        {
-               return fSourceFileCount;
+               LocatableFile* sourceFile = function->SourceFile();
+               if (sourceFile == NULL)
+                       return _AddFunctionNode(sourcelessNode, function, NULL);
+
+               BString sourcePath;
+               sourceFile->GetPath(sourcePath);
+               if (sourcePath.IsEmpty())
+                       return false;
+
+               return _AddNextPathComponent(NULL, sourcePath, function, 
sourceFile);
        }
 
-private:
-       int32 _CountSourceFileFunctions(int32 sourceIndex) const
+       bool _AddNextPathComponent(SourcePathComponentNode* parent,
+               BString& childPath, FunctionInstance* function, LocatableFile* 
file)
        {
-               if (sourceIndex < 0 || sourceIndex >= fSourceFileCount)
-                       return 0;
+               if (childPath[0] == '/')
+                       childPath.Remove(0, 1);
+
+               BString pathComponent;
+               int32 pathSeparatorIndex = childPath.FindFirst('/');
+               if (pathSeparatorIndex == -1)
+                       pathComponent = childPath;
+               else
+                       childPath.MoveInto(pathComponent, 0, 
pathSeparatorIndex);
+
+               SourcePathComponentNode* currentNode = NULL;
+               if (parent == NULL) {
+                       currentNode = 
fChildPathComponents.BinarySearchByKey(pathComponent,
+                               
SourcePathComponentNode::CompareByComponentName);
+               } else
+                       currentNode = parent->FindChildByName(pathComponent);
+
+               if (currentNode == NULL) {
+                       currentNode = new(std::nothrow) 
SourcePathComponentNode(parent,
+                               pathComponent, NULL, NULL);
+                       if (currentNode == NULL)
+                               return false;
+                       ObjectDeleter<SourcePathComponentNode> 
nodeDeleter(currentNode);
+                       if (parent != NULL) {
+                               if (!parent->AddChild(currentNode))
+                                       return false;
+                       } else {
+                               if 
(!fChildPathComponents.BinaryInsert(currentNode,
+                                       
&SourcePathComponentNode::CompareComponents)) {
+                                       return false;
+                               }
+                       }
+                       nodeDeleter.Detach();
+               }
+
+               if (pathSeparatorIndex == -1)
+                       return _AddFunctionNode(currentNode, function, file);
+
+               return _AddNextPathComponent(currentNode, childPath, function, 
file);
+       }
+
+       bool _AddFunctionNode(SourcePathComponentNode* parent,
+               FunctionInstance* function, LocatableFile* file)
+       {
+               SourcePathComponentNode* functionNode = new(std::nothrow)
+                       SourcePathComponentNode(parent, function->PrettyName(), 
file,
+                               function);
+
+               if (functionNode == NULL)
+                       return B_NO_MEMORY;
 
-               int32 nextFunctionIndex = sourceIndex + 1 < fSourceFileCount
-                       ? fSourceFileIndices[sourceIndex + 1] : fFunctionCount;
-               return nextFunctionIndex - fSourceFileIndices[sourceIndex];
+               ObjectDeleter<SourcePathComponentNode> 
nodeDeleter(functionNode);
+
+               if (!parent->AddChild(functionNode))
+                       return false;
+
+               nodeDeleter.Detach();
+               return true;
        }
 
        static int _CompareSourceFileNames(LocatableFile* a, LocatableFile* b)
@@ -290,11 +473,12 @@ private:
        }
 
 private:
-       ImageDebugInfo*         fImageDebugInfo;
-       FunctionInstance**      fFunctions;
-       int32                           fFunctionCount;
-       int32*                          fSourceFileIndices;
-       int32                           fSourceFileCount;
+       typedef BObjectList<SourcePathComponentNode> ChildPathComponentList;
+
+private:
+       ImageDebugInfo*                 fImageDebugInfo;
+       ChildPathComponentList  fChildPathComponents;
+       SourcePathComponentNode* fSourcelessNode;
 };
 
 
@@ -364,7 +548,7 @@ ImageFunctionsView::SetImageDebugInfo(ImageDebugInfo* 
imageDebugInfo)
 
        // If there's only one source file (i.e. "no source file"), expand the 
item.
        if (fImageDebugInfo != NULL
-               && fFunctionsTableModel->CountSourceFiles() == 1) {
+               && fFunctionsTableModel->CountChildren(fFunctionsTableModel) == 
1) {
                TreeTablePath path;
                path.AddComponent(0);
                fFunctionsTable->SetNodeExpanded(path, true, false);
@@ -388,6 +572,7 @@ ImageFunctionsView::SetFunction(FunctionInstance* function)
                fFunctionsTable->SetNodeExpanded(path, true, true);
                fFunctionsTable->SelectNode(path, false);
                fFunctionsTable->ScrollToNode(path);
+               fFunctionsTable->ResizeAllColumnsToPreferred();
        } else
                fFunctionsTable->DeselectAllNodes();
 }
diff --git 
a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h 
b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h
index eb4ed26..55fb959 100644
--- a/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h
+++ b/src/apps/debugger/user_interface/gui/team_window/ImageFunctionsView.h
@@ -1,5 +1,6 @@
 /*
  * Copyright 2009, Ingo Weinhold, ingo_weinhold@xxxxxx.
+ * Copyright 2013, Rene Gollent, rene@xxxxxxxxxxx.
  * Distributed under the terms of the MIT License.
  */
 #ifndef IMAGE_FUNCTIONS_VIEW_H
@@ -36,6 +37,7 @@ public:
 
 private:
                        class FunctionsTableModel;
+                       class SourcePathComponentNode;
 
 private:
        // TreeTableListener


Other related posts:

  • » [haiku-commits] haiku: hrev45645 - src/apps/debugger/user_interface/gui/team_window - anevilyak