- Fixed bug when bp is set on same addr
authorStefan Huber <shuber2@gmail.com>
Mon, 9 Jun 2008 18:07:27 +0000 (20:07 +0200)
committerStefan Huber <shuber2@gmail.com>
Mon, 9 Jun 2008 18:07:27 +0000 (20:07 +0200)
- Adding Configuration loading/writing
- Introducing common StatusFrame class

BreakpointsFrame.py
Configuration.py [new file with mode: 0755]
DbgTerminal.py
GdbTerminal.py
MainControlWindow.py
StatusFrame.py [new file with mode: 0644]
StatusWindow.py
WatchesFrame.py
pygdb.py
pygdb.vim

index 9b709b403ea610f9721b841f1a1fb427ef75a079..3093fbbe18c047c2e44361dfa75a8d4c560732df 100644 (file)
@@ -11,15 +11,16 @@ import string
 import vte
 
 import DbgTerminal
+import StatusFrame
 
 
-class BreakpointsFrame (gtk.Frame):
+class BreakpointsFrame (StatusFrame.StatusFrame):
 
 
        def __init__(self, debugger):
 
-               gtk.Frame.__init__(self, "Breakpoints")
-               self.debugger = debugger
+               StatusFrame.StatusFrame.__init__(self, debugger)
+               self.set_label("Breakpoints")
 
                vbox = gtk.VBox(False, 5)
                self.add(vbox)
@@ -135,6 +136,18 @@ class BreakpointsFrame (gtk.Frame):
                        dialog.destroy()
 
 
+       def applyConfiguration(self, conf):
+               for b in conf.breakpoints:
+                       self.addBreakpoint(b["file"], b["lineno"], b["cond"])
+
+       def fillConfiguration(self, conf):
+               iter = self.model.get_iter_first()
+               while iter != None:
+                       spec, = self.model.get(iter, 1)
+                       conf.parseBreak(spec)
+                       iter = self.model.iter_next(iter)
+
+
 
        def addBreakpointToList(self, no, file, lineno, cond=None):
                iter = self.model.append()
@@ -167,10 +180,10 @@ class BreakpointsFrame (gtk.Frame):
                if not self.debugger.isActive():
                        return
 
-               self.updateValues()
+               self.updateValues(None)
 
 
-       def updateValues(self):
+       def updateValues(self, pos):
                
                bpnts = self.debugger.getBreakpoints()
 
diff --git a/Configuration.py b/Configuration.py
new file mode 100755 (executable)
index 0000000..7dcd290
--- /dev/null
@@ -0,0 +1,99 @@
+#!/usr/bin/python
+#shuber, 2008-06-09
+
+__author__ = "shuber"
+
+
+
+import re
+import string
+
+import StatusWindow
+
+class Configuration:
+
+       def __init__(self):
+               self.breakpoints = []
+               self.watches = []
+
+
+       def load(self, filename):
+               try:
+                       cnt = 0
+                       #Parse all lines
+                       for line in file(filename).readlines():
+                               cnt += 1
+
+                               #Get command and tail
+                               cmd = string.split(line)[0]
+                               tail = string.join(string.split(line)[1:])
+                               
+                               if cmd == "break":
+                                       self.parseBreak(tail)
+                               elif cmd == "watch":
+                                       self.parseWatch(tail)
+                               else:
+                                       cnt -= 1
+                                       print "Unkown command", cmd
+                       return cnt
+               except IOError:
+                       return None
+
+       def store(self, filename):
+
+               f = file(filename, "w")
+
+               for b in self.breakpoints:
+                       self.__writeBreak(f, b)
+
+               for w in self.watches:
+                       self.__writeWatch(f, w)
+
+
+       def parseBreak(self, tail):
+
+               tail = tail.strip()
+               rx = re.compile("^[\w\._\-]+:\d+(\s+if\s+\S+.*)?$")
+
+               if not rx.search(tail):
+                       print "Wrong breakpoint format:", tail
+                       return
+
+               preif = string.split(tail, "if")[0].strip()
+               postif = string.join( string.split(tail, "if")[1:], "if").strip()
+
+               [file,lineno] = string.split(preif, ":")
+               lineno = int(lineno)
+
+               cond = None
+               if postif != "":
+                       cond = postif
+
+               self.addBreak(file, lineno, cond)
+
+
+       def parseWatch(self, tail):
+               self.addWatch(tail)
+
+
+       def __writeBreak(self, f, b):
+               if b["cond"] != None:
+                       f.write("break %(file)s:%(lineno)d if %(cond)s\n" % b)
+               else:
+                       f.write("break %(file)s:%(lineno)d\n" % b)
+
+       def __writeWatch(self, f, w):
+               f.write("watch %(expr)s\n" % w)
+
+
+       def addBreak(self, file, lineno, cond=None):            
+               self.breakpoints += [ {"file" : file, "lineno" : lineno, "cond" : cond} ]
+
+       def addWatch(self, expr):
+               self.watches += [ {"expr" : expr.strip() } ]
+
+       def __str__(self):
+               return "breakpoints=" + str(self.breakpoints) + ", watches=" + str(self.watches)
+
+
+
index 21aa1c42d790f4b1bc230be0e51c54715b627466..8beec4652f97750b6a553710185b6c92b5295e37 100644 (file)
@@ -19,20 +19,15 @@ import ClientIOTerminal
 
 class DbgTerminal (vte.Terminal):
 
