Files
odo/vendor/github.com/hinshun/vt10x/parse.go
Anand Kumar Singh 3eb92b6a47 POC for odo interactive testing (#5466)
* POC for odo interactive testing

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* add interactive tests to make target test-integration

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* [WIP] use func to pass test instructions

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* cleanup comments/test

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* cleanup minor changes

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* fix unit test failure

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* skip for windows

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* skip for windows by not compiling, cleanup

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* cleanup, and add the make target to test files

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* incorporate review, adding comments, cleanup

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* fix failing make validate

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* update test dependency, and possible fix for windows

Signed-off-by: anandrkskd <anandrkskd@gmail.com>

* Revert "update test dependency, and possible fix for windows"

This reverts commit 55580b7dc5.

* Final cleanup

Signed-off-by: anandrkskd <anandrkskd@gmail.com>
2022-03-02 13:50:26 -05:00

204 lines
4.2 KiB
Go

package vt10x
func isControlCode(c rune) bool {
return c < 0x20 || c == 0177
}
func (t *State) parse(c rune) {
t.logf("%q", string(c))
if isControlCode(c) {
if t.handleControlCodes(c) || t.cur.Attr.Mode&attrGfx == 0 {
return
}
}
// TODO: update selection; see st.c:2450
if t.mode&ModeWrap != 0 && t.cur.State&cursorWrapNext != 0 {
t.lines[t.cur.Y][t.cur.X].Mode |= attrWrap
t.newline(true)
}
if t.mode&ModeInsert != 0 && t.cur.X+1 < t.cols {
// TODO: move shiz, look at st.c:2458
t.logln("insert mode not implemented")
}
t.setChar(c, &t.cur.Attr, t.cur.X, t.cur.Y)
if t.cur.X+1 < t.cols {
t.moveTo(t.cur.X+1, t.cur.Y)
} else {
t.cur.State |= cursorWrapNext
}
}
func (t *State) parseEsc(c rune) {
if t.handleControlCodes(c) {
return
}
next := t.parse
t.logf("%q", string(c))
switch c {
case '[':
next = t.parseEscCSI
case '#':
next = t.parseEscTest
case 'P', // DCS - Device Control String
'_', // APC - Application Program Command
'^', // PM - Privacy Message
']', // OSC - Operating System Command
'k': // old title set compatibility
t.str.reset()
t.str.typ = c
next = t.parseEscStr
case '(': // set primary charset G0
next = t.parseEscAltCharset
case ')', // set secondary charset G1 (ignored)
'*', // set tertiary charset G2 (ignored)
'+': // set quaternary charset G3 (ignored)
case 'D': // IND - linefeed
if t.cur.Y == t.bottom {
t.scrollUp(t.top, 1)
} else {
t.moveTo(t.cur.X, t.cur.Y+1)
}
case 'E': // NEL - next line
t.newline(true)
case 'H': // HTS - horizontal tab stop
t.tabs[t.cur.X] = true
case 'M': // RI - reverse index
if t.cur.Y == t.top {
t.scrollDown(t.top, 1)
} else {
t.moveTo(t.cur.X, t.cur.Y-1)
}
case 'Z': // DECID - identify terminal
// TODO: write to our writer our id
case 'c': // RIS - reset to initial state
t.reset()
case '=': // DECPAM - application keypad
t.mode |= ModeAppKeypad
case '>': // DECPNM - normal keypad
t.mode &^= ModeAppKeypad
case '7': // DECSC - save cursor
t.saveCursor()
case '8': // DECRC - restore cursor
t.restoreCursor()
case '\\': // ST - stop
default:
t.logf("unknown ESC sequence '%c'\n", c)
}
t.state = next
}
func (t *State) parseEscCSI(c rune) {
if t.handleControlCodes(c) {
return
}
t.logf("%q", string(c))
if t.csi.put(byte(c)) {
t.state = t.parse
t.handleCSI()
}
}
func (t *State) parseEscStr(c rune) {
t.logf("%q", string(c))
switch c {
case '\033':
t.state = t.parseEscStrEnd
case '\a': // backwards compatiblity to xterm
t.state = t.parse
t.handleSTR()
default:
t.str.put(c)
}
}
func (t *State) parseEscStrEnd(c rune) {
if t.handleControlCodes(c) {
return
}
t.logf("%q", string(c))
t.state = t.parse
if c == '\\' {
t.handleSTR()
}
}
func (t *State) parseEscAltCharset(c rune) {
if t.handleControlCodes(c) {
return
}
t.logf("%q", string(c))
switch c {
case '0': // line drawing set
t.cur.Attr.Mode |= attrGfx
case 'B': // USASCII
t.cur.Attr.Mode &^= attrGfx
case 'A', // UK (ignored)
'<', // multinational (ignored)
'5', // Finnish (ignored)
'C', // Finnish (ignored)
'K': // German (ignored)
default:
t.logf("unknown alt. charset '%c'\n", c)
}
t.state = t.parse
}
func (t *State) parseEscTest(c rune) {
if t.handleControlCodes(c) {
return
}
// DEC screen alignment test
if c == '8' {
for y := 0; y < t.rows; y++ {
for x := 0; x < t.cols; x++ {
t.setChar('E', &t.cur.Attr, x, y)
}
}
}
t.state = t.parse
}
func (t *State) handleControlCodes(c rune) bool {
if !isControlCode(c) {
return false
}
switch c {
// HT
case '\t':
t.putTab(true)
// BS
case '\b':
t.moveTo(t.cur.X-1, t.cur.Y)
// CR
case '\r':
t.moveTo(0, t.cur.Y)
// LF, VT, LF
case '\f', '\v', '\n':
// go to first col if mode is set
t.newline(t.mode&ModeCRLF != 0)
// BEL
case '\a':
// TODO: emit sound
// TODO: window alert if not focused
// ESC
case 033:
t.csi.reset()
t.state = t.parseEsc
// SO, SI
case 016, 017:
// different charsets not supported. apps should use the correct
// alt charset escapes, probably for line drawing
// SUB, CAN
case 032, 030:
t.csi.reset()
// ignore ENQ, NUL, XON, XOFF, DEL
case 005, 000, 021, 023, 0177:
default:
return false
}
return true
}