mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-10-03 01:15:11 -04:00
Point the go-micro.dev/v4 replace at the latest main-v4 maintenance branch commit in butonic/go-micro (cd412c15) instead of the v4.11.3 tag. The new base is upstream v4.11.1 plus the registry cache node-TTL fixes (upstream #2715, #2736, #2740), the concurrent map access fix (upstream #2794), plus further dependency updates and test fixes on the maintenance branch. The branch also modernizes go-micro's own go.mod (go 1.26, lego, dario.cat/mergo v1, x/deque v2, ...), and MVS pulls the aligned versions into this module: lego v4.35.2 -> lego/v5 v5.5.2, go-jose/go-jose/v4 -> v4.1.5, gofrs/flock -> v0.13.1, mattn/go-isatty -> v0.0.24, go.uber.org/zap -> v1.28.0, x/net -> 0.59.0, miekg/dns -> 1.1.73, moby api/client, ProtonMail/go-crypto -> 1.5.2, klauspost/compress -> 1.20.1, gorilla/handlers -> 1.5.2, gobwas/ws -> 1.4.0, nxadm/tail -> 1.4.11, ... Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
149 lines
3.3 KiB
Go
149 lines
3.3 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 {
|
|
return nil
|
|
}
|
|
return ap.changeState(newState)
|
|
}
|
|
|
|
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
|
|
}
|