15cb11df2bb233c8c7881db3e2c255cf0de77327
[pygdb.git] / GdbTerminal.py
1 #!/usr/bin/python
2 #shuber, 2008-06-04
3
4 __author__ = "shuber"
5
6
7 import gtk
8 import os
9 import re
10 import string
11 import sys
12 import time
13
14 import DbgTerminal
15
16
17 class GdbTerminal (DbgTerminal.DbgTerminal):
18
19
20 def __init__(self, clientCmd):
21 DbgTerminal.DbgTerminal.__init__(self, clientCmd)
22
23 def getArgv(self):
24 return ["gdb", "--fullname", string.split(self.clientCmd)[0]]
25
26 def setPty(self, pty):
27 ttyname = os.ttyname(pty)
28 self.feed_child("set inferior-tty %s\n" % (ttyname,))
29
30 def setRun(self):
31 argv = string.join(string.split(self.clientCmd)[1:])
32 self.feed_child("run " + argv + "\n")
33
34 def setContinue(self):
35 self.feed_child("cont\n");
36
37 def setStepover(self):
38 self.feed_child("next\n");
39
40 def setStepin(self):
41 self.feed_child("step\n");
42
43 def setQuit(self):
44 self.feed_child("quit\n")
45 self.waitForNewline()
46 self.feed_child("y\n");
47
48 def setBreakpoint(self, file, lineno, condition=None):
49 his = self.getHistoryLen()
50 if condition==None:
51 self.feed_child("break %s:%s\n" % (file, str(lineno)))
52 else:
53 self.feed_child("break %s:%s if %s\n" % \
54 (file, str(lineno), condition))
55
56 rx = re.compile("^Breakpoint |^No |^\(gdb\) ")
57 his, response = self.waitForRx(rx, his)
58
59 answer = None
60
61 if response[0:10] == "Breakpoint":
62 answer = string.split(response)[1].strip()
63
64 #Wants an answer: "No"
65 if response[0:14] == "No source file":
66 self.feed_child("n\n");
67
68 #Wait again for (gdb)...
69 self.waitForActivation(his)
70
71 return answer
72
73
74 def delBreakpoint(self, breakpoint):
75 his = self.getHistoryLen()
76 self.feed_child("del breakpoint %s\n" % (breakpoint,))
77 self.waitForActivation(his)
78
79 def getBreakpoints(self):
80 starthis = self.getHistoryLen()
81 self.feed_child("info breakpoints\n")
82 endhis, response = self.__waitForPrompt(starthis)
83
84 rxbp = re.compile("^\d+\s+breakpoint")
85 rxpos = re.compile("^.* at \S+:\d+$")
86 rxcond = re.compile("^\tstop only if")
87
88 bpnts = []
89 bplines = self.history[starthis+1:endhis]
90 i = 0
91
92 #Parse the resulting lines
93 while i<len(bplines):
94 line = bplines[i]
95
96 if not rxbp.search(line):
97 i += 1
98 continue
99
100 #Get number of breakpoint
101 no = string.split(line)[0]
102
103 #This line does not contain the file!
104 if not rxpos.search(line):
105 i += 1
106 line = bplines[i]
107
108 pos = string.split(line)[-1]
109 [file,lineno] = string.split(pos,":")
110 cond = None
111
112 if i+1<len(bplines) and rxcond.search(bplines[i+1]):
113 i +=1
114 line = bplines[i]
115 pre,cond = string.split(line,"if")
116 cond = cond.strip()
117
118 bpnts += [[no, file, lineno, cond]]
119 i += 1
120
121 return bpnts
122
123
124
125 def getExpression(self, expr):
126
127 his = self.getHistoryLen()
128 self.feed_child("print " + expr + "\n")
129 his, response = self.__waitForPrompt(his)
130 answer = self.history[his-1]
131
132 if len(string.split(answer, "=")) == 1:
133 return answer.strip()
134
135 split = string.split(answer, "=")
136 return string.join(split[1:], "=").strip()
137
138
139 def waitForActivation(self, starthis):
140
141 self.setActive(False)
142 endhis, response = self.__waitForPrompt(starthis)
143 self.setActive(True)
144
145 for his in reversed(range(starthis+1,endhis)):
146 if self.history[his][0:2]=="\x1a\x1a":
147 tuples = string.split(self.history[his][2:], ":")
148 return tuples[0], int(tuples[1])
149
150 return None
151
152
153 def __waitForPrompt(self, his):
154 rx = re.compile("^\(gdb\) ")
155 return self.waitForRx(rx,his)
156
157
158 def testForActivity(self, his):
159 """Test whether debugger got active again"""
160 rx = re.compile("^\(gdb\) ")
161
162 #Aha! There is a prompt...
163 if rx.search(self.history[his]):
164 line = self.history[his-1]
165
166 if line[0:2]=="\x1a\x1a":
167 tuples = string.split(line[2:], ":")
168 tuples[1] = int(tuples[1])
169 return "break", [tuples[0], int(tuples[1])]
170
171 if string.find(line, "Program exited") == 0:
172 code = string.split(line)[-1]
173 code = code[:-1]
174 return "exited", code
175
176 return None
177
178
179 def testForInactivity(self, his):
180 """Test whether debugger got inactive"""
181 line = self.history[his]
182
183 if string.find(line, "Starting program:") == 0:
184 prog = string.join( string.split(line)[1:])
185 return "started", prog
186
187 if string.find(line, "Continuing.") == 0:
188 return "continued", None
189
190 if string.find(line, "\x1a\x1a") == 0:
191 rxcont = re.compile("^\(gdb\)\s+(cont|step|next|stepi|nexti)")
192
193 if rxcont.search(self.history[his-1]):
194 return "stepped", None
195
196 return None
197
198
199
200
201
202
203
204
205 if __name__ == "__main__":
206
207
208 dbgterm = GdbTerminal(string.join(sys.argv[1:]))
209 dbgwnd = DbgTerminal.DbgWindow(dbgterm)
210
211 gtk.main()
212
213
214
215