-       isactive = True
-       lastrow = 0
-       history = []
-       childpid = None
-
-
-       def __init__(self, clientCmd, exitcb=None):
+       def __init__(self, clientCmd):
 
                vte.Terminal.__init__(self)
 
-               def onChildExited():
-                       self.childpid = None
-                       if exitcb != None:
-                               exitcb()
+               #Set members
+               self.childpid = None
+               self.history = []
+               self.lastrow = 0
+               self.isactive = True
 
                #Start debugger
                self.clientCmd = clientCmd
@@ -41,7 +36,7 @@ class DbgTerminal (vte.Terminal):
 
                #Set up terminal window and initialize debugger
                self.connect("cursor-moved", self.contents_changed)
-               self.connect("child-exited", lambda *w: onChildExited())
+               self.connect("child-exited", lambda *w: gtk.main_quit())
 
                #font description
                fontdesc = pango.FontDescription("monospace 9")
@@ -56,6 +51,7 @@ class DbgTerminal (vte.Terminal):
        def stopDbg(self):
 
                if self.childpid != None:
+                       #9=KILL, 15=TERM
                        os.kill(self.childpid, 15);
                        self.childpid = None
 
index 4fb4a35b8dd8c2494f76a759a6fbcbeb0cb626f9..304e39ab622185cd2132e616fe17c0cd5c89b261 100755 (executable)
@@ -17,8 +17,8 @@ import DbgTerminal
 class GdbTerminal (DbgTerminal.DbgTerminal):
 
 
-       def __init__(self, clientCmd, exitcb=None):
-               DbgTerminal.DbgTerminal.__init__(self, clientCmd, exitcb)
+       def __init__(self, clientCmd):
+               DbgTerminal.DbgTerminal.__init__(self, clientCmd)
 
        def getArgv(self):
                return ["gdb", "--fullname", string.split(self.clientCmd)[0]]
@@ -34,7 +34,6 @@ class GdbTerminal (DbgTerminal.DbgTerminal):
                self.feed_child("run " + argv + "\n")
                return self.waitForActivation(his)
 
-
        def setContinue(self):
                his = self.getHistoryLen()
                self.feed_child("cont\n");
@@ -63,20 +62,22 @@ class GdbTerminal (DbgTerminal.DbgTerminal):
                        self.feed_child("break %s:%s if %s\n" % \
                                        (file, str(lineno), condition))
 
-               rx = re.compile("^Breakpoint |^No|^\(gdb\) ")
+               rx = re.compile("^Breakpoint |^No |^\(gdb\) ")
                his, response = self.waitForRx(rx, his)
 
                if response[0:10] == "Breakpoint":
                        return string.split(response)[1].strip()
-               if response[0:5] == "(gdb)":
-                       return None
+
                if response[0:14] == "No source file":
                        self.feed_child("n\n");
                        return None
-               if response[0:3] == "No ":
-                       return None
-                       
-               return NotImplementedError()
+
+               #Wait again for gdb
+               if response[0:5] != "(gdb)":
+                       his, response = self.waitForRx(rx,his)
+
+               return None
+
 
        def delBreakpoint(self, breakpoint):
                self.feed_child("del breakpoint %s\n" % (breakpoint,))
index 6dbbf2e101b5698ae01e4a35bc5e8350773c746c..13d32eed6667f784c079b5a6ff89bae6d5e2187d 100644 (file)
@@ -16,16 +16,14 @@ import ClientIOTerminal
 
 class MainControlWindow (gtk.Window):
 
