[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: playground/devtools/kategdbplugin
From: Ian Wakeling <ian.wakeling () ntlworld ! com>
Date: 2010-07-31 23:51:33
Message-ID: 20100731235133.A7970AC783 () svn ! kde ! org
[Download RAW message or body]
SVN commit 1157717 by ianwakeling:
Ensure that breakpoints have been successfully set before going on to jump/continue \
commands in move-pc and run-to-cursor. Build on that to add tracking of breakpoints \
being set / cleared, etc and use it to hook in slighty restructured version of code \
from Kare for displaying breakpoints in editor window.
M +109 -9 debugview.cpp
M +30 -3 debugview.h
M +100 -3 plugin_kategdb.cpp
M +4 -0 plugin_kategdb.h
--- trunk/playground/devtools/kategdbplugin/debugview.cpp #1157716:1157717
@@ -170,7 +170,7 @@
{
QString cmd( "break " );
QString lineNum;
- lineNum.setNum( line );
+ lineNum.setNum( line + 1 );
cmd += url.path() + ":" + lineNum;
issueCommand( cmd );
}
@@ -182,7 +182,7 @@
{
QString cmd( "tbreak " );
QString lineNum;
- lineNum.setNum( line );
+ lineNum.setNum( line + 1 );
cmd += url.path() + ":" + lineNum;
issueCommand( cmd, new MovePCCompletion( url, line ) );
}
@@ -194,7 +194,7 @@
{
QString cmd( "tbreak " );
QString lineNum;
- lineNum.setNum( line );
+ lineNum.setNum( line + 1 );
cmd += url.path() + ":" + lineNum;
issueCommand( cmd, new RunToCursorCompletion() );
}
@@ -314,8 +314,9 @@
}
DebugView::MovePCCompletion::MovePCCompletion( KUrl const& url, int line )
-: url( url ),
- line( line )
+: destUrl( url ),
+ destLine( line ),
+ tbreakOK( false )
{
}
@@ -325,14 +326,28 @@
void DebugView::MovePCCompletion::operator()( DebugView* view )
{
+ if( tbreakOK )
+ {
QString cmd( "jump " );
QString lineNum;
- lineNum.setNum( line );
- cmd += url.path() + ":" + lineNum;
+ lineNum.setNum( destLine );
+ cmd += destUrl.path() + ":" + lineNum;
view->issueCommand( cmd );
}
+ else
+ {
+ view->outputText( "tbreak failed: aborting move-pc" );
+ view->promptInput();
+ }
+}
+void DebugView::MovePCCompletion::breakpointSet()
+{
+ tbreakOK = true;
+}
+
DebugView::RunToCursorCompletion::RunToCursorCompletion()
+: tbreakOK( false )
{
}
@@ -342,9 +357,22 @@
void DebugView::RunToCursorCompletion::operator()( DebugView* view )
{
+ if( tbreakOK )
+ {
view->issueCommand( "continue" );
}
+ else
+ {
+ view->outputText( "tbreak failed: aborting run-to-cursor" );
+ view->promptInput();
+ }
+}
+void DebugView::RunToCursorCompletion::breakpointSet()
+{
+ tbreakOK = true;
+}
+
void DebugView::processOutput( QString const& output )
{
QRegExp prompt( "\\(gdb\\).*" );
@@ -352,6 +380,7 @@
QRegExp stackFrame( \
"#\\d+\\s+(?:0x[\\da-f]+\\s*in\\s*)?[^\\s]+\\s*\\([^)]*\\)\\s*at\\s*([^:]+):\\d+.*" \
);
QRegExp changeFile( \
"(?:Breakpoint\\s*\\d+,\\s*|0x[\\da-f]+\\s*in\\s*)?[^\\s]+\\s*\\([^)]*\\)\\s*at\\s*([^:]+):(\\d+).*" \
); QRegExp changeLine( "(\\d+)\\s+.*" );
+ QRegExp breakpointConfirmation( \
"Breakpoint\\s*(\\d+)\\s*at\\s*0x[\\da-f]+:\\s*file\\s*([^,]+),\\s*line\\s*(\\d+).*" \
); QStringList lines = output.split( '\n' );
for( QStringList::Iterator it = lines.begin();
@@ -434,7 +463,7 @@
int lineNum = changeFile.cap( 2 ).toInt();
// GDB uses 1 based line numbers, kate uses 0 based...
- emit debugLocationChanged( currentFile.toLatin1(), lineNum - 1 \
); + emit debugLocationChanged( currentFile.toLocal8Bit(), lineNum \
- 1 ); }
else if( changeLine.exactMatch( line ) )
{
@@ -448,8 +477,26 @@
}
// GDB uses 1 based line numbers, kate uses 0 based...
- emit debugLocationChanged( currentFile.toLatin1(), lineNum - 1 \
); + emit debugLocationChanged( currentFile.toLocal8Bit(), lineNum \
- 1 ); }
+ else if( breakpointConfirmation.exactMatch( line ) )
+ {
+ int bpNum = breakpointConfirmation.cap( 1 ).toInt();
+ QString file = breakpointConfirmation.cap( 2 ).trimmed();
+ int lineNum = breakpointConfirmation.cap( 3 ).toInt();
+
+ breakpoints.append( Breakpoint( bpNum, file, lineNum ) );
+
+ // GDB uses 1 based line numbers, kate uses 0 based...
+ emit breakpointSet( file.toLocal8Bit(), lineNum - 1 );
+
+ if( commandCompletion != NULL )
+ {
+ commandCompletion->breakpointSet();
+ }
+
+ outputText( line );
+ }
else if( prompt.exactMatch( line ) )
{
if( commandCompletion != NULL )
@@ -508,6 +555,14 @@
void DebugView::issueCommand( QString const& cmd, CommandCompletion* completion )
{
+ QRegExp breakpointCmd( "(de?l?e?t?e?|disa?b?l?e?|ena?b?l?e?)(?:\\s*(\\d+))?.*" \
); +
+ if( breakpointCmd.exactMatch( cmd ) )
+ {
+ updateBreakpointState( breakpointCmd.cap( 1 ),
+ breakpointCmd.cap( 2 ) );
+ }
+
commandCompletion = completion;
outputText( "(gdb) " + cmd );
inputArea->clear();
@@ -517,3 +572,48 @@
debugProcess->write( cmd.toLocal8Bit() );
debugProcess->write( "\n" );
}
+
+void DebugView::updateBreakpointState( QString const& cmd, QString const& bpNum )
+{
+ QList<Breakpoint>::iterator iter = breakpoints.begin();
+
+ // d[elete], dis[able] and en[able] without a breakpoint number all mean
+ // do that command for all breakpoints
+ while( iter != breakpoints.end() )
+ {
+ if( bpNum.isEmpty() ||
+ bpNum.toInt() == iter->bpNum )
+ {
+ if( cmd.length() < 2 || cmd.at(1) == 'e' )
+ {
+ emit breakpointClear( iter->fileName.toLocal8Bit(),
+ iter->lineNum - 1 );
+ iter = breakpoints.erase( iter );
+ }
+ else
+ {
+ if( cmd.at(1) == 'i' )
+ {
+ emit breakpointDisable( iter->fileName.toLocal8Bit(),
+ iter->lineNum - 1 );
+ }
+ else if( cmd.at(1) == 'n' )
+ {
+ emit breakpointEnable( iter->fileName.toLocal8Bit(),
+ iter->lineNum - 1 );
+ }
+ ++iter;
+ }
+
+ if( !bpNum.isEmpty() )
+ {
+ // only supposed to be doing one and we've found it
+ iter = breakpoints.end();
+ }
+ }
+ else
+ {
+ ++iter;
+ }
+ }
+}
--- trunk/playground/devtools/kategdbplugin/debugview.h #1157716:1157717
@@ -60,6 +60,10 @@
//Signals
signals:
void debugLocationChanged( const char* filename, int lineNum );
+ void breakpointSet( const char* filename, int lineNum );
+ void breakpointClear( const char* filename, int lineNum );
+ void breakpointDisable( const char* filename, int lineNum );
+ void breakpointEnable( const char* filename, int lineNum );
private:
enum State
@@ -84,6 +88,7 @@
CommandCompletion() {}
virtual ~CommandCompletion() {}
virtual void operator()( DebugView* view ) = 0;
+ virtual void breakpointSet() {}
};
class MovePCCompletion : public CommandCompletion
@@ -92,20 +97,40 @@
MovePCCompletion( KUrl const& url, int line );
virtual ~MovePCCompletion();
virtual void operator()( DebugView* view );
+ virtual void breakpointSet();
private:
- KUrl url;
- int line;
+ KUrl destUrl;
+ int destLine;
+ bool tbreakOK;
};
- struct RunToCursorCompletion : public CommandCompletion
+ class RunToCursorCompletion : public CommandCompletion
{
public:
RunToCursorCompletion();
virtual ~RunToCursorCompletion();
virtual void operator()( DebugView* view );
+ virtual void breakpointSet();
+
+ private:
+ bool tbreakOK;
};
+ struct Breakpoint
+ {
+ Breakpoint( int bpNum, QString const& fileName, int lineNum )
+ : bpNum( bpNum ),
+ fileName( fileName ),
+ lineNum( lineNum )
+ {
+ }
+
+ int bpNum;
+ QString fileName;
+ int lineNum;
+ };
+
private:
void processOutput( QString const& output );
void echoOutput( QString const& line );
@@ -113,6 +138,7 @@
void outputText( QString const& text );
void issueCommand( QString const& cmd,
class CommandCompletion* completion = NULL );
+ void updateBreakpointState( QString const& cmd, QString const& bpNum );
private:
QVBoxLayout* layout;
@@ -130,6 +156,7 @@
QPoint outputLength;
QString lastCommand;
CommandCompletion* commandCompletion;
+ QList<Breakpoint> breakpoints;
};
#endif
--- trunk/playground/devtools/kategdbplugin/plugin_kategdb.cpp #1157716:1157717
@@ -3,6 +3,7 @@
//
//
// Copyright (c) 2010 Ian Wakeling <ian.wakeling@ntlworld.com>
+// Copyright (c) 2010 Kåre Särs <kare.sars@iki.fi>
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public
@@ -34,6 +35,7 @@
#include <kate/application.h>
#include <ktexteditor/view.h>
#include <ktexteditor/document.h>
+#include <ktexteditor/markinterface.h>
K_PLUGIN_FACTORY(KatePluginGDBFactory, registerPlugin<KatePluginGDB>();)
K_EXPORT_PLUGIN(KatePluginGDBFactory(
@@ -75,6 +77,14 @@
connect( debugView, SIGNAL( debugLocationChanged( const char*, int ) ),
this, SLOT( slotGoTo( const char*, int ) ) );
+ connect( debugView, SIGNAL( breakpointSet( const char*, int ) ),
+ this, SLOT( slotBreakpointSet( const char*, int ) ) );
+ connect( debugView, SIGNAL( breakpointClear( const char*, int ) ),
+ this, SLOT( slotBreakpointClear( const char*, int ) ) );
+ connect( debugView, SIGNAL( breakpointDisable( const char*, int ) ),
+ this, SLOT( slotBreakpointDisable( const char*, int ) ) );
+ connect( debugView, SIGNAL( breakpointEnable( const char*, int ) ),
+ this, SLOT( slotBreakpointEnable( const char*, int ) ) );
KAction* a = actionCollection()->addAction( "debug" );
a->setText( i18n( "Start Debugging" ) );
@@ -177,13 +187,100 @@
KUrl url = debugView->resolveFileName( fileName );
// skip not existing files
- if (!QFile::exists (url.toLocalFile ()))
- return;
-
+ if( QFile::exists( url.toLocalFile() ) )
+ {
KTextEditor::View* editView = mainWindow()->openUrl( url );
editView->setCursorPosition( KTextEditor::Cursor( lineNum, 0 ) );
}
+}
+void KatePluginGDBView::slotBreakpointSet( const char* fileName, int lineNum )
+{
+ KUrl url = debugView->resolveFileName( fileName );
+
+ // skip not existing files
+ if( QFile::exists( url.toLocalFile() ) )
+ {
+ KTextEditor::View* editView = mainWindow()->openUrl( url );
+ KTextEditor::MarkInterface* mark =
+ qobject_cast<KTextEditor::MarkInterface*>( editView->document() );
+
+ if( mark != NULL )
+ {
+ mark->setMarkDescription(
+ KTextEditor::MarkInterface::BreakpointActive,
+ i18n("Breakpoint") );
+ mark->setMarkPixmap( KTextEditor::MarkInterface::BreakpointActive,
+ KIcon("media-playback-pause").pixmap(10,10) );
+ mark->addMark( lineNum,
+ KTextEditor::MarkInterface::BreakpointActive );
+ }
+ }
+}
+
+void KatePluginGDBView::slotBreakpointClear( const char* fileName, int lineNum )
+{
+ KUrl url = debugView->resolveFileName( fileName );
+
+ // skip not existing files
+ if( QFile::exists( url.toLocalFile() ) )
+ {
+ KTextEditor::View* editView = mainWindow()->openUrl( url );
+ KTextEditor::MarkInterface* mark =
+ qobject_cast<KTextEditor::MarkInterface*>( editView->document() );
+
+ if( mark != NULL )
+ {
+ mark->removeMark( lineNum,
+ KTextEditor::MarkInterface::BreakpointActive |
+ KTextEditor::MarkInterface::BreakpointDisabled );
+ }
+ }
+}
+
+void KatePluginGDBView::slotBreakpointDisable( const char* fileName, int lineNum )
+{
+ KUrl url = debugView->resolveFileName( fileName );
+
+ // skip not existing files
+ if( QFile::exists( url.toLocalFile() ) )
+ {
+ KTextEditor::View* editView = mainWindow()->openUrl( url );
+ KTextEditor::MarkInterface* mark =
+ qobject_cast<KTextEditor::MarkInterface*>( editView->document() );
+
+ if( mark != NULL )
+ {
+ mark->setMarkDescription(
+ KTextEditor::MarkInterface::BreakpointDisabled,
+ i18n("Disabled Breakpoint") );
+ mark->setMarkPixmap( KTextEditor::MarkInterface::BreakpointDisabled,
+ KIcon("media-playback-pause").pixmap(10,10) );
+ mark->addMark( lineNum,
+ KTextEditor::MarkInterface::BreakpointDisabled );
+ }
+ }
+}
+
+void KatePluginGDBView::slotBreakpointEnable( const char* fileName, int lineNum )
+{
+ KUrl url = debugView->resolveFileName( fileName );
+
+ // skip not existing files
+ if( QFile::exists( url.toLocalFile() ) )
+ {
+ KTextEditor::View* editView = mainWindow()->openUrl( url );
+ KTextEditor::MarkInterface* mark =
+ qobject_cast<KTextEditor::MarkInterface*>( editView->document() );
+
+ if( mark != NULL )
+ {
+ mark->removeMark( lineNum,
+ KTextEditor::MarkInterface::BreakpointDisabled );
+ }
+ }
+}
+
void KatePluginGDBView::enableDebugActions( bool enable )
{
static char const* actions[] =
--- trunk/playground/devtools/kategdbplugin/plugin_kategdb.h #1157716:1157717
@@ -75,6 +75,10 @@
void slotMovePC();
void slotRunToCursor();
void slotGoTo( const char* fileName, int lineNum );
+ void slotBreakpointSet( const char* fileName, int lineNum );
+ void slotBreakpointClear( const char* fileName, int lineNum );
+ void slotBreakpointEnable( const char* fileName, int lineNum );
+ void slotBreakpointDisable( const char* fileName, int lineNum );
private:
void enableDebugActions( bool enable );
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic