added an install info
[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 self.lastc, self.lastr = 0,0
32
33 #Start debugger
34 self.clientCmd = clientCmd
35 #Open pseudo-terminal where to-be-debugged process reads/writes to
36 self.client_ptymaster, self.client_ptyslave = pty.openpty()
37
38 #Set up terminal window and initialize debugger
39 self.connect("cursor-moved", self.contents_changed)
40 self.connect("child-exited", quitHandler)
41
42 #font description
43 fontdesc = pango.FontDescription("monospace 9")
44 self.set_font(fontdesc)
45
46
47 def initialize(self):
48 self.childpid = self.fork_command( self.getCommand(), self.getArgv())
49 self.waitForActivation(0)
50 self.setPty(self.client_ptyslave)
51
52 def stopDbg(self):
53
54 if self.childpid != None:
55 #9=KILL, 15=TERM
56 os.kill(self.childpid, 15);
57 self.childpid = None
58
59
60
61 def contents_changed(self, term):
62 assert( self.getHistoryLen()>0 )
63
64 c,r = term.get_cursor_position()
65 text = self.get_text_range(self.lastr,self.lastc,r,c-1,lambda *w:True)
66 self.lastc, self.lastr = c,r
67
68 #Remove annoying \n at the end
69 assert(text[-1] == "\n")
70 text = text[:-1]
71
72 #Get the lines and remove empty lines
73 lines = string.split(text, "\n")
74
75
76 #Remove the incomplete line
77 len = self.getHistoryLen()
78 self.history[-1] += lines[0]
79 self.history += lines[1:]
80
81 for l in self.history[len:]:
82 pass
83
84
85 def waitForNewline(self):
86 l = self.getHistoryLen()
87 while not self.getHistoryLen() > l:
88 gtk.main_iteration()
89
90 def getHistoryLen(self):
91 return len(self.history)
92
93 def waitForRx(self, rx, start):
94 curr = start
95 while True:
96 assert( curr>=start )
97 for no in range(curr, self.getHistoryLen()):
98 line = self.history[no]
99 if rx.search(line):
100 return no, line
101
102 #Do not forget the last line
103 curr = max(start,self.getHistoryLen()-1)
104 gtk.main_iteration()
105
106
107 def getCommand(self):
108 return self.getArgv()[0];
109
110 def getArgv(self):
111 raise NotImplementedError()
112
113 def setPty(self, pty):
114 raise NotImplementedError()
115
116 def setRun(self):
117 raise NotImplementedError()
118
119 def setContinue(self):
120 raise NotImplementedError()
121
122 def setStepover(self):
123 raise NotImplementedError()
124
125 def setStepin(self):
126 raise NotImplementedError()
127
128 def setQuit(self):
129 raise NotImplementedError()
130
131 def setBreakpoint(self, file, lineno, condition=False):
132 raise NotImplementedError()
133
134 def delBreakpoint(self, breakpoint):
135 raise NotImplementedError()
136
137 def getExpression(self, expr):
138 raise NotImplementedError()
139
140 def waitForActivation(self, his):
141 raise NotImplementedError()
142
143 def setActive(self, isactive):
144 self.isactive = isactive
145
146 def isActive(self):
147 return self.isactive
148
149
150
151 def quitHandler(*w):
152 try:
153 gtk.main_quit()
154 except:
155 pass
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", quitHandler)
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