new feature: selecting on breakpoint sets entry-ctrl-text
[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 def __init__(self, clientCmd):
23
24 vte.Terminal.__init__(self)
25
26 #Set members
27 self.childpid = None
28 self.history = []
29 self.lastrow = 0
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", lambda *w: gtk.main_quit())
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.setPty(self.client_ptyslave)
49 self.waitForActivation()
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 c,r = term.get_cursor_position()
62
63 if self.lastrow <= r:
64 text = self.get_text_range(self.lastrow,0,r,-1,lambda *w:True)
65
66 #Remove the incomplete line
67 if self.getHistoryLen()>0 and (len(self.history[-1])==0 or self.history[-1]!='\n') :
68 del self.history[-1]
69
70 #Get the lines and remove empty lines
71 lines = string.split(text, "\n")
72
73 #Remove last empty line...
74 if lines[-1] == "":
75 del lines[-1]
76
77 #Add lines to history
78 self.history += [l+"\n" for l in lines[:-1]]
79 self.history += [lines[-1]]
80 self.lastrow = r
81
82
83 def waitForNewline(self):
84 r = self.lastrow
85 while not self.lastrow > r:
86 gtk.main_iteration()
87
88 def getHistoryLen(self):
89 return len(self.history)
90
91 def waitForRx(self, rx, start=None):
92
93 if start == None:
94 start = self.getHistoryLen()
95 if start < 0:
96 start = 0
97
98 while True:
99 for no in range(start, self.getHistoryLen()):
100 line = self.history[no]
101 if rx.search(line):
102 return no, line
103
104 start = self.getHistoryLen()
105 gtk.main_iteration()
106
107
108 def getCommand(self):
109 return self.getArgv()[0];
110
111 def getArgv(self):
112 raise NotImplementedError()
113
114 def setPty(self, pty):
115 raise NotImplementedError()
116
117 def setRun(self):
118 raise NotImplementedError()
119
120 def setContinue(self):
121 raise NotImplementedError()
122
123 def setStepover(self):
124 raise NotImplementedError()
125
126 def setStepin(self):
127 raise NotImplementedError()
128
129 def setQuit(self):
130 raise NotImplementedError()
131
132 def setBreakpoint(self, file, lineno, condition=False):
133 raise NotImplementedError()
134
135 def delBreakpoint(self, breakpoint):
136 raise NotImplementedError()
137
138 def getExpression(self, expr):
139 raise NotImplementedError()
140
141 def waitForActivation(self, his):
142 raise NotImplementedError()
143
144 def setActive(self, isactive):
145 self.isactive = isactive
146
147 def isActive(self):
148 return self.isactive
149
150
151
152
153
154
155 class DbgWindow (gtk.Window):
156
157 clientIOWnd = None
158
159
160 def __init__(self, terminal):
161
162 #Set up some members
163 self.terminal = terminal
164
165 #Set up GTK stuff
166 gtk.Window.__init__(self)
167 self.connect("destroy", lambda *w: gtk.main_quit())
168
169 #Set title and add terminal
170 self.set_title("Debugger I/O")
171 self.terminal.history = []
172 self.terminal.history_length = 5
173 self.add(self.terminal)
174
175 #Show the window
176 self.show_all()
177
178 def toggleClientIOWindow(self):
179 if not self.clientIOWnd:
180 self.clientIOWnd = ClientIOTerminal.ClientIOWindow(self, \
181 self.terminal.client_ptymaster)
182 else:
183 self.clientIOWnd.destroy()
184 self.clientIOWnd = None
185
186 def isClientIOWindowExisting(self):
187 return self.clientIOWnd != None
188
189
190