-       #Callbacks for new positions
-       newPosCbs = []
-
-       def __init__(self, dbgterm, closecb=None):
+       def __init__(self, dbgterm):
 
                #Set up GTK stuff
                gtk.Window.__init__(self)
+               self.connect("destroy", lambda *w: gtk.main_quit() )
 
-               if closecb!=None:
-                       self.connect("destroy", lambda *w: closecb() )
+               #Callbacks for new positions
+               self.newPosCbs = []
 
                #Set terminals
                self.dbgterm = dbgterm
diff --git a/StatusFrame.py b/StatusFrame.py
new file mode 100644 (file)
index 0000000..37f7bbf
--- /dev/null
@@ -0,0 +1,26 @@
+#!/usr/bin/python
+#shuber, 2008-06-09
+
+__author__ = "shuber"
+
+
+import gtk
+
+
+class StatusFrame (gtk.Frame):
+
+       def __init__(self, debugger):
+               gtk.Frame.__init__(self)
+               self.debugger = debugger
+
+       def applyConfiguration(self, conf):
+               raise NotImplemented()
+
+       def fillConfiguration(self, conf):
+               raise NotImplemented()
+
+       def updateValues(self, pos):
+               raise NotImplemented()
+
+
+
index 84811c2c7248d610d54b7f6534f047c31d7b14d2..121c0b8a7f5b9375e2b6614ffa90abf3ad427d1e 100644 (file)
@@ -7,29 +7,22 @@ __author__ = "shuber"
 import gtk
 import vte
 
-import WatchesFrame
 import BreakpointsFrame
+import WatchesFrame
+
 
 
 class StatusWindow (gtk.Window):
 
-       def __init__(self, mainctrlwnd, debugger, closecb=None):
+       def __init__(self, mainctrlwnd, debugger):
 
                gtk.Window.__init__(self)
-               self.set_screen(mainctrlwnd.get_screen())
-
+               self.debugger = debugger
+               
                self.set_border_width(5)
                self.set_title("Status")
                self.set_default_size(400,600)
-
-               if closecb!=None:
-                       self.connect("destroy", lambda *w: closecb())
-
-
-               #Register callback function for new positions
-               self.mainctrlwnd = mainctrlwnd
-               mainctrlwnd.newPosCbs += [self.updateValues]
-
+               self.connect("destroy", lambda *w: gtk.main_quit())
 
                vbox = gtk.VBox(False, 5)
                self.add(vbox)
@@ -39,15 +32,34 @@ class StatusWindow (gtk.Window):
                vpaned = gtk.VPaned()
                vbox.add(vpaned)
 
-               self.watchesFrame = WatchesFrame.WatchesFrame(debugger)
-               vpaned.add1(self.watchesFrame)
+               #Adding the frames
+               self.frames = []
+               self.frames += [WatchesFrame.WatchesFrame(debugger)]
+               self.frames += [BreakpointsFrame.BreakpointsFrame(debugger)]
+               vpaned.add1(self.frames[0])
+               vpaned.add2(self.frames[1])
 
-               self.breakpointsFrame = BreakpointsFrame.BreakpointsFrame(debugger)
-               vpaned.add2(self.breakpointsFrame)
+               #Register callback function for new positions
+               #and update the values
+               mainctrlwnd.newPosCbs += [self.updateValues]
 
                self.show_all()
 
 
+       def applyConfiguration(self, conf):
+
+               while not self.debugger.isActive():
+                       gtk.main_iteration()
+
+               for f in self.frames:
+                       f.applyConfiguration(conf)
+
+
+       def fillConfiguration(self, conf):
+               for f in self.frames:
+                       f.fillConfiguration(conf)
+
+
        def updateValues(self, pos):
 
                if pos == None:
@@ -56,7 +68,7 @@ class StatusWindow (gtk.Window):
                        file, lineno = pos
                        self.status.set_text("%s:%s" % (file, lineno))
 
-               self.watchesFrame.updateValues()
-               self.breakpointsFrame.updateValues()
+               for f in self.frames:
+                       f.updateValues(pos)
 
 
index a792501b956ef26f5efff9c686ddcd7e064a9fc2..675e47ccb36f49328dc7c100c10d0f53e23f6443 100644 (file)
@@ -9,15 +9,16 @@ import gtk
 import vte
 
 import DbgTerminal
+import StatusFrame
 
 
-class WatchesFrame (gtk.Frame):
+class WatchesFrame (StatusFrame.StatusFrame):
 
 
        def __init__(self, debugger):
 
