mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
![Sebastiaan van Stijn](/assets/img/avatar_default.png)
This patch updates all dependencies to match what is used in moby/moby. Making the dependencies match what is used in that repository makes sure we test with the same version as libnetwork is later built with in moby. This also gets rid of some temporary forks that were needed during the migration of Sirupsen/logrus to sirupsen/logrus. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
151 lines
3.4 KiB
Go
151 lines
3.4 KiB
Go
package ansiterm
|
|
|
|
import (
|
|
"errors"
|
|
"log"
|
|
"os"
|
|
)
|
|
|
|
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
|
|
|
|
logf func(string, ...interface{})
|
|
}
|
|
|
|
type Option func(*AnsiParser)
|
|
|
|
func WithLogf(f func(string, ...interface{})) Option {
|
|
return func(ap *AnsiParser) {
|
|
ap.logf = f
|
|
}
|
|
}
|
|
|
|
func CreateParser(initialState string, evtHandler AnsiEventHandler, opts ...Option) *AnsiParser {
|
|
ap := &AnsiParser{
|
|
eventHandler: evtHandler,
|
|
context: &ansiContext{},
|
|
}
|
|
for _, o := range opts {
|
|
o(ap)
|
|
}
|
|
|
|
if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" {
|
|
logFile, _ := os.Create("ansiParser.log")
|
|
logger := log.New(logFile, "", log.LstdFlags)
|
|
if ap.logf != nil {
|
|
l := ap.logf
|
|
ap.logf = func(s string, v ...interface{}) {
|
|
l(s, v...)
|
|
logger.Printf(s, v...)
|
|
}
|
|
} else {
|
|
ap.logf = logger.Printf
|
|
}
|
|
}
|
|
|
|
if ap.logf == nil {
|
|
ap.logf = func(string, ...interface{}) {}
|
|
}
|
|
|
|
ap.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: ap}}
|
|
ap.csiParam = csiParamState{baseState{name: "CsiParam", parser: ap}}
|
|
ap.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: ap}}
|
|
ap.escape = escapeState{baseState{name: "Escape", parser: ap}}
|
|
ap.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: ap}}
|
|
ap.error = errorState{baseState{name: "Error", parser: ap}}
|
|
ap.ground = groundState{baseState{name: "Ground", parser: ap}}
|
|
ap.oscString = oscStringState{baseState{name: "OscString", parser: ap}}
|
|
|
|
ap.stateMap = []state{
|
|
ap.csiEntry,
|
|
ap.csiParam,
|
|
ap.dcsEntry,
|
|
ap.escape,
|
|
ap.escapeIntermediate,
|
|
ap.error,
|
|
ap.ground,
|
|
ap.oscString,
|
|
}
|
|
|
|
ap.currState = getState(initialState, ap.stateMap)
|
|
|
|
ap.logf("CreateParser: parser %p", ap)
|
|
return ap
|
|
}
|
|
|
|
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 {
|
|
ap.logf("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 {
|
|
ap.logf("ChangeState %s --> %s", ap.currState.Name(), newState.Name())
|
|
|
|
// Exit old state
|
|
if err := ap.currState.Exit(); err != nil {
|
|
ap.logf("Exit state '%s' failed with : '%v'", ap.currState.Name(), err)
|
|
return err
|
|
}
|
|
|
|
// Perform transition action
|
|
if err := ap.currState.Transition(newState); err != nil {
|
|
ap.logf("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 {
|
|
ap.logf("Enter state '%s' failed with: '%v'", newState.Name(), err)
|
|
return err
|
|
}
|
|
|
|
ap.currState = newState
|
|
return nil
|
|
}
|