00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
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;
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
00122 clear();
00123 while (char *end = strchr(str, '\n'))
00124 {
00125
00126 *end = 0;
00127 if (*str == '*' || *str == ' ')
00128 {
00129 QString threadDesc = QString(str);
00130 ThreadStackItem* thread = new ThreadStackItem(this, str);
00131
00132 if (*str == '*')
00133 viewedThread_ = thread;
00134 }
00135 str = end+1;
00136 }
00137 }
00138
00139
00140
00141 void FramestackWidget::parseGDBBacktraceList(char *str)
00142 {
00143
00144
00145
00146
00147
00148
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
00161 if (*str == '#')
00162 {
00163
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;
00172 }
00173
00174
00175
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;
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"