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