StatusFrame.StatusFrame.__init__(self, debugger)
self.set_label("Breakpoints")
+ debugger.gotActiveCallback += [self.updateValues]
+
vbox = gtk.VBox(False, 5)
self.add(vbox)
def applyConfiguration(self, conf):
for b in conf.breakpoints:
self.addBreakpoint(b["file"], b["lineno"], b["cond"])
- self.updateValues(None)
+ self.updateValues(None, None)
def fillConfiguration(self, conf):
iter = self.model.get_iter_first()
if not self.debugger.isActive():
return
- self.updateValues(None)
+ self.updateValues(None, None)
- def updateValues(self, pos):
+ def updateValues(self, status, param):
bpnts = self.debugger.getBreakpoints()
__author__ = "shuber"
+import gobject
import gtk
import os
import pango
self.history = [""]
self.isactive = True
self.lastc, self.lastr = 0,0
+ self.gotActiveCallback = []
+ self.gotInactiveCallback = []
+ self.activityChanged = None
#Start debugger
self.clientCmd = clientCmd
#Set up terminal window and initialize debugger
self.connect("cursor-moved", self.contents_changed)
self.connect("child-exited", quitHandler)
+ gobject.timeout_add(50, self.checkActivityChanged)
#font description
fontdesc = pango.FontDescription("monospace 9")
os.kill(self.childpid, 15);
self.childpid = None
+ def checkActivityChanged(self):
+
+ try:
+
+ #There was activity
+ if self.activityChanged != None:
+
+ res = self.activityChanged
+ self.activityChanged = None
+
+ status, param = res
+ if self.isActive():
+ for cb in self.gotActiveCallback:
+ cb(status, param)
+ else:
+ for cb in self.gotInactiveCallback:
+ cb(status, param)
+ except:
+ pass
+
+ return True
+
def contents_changed(self, term):
#Remove annoying \n at the end
assert(text[-1] == "\n")
text = text[:-1]
-
#Get the lines and remove empty lines
lines = string.split(text, "\n")
-
#Remove the incomplete line
- len = self.getHistoryLen()
+ len = max(0,self.getHistoryLen()-1)
self.history[-1] += lines[0]
self.history += lines[1:]
- for l in self.history[len:]:
- pass
+
+ #Check if activity status has been changed
+ for i in range(len, self.getHistoryLen()):
+ line = self.history[i]
+
+ res = self.testForActivity(i)
+ if res != None and not self.isActive():
+ self.setActive(True)
+ self.activityChanged = res
+
+ res = self.testForInactivity(i)
+ if res != None and self.isActive():
+ self.setActive(False)
+ self.activityChanged = res
+
def waitForNewline(self):
def waitForActivation(self, his):
raise NotImplementedError()
+ def testForActivity(self, his):
+ raise NotImplementedError()
+
+ def testForInactivity(self, his):
+ raise NotImplementedError()
+
def setActive(self, isactive):
self.isactive = isactive
def setPty(self, pty):
ttyname = os.ttyname(pty)
- his = self.getHistoryLen()
self.feed_child("set inferior-tty %s\n" % (ttyname,))
- self.waitForActivation(his)
def setRun(self):
- his = self.getHistoryLen()
argv = string.join(string.split(self.clientCmd)[1:])
self.feed_child("run " + argv + "\n")
- return self.waitForActivation(his)
def setContinue(self):
- his = self.getHistoryLen()
self.feed_child("cont\n");
- return self.waitForActivation(his)
def setStepover(self):
- his = self.getHistoryLen()
self.feed_child("next\n");
- return self.waitForActivation(his)
def setStepin(self):
- his = self.getHistoryLen()
self.feed_child("step\n");
- return self.waitForActivation(his)
def setQuit(self):
self.feed_child("quit\n")
for his in reversed(range(starthis+1,endhis)):
if self.history[his][0:2]=="\x1a\x1a":
tuples = string.split(self.history[his][2:], ":")
- return tuples[0:2]
+ return tuples[0], int(tuples[1])
return None
return self.waitForRx(rx,his)
+ def testForActivity(self, his):
+ """Test whether debugger got active again"""
+ rx = re.compile("^\(gdb\) ")
+
+ #Aha! There is a prompt...
+ if rx.search(self.history[his]):
+ line = self.history[his-1]
+
+ if line[0:2]=="\x1a\x1a":
+ tuples = string.split(line[2:], ":")
+ tuples[1] = int(tuples[1])
+ return "break", [tuples[0], int(tuples[1])]
+
+ if string.find(line, "Program exited") == 0:
+ code = string.split(line)[-1]
+ code = code[:-1]
+ return "exited", code
+
+ return None
+
+
+ def testForInactivity(self, his):
+ """Test whether debugger got inactive"""
+ line = self.history[his]
+ rxcont = re.compile("^\(gdb\)\s+(cont|step|next|stepi|nexti)")
+
+ if string.find(line, "Starting program:") == 0:
+ prog = string.join( string.split(line)[1:])
+ return "started", prog
+
+ if rxcont.search(line):
+ return "continued", None
+
+ return None
+
+
+
+
+
+
if __name__ == "__main__":
gtk.Window.__init__(self)
self.connect("destroy", DbgTerminal.quitHandler )
- #Callbacks for new positions
- self.newPosCbs = []
+ dbgterm.gotActiveCallback += [self.enableButtons]
+ dbgterm.gotInactiveCallback += [self.disableButtons]
#Set terminals
self.dbgterm = dbgterm
def runBtnClicked(self, btn):
- self.disableButtons()
pos = self.dbgterm.setRun()
- self.newSourcePosition(pos)
- self.enableButtons()
def continueBtnClicked(self, btn):
- self.disableButtons()
pos = self.dbgterm.setContinue()
- self.newSourcePosition(pos)
- self.enableButtons()
def stepoverBtnClicked(self, btn):
- self.disableButtons()
pos = self.dbgterm.setStepover()
- self.newSourcePosition(pos)
- self.enableButtons()
def stepinBtnClicked(self, btn):
- self.disableButtons()
pos = self.dbgterm.setStepin()
- self.newSourcePosition(pos)
- self.enableButtons()
def quitBtnClicked(self, btn):
self.dbgterm.setQuit()
- def disableButtons(self):
+ def disableButtons(self, *w):
self.runBtn.handler_block(self.runBtnHandler)
self.continueBtn.handler_block(self.continueBtnHandler)
self.stepoverBtn.handler_block(self.stepoverBtnHandler)
self.stepinBtn.handler_block(self.stepinBtnHandler)
self.quitBtn.handler_block(self.quitBtnHandler)
- def enableButtons(self):
+ def enableButtons(self, *w):
self.runBtn.handler_unblock(self.runBtnHandler)
self.continueBtn.handler_unblock(self.continueBtnHandler)
self.stepoverBtn.handler_unblock(self.stepoverBtnHandler)
self.stepinBtn.handler_unblock(self.stepinBtnHandler)
self.quitBtn.handler_unblock(self.quitBtnHandler)
- def newSourcePosition(self, pos):
- #Call the callbacks
- for cb in self.newPosCbs:
- cb(pos)
-
-
--- /dev/null
+#!/usr/bin/python
+#shuber, 2008-06-04
+
+__author__ = "shuber"
+
+
+import gobject
+import gtk
+import re
+import os
+import string
+import vte
+
+import DbgTerminal
+import StatusFrame
+
+
+class PositionFrame (StatusFrame.StatusFrame):
+
+
+ def __init__(self, debugger):
+
+ StatusFrame.StatusFrame.__init__(self, debugger)
+ self.set_label("Position")
+
+ debugger.gotActiveCallback += [self.updateValues]
+ debugger.gotInactiveCallback += [self.updateValues]
+
+ self.file = None
+ self.lineno = 0
+
+ vbox = gtk.VBox(False, 5)
+ self.add(vbox)
+
+ hbox = gtk.HBox(False, 4)
+ vbox.pack_start(hbox, False, False)
+ self.openBtn = gtk.Button(":e")
+ hbox.pack_start(self.openBtn, False, False)
+ self.positionLabel = gtk.Label()
+ hbox.pack_start(self.positionLabel, False, False)
+
+ sw = gtk.ScrolledWindow()
+ sw.set_shadow_type(gtk.SHADOW_ETCHED_IN)
+ sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
+ vbox.add(sw)
+
+ self.srcview = gtk.TextView()
+ sw.add(self.srcview)
+
+ self.openBtn.connect("clicked", self.openBtnClicked)
+
+
+ def openBtnClicked(self, btn):
+
+ if not self.debugger.isActive():
+ return
+
+ if self.file!=None:
+ try:
+ cmd = 'gvim -R -c ":%d" %s' % (self.lineno, self.file)
+ os.system(cmd)
+ except OSError:
+ dialog = gtk.MessageDialog(None, \
+ gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, \
+ gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, \
+ "Error calling editor with '%s'." % cmd)
+ dialog.run()
+ dialog.destroy()
+
+
+ def updateValues(self, status, param):
+
+ if status == "break":
+ self.file, self.lineno = param
+ self.positionLabel.set_label("%s:%d" % (self.file, self.lineno))
+ else:
+ self.file, self.lineno = None, 0
+
+ if status == "exited":
+ self.positionLabel.set_label("Exited.")
+ elif status == "started":
+ self.positionLabel.set_label("Started.")
+ elif status == "continued":
+ self.positionLabel.set_label("Continued.")
+ else:
+ self.positionLabel.set_label(status)
+
+
+ def applyConfiguration(self, conf):
+ pass
+
+ def fillConfiguration(self, conf):
+ pass
+
import DbgTerminal
import BreakpointsFrame
+import PositionFrame
import WatchesFrame
class StatusWindow (gtk.Window):
- def __init__(self, mainctrlwnd, debugger):
-
+ def __init__(self, debugger):
gtk.Window.__init__(self)
+
self.debugger = debugger
self.set_border_width(5)
self.set_default_size(400,600)
self.connect("destroy", DbgTerminal.quitHandler)
+
+ #Vbox container of frames
vbox = gtk.VBox(False, 5)
self.add(vbox)
- hbox = gtk.HBox(False, 5)
- vbox.pack_start(hbox, False, False)
+
+ #Adding the frames
+ self.frames = []
+ self.frames += [PositionFrame.PositionFrame(debugger), \
+ WatchesFrame.WatchesFrame(debugger), \
+ BreakpointsFrame.BreakpointsFrame(debugger) ]
- self.viewBtn = gtk.Button("View")
- self.viewBtn.connect("clicked", self.viewBtnClicked)
- hbox.pack_start(self.viewBtn, False, False)
- self.status = gtk.Label("Not Running")
- hbox.pack_start(self.status, False, False)
+ #First paned window
self.paned1 = gtk.VPaned()
vbox.add(self.paned1)
+ #Second one
+ self.paned2 = gtk.VPaned()
+ self.paned1.add2(self.paned2)
- #Adding the frames
- self.frames = []
- self.frames += [WatchesFrame.WatchesFrame(debugger)]
- self.frames += [BreakpointsFrame.BreakpointsFrame(debugger)]
- self.paned1.add1(self.frames[0])
- self.paned1.add2(self.frames[1])
-
- #Register callback function for new positions
- #and update the values
- mainctrlwnd.newPosCbs += [self.updateValues]
+ self.paned1.add1(self.frames[1])
+ self.paned2.add1(self.frames[2])
+ self.paned2.add2(self.frames[0])
self.show_all()
w = conf.findInt("statuswnd-width")
h = conf.findInt("statuswnd-height")
paned1 = conf.findInt("statuswnd-paned1")
+ paned2 = conf.findInt("statuswnd-paned2")
if w!=None and h!=None:
self.resize(w,h)
if paned1!=None:
self.paned1.set_position(paned1)
+ if paned2!=None:
+ self.paned2.set_position(paned2)
while not self.debugger.isActive():
conf.addInt("statuswnd-width", self.get_size()[0])
conf.addInt("statuswnd-height", self.get_size()[1])
conf.addInt("statuswnd-paned1", self.paned1.get_position())
+ conf.addInt("statuswnd-paned2", self.paned2.get_position())
for f in self.frames:
f.fillConfiguration(conf)
-
- def updateValues(self, pos):
-
- if pos == None:
- self.status.set_text("Exited")
- else:
- file, lineno = pos
- self.status.set_text("%s:%s" % (file, lineno))
-
- for f in self.frames:
- f.updateValues(pos)
-
-
- def viewBtnClicked(self, btn):
-
- status = self.status.get_label().strip()
- rx = re.compile("\S+:\d+")
-
- #It is a path
- if rx.search(status):
- try:
- [file,lineno] = string.split(status,":")
- lineno = int(lineno)
-
- os.system('gvim -R -c ":%d" %s' % (lineno,file))
-
- except OSError:
- pass
-
-
-
StatusFrame.StatusFrame.__init__(self, debugger)
self.set_label("Watches")
+ debugger.gotActiveCallback += [self.updateValues]
+
vbox = gtk.VBox(False, 5)
self.add(vbox)
for w in conf.watches:
iter = self.model.append()
self.model.set(iter, 0, w["expr"], 1, "<unkown>", 2, True)
- self.updateValues(None)
+ self.updateValues(None, None)
def fillConfiguration(self, conf):
iter = model.get_iter(path)
model.remove(iter)
- def updateValues(self, pos):
+ def updateValues(self, status, param):
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)
+ res = self.debugger.getExpression(expr)
+ self.model.set(iter, 1, res)
iter = self.model.iter_next(iter)
#Create windows
mainCtrlWnd = MainControlWindow.MainControlWindow(dbgterm)
- statusWnd = StatusWindow.StatusWindow(mainCtrlWnd, dbgterm)
+ statusWnd = StatusWindow.StatusWindow(dbgterm)
dbgterm.initialize()
#Load configuration