summaryrefslogtreecommitdiff
path: root/vendor/github.com/Azure/go-ansiterm/parser.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/Azure/go-ansiterm/parser.go')
-rw-r--r--vendor/github.com/Azure/go-ansiterm/parser.go136
1 files changed, 136 insertions, 0 deletions
diff --git a/vendor/github.com/Azure/go-ansiterm/parser.go b/vendor/github.com/Azure/go-ansiterm/parser.go
new file mode 100644
index 000000000..3286a9cb5
--- /dev/null
+++ b/vendor/github.com/Azure/go-ansiterm/parser.go
@@ -0,0 +1,136 @@
+package ansiterm
+
+import (
+ "errors"
+ "io/ioutil"
+ "os"
+
+ "github.com/sirupsen/logrus"
+)
+
+var logger *logrus.Logger
+
+type AnsiParser struct {
+ currState state
+ eventHandler AnsiEventHandler
+ context *ansiContext
+ csiEntry state
+ csiParam state
+ dcsEntry state
+ escape state
+ escapeIntermediate state
+ error state
+ ground state
+ oscString state
+ stateMap []state
+}
+
+func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser {
+ logFile := ioutil.Discard
+
+ if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" {
+ logFile, _ = os.Create("ansiParser.log")
+ }
+
+ logger = &logrus.Logger{
+ Out: logFile,
+ Formatter: new(logrus.TextFormatter),
+ Level: logrus.InfoLevel,
+ }
+
+ parser := &AnsiParser{
+ eventHandler: evtHandler,
+ context: &ansiContext{},
+ }
+
+ parser.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: parser}}
+ parser.csiParam = csiParamState{baseState{name: "CsiParam", parser: parser}}
+ parser.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: parser}}
+ parser.escape = escapeState{baseState{name: "Escape", parser: parser}}
+ parser.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: parser}}
+ parser.error = errorState{baseState{name: "Error", parser: parser}}
+ parser.ground = groundState{baseState{name: "Ground", parser: parser}}
+ parser.oscString = oscStringState{baseState{name: "OscString", parser: parser}}
+
+ parser.stateMap = []state{
+ parser.csiEntry,
+ parser.csiParam,
+ parser.dcsEntry,
+ parser.escape,
+ parser.escapeIntermediate,
+ parser.error,
+ parser.ground,
+ parser.oscString,
+ }
+
+ parser.currState = getState(initialState, parser.stateMap)
+
+ logger.Infof("CreateParser: parser %p", parser)
+ return parser
+}
+
+func getState(name string, states []state) state {
+ for _, el := range states {
+ if el.Name() == name {
+ return el
+ }
+ }
+
+ return nil
+}
+
+func (ap *AnsiParser) Parse(bytes []byte) (int, error) {
+ for i, b := range bytes {
+ if err := ap.handle(b); err != nil {
+ return i, err
+ }
+ }
+
+ return len(bytes), ap.eventHandler.Flush()
+}
+
+func (ap *AnsiParser) handle(b byte) error {
+ ap.context.currentChar = b
+ newState, err := ap.currState.Handle(b)
+ if err != nil {
+ return err
+ }
+
+ if newState == nil {
+ logger.Warning("newState is nil")
+ return errors.New("New state of 'nil' is invalid.")
+ }
+
+ if newState != ap.currState {
+ if err := ap.changeState(newState); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (ap *AnsiParser) changeState(newState state) error {
+ logger.Infof("ChangeState %s --> %s", ap.currState.Name(), newState.Name())
+
+ // Exit old state
+ if err := ap.currState.Exit(); err != nil {
+ logger.Infof("Exit state '%s' failed with : '%v'", ap.currState.Name(), err)
+ return err
+ }
+
+ // Perform transition action
+ if err := ap.currState.Transition(newState); err != nil {
+ logger.Infof("Transition from '%s' to '%s' failed with: '%v'", ap.currState.Name(), newState.Name, err)
+ return err
+ }
+
+ // Enter new state
+ if err := newState.Enter(); err != nil {
+ logger.Infof("Enter state '%s' failed with: '%v'", newState.Name(), err)
+ return err
+ }
+
+ ap.currState = newState
+ return nil
+}