-               gtk.Frame.__init__(self, "Watches")
-               self.debugger = debugger
+               StatusFrame.StatusFrame.__init__(self, debugger)
+               self.set_label("Watches")
 
                vbox = gtk.VBox(False, 5)
                self.add(vbox)
@@ -87,13 +88,25 @@ class WatchesFrame (gtk.Frame):
                        model.set(iter, 1, res)
 
 
+       def applyConfiguration(self, conf):
+               for w in conf.watches:
+                       iter = self.model.append()
+                       self.model.set(iter, 0, w["expr"], 1, "<unkown>", 2, True)
+               self.updateValues(None)
+
+
+       def fillConfiguration(self, conf):
+               iter = self.model.get_iter_first()
+               while iter != None:
+                       expr, = self.model.get(iter, 0)
+                       conf.parseWatch(expr)
+                       iter = self.model.iter_next(iter)
 
 
        def addBtnClicked(self, btn):
                iter = self.model.append()
                self.model.set(iter, 0, "0", 1, "0", 2, True)
 
-
        def delBtnClicked(self, btn):
                selection = self.tv.get_selection()
                model, paths = selection.get_selected_rows()
@@ -102,13 +115,9 @@ class WatchesFrame (gtk.Frame):
                        iter = model.get_iter(path)
                        model.remove(iter)
 
-
-       def updateValues(self):
-
+       def updateValues(self, pos):
                iter = self.model.get_iter_first()
-
                while iter != None:
-
                        expr, = self.model.get(iter, 0)
                         res = self.debugger.getExpression(expr)
                         self.model.set(iter, 1, res)
index d3cf2690d478bec972ca7fd70cd696d1bf320fe4..6b6f5d3d2953a45b2ec603e2d4eef31ffc850b9d 100755 (executable)
--- a/pygdb.py
+++ b/pygdb.py
@@ -8,39 +8,33 @@ import os
 import string
 import sys
 
+import Configuration
 import GdbTerminal
 import MainControlWindow
 import StatusWindow
 
 
-def launchDebugger(clientCmd, quitonclose=True):
-
-       
-
-       def hideWindows():
-               #Kill the debugger
-               dbgterm.stopDbg()
-
-               mainCtrlWnd.destroy()
-               statusWnd.destroy()
-               gtk.main_quit()
-       
-
-       #Determine the closing callback func
-       if quitonclose:
-               destroycb = gtk.main_quit
-       else:
-               destroycb = hideWindows
+def launchDebugger(clientCmd):
 
        #Create Terminal
-       dbgterm = GdbTerminal.GdbTerminal(clientCmd, destroycb)
+       dbgterm = GdbTerminal.GdbTerminal(clientCmd)
 
        #Create windows
-       mainCtrlWnd = MainControlWindow.MainControlWindow(dbgterm, destroycb)
-       statusWnd = StatusWindow.StatusWindow(mainCtrlWnd, dbgterm, destroycb)
+       mainCtrlWnd = MainControlWindow.MainControlWindow(dbgterm)
+       statusWnd = StatusWindow.StatusWindow(mainCtrlWnd, dbgterm)
        dbgterm.initialize()
 
-       return dbgterm, mainCtrlWnd, statusWnd
+       #Load configuration
+       conf = Configuration.Configuration()
+       conf.load(".pygdb.conf")
+       statusWnd.applyConfiguration(conf)
+       
+       gtk.main()
+
+       #Store config
+       conf = Configuration.Configuration()
+       statusWnd.fillConfiguration(conf)
+       conf.store(".pygdb.conf")
 
 
 
@@ -54,6 +48,5 @@ if __name__ == "__main__":
        #Create the terminals
        clientCmd = string.join(sys.argv[1:])
        launchDebugger(clientCmd)
-       gtk.main()
 
 
index 244e6322a74d3758d349c64ca16b6a5e4b3c2bd7..b67dd791dbc75626a6e8ee2761253479f63ee66f 100644 (file)
--- a/pygdb.vim
+++ b/pygdb.vim
@@ -40,7 +40,13 @@ def gdbLaunch():
        global gdbterm, mainctrlwnd, statuswnd, gdbBps, clientcmd, gdbthread
 
 
-       clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd)
+       clientcmd = vim.eval("input('Client commando: ', '%s')" % clientcmd).strip()
+
+
+       if clientcmd.strip()=="":
+               print "No command given!"
+               return
+
        gdbterm, mainctrlwnd, statuswnd = pygdb.launchDebugger(clientcmd, False)
 
        for bp in gdbBps: