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