Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: third_party/pexpect/ANSI.py

Issue 11360098: Roll third_party/pexpect 509:533 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase after licensecheck.pl Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | third_party/pexpect/FSM.py » ('j') | tools/checklicenses/checklicenses.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 """This implements an ANSI terminal emulator as a subclass of screen. 1 """This implements an ANSI (VT100) terminal emulator as a subclass of screen.
2 2
3 $Id: ANSI.py 491 2007-12-16 20:04:57Z noah $ 3 PEXPECT LICENSE
4
5 This license is approved by the OSI and FSF as GPL-compatible.
6 http://opensource.org/licenses/isc-license.txt
7
8 Copyright (c) 2012, Noah Spurrier <noah@noah.org>
9 PERMISSION TO USE, COPY, MODIFY, AND/OR DISTRIBUTE THIS SOFTWARE FOR ANY
10 PURPOSE WITH OR WITHOUT FEE IS HEREBY GRANTED, PROVIDED THAT THE ABOVE
11 COPYRIGHT NOTICE AND THIS PERMISSION NOTICE APPEAR IN ALL COPIES.
12 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
4 """ 20 """
21
5 # references: 22 # references:
23 # http://en.wikipedia.org/wiki/ANSI_escape_code
6 # http://www.retards.org/terminals/vt102.html 24 # http://www.retards.org/terminals/vt102.html
7 # http://vt100.net/docs/vt102-ug/contents.html 25 # http://vt100.net/docs/vt102-ug/contents.html
8 # http://vt100.net/docs/vt220-rm/ 26 # http://vt100.net/docs/vt220-rm/
9 # http://www.termsys.demon.co.uk/vtansi.htm 27 # http://www.termsys.demon.co.uk/vtansi.htm
10 28
11 import screen 29 import screen
12 import FSM 30 import FSM
13 import copy 31 import copy
14 import string 32 import string
15 33
16 def Emit (fsm): 34 #
35 # The 'Do.*' functions are helper functions for the ANSI class.
36 #
37 def DoEmit (fsm):
17 38
18 screen = fsm.memory[0] 39 screen = fsm.memory[0]
19 screen.write_ch(fsm.input_symbol) 40 screen.write_ch(fsm.input_symbol)
20 41
21 def StartNumber (fsm): 42 def DoStartNumber (fsm):
22 43
23 fsm.memory.append (fsm.input_symbol) 44 fsm.memory.append (fsm.input_symbol)
24 45
25 def BuildNumber (fsm): 46 def DoBuildNumber (fsm):
26 47
27 ns = fsm.memory.pop() 48 ns = fsm.memory.pop()
28 ns = ns + fsm.input_symbol 49 ns = ns + fsm.input_symbol
29 fsm.memory.append (ns) 50 fsm.memory.append (ns)
30 51
31 def DoBackOne (fsm): 52 def DoBackOne (fsm):
32 53
33 screen = fsm.memory[0] 54 screen = fsm.memory[0]
34 screen.cursor_back () 55 screen.cursor_back ()
35 56
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 elif arg == 2: 128 elif arg == 2:
108 screen.erase_screen() 129 screen.erase_screen()
109 130
110 def DoEraseEndOfLine (fsm): 131 def DoEraseEndOfLine (fsm):
111 132
112 screen = fsm.memory[0] 133 screen = fsm.memory[0]
113 screen.erase_end_of_line() 134 screen.erase_end_of_line()
114 135
115 def DoEraseLine (fsm): 136 def DoEraseLine (fsm):
116 137
138 arg = int(fsm.memory.pop())
117 screen = fsm.memory[0] 139 screen = fsm.memory[0]
118 if arg == 0: 140 if arg == 0:
119 screen.end_of_line() 141 screen.erase_end_of_line()
120 elif arg == 1: 142 elif arg == 1:
121 screen.start_of_line() 143 screen.erase_start_of_line()
122 elif arg == 2: 144 elif arg == 2:
123 screen.erase_line() 145 screen.erase_line()
124 146
125 def DoEnableScroll (fsm): 147 def DoEnableScroll (fsm):
126 148
127 screen = fsm.memory[0] 149 screen = fsm.memory[0]
128 screen.scroll_screen() 150 screen.scroll_screen()
129 151
130 def DoCursorSave (fsm): 152 def DoCursorSave (fsm):
131 153
(...skipping 11 matching lines...) Expand all
143 r2 = int(fsm.memory.pop()) 165 r2 = int(fsm.memory.pop())
144 r1 = int(fsm.memory.pop()) 166 r1 = int(fsm.memory.pop())
145 screen.scroll_screen_rows (r1,r2) 167 screen.scroll_screen_rows (r1,r2)
146 168
147 def DoMode (fsm): 169 def DoMode (fsm):
148 170
149 screen = fsm.memory[0] 171 screen = fsm.memory[0]
150 mode = fsm.memory.pop() # Should be 4 172 mode = fsm.memory.pop() # Should be 4
151 # screen.setReplaceMode () 173 # screen.setReplaceMode ()
152 174
153 def Log (fsm): 175 def DoLog (fsm):
154 176
155 screen = fsm.memory[0] 177 screen = fsm.memory[0]
156 fsm.memory = [screen] 178 fsm.memory = [screen]
157 fout = open ('log', 'a') 179 fout = open ('log', 'a')
158 fout.write (fsm.input_symbol + ',' + fsm.current_state + '\n') 180 fout.write (fsm.input_symbol + ',' + fsm.current_state + '\n')
159 fout.close() 181 fout.close()
160 182
161 class term (screen.screen): 183 class term (screen.screen):
162 """This is a placeholder. 184
163 In theory I might want to add other terminal types. 185 """This class is an abstract, generic terminal.
164 """ 186 This does nothing. This is a placeholder that
187 provides a common base class for other terminals
188 such as an ANSI terminal. """
189
165 def __init__ (self, r=24, c=80): 190 def __init__ (self, r=24, c=80):
191
166 screen.screen.__init__(self, r,c) 192 screen.screen.__init__(self, r,c)
167 193
168 class ANSI (term): 194 class ANSI (term):
169 195
170 """This class encapsulates a generic terminal. It filters a stream and 196 """This class implements an ANSI (VT100) terminal.
171 maintains the state of a screen object. """ 197 It is a stream filter that recognizes ANSI terminal
198 escape sequences and maintains the state of a screen object. """
172 199
173 def __init__ (self, r=24,c=80): 200 def __init__ (self, r=24,c=80):
174 201
175 term.__init__(self,r,c) 202 term.__init__(self,r,c)
176 203
177 #self.screen = screen (24,80) 204 #self.screen = screen (24,80)
178 self.state = FSM.FSM ('INIT',[self]) 205 self.state = FSM.FSM ('INIT',[self])
179 self.state.set_default_transition (Log, 'INIT') 206 self.state.set_default_transition (DoLog, 'INIT')
180 self.state.add_transition_any ('INIT', Emit, 'INIT') 207 self.state.add_transition_any ('INIT', DoEmit, 'INIT')
181 self.state.add_transition ('\x1b', 'INIT', None, 'ESC') 208 self.state.add_transition ('\x1b', 'INIT', None, 'ESC')
182 self.state.add_transition_any ('ESC', Log, 'INIT') 209 self.state.add_transition_any ('ESC', DoLog, 'INIT')
183 self.state.add_transition ('(', 'ESC', None, 'G0SCS') 210 self.state.add_transition ('(', 'ESC', None, 'G0SCS')
184 self.state.add_transition (')', 'ESC', None, 'G1SCS') 211 self.state.add_transition (')', 'ESC', None, 'G1SCS')
185 self.state.add_transition_list ('AB012', 'G0SCS', None, 'INIT') 212 self.state.add_transition_list ('AB012', 'G0SCS', None, 'INIT')
186 self.state.add_transition_list ('AB012', 'G1SCS', None, 'INIT') 213 self.state.add_transition_list ('AB012', 'G1SCS', None, 'INIT')
187 self.state.add_transition ('7', 'ESC', DoCursorSave, 'INIT') 214 self.state.add_transition ('7', 'ESC', DoCursorSave, 'INIT')
188 self.state.add_transition ('8', 'ESC', DoCursorRestore, 'INIT') 215 self.state.add_transition ('8', 'ESC', DoCursorRestore, 'INIT')
189 self.state.add_transition ('M', 'ESC', DoUpReverse, 'INIT') 216 self.state.add_transition ('M', 'ESC', DoUpReverse, 'INIT')
190 self.state.add_transition ('>', 'ESC', DoUpReverse, 'INIT') 217 self.state.add_transition ('>', 'ESC', DoUpReverse, 'INIT')
191 self.state.add_transition ('<', 'ESC', DoUpReverse, 'INIT') 218 self.state.add_transition ('<', 'ESC', DoUpReverse, 'INIT')
192 self.state.add_transition ('=', 'ESC', None, 'INIT') # Selects applicati on keypad. 219 self.state.add_transition ('=', 'ESC', None, 'INIT') # Selects applicati on keypad.
193 self.state.add_transition ('#', 'ESC', None, 'GRAPHICS_POUND') 220 self.state.add_transition ('#', 'ESC', None, 'GRAPHICS_POUND')
194 self.state.add_transition_any ('GRAPHICS_POUND', None, 'INIT') 221 self.state.add_transition_any ('GRAPHICS_POUND', None, 'INIT')
195 self.state.add_transition ('[', 'ESC', None, 'ELB') 222 self.state.add_transition ('[', 'ESC', None, 'ELB')
196 # ELB means Escape Left Bracket. That is ^[[ 223 # ELB means Escape Left Bracket. That is ^[[
197 self.state.add_transition ('H', 'ELB', DoHomeOrigin, 'INIT') 224 self.state.add_transition ('H', 'ELB', DoHomeOrigin, 'INIT')
198 self.state.add_transition ('D', 'ELB', DoBackOne, 'INIT') 225 self.state.add_transition ('D', 'ELB', DoBackOne, 'INIT')
199 self.state.add_transition ('B', 'ELB', DoDownOne, 'INIT') 226 self.state.add_transition ('B', 'ELB', DoDownOne, 'INIT')
200 self.state.add_transition ('C', 'ELB', DoForwardOne, 'INIT') 227 self.state.add_transition ('C', 'ELB', DoForwardOne, 'INIT')
201 self.state.add_transition ('A', 'ELB', DoUpOne, 'INIT') 228 self.state.add_transition ('A', 'ELB', DoUpOne, 'INIT')
202 self.state.add_transition ('J', 'ELB', DoEraseDown, 'INIT') 229 self.state.add_transition ('J', 'ELB', DoEraseDown, 'INIT')
203 self.state.add_transition ('K', 'ELB', DoEraseEndOfLine, 'INIT') 230 self.state.add_transition ('K', 'ELB', DoEraseEndOfLine, 'INIT')
204 self.state.add_transition ('r', 'ELB', DoEnableScroll, 'INIT') 231 self.state.add_transition ('r', 'ELB', DoEnableScroll, 'INIT')
205 self.state.add_transition ('m', 'ELB', None, 'INIT') 232 self.state.add_transition ('m', 'ELB', None, 'INIT')
206 self.state.add_transition ('?', 'ELB', None, 'MODECRAP') 233 self.state.add_transition ('?', 'ELB', None, 'MODECRAP')
207 self.state.add_transition_list (string.digits, 'ELB', StartNumber, 'NUMB ER_1') 234 self.state.add_transition_list (string.digits, 'ELB', DoStartNumber, 'NU MBER_1')
208 self.state.add_transition_list (string.digits, 'NUMBER_1', BuildNumber, 'NUMBER_1') 235 self.state.add_transition_list (string.digits, 'NUMBER_1', DoBuildNumber , 'NUMBER_1')
209 self.state.add_transition ('D', 'NUMBER_1', DoBack, 'INIT') 236 self.state.add_transition ('D', 'NUMBER_1', DoBack, 'INIT')
210 self.state.add_transition ('B', 'NUMBER_1', DoDown, 'INIT') 237 self.state.add_transition ('B', 'NUMBER_1', DoDown, 'INIT')
211 self.state.add_transition ('C', 'NUMBER_1', DoForward, 'INIT') 238 self.state.add_transition ('C', 'NUMBER_1', DoForward, 'INIT')
212 self.state.add_transition ('A', 'NUMBER_1', DoUp, 'INIT') 239 self.state.add_transition ('A', 'NUMBER_1', DoUp, 'INIT')
213 self.state.add_transition ('J', 'NUMBER_1', DoErase, 'INIT') 240 self.state.add_transition ('J', 'NUMBER_1', DoErase, 'INIT')
214 self.state.add_transition ('K', 'NUMBER_1', DoEraseLine, 'INIT') 241 self.state.add_transition ('K', 'NUMBER_1', DoEraseLine, 'INIT')
215 self.state.add_transition ('l', 'NUMBER_1', DoMode, 'INIT') 242 self.state.add_transition ('l', 'NUMBER_1', DoMode, 'INIT')
216 ### It gets worse... the 'm' code can have infinite number of 243 ### It gets worse... the 'm' code can have infinite number of
217 ### number;number;number before it. I've never seen more than two, 244 ### number;number;number before it. I've never seen more than two,
218 ### but the specs say it's allowed. crap! 245 ### but the specs say it's allowed. crap!
219 self.state.add_transition ('m', 'NUMBER_1', None, 'INIT') 246 self.state.add_transition ('m', 'NUMBER_1', None, 'INIT')
220 ### LED control. Same problem as 'm' code. 247 ### LED control. Same implementation problem as 'm' code.
221 self.state.add_transition ('q', 'NUMBER_1', None, 'INIT') 248 self.state.add_transition ('q', 'NUMBER_1', None, 'INIT')
222 249
223 # \E[?47h appears to be "switch to alternate screen" 250 # \E[?47h switch to alternate screen
224 # \E[?47l restores alternate screen... I think. 251 # \E[?47l restores to normal screen from alternate screen.
225 self.state.add_transition_list (string.digits, 'MODECRAP', StartNumber, 'MODECRAP_NUM') 252 self.state.add_transition_list (string.digits, 'MODECRAP', DoStartNumber , 'MODECRAP_NUM')
226 self.state.add_transition_list (string.digits, 'MODECRAP_NUM', BuildNumb er, 'MODECRAP_NUM') 253 self.state.add_transition_list (string.digits, 'MODECRAP_NUM', DoBuildNu mber, 'MODECRAP_NUM')
227 self.state.add_transition ('l', 'MODECRAP_NUM', None, 'INIT') 254 self.state.add_transition ('l', 'MODECRAP_NUM', None, 'INIT')
228 self.state.add_transition ('h', 'MODECRAP_NUM', None, 'INIT') 255 self.state.add_transition ('h', 'MODECRAP_NUM', None, 'INIT')
229 256
230 #RM Reset Mode Esc [ Ps l none 257 #RM Reset Mode Esc [ Ps l none
231 self.state.add_transition (';', 'NUMBER_1', None, 'SEMICOLON') 258 self.state.add_transition (';', 'NUMBER_1', None, 'SEMICOLON')
232 self.state.add_transition_any ('SEMICOLON', Log, 'INIT') 259 self.state.add_transition_any ('SEMICOLON', DoLog, 'INIT')
233 self.state.add_transition_list (string.digits, 'SEMICOLON', StartNumber, 'NUMBER_2') 260 self.state.add_transition_list (string.digits, 'SEMICOLON', DoStartNumbe r, 'NUMBER_2')
234 self.state.add_transition_list (string.digits, 'NUMBER_2', BuildNumber, 'NUMBER_2') 261 self.state.add_transition_list (string.digits, 'NUMBER_2', DoBuildNumber , 'NUMBER_2')
235 self.state.add_transition_any ('NUMBER_2', Log, 'INIT') 262 self.state.add_transition_any ('NUMBER_2', DoLog, 'INIT')
236 self.state.add_transition ('H', 'NUMBER_2', DoHome, 'INIT') 263 self.state.add_transition ('H', 'NUMBER_2', DoHome, 'INIT')
237 self.state.add_transition ('f', 'NUMBER_2', DoHome, 'INIT') 264 self.state.add_transition ('f', 'NUMBER_2', DoHome, 'INIT')
238 self.state.add_transition ('r', 'NUMBER_2', DoScrollRegion, 'INIT') 265 self.state.add_transition ('r', 'NUMBER_2', DoScrollRegion, 'INIT')
239 ### It gets worse... the 'm' code can have infinite number of 266 ### It gets worse... the 'm' code can have infinite number of
240 ### number;number;number before it. I've never seen more than two, 267 ### number;number;number before it. I've never seen more than two,
241 ### but the specs say it's allowed. crap! 268 ### but the specs say it's allowed. crap!
242 self.state.add_transition ('m', 'NUMBER_2', None, 'INIT') 269 self.state.add_transition ('m', 'NUMBER_2', None, 'INIT')
243 ### LED control. Same problem as 'm' code. 270 ### LED control. Same problem as 'm' code.
244 self.state.add_transition ('q', 'NUMBER_2', None, 'INIT') 271 self.state.add_transition ('q', 'NUMBER_2', None, 'INIT')
272 self.state.add_transition (';', 'NUMBER_2', None, 'SEMICOLON_X')
273
274 # Create a state for 'q' and 'm' which allows an infinite number of igno red numbers
275 self.state.add_transition_any ('SEMICOLON_X', DoLog, 'INIT')
276 self.state.add_transition_list (string.digits, 'SEMICOLON_X', None, 'NUM BER_X')
277 self.state.add_transition_any ('NUMBER_X', DoLog, 'INIT')
278 self.state.add_transition ('m', 'NUMBER_X', None, 'INIT')
279 self.state.add_transition ('q', 'NUMBER_X', None, 'INIT')
280 self.state.add_transition (';', 'NUMBER_2', None, 'SEMICOLON_X')
245 281
246 def process (self, c): 282 def process (self, c):
247 283
248 self.state.process(c) 284 self.state.process(c)
249 285
250 def process_list (self, l): 286 def process_list (self, l):
251 287
252 self.write(l) 288 self.write(l)
253 289
254 def write (self, s): 290 def write (self, s):
255 291
256 for c in s: 292 for c in s:
257 self.process(c) 293 self.process(c)
258 294
259 def flush (self): 295 def flush (self):
260 296
261 pass 297 pass
262 298
263 def write_ch (self, ch): 299 def write_ch (self, ch):
264 300
265 """This puts a character at the current cursor position. cursor 301 """This puts a character at the current cursor position. The cursor
266 position if moved forward with wrap-around, but no scrolling is done if 302 position is moved forward with wrap-around, but no scrolling is done if
267 the cursor hits the lower-right corner of the screen. """ 303 the cursor hits the lower-right corner of the screen. """
268 304
269 #\r and \n both produce a call to crlf(). 305 #\r and \n both produce a call to cr() and lf(), respectively.
270 ch = ch[0] 306 ch = ch[0]
271 307
272 if ch == '\r': 308 if ch == '\r':
273 # self.crlf() 309 self.cr()
274 return 310 return
275 if ch == '\n': 311 if ch == '\n':
276 self.crlf() 312 self.crlf()
277 return 313 return
278 if ch == chr(screen.BS): 314 if ch == chr(screen.BS):
279 self.cursor_back() 315 self.cursor_back()
280 self.put_abs(self.cur_r, self.cur_c, ' ')
281 return 316 return
282
283 if ch not in string.printable: 317 if ch not in string.printable:
284 fout = open ('log', 'a') 318 fout = open ('log', 'a')
285 fout.write ('Nonprint: ' + str(ord(ch)) + '\n') 319 fout.write ('Nonprint: ' + str(ord(ch)) + '\n')
286 fout.close() 320 fout.close()
287 return 321 return
288 self.put_abs(self.cur_r, self.cur_c, ch) 322 self.put_abs(self.cur_r, self.cur_c, ch)
289 old_r = self.cur_r 323 old_r = self.cur_r
290 old_c = self.cur_c 324 old_c = self.cur_c
291 self.cursor_forward() 325 self.cursor_forward()
292 if old_c == self.cur_c: 326 if old_c == self.cur_c:
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
325 # '(His sense of smell.)' 359 # '(His sense of smell.)'
326 # self.fill('.') 360 # self.fill('.')
327 # self.cursor_home() 361 # self.cursor_home()
328 # for c in write_text: 362 # for c in write_text:
329 # self.write_ch (c) 363 # self.write_ch (c)
330 # print str(self) 364 # print str(self)
331 # 365 #
332 #if __name__ == '__main__': 366 #if __name__ == '__main__':
333 # t = ANSI(6,65) 367 # t = ANSI(6,65)
334 # t.test() 368 # t.test()
OLDNEW
« no previous file with comments | « no previous file | third_party/pexpect/FSM.py » ('j') | tools/checklicenses/checklicenses.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698