KDevelop API Documentation

framestackwidget.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002     begin                : Sun Aug 8 1999
00003     copyright            : (C) 1999 by John Birch
00004     email                : jbb@kdevelop.org
00005  ***************************************************************************/
00006 
00007 /***************************************************************************
00008  *                                                                         *
00009  *   This program is free software; you can redistribute it and/or modify  *
00010  *   it under the terms of the GNU General Public License as published by  *
00011  *   the Free Software Foundation; either version 2 of the License, or     *
00012  *   (at your option) any later version.                                   *
00013  *                                                                         *
00014  ***************************************************************************/
00015 
00016 #include "framestackwidget.h"
00017 #include "gdbparser.h"
00018 
00019 #include <klocale.h>
00020 
00021 #include <qheader.h>
00022 #include <qlistbox.h>
00023 #include <qregexp.h>
00024 #include <qstrlist.h>
00025 
00026 #include <ctype.h>
00027 
00028 
00029 /***************************************************************************/
00030 /***************************************************************************/
00031 /***************************************************************************/
00032 
00033 namespace GDBDebugger
00034 {
00035 
00036 FramestackWidget::FramestackWidget(QWidget *parent, const char *name, WFlags f)
00037         : QListView(parent, name, f),
00038         viewedThread_(0)
00039 {
00040     setRootIsDecorated(true);
00041     setSorting(-1);
00042     setSelectionMode(Single);
00043     addColumn(QString::null);
00044     header()->hide();
00045 
00046     connect( this, SIGNAL(clicked(QListViewItem*)),
00047              this, SLOT(slotSelectionChanged(QListViewItem*)) );
00048 }
00049 
00050 
00051 /***************************************************************************/
00052 
00053 FramestackWidget::~FramestackWidget()
00054 {}
00055 
00056 /***************************************************************************/
00057 
00058 QListViewItem *FramestackWidget::lastChild() const
00059 {
00060     QListViewItem* child = firstChild();
00061     if (child)
00062         while (QListViewItem* nextChild = child->nextSibling())
00063             child = nextChild;
00064 
00065     return child;
00066 }
00067 
00068 // **************************************************************************
00069 
00070 void FramestackWidget::clear()
00071 {
00072     viewedThread_     = 0;
00073 
00074     QListView::clear();
00075 }
00076 
00077 /***************************************************************************/
00078 
00079 void FramestackWidget::slotSelectionChanged(QListViewItem *thisItem)
00080 {
00081     ThreadStackItem *thread = dynamic_cast<ThreadStackItem*> (thisItem);
00082     if (thread)
00083     {
00084         slotSelectFrame(0, thread->threadNo());
00085     }
00086     else
00087     {
00088         FrameStackItem *frame = dynamic_cast<FrameStackItem*> (thisItem);
00089         if (frame)
00090             slotSelectFrame(frame->frameNo(), frame->threadNo());
00091     }
00092 }
00093 
00094 /***************************************************************************/
00095 
00096 // someone (the vartree :-)) wants us to select this frame.
00097 void FramestackWidget::slotSelectFrame(int frameNo, int threadNo)
00098 {
00099     FrameStackItem *frame = 0;
00100     if (threadNo != -1)
00101     {
00102         viewedThread_ = findThread(threadNo);
00103         if (!viewedThread_)
00104         {
00105             Q_ASSERT(!viewedThread_);
00106             return;                 // fatal
00107         }
00108     }
00109 
00110     frame = findFrame(frameNo, threadNo);
00111     if (frame)
00112         setSelected(frame, true);
00113 
00114     emit selectFrame(frameNo, threadNo, !(frame));
00115 }
00116 
00117 /***************************************************************************/
00118 
00119 void FramestackWidget::parseGDBThreadList(char *str)
00120 {
00121     // on receipt of a thread list we must always clear the list.
00122     clear();
00123     while (char *end = strchr(str, '\n'))
00124     {
00125         // make it a string and skip non-thread list strings
00126         *end = 0;
00127         if (*str == '*' || *str == ' ')
00128         {
00129             QString threadDesc = QString(str);
00130             ThreadStackItem* thread = new ThreadStackItem(this, str);
00131             // The thread with a '*' is always the viewedthread
00132             if (*str == '*')
00133                 viewedThread_ = thread;
00134         }
00135         str = end+1;
00136     }
00137 }
00138 
00139 /***************************************************************************/
00140 
00141 void FramestackWidget::parseGDBBacktraceList(char *str)
00142 {
00143     // #0  Test::Test (this=0x8073b20, parent=0x0, name=0x0) at test.cpp:224
00144     // #1  0x804bba9 in main (argc=1, argv=0xbffff9c4) at main.cpp:24
00145 
00146     // If we don't have a thread program then clear the list.
00147     // We don't have to clear the list in a threaded programe because that's
00148     // already been done in the parseGDBThreadList() method.
00149     if (!viewedThread_)
00150         clear();
00151 
00152     if(!strlen(str))
00153         return;
00154     
00155     if (strncmp(str, "No stack.", 9) == 0)
00156         return;
00157 
00158     while (char* end = strchr(str, '\n'))
00159     {
00160         // Don't bother with extra data
00161         if (*str == '#')
00162         {
00163             // make it a string
00164             *end = 0;
00165             QString frameDesc = QString(str);
00166             if (viewedThread_)
00167                 new FrameStackItem(viewedThread_, frameDesc);
00168             else
00169                 new FrameStackItem(this, frameDesc);
00170         }
00171         str = end+1;                          // next string
00172     }
00173 
00174     // Make sure the first frame in the stopped backtrace is selected
00175     // and open
00176     if (viewedThread_)
00177         viewedThread_->setOpen(true);
00178     else
00179     {
00180         if (FrameStackItem* frame = (FrameStackItem*) firstChild())
00181             frame->setOpen(true);
00182     }
00183 }
00184 
00185 /***************************************************************************/
00186 
00187 QString FramestackWidget::getFrameName(int frameNo, int threadNo)
00188 {
00189     FrameStackItem *frame = findFrame(frameNo, threadNo);
00190     if (frame)
00191     {
00192         QString frameStr = frame->text(0);
00193         const char *frameData = frameStr.latin1();
00194         if (char *paramStart = strchr(frameData, '('))
00195         {
00196             char *fnstart = paramStart-2;
00197             while (fnstart > frameData)
00198             {
00199                 if (isspace(*fnstart))
00200                     break;
00201                 fnstart--;
00202             }
00203             if (threadNo != -1)
00204             {
00205                 QString frameName("T%1#%2 %3(...)");
00206                 return frameName.arg(threadNo).arg(frameNo)
00207                        .arg(QCString(fnstart, paramStart-fnstart+1));
00208             }
00209 
00210             QString frameName("#%1 %2(...)");
00211             return frameName.arg(frameNo).arg(
00212                                 QCString(fnstart, paramStart-fnstart+1));
00213         }
00214     }
00215     return i18n("No stack");
00216 }
00217 
00218 // **************************************************************************
00219 
00220 ThreadStackItem *FramestackWidget::findThread(int threadNo)
00221 {
00222     QListViewItem *sibling = firstChild();
00223     while (sibling)
00224     {
00225         ThreadStackItem *thread = dynamic_cast<ThreadStackItem*> (sibling);
00226         if (thread && thread->threadNo() == threadNo)
00227         {
00228             return thread;
00229         }
00230         sibling = sibling->nextSibling();
00231     }
00232 
00233     return 0;
00234 }
00235 
00236 // **************************************************************************
00237 
00238 FrameStackItem *FramestackWidget::findFrame(int frameNo, int threadNo)
00239 {
00240     QListViewItem* frameItem = 0;
00241 
00242     if (threadNo != -1)
00243     {
00244         ThreadStackItem *thread = findThread(threadNo);
00245         if (thread == 0)
00246             return 0;     // no matching thread?
00247         frameItem = thread->firstChild();
00248     }
00249     else
00250         frameItem = firstChild();
00251 
00252     while (frameItem)
00253     {
00254         if (((FrameStackItem*)frameItem)->frameNo() == frameNo)
00255             break;
00256 
00257         frameItem = frameItem->nextSibling();
00258     }
00259     return (FrameStackItem*)frameItem;
00260 }
00261 
00262 // **************************************************************************
00263 // **************************************************************************
00264 // **************************************************************************
00265 
00266 FrameStackItem::FrameStackItem(FramestackWidget *parent, const QString &frameDesc)
00267         : QListViewItem(parent, parent->lastChild()),
00268         frameNo_(-1),
00269         threadNo_(-1)
00270 {
00271     setText(VarNameCol, frameDesc);
00272     QRegExp num("[0-9]*");
00273     int start;
00274     if ((start=num.search(frameDesc,1))>=0)
00275         frameNo_ = frameDesc.mid(start, num.matchedLength()).toInt();
00276 }
00277 
00278 // **************************************************************************
00279 
00280 FrameStackItem::FrameStackItem(ThreadStackItem *parent, const QString &frameDesc)
00281         : QListViewItem(parent, parent->lastChild()),
00282         frameNo_(-1),
00283         threadNo_(parent->threadNo())
00284 {
00285     setText(VarNameCol, frameDesc);
00286     QRegExp num("[0-9]*");
00287     int start;
00288     if ((start=num.search(frameDesc,1))>=0)
00289         frameNo_ = frameDesc.mid(start, num.matchedLength()).toInt();
00290 }
00291 
00292 // **************************************************************************
00293 
00294 FrameStackItem::~FrameStackItem()
00295 {}
00296 
00297 // **************************************************************************
00298 
00299 QListViewItem *FrameStackItem::lastChild() const
00300 {
00301     QListViewItem* child = firstChild();
00302     if (child)
00303         while (QListViewItem* nextChild = child->nextSibling())
00304             child = nextChild;
00305 
00306     return child;
00307 }
00308 
00309 // **************************************************************************
00310 
00311 void FrameStackItem::setOpen(bool open)
00312 {
00313     if (open)
00314         ((FramestackWidget*)listView())->slotSelectFrame(0, threadNo());
00315 
00316     QListViewItem::setOpen(open);
00317 }
00318 
00319 // **************************************************************************
00320 // **************************************************************************
00321 // **************************************************************************
00322 
00323 ThreadStackItem::ThreadStackItem(FramestackWidget *parent, const QString &threadDesc)
00324         : QListViewItem(parent, threadDesc),
00325         threadNo_(-1)
00326 {
00327     setText(VarNameCol, threadDesc);
00328     setExpandable(true);
00329     QRegExp num("[0-9]*");
00330     int start;
00331     if ((start=num.search(threadDesc,2))>=0)
00332         threadNo_ = threadDesc.mid(start, num.matchedLength()).toInt();
00333 }
00334 
00335 // **************************************************************************
00336 
00337 ThreadStackItem::~ThreadStackItem()
00338 {}
00339 
00340 // **************************************************************************
00341 
00342 QListViewItem *ThreadStackItem::lastChild() const
00343 {
00344     QListViewItem* child = firstChild();
00345     if (child)
00346         while (QListViewItem* nextChild = child->nextSibling())
00347             child = nextChild;
00348 
00349     return child;
00350 }
00351 
00352 // **************************************************************************
00353 
00354 void ThreadStackItem::setOpen(bool open)
00355 {
00356     if (open)
00357         ((FramestackWidget*)listView())->slotSelectFrame(0, threadNo());
00358 
00359     QListViewItem::setOpen(open);
00360 }
00361 
00362 }
00363 
00364 /***************************************************************************/
00365 /***************************************************************************/
00366 /***************************************************************************/
00367 
00368 #include "framestackwidget.moc"
KDE Logo
This file is part of the documentation for KDevelop Version 3.1.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Feb 22 09:22:29 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003