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