diff options
author | noah <noah@656d521f-e311-0410-88e0-e7920216d269> | 2002-08-27 17:59:53 +0000 |
---|---|---|
committer | noah <noah@656d521f-e311-0410-88e0-e7920216d269> | 2002-08-27 17:59:53 +0000 |
commit | def53377ff29c004e37e135f4182dec0c7d55703 (patch) | |
tree | 48659d45f6883f43c13fb70adcb3a2a7b7701123 /pexpect/ANSI.py | |
parent | e81cbe17d8ec5557c32b64d92306cd0183bda62d (diff) | |
download | pexpect-def53377ff29c004e37e135f4182dec0c7d55703.tar.gz |
Cleaning up ANSI.py. New ANSI name and new method 'get_region()' for screen.py.
git-svn-id: http://pexpect.svn.sourceforge.net/svnroot/pexpect/trunk@24 656d521f-e311-0410-88e0-e7920216d269
Diffstat (limited to 'pexpect/ANSI.py')
-rwxr-xr-x | pexpect/ANSI.py | 224 |
1 files changed, 224 insertions, 0 deletions
diff --git a/pexpect/ANSI.py b/pexpect/ANSI.py new file mode 100755 index 0000000..0ae3969 --- /dev/null +++ b/pexpect/ANSI.py @@ -0,0 +1,224 @@ +#!/usr/bin/env python + +# references: +# http://www.retards.org/terminals/vt102.html +# http://vt100.net/docs/vt102-ug/contents.html +# http://vt100.net/docs/vt220-rm/ +# http://www.termsys.demon.co.uk/vtansi.htm +# + +import screen +import FSM +import copy +import string + + + +def Emit (fsm): + screen = fsm.something[0] + screen.write(fsm.input_symbol) +def StartNumber (fsm): + fsm.something.append (fsm.input_symbol) +def BuildNumber (fsm): + ns = fsm.something.pop() + ns = ns + fsm.input_symbol + fsm.something.append (ns) +def DoBackOne (fsm): + screen = fsm.something[0] + screen.cursor_back () +def DoBack (fsm): + count = int(fsm.something.pop()) + screen = fsm.something[0] + screen.cursor_back (count) +def DoDownOne (fsm): + screen = fsm.something[0] + screen.cursor_down () +def DoDown (fsm): + count = int(fsm.something.pop()) + screen = fsm.something[0] + screen.cursor_down (count) +def DoForwardOne (fsm): + screen = fsm.something[0] + screen.cursor_forward () +def DoForward (fsm): + count = int(fsm.something.pop()) + screen = fsm.something[0] + screen.cursor_forward (count) +def DoUpReverse (fsm): + screen = fsm.something[0] + screen.cursor_up_reverse() +def DoUpOne (fsm): + screen = fsm.something[0] + screen.cursor_up () +def DoUp (fsm): + count = int(fsm.something.pop()) + screen = fsm.something[0] + screen.cursor_up (count) +def DoHome (fsm): + c = int(fsm.something.pop()) + r = int(fsm.something.pop()) + screen = fsm.something[0] + screen.cursor_home (r,c) +def DoHomeOrigin (fsm): + c = 1 + r = 1 + screen = fsm.something[0] + screen.cursor_home (r,c) +def DoEraseDown (fsm): + screen = fsm.something[0] + screen.erase_down() +def DoErase (fsm): + arg = int(fsm.something.pop()) + screen = fsm.something[0] + if arg == 0: + screen.erase_down() + elif arg == 1: + screen.erase_up() + elif arg == 2: + screen.erase_screen() +def DoEraseEndOfLine (fsm): + screen = fsm.something[0] + screen.erase_end_of_line() +def DoEraseLine (fsm): + screen = fsm.something[0] + if arg == 0: + screen.end_of_line() + elif arg == 1: + screen.start_of_line() + elif arg == 2: + screen.erase_line() +def DoEnableScroll (fsm): + # Scrolling is on by default. + pass +def DoCursorSave (fsm): + screen = fsm.something[0] + screen.cursor_save_attrs() +def DoCursorRestore (fsm): + screen = fsm.something[0] + screen.cursor_restore_attrs() + +def DoMode (fsm): + screen = fsm.something[0] + mode = fsm.something.pop() # Should be 4 + # screen.setReplaceMode () +def Log (fsm): + screen = fsm.something[0] + fsm.something = [screen] + fout = open ('log', 'a') + fout.write (fsm.input_symbol + ',' + fsm.current_state + '\n') + fout.close() + +class term (screen.screen): + def __init__ (self, r=24, c=80): + screen.screen.__init__(self, r,c) + +class ANSI (term): + '''This class encapsulates a generic terminal. + It filters a stream and maintains the state of + a screen object. + ''' + def __init__ (self, r=24,c=80): + term.__init__(self,r,c) + + #self.screen = screen (24,80) + self.state = FSM.FSM ('INIT',[self]) + self.state.set_default_transition (Log, 'INIT') + self.state.add_transition_any ('INIT', Emit, 'INIT') + self.state.add_transition ('\x1b', 'INIT', None, 'ESC') + self.state.add_transition_any ('ESC', Log, 'INIT') + self.state.add_transition ('(', 'ESC', None, 'G0SCS') + self.state.add_transition (')', 'ESC', None, 'G1SCS') + self.state.add_transition_list ('AB012', 'G0SCS', None, 'INIT') + self.state.add_transition_list ('AB012', 'G1SCS', None, 'INIT') + self.state.add_transition ('[', 'ESC', None, 'ELB') + self.state.add_transition ('7', 'ESC', DoCursorSave, 'INIT') + self.state.add_transition ('8', 'ESC', DoCursorRestore, 'INIT') + self.state.add_transition ('M', 'ESC', DoUpReverse, 'INIT') + self.state.add_transition ('=', 'ESC', None, 'INIT') # Selects application keypad. + self.state.add_transition ('#', 'ESC', None, 'GRAPHICS_POUND') + self.state.add_transition_any ('GRAPHICS_POUND', None, 'INIT') + # ELB means Escape Left Bracket. That is ^[[ + self.state.add_transition ('H', 'ELB', DoHomeOrigin, 'INIT') + self.state.add_transition ('D', 'ELB', DoBackOne, 'INIT') + self.state.add_transition ('B', 'ELB', DoDownOne, 'INIT') + self.state.add_transition ('C', 'ELB', DoForwardOne, 'INIT') + self.state.add_transition ('A', 'ELB', DoUpOne, 'INIT') + self.state.add_transition ('J', 'ELB', DoEraseDown, 'INIT') + self.state.add_transition ('K', 'ELB', DoEraseEndOfLine, 'INIT') + self.state.add_transition ('r', 'ELB', DoEnableScroll, 'INIT') + self.state.add_transition ('m', 'ELB', None, 'INIT') + self.state.add_transition ('?', 'ELB', None, 'MODECRAP') + self.state.add_transition_list (string.digits, 'ELB', StartNumber, 'NUMBER_1') + self.state.add_transition_list (string.digits, 'NUMBER_1', BuildNumber, 'NUMBER_1') + self.state.add_transition ('D', 'NUMBER_1', DoBack, 'INIT') + self.state.add_transition ('B', 'NUMBER_1', DoDown, 'INIT') + self.state.add_transition ('C', 'NUMBER_1', DoForward, 'INIT') + self.state.add_transition ('A', 'NUMBER_1', DoUp, 'INIT') + self.state.add_transition ('J', 'NUMBER_1', DoErase, 'INIT') + self.state.add_transition ('K', 'NUMBER_1', DoEraseLine, 'INIT') + self.state.add_transition ('l', 'NUMBER_1', DoMode, 'INIT') + self.state.add_transition ('m', 'NUMBER_1', None, 'INIT') + + # \E[?47h appears to be "switch to alternate screen" + # \E[?47l restores alternate screen... I think. + self.state.add_transition_list (string.digits, 'MODECRAP', StartNumber, 'MODECRAP_NUM') + self.state.add_transition_list (string.digits, 'MODECRAP_NUM', BuildNumber, 'MODECRAP_NUM') + self.state.add_transition ('l', 'MODECRAP_NUM', None, 'INIT') + self.state.add_transition ('h', 'MODECRAP_NUM', None, 'INIT') + +#RM Reset Mode Esc [ Ps l none + self.state.add_transition (';', 'NUMBER_1', None, 'SEMICOLON') + self.state.add_transition_any ('SEMICOLON', Log, 'INIT') + self.state.add_transition_list (string.digits, 'SEMICOLON', StartNumber, 'NUMBER_2') + self.state.add_transition_list (string.digits, 'NUMBER_2', BuildNumber, 'NUMBER_2') + self.state.add_transition_any ('NUMBER_2', Log, 'INIT') + self.state.add_transition ('H', 'NUMBER_2', DoHome, 'INIT') + self.state.add_transition ('f', 'NUMBER_2', DoHome, 'INIT') + def process (self, c): + self.state.process(c) + def test (self): + dump = file('dump').read() + for c in dump: + self.state.process(c) + print str(self) + + + def write (self, ch): + '''Puts a character at the current cursor position. + cursor position if moved forward with wrap-around, but + no scrolling is done if the cursor hits the lower-right corner + of the screen. + \r and \n both produce a call to crlf(). + ''' + ch = ch[0] + + if ch == '\r': + self.crlr() + return + if ch == '\n': + self.crlf() + return + if ch == chr(screen.BS): + self.cursor_back() + self.put(self.cur_r, self.cur_c, ' ') + return + + if ch not in string.printable: + fout = open ('log', 'a') + fout.write ('Nonprint: ' + str(ord(ch))) + fout.close() + + return + self.put_abs(self.cur_r, self.cur_c, ch) + old_r = self.cur_r + old_c = self.cur_c + self.cursor_forward() + if old_c == self.cur_c: + self.cursor_down() + if old_r != self.cur_r: + self.cursor_home (self.cur_r, 1) + else: + self.scroll_up () + self.cursor_home (self.cur_r, 1) + self.erase_line() + |