// handle a byte and return whether the byte should go to output
handle a byte and return whether the byte should go to output
// handle a byte and return whether the byte should go to output
func (s *parserState) handle(b byte) (bool, error) {
	previousByte := s.previousByte
	s.previousByte = b
	var handlerError error
	switch s.state {
	default: 
		if b == escape || (s.utf8Escapes && b == 0xc2) {
			s.state = readEscape
			return false, handlerError
		}
		return true, handlerError
	case readEscape:
		if s.utf8Escapes && previousByte == 0xc2 {
			if b >= 0x80 && b <= 0x9f {
				s.seqBuf[0] = b - 0x40
				s.seqBufI = 1
				s.paramsBufI = 0
				if s.hasParams(b - 0x40) {
					s.state = readEscapeParams
				} else {
					handlerError = s.handleEscape()
					s.state = readNormal
				}
				return false, handlerError
			}
			s.extraByte = previousByte
			s.state = readNormal
			return true, handlerError
		}
		if b >= 0x20 && b <= 0x7e {
			if s.seqBufI < escapeSequenceMaxLength {
				s.seqBuf[s.seqBufI] = b
				s.seqBufI++
			}
			if b >= 0x30 {
				s.paramsBufI = 0
				if s.hasParams(b) {
					s.state = readEscapeParams
				} else {
					handlerError = s.handleEscape()
					s.state = readNormal
				}
			}
		} else {
			s.state = readNormal
			s.seqBufI = 0
		}
		return false, handlerError
	case readEscapeParams:
		var finalByte byte
		if s.seqBufI > 0 {
			finalByte = s.seqBuf[s.seqBufI-1]
		}
		if s.paramsBufI < escapeSequenceParamsMaxLength {
			s.paramsBuf[s.paramsBufI] = b
			s.paramsBufI++
		}
		switch finalByte {
		case '[': 
			if s.paramsBufI == 1 || (previousByte >= 0x30 && previousByte <= 0x3f) {
				if !(b >= 0x20 && b <= 0x7e) {
					s.state = readNormal
					s.seqBufI = 0
					return false, handlerError
				}
			} else if previousByte >= 0x20 && previousByte <= 0x2f {
				if !((b >= 0x20 && b <= 0x2f) || (b >= 0x40 && b <= 0x7e)) {
					s.state = readNormal
					s.seqBufI = 0
					return false, handlerError
				}
			}
			if b >= 0x40 && b <= 0x7e {
				handlerError = s.handleEscape()
				s.state = readNormal
			}
		default: 
			if (previousByte == escape && b == '\\') ||
				(s.utf8Escapes && previousByte == 0xc2 && b == 0x9c) ||
				s.paramsBufI == escapeSequenceParamsMaxLength ||
				(finalByte == ']' && b == '\x07') {
				handlerError = s.handleEscape()
				s.state = readNormal
				s.seqBufI = 0
			}
		}
		return false, handlerError
	}
}
func ( s * parserState ) handle ( b byte ) ( bool , error ) { previousByte := s . previousByte s . previousByte = b var handlerError error switch s . state { default : if b == escape || ( s . utf8Escapes && b == 0xc2 ) { s . state = readEscape return false , handlerError } return true , handlerError case readEscape : if s . utf8Escapes && previousByte == 0xc2 { if b >= 0x80 && b <= 0x9f { s . seqBuf [ 0 ] = b - 0x40 s . seqBufI = 1 s . paramsBufI = 0 if s . hasParams ( b - 0x40 ) { s . state = readEscapeParams } else { handlerError = s . handleEscape ( ) s . state = readNormal } return false , handlerError } s . extraByte = previousByte s . state = readNormal return true , handlerError } if b >= 0x20 && b <= 0x7e { if s . seqBufI < escapeSequenceMaxLength { s . seqBuf [ s . seqBufI ] = b s . seqBufI ++ } if b >= 0x30 { s . paramsBufI = 0 if s . hasParams ( b ) { s . state = readEscapeParams } else { handlerError = s . handleEscape ( ) s . state = readNormal } } } else { s . state = readNormal s . seqBufI = 0 } return false , handlerError case readEscapeParams : var finalByte byte if s . seqBufI > 0 { finalByte = s . seqBuf [ s . seqBufI - 1 ] } if s . paramsBufI < escapeSequenceParamsMaxLength { s . paramsBuf [ s . paramsBufI ] = b s . paramsBufI ++ } switch finalByte { case '[' : if s . paramsBufI == 1 || ( previousByte >= 0x30 && previousByte <= 0x3f ) { if ! ( b >= 0x20 && b <= 0x7e ) { s . state = readNormal s . seqBufI = 0 return false , handlerError } } else if previousByte >= 0x20 && previousByte <= 0x2f { if ! ( ( b >= 0x20 && b <= 0x2f ) || ( b >= 0x40 && b <= 0x7e ) ) { s . state = readNormal s . seqBufI = 0 return false , handlerError } } if b >= 0x40 && b <= 0x7e { handlerError = s . handleEscape ( ) s . state = readNormal } default : if ( previousByte == escape && b == '\\' ) || ( s . utf8Escapes && previousByte == 0xc2 && b == 0x9c ) || s . paramsBufI == escapeSequenceParamsMaxLength || ( finalByte == ']' && b == '\x07' ) { handlerError = s . handleEscape ( ) s . state = readNormal s . seqBufI = 0 } } return false , handlerError } }
handle a byte and return whether the byte should go to output
handle a byte and return whether the byte should go to output
// readNormal // intermediate or final byte // final byte // unknown sequence; swallow the sequence but resume normal output // CSI // invalid parameters // invalid parameters // ST-terminated // if an ST-terminated sequence is too long, just truncate it // allow xterm BEL-terminated OSC