#Start debugger
self.clientCmd = clientCmd
- self.fork_command( self.getDbgCommand(), self.getDbgArgv())
+ self.fork_command( self.getCommand(), self.getArgv())
#Open pseudo-terminal where to-be-debugged process reads/writes to
self.client_ptymaster, self.client_ptyslave = pty.openpty()
- self.setDbgPty(self.client_ptyslave)
+ self.setPty(self.client_ptyslave)
#Set up terminal window and initialize debugger
self.connect("cursor-moved", self.contents_changed)
def contents_changed(self, term):
c,r = term.get_cursor_position()
- if self.lastrow < r:
- text = self.get_text_range(self.lastrow,0,r-1,-1,lambda *w:True)
- self.history += string.split(text, "\n")
+ if self.lastrow <= r:
+ text = self.get_text_range(self.lastrow,0,r,-1,lambda *w:True)
+
+ #Remove the incomplete line
+ if self.getHistoryLen()>0 and (len(self.history[-1])==0 or self.history[-1]!='\n') :
+ del self.history[-1]
+
+ #Get the lines and remove empty lines
+ lines = string.split(text, "\n")
+
+ #Remove last empty line...
+ if lines[-1] == "":
+ del lines[-1]
+
+ #Add lines to history
+ self.history += [l+"\n" for l in lines[:-1]]
+ self.history += [lines[-1]]
self.lastrow = r
- def waitForDbgNewline(self):
+
+ def waitForNewline(self):
r = self.lastrow
while not self.lastrow > r:
gtk.main_iteration()
def getHistoryLen(self):
return len(self.history)
- def waitForDbgRx(self, rx, start=None):
+ def waitForRx(self, rx, start=None):
if start == None:
start = self.getHistoryLen()
return no, line
start = self.getHistoryLen()
- self.waitForDbgNewline()
+ gtk.main_iteration()
+
+ def getCommand(self):
+ return self.getArgv()[0];
- def getDbgCommand(self):
- return self.getDbgArgv()[0];
+ def getArgv(self):
+ raise NotImplementedError()
+
+ def setPty(self, pty):
+ raise NotImplementedError()
- def getDbgArgv(self):
+ def setRun(self):
raise NotImplementedError()
- def setDbgPty(self, pty):
+ def setContinue(self):
raise NotImplementedError()
- def setDbgRun(self):
+ def setStepover(self):
raise NotImplementedError()
- def setDbgQuit(self):
+ def setStepin(self):
raise NotImplementedError()
- def setDbgContinue(self):
+ def setQuit(self):
raise NotImplementedError()
- def setDbgBreakpoint(self, file, lineno):
+ def setBreakpoint(self, file, lineno):
raise NotImplementedError()
- def getDbgExpression(self, expr):
+ def getExpression(self, expr):
raise NotImplementedError()
- def getDbgLastLine(self):
+ def getLastLine(self):
if len(self.history) == 0:
return None
wnd.toggleClientIOWindow()
- term.setDbgBreakpoint("main.cpp", 15)
- term.setDbgRun()
- res = term.getDbgExpression("a")
+ term.setBreakpoint("main.cpp", 15)
+ term.setRun()
+ res = term.getExpression("a")
print "Result = ", res
- term.setDbgQuit()
+ term.setQuit()
def __init__(self, clientCmd):
DbgTerminal.DbgTerminal.__init__(self, clientCmd)
- def getDbgArgv(self):
+ def getArgv(self):
return ["gdb", "--fullname", string.split(self.clientCmd)[0]]
- def setDbgPty(self, pty):
+ def setPty(self, pty):
ttyname = os.ttyname(pty)
self.feed_dbg("set inferior-tty %s\n" % (ttyname,))
- def setDbgRun(self):
+ def setRun(self):
+
+ his = self.getHistoryLen()
argv = string.join(string.split(self.clientCmd)[1:])
self.feed_dbg("run " + argv + "\n")
+ return self.waitForPosition(his)
- def setDbgQuit(self):
- self.feed_dbg("quit\n")
- self.waitForDbgNewline()
- self.feed_dbg("y\n");
- def setDbgContinue(self):
+ def setContinue(self):
+ his = self.getHistoryLen()
self.feed_dbg("cont\n");
+ return self.waitForPosition(his)
+
+ def setStepover(self):
+ his = self.getHistoryLen()
+ self.feed_dbg("next\n");
+ return self.waitForPosition(his)
+
+ def setStepin(self):
+ his = self.getHistoryLen()
+ self.feed_dbg("step\n");
+ return self.waitForPosition(his)
+
+ def setQuit(self):
+ self.feed_dbg("quit\n")
+ self.waitForNewline()
+ self.feed_dbg("y\n");
- def setDbgBreakpoint(self, file, lineno):
+ def setBreakpoint(self, file, lineno):
self.feed_dbg("break %s:%d\n" % (file, lineno))
- def getDbgExpression(self, expr):
+ def getExpression(self, expr):
his = self.getHistoryLen()
self.feed_dbg("print " + expr + "\n")
rx = re.compile("^\$[1-9][0-9]* = .*$")
- his, response = self.waitForDbgRx(rx, his)
+ his, response = self.waitForRx(rx, his)
split = string.split(response, "=")
return string.join(split[1:], "=").strip()
+ def waitForPosition(self, his):
+ rx = re.compile("^\(gdb\) $")
+ his, reponse = self.waitForRx(rx,his)
+
+ if self.history[his-1][0:2]=="\x1a\x1a":
+ tuples = string.split(self.history[his-1][2:], ":")
+ return tuples[0:2]
+
+ return None
+
+
if __name__ == "__main__":
--- /dev/null
+#!/usr/bin/python
+#shuber, 2008-06-04
+
+__author__ = "shuber"
+
+
+import gtk
+import string
+import sys
+import vte
+
+
+import GdbTerminal
+import ClientIOTerminal
+
+
+class MainControlWindow (gtk.Window):
+
+ #Callbacks for new positions
+ newPosCbs = []
+
+ def __init__(self, dbgterm):
+
+ #Set up GTK stuff
+ gtk.Window.__init__(self)
+ self.connect("destroy", lambda *w: gtk.main_quit())
+
+ #Set terminals
+ self.dbgterm = dbgterm
+ self.clientioterm = ClientIOTerminal.ClientIOTerminal(self.dbgterm.client_ptymaster)
+
+ #Set title and add terminal
+ self.set_title("Main Control")
+ self.set_border_width(5)
+
+
+ #The main horizontal pane left=buttons, right=terminals
+ hbox = gtk.HBox(False,0)
+ self.add(hbox)
+ hpaned = gtk.HPaned()
+ hbox.pack_start(hpaned, True, True)
+
+
+
+ #Plug together the buttons
+ vbox = gtk.VButtonBox()
+ vbox.set_layout(gtk.BUTTONBOX_START)
+ hpaned.add1(vbox)
+
+ self.runBtn = gtk.Button("Run")
+ vbox.add(self.runBtn)
+ self.continueBtn = gtk.Button("Continue")
+ vbox.add(self.continueBtn)
+ self.stepoverBtn = gtk.Button("Step Over")
+ vbox.add(self.stepoverBtn)
+ self.stepinBtn = gtk.Button("Step In")
+ vbox.add(self.stepinBtn)
+ self.quitBtn = gtk.Button("Quit")
+ vbox.add(self.quitBtn)
+
+
+ #Plug together the terminals
+ vbox = gtk.VBox()
+ hpaned.add2(vbox)
+
+ vpaned = gtk.VPaned()
+ vbox.pack_start(vpaned, True, True)
+ vpaned.add(self.dbgterm)
+ vpaned.add(self.clientioterm)
+
+
+ #Install handlers
+ self.runBtnHandler = self.runBtn.connect('clicked', self.runBtnClicked)
+ self.continueBtnHandler = self.continueBtn.connect('clicked', self.continueBtnClicked)
+ self.stepoverBtnHandler = self.stepoverBtn.connect('clicked', self.stepoverBtnClicked)
+ self.stepinBtnHandler = self.stepinBtn.connect('clicked', self.stepinBtnClicked)
+ self.quitBtnHandler = self.quitBtn.connect('clicked', self.quitBtnClicked)
+
+ #Show the window
+ self.show_all()
+
+
+
+ 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):
+ 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):
+ 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)
+
+
+
+
+if __name__ == "__main__":
+
+ def newpos(pos):
+ print "new pos: ", pos
+
+
+ clientCmd = string.join(sys.argv[1:])
+ dbgterm = GdbTerminal.GdbTerminal(clientCmd)
+ mainCtrlWnd = MainControlWindow(dbgterm)
+
+ mainCtrlWnd.newPosCbs += [newpos]
+
+ gtk.main()
+
+