19 import ClientIOTerminal
23 class DbgTerminal (vte
.Terminal
):
25 def __init__(self
, clientCmd
):
27 vte
.Terminal
.__init
__(self
)
33 self
.lastc
, self
.lastr
= 0,0
34 self
.gotActiveCallback
= []
35 self
.gotInactiveCallback
= []
36 self
.activityChanged
= None
39 self
.clientCmd
= clientCmd
40 #Open pseudo-terminal where to-be-debugged process reads/writes to
41 self
.client_ptymaster
, self
.client_ptyslave
= pty
.openpty()
43 #Set up terminal window and initialize debugger
44 self
.connect("cursor-moved", self
.contents_changed
)
45 self
.connect("child-exited", quitHandler
)
46 gobject
.timeout_add(50, self
.checkActivityChanged
)
49 fontdesc
= pango
.FontDescription("monospace 9")
50 self
.set_font(fontdesc
)
54 self
.childpid
= self
.fork_command( self
.getCommand(), self
.getArgv())
56 self
.setPty(self
.client_ptyslave
)
60 if self
.childpid
!= None:
62 os
.kill(self
.childpid
, 15);
65 def checkActivityChanged(self
):
70 if self
.activityChanged
!= None:
72 res
= self
.activityChanged
73 self
.activityChanged
= None
77 print "got active: ", res
78 for cb
in self
.gotActiveCallback
:
81 print "got inactive: ", res
82 for cb
in self
.gotInactiveCallback
:
91 def contents_changed(self
, term
):
92 assert( self
.getHistoryLen()>0 )
94 c
,r
= term
.get_cursor_position()
95 text
= self
.get_text_range(self
.lastr
,0,r
,c
,lambda *w
:True)
96 self
.lastc
, self
.lastr
= c
,r
98 #Remove annoying \n at the end
99 assert(text
[-1] == "\n")
102 #Get the lines and remove empty lines
103 lines
= string
.split(text
, "\n")
105 #Remove the incomplete line
106 len = max(0,self
.getHistoryLen())
107 self
.history
[-1] = lines
[0]
108 self
.history
+= lines
[1:]
111 #Check if activity status has been changed
112 for i
in range(len, self
.getHistoryLen()):
113 line
= self
.history
[i
]
115 res
= self
.testForInactivity(i
)
117 while self
.activityChanged
!= None:
118 print "wait for pending activity"
121 self
.setActive(False)
122 self
.activityChanged
= res
124 res
= self
.testForActivity(i
)
126 while self
.activityChanged
!= None:
127 print "wait for pending activity"
131 self
.activityChanged
= res
136 def waitForNewline(self
):
137 l
= self
.getHistoryLen()
138 while not self
.getHistoryLen() > l
:
141 def getHistoryLen(self
):
142 return len(self
.history
)
144 def waitForRx(self
, pat
, start
):
149 assert( curr
>=start
)
150 for no
in range(curr
, self
.getHistoryLen()):
151 line
= self
.history
[no
]
155 #Do not forget the last line
156 curr
= max(start
,self
.getHistoryLen()-1)
157 lr
, lc
= self
.lastr
, self
.lastc
159 while (self
.lastr
, self
.lastc
) == (lr
,lc
):
163 def getCommand(self
):
164 return self
.getArgv()[0];
167 raise NotImplementedError()
169 def setPty(self
, pty
):
170 raise NotImplementedError()
173 raise NotImplementedError()
175 def setContinue(self
):
176 raise NotImplementedError()
178 def setStepover(self
):
179 raise NotImplementedError()
182 raise NotImplementedError()
185 raise NotImplementedError()
187 def setBreakpoint(self
, file, lineno
, condition
=False):
188 raise NotImplementedError()
190 def delBreakpoint(self
, breakpoint
):
191 raise NotImplementedError()
193 def getExpression(self
, expr
):
194 raise NotImplementedError()
196 def waitForPrompt(self
, his
):
197 raise NotImplementedError()
199 def testForActivity(self
, his
):
200 raise NotImplementedError()
202 def testForInactivity(self
, his
):
203 raise NotImplementedError()
205 def setActive(self
, isactive
):
206 self
.isactive
= isactive
221 class DbgWindow (gtk
.Window
):
226 def __init__(self
, terminal
):
229 self
.terminal
= terminal
232 gtk
.Window
.__init
__(self
)
233 self
.connect("destroy", quitHandler
)
235 #Set title and add terminal
236 self
.set_title("Debugger I/O")
237 self
.terminal
.history
= []
238 self
.terminal
.history_length
= 5
239 self
.add(self
.terminal
)
244 def toggleClientIOWindow(self
):
245 if not self
.clientIOWnd
:
246 self
.clientIOWnd
= ClientIOTerminal
.ClientIOWindow(self
, \
247 self
.terminal
.client_ptymaster
)
249 self
.clientIOWnd
.destroy()
250 self
.clientIOWnd
= None
252 def isClientIOWindowExisting(self
):
253 return self
.clientIOWnd
!= None