1 /*
2 SPDX-FileCopyrightText: 2012 Sven Brauch <svenbrauch@googlemail.com>
3
4 SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 #include "pdbframestackmodel.h"
8 #include "debugsession.h"
9 #include <QRegExp>
10
11 #include <QDebug>
12 #include "debuggerdebug.h"
13
14 using namespace KDevelop;
15
16 namespace Python {
17
PdbFrameStackModel(IDebugSession * session)18 PdbFrameStackModel::PdbFrameStackModel(IDebugSession* session): FrameStackModel(session), m_debuggerAtFrame(0)
19 {
20
21 }
22
debuggerAtFrame() const23 int PdbFrameStackModel::debuggerAtFrame() const
24 {
25 return m_debuggerAtFrame;
26 }
27
setDebuggerAtFrame(int newFrame)28 void PdbFrameStackModel::setDebuggerAtFrame(int newFrame)
29 {
30 // Q_ASSERT(newFrame >= 0);
31 m_debuggerAtFrame = newFrame;
32 }
33
framesFetched(QByteArray framelist)34 void PdbFrameStackModel::framesFetched(QByteArray framelist)
35 {
36 qCDebug(KDEV_PYTHON_DEBUGGER) << "frames fetched:" << framelist;
37 QList<QByteArray> lines = framelist.split('\n');
38 QList<FrameItem> frames;
39 bool parsingLocation = false;
40 FrameItem* currentFrame = nullptr;
41 int framesCount = 0;
42 foreach ( const QString& line, lines ) {
43 if ( line.startsWith("-> ") ) {
44 parsingLocation = true;
45 if ( currentFrame ) {
46 frames << *currentFrame;
47 }
48 currentFrame = new FrameItem();
49 currentFrame->nr = framesCount;
50 framesCount++;
51 }
52 else if ( parsingLocation ) {
53 QRegExp location("(\\>?)\\s*(.*)\\(([0-9]+)\\)(.*)");
54 // version 1 has some *really* weird "greedy" ruleset which makes no sense at all for me
55 location.setPatternSyntax(QRegExp::RegExp2);
56 if ( location.exactMatch(line) ) {
57 qCDebug(KDEV_PYTHON_DEBUGGER) << location.capturedTexts();
58 if ( ! location.capturedTexts().at(1).isEmpty() ) {
59 m_debuggerAtFrame = framesCount;
60 }
61 currentFrame->file = QUrl::fromLocalFile(location.capturedTexts().at(2));
62 currentFrame->line = location.capturedTexts().at(3).toInt() - 1;
63 currentFrame->name = location.capturedTexts().at(4);
64 }
65 else {
66 qCDebug(KDEV_PYTHON_DEBUGGER) << "regular expression mismatches" << line;
67 }
68 }
69 }
70 m_debuggerAtFrame = framesCount - m_debuggerAtFrame - 1;
71 qCDebug(KDEV_PYTHON_DEBUGGER) << "at frame:" << m_debuggerAtFrame;
72 QVector<FrameItem> framesReversed;
73 framesReversed.reserve(frames.length());
74 for ( int i = frames.length() - 1; i >= 0; i-- ) {
75 framesReversed.append(frames.at(i));
76 framesReversed.last().nr = framesCount - i - 2;
77 }
78 setFrames(0, framesReversed);
79 }
80
threadsFetched(QByteArray threadsData)81 void PdbFrameStackModel::threadsFetched(QByteArray threadsData)
82 {
83 qCDebug(KDEV_PYTHON_DEBUGGER) << "threads fetched" << threadsData;
84 qCDebug(KDEV_PYTHON_DEBUGGER) << "Implement me: Thread debugging is not supported by pdb.";
85 QVector<ThreadItem> threads;
86 ThreadItem mainThread;
87 mainThread.nr = 0;
88 mainThread.name = "main thread";
89 threads << mainThread;
90 setThreads(threads);
91 setCurrentThread(0);
92 }
93
fetchFrames(int,int,int)94 void PdbFrameStackModel::fetchFrames(int /*threadNumber*/, int /*from*/, int /*to*/)
95 {
96 qCDebug(KDEV_PYTHON_DEBUGGER) << "frames requested";
97 InternalPdbCommand* cmd = new InternalPdbCommand(this, "framesFetched", "where\n");
98 static_cast<DebugSession*>(session())->addCommand(cmd);
99 }
100
fetchThreads()101 void PdbFrameStackModel::fetchThreads()
102 {
103 qCDebug(KDEV_PYTHON_DEBUGGER) << "threads requested";
104 // pdb doesn't support threads.
105 InternalPdbCommand* cmd = new InternalPdbCommand(this, "threadsFetched", "pass\n");
106 static_cast<DebugSession*>(session())->addCommand(cmd);
107 }
108
109 }
110
111