[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