- fixing problem of destroying windows -> segfault
[pygdb.git] / DbgTerminal.py
1 #!/usr/bin/python
2 #shuber, 2008-06-04
3
4 __author__ = "shuber"
5
6
7 import gtk
8 import os
9 import pango
10 import pty
11 import string
12 import time
13 import threading
14 import vte
15
16 import ClientIOTerminal
17
18
19
20 class DbgTerminal (vte.Terminal):
21
22 isactive = True
23 lastrow = 0
24 history = []
25 childpid = None
26
27
28 def __init__(self, clientCmd, exitcb=None):
29
30 vte.Terminal.__init__(self)
31
32 def onChildExited():
33 self.childpid = None
34 if exitcb != None:
35 exitcb()
36
37 #Start debugger
38 self.clientCmd = clientCmd
39 #Open pseudo-terminal where to-be-debugged process reads/writes to
40 self.client_ptymaster, self.client_ptyslave = pty.openpty()
41
42 #Set up terminal window and initialize debugger
43 self.connect("cursor-moved", self.contents_changed)
44 self.connect("child-exited", lambda *w: onChildExited())
45
46 #font description
47 fontdesc = pango.FontDescription("monospace 9")
48 self.set_font(fontdesc)
49
50
51 def initialize(self):
52 self.childpid = self.fork_command( self.getCommand(), self.getArgv())
53 self.setPty(self.client_ptyslave)
54 self.waitForActivation()
55
56 def stopDbg(self):
57
58 if self.childpid != None:
59 os.kill(self.childpid, 15);
60 self.childpid = None
61
62
63
64 def contents_changed(self, term):
65 c,r = term.get_cursor_position()
66
67 if self.lastrow <= r:
68 text = self.get_text_range(self.lastrow,0,r,-1,lambda *w:True)
69
70 #Remove the incomplete line
71 if self.getHistoryLen()>0 and (len(self.history[-1])==0 or self.history[-1]!='\n') :
72 del self.history[-1]
73
74 #Get the lines and remove empty lines
75 lines = string.split(text, "\n")
76
77 #Remove last empty line...
78 if lines[-1] == "":
79 del lines[-1]
80
81 #Add lines to history
82 self.history += [l+"\n" for l in lines[:-1]]
83 self.history += [lines[-1]]
84 self.lastrow = r
85
86
87 def waitForNewline(self):
88 r = self.lastrow
89 while not self.lastrow > r:
90 gtk.main_iteration()
91
92 def getHistoryLen(self):
93 return len(self.history)
94
95 def waitForRx(self, rx, start=None):
96
97 if start == None:
98 start = self.getHistoryLen()
99 if start < 0:
100 start = 0
101
102 while True:
103 for no in range(start, self.getHistoryLen()):
104 line = self.history[no]
105 if rx.search(line):
106 return no, line
107
108 start = self.getHistoryLen()
109 gtk.main_iteration()
110
111
112 def getCommand(self):
113 return self.getArgv()[0];
114
115 def getArgv(self):
116 raise NotImplementedError()
117
118 def setPty(self, pty):
119 raise NotImplementedError()
120
121 def setRun(self):
122 raise NotImplementedError()
123
124 def setContinue(self):
125 raise NotImplementedError()
126
127 def setStepover(self):
128 raise NotImplementedError()
129
130 def setStepin(self):
131 raise NotImplementedError()
132
133 def setQuit(self):
134 raise NotImplementedError()
135
136 def setBreakpoint(self, file, lineno, condition=False):
137 raise NotImplementedError()
138
139 def delBreakpoint(self, breakpoint):
140 raise NotImplementedError()
141
142 def getExpression(self, expr):
143 raise NotImplementedError()
144
145 def waitForActivation(self, his):
146 raise NotImplementedError()
147
148 def setActive(self, isactive):
149 self.isactive = isactive
150
151 def isActive(self):
152 return self.isactive
153
154
155
156
157
158
159 class DbgWindow (gtk.Window):
160
161 clientIOWnd = None
162
163
164 def __init__(self, terminal):
165
166 #Set up some members
167 self.terminal = terminal
168
169 #Set up GTK stuff
170 gtk.Window.__init__(self)
171 self.connect("destroy", lambda *w: gtk.main_quit())
172
173 #Set title and add terminal
174 self.set_title("Debugger I/O")
175 self.terminal.history = []
176 self.terminal.history_length = 5
177 self.add(self.terminal)
178
179 #Show the window
180 self.show_all()
181
182 def toggleClientIOWindow(self):
183 if not self.clientIOWnd:
184 self.clientIOWnd = ClientIOTerminal.ClientIOWindow(self, \
185 self.terminal.client_ptymaster)
186 else:
187 self.clientIOWnd.destroy()
188 self.clientIOWnd = None
189
190 def isClientIOWindowExisting(self):
191 return self.clientIOWnd != None
192
193
194