KDevelop API Documentation

languages/cpp/debugger/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.0.4.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Oct 6 17:39:01 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003