Skip to content

Commit

Permalink
Remove logrus dependency, and add functional options to specify logger
Browse files Browse the repository at this point in the history
This changeset removes the non-standard dependency to logrus, leaving
the only dependencies used in ansiterm and winterm as Go standard lib
packages. This also has the added benefit of removing a superfulous
package level variable (logger) in both ansiterm and winterm.

The changes made here introduce a backwards compatible change to the
API signatures of ansiterm.CreateParser and winterm.CreateWinEventHandler
by introducing the optional functional parameters pattern on both.
Additionally, both ansiterm and winterm packages receive a WithLogf()
func to specify a logging func to use, which can be passed a func
with the standard Printf signature, ie: func(string, ...interface{}).

This maintains the existing behavior of checking for the environment
variable DEBUG_TERMINAL, and writing to the files ansiParser.log and
winEventHandler.log. For ansiterm/winterm, if a logging func has been
specified as well as having DEBUG_TERMINAL set, then both the respective
*.log file and the passed logging func will receive the data.

Note: for simplicity purposes, the single instance in ansiterm where
there was a "warning" and "error" was logged has been changed to use the
single log, but the messages have been prefixed with WARNING and ERROR
respectively. This was done entirely for simplicity reasons.
Additionally 2 other logging calls have been removed where it was
prudent to do so, and one other logging line was moved to a different
location in order to avoid changing some utility funcs.
  • Loading branch information
kenshaw committed Sep 25, 2017
1 parent 19f72df commit 7fe486d
Show file tree
Hide file tree
Showing 11 changed files with 143 additions and 118 deletions.
4 changes: 2 additions & 2 deletions csi_entry_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type csiEntryState struct {
}

func (csiState csiEntryState) Handle(b byte) (s state, e error) {
logger.Infof("CsiEntry::Handle %#x", b)
csiState.parser.logf("CsiEntry::Handle %#x", b)

nextState, err := csiState.baseState.Handle(b)
if nextState != nil || err != nil {
Expand All @@ -25,7 +25,7 @@ func (csiState csiEntryState) Handle(b byte) (s state, e error) {
}

func (csiState csiEntryState) Transition(s state) error {
logger.Infof("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name())
csiState.parser.logf("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name())
csiState.baseState.Transition(s)

switch s {
Expand Down
4 changes: 2 additions & 2 deletions csi_param_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type csiParamState struct {
}

func (csiState csiParamState) Handle(b byte) (s state, e error) {
logger.Infof("CsiParam::Handle %#x", b)
csiState.parser.logf("CsiParam::Handle %#x", b)

nextState, err := csiState.baseState.Handle(b)
if nextState != nil || err != nil {
Expand All @@ -26,7 +26,7 @@ func (csiState csiParamState) Handle(b byte) (s state, e error) {
}

func (csiState csiParamState) Transition(s state) error {
logger.Infof("CsiParam::Transition %s --> %s", csiState.Name(), s.Name())
csiState.parser.logf("CsiParam::Transition %s --> %s", csiState.Name(), s.Name())
csiState.baseState.Transition(s)

switch s {
Expand Down
4 changes: 2 additions & 2 deletions escape_intermediate_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type escapeIntermediateState struct {
}

func (escState escapeIntermediateState) Handle(b byte) (s state, e error) {
logger.Infof("escapeIntermediateState::Handle %#x", b)
escState.parser.logf("escapeIntermediateState::Handle %#x", b)
nextState, err := escState.baseState.Handle(b)
if nextState != nil || err != nil {
return nextState, err
Expand All @@ -24,7 +24,7 @@ func (escState escapeIntermediateState) Handle(b byte) (s state, e error) {
}

func (escState escapeIntermediateState) Transition(s state) error {
logger.Infof("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name())
escState.parser.logf("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name())
escState.baseState.Transition(s)

switch s {
Expand Down
4 changes: 2 additions & 2 deletions escape_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type escapeState struct {
}

func (escState escapeState) Handle(b byte) (s state, e error) {
logger.Infof("escapeState::Handle %#x", b)
escState.parser.logf("escapeState::Handle %#x", b)
nextState, err := escState.baseState.Handle(b)
if nextState != nil || err != nil {
return nextState, err
Expand All @@ -28,7 +28,7 @@ func (escState escapeState) Handle(b byte) (s state, e error) {
}

func (escState escapeState) Transition(s state) error {
logger.Infof("Escape::Transition %s --> %s", escState.Name(), s.Name())
escState.parser.logf("Escape::Transition %s --> %s", escState.Name(), s.Name())
escState.baseState.Transition(s)

switch s {
Expand Down
2 changes: 1 addition & 1 deletion osc_string_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ type oscStringState struct {
}

func (oscState oscStringState) Handle(b byte) (s state, e error) {
logger.Infof("OscString::Handle %#x", b)
oscState.parser.logf("OscString::Handle %#x", b)
nextState, err := oscState.baseState.Handle(b)
if nextState != nil || err != nil {
return nextState, err
Expand Down
99 changes: 57 additions & 42 deletions parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,10 @@ package ansiterm

import (
"errors"
"io/ioutil"
"log"
"os"

"github.com/sirupsen/logrus"
)

var logger *logrus.Logger

type AnsiParser struct {
currState state
eventHandler AnsiEventHandler
Expand All @@ -23,50 +19,69 @@ type AnsiParser struct {
ground state
oscString state
stateMap []state

logf func(string, ...interface{})
}

func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser {
logFile := ioutil.Discard
type Option func(*AnsiParser)

if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" {
logFile, _ = os.Create("ansiParser.log")
}

logger = &logrus.Logger{
Out: logFile,
Formatter: new(logrus.TextFormatter),
Level: logrus.InfoLevel,
func WithLogf(f func(string, ...interface{})) Option {
return func(ap *AnsiParser) {
ap.logf = f
}
}

parser := &AnsiParser{
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{}) {}
}

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,
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,
}

parser.currState = getState(initialState, parser.stateMap)
ap.currState = getState(initialState, ap.stateMap)

logger.Infof("CreateParser: parser %p", parser)
return parser
ap.logf("CreateParser: parser %p", ap)
return ap
}

func getState(name string, states []state) state {
Expand Down Expand Up @@ -97,7 +112,7 @@ func (ap *AnsiParser) handle(b byte) error {
}

if newState == nil {
logger.Warning("newState is nil")
ap.logf("WARNING: newState is nil")
return errors.New("New state of 'nil' is invalid.")
}

Expand All @@ -111,23 +126,23 @@ func (ap *AnsiParser) handle(b byte) error {
}

func (ap *AnsiParser) changeState(newState state) error {
logger.Infof("ChangeState %s --> %s", ap.currState.Name(), newState.Name())
ap.logf("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)
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 {
logger.Infof("Transition from '%s' to '%s' failed with: '%v'", ap.currState.Name(), newState.Name, err)
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 {
logger.Infof("Enter state '%s' failed with: '%v'", newState.Name(), err)
ap.logf("Enter state '%s' failed with: '%v'", newState.Name(), err)
return err
}

Expand Down
4 changes: 0 additions & 4 deletions parser_action_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ func parseParams(bytes []byte) ([]string, error) {
params = append(params, s)
}

logger.Infof("Parsed params: %v with length: %d", params, len(params))
return params, nil
}

Expand All @@ -37,7 +36,6 @@ func parseCmd(context ansiContext) (string, error) {

func getInt(params []string, dflt int) int {
i := getInts(params, 1, dflt)[0]
logger.Infof("getInt: %v", i)
return i
}

Expand All @@ -60,8 +58,6 @@ func getInts(params []string, minCount int, dflt int) []int {
}
}

logger.Infof("getInts: %v", ints)

return ints
}

Expand Down
17 changes: 7 additions & 10 deletions parser_actions.go
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
package ansiterm

import (
"fmt"
)

func (ap *AnsiParser) collectParam() error {
currChar := ap.context.currentChar
logger.Infof("collectParam %#x", currChar)
ap.logf("collectParam %#x", currChar)
ap.context.paramBuffer = append(ap.context.paramBuffer, currChar)
return nil
}

func (ap *AnsiParser) collectInter() error {
currChar := ap.context.currentChar
logger.Infof("collectInter %#x", currChar)
ap.logf("collectInter %#x", currChar)
ap.context.paramBuffer = append(ap.context.interBuffer, currChar)
return nil
}

func (ap *AnsiParser) escDispatch() error {
cmd, _ := parseCmd(*ap.context)
intermeds := ap.context.interBuffer
logger.Infof("escDispatch currentChar: %#x", ap.context.currentChar)
logger.Infof("escDispatch: %v(%v)", cmd, intermeds)
ap.logf("escDispatch currentChar: %#x", ap.context.currentChar)
ap.logf("escDispatch: %v(%v)", cmd, intermeds)

switch cmd {
case "D": // IND
Expand All @@ -43,8 +39,9 @@ func (ap *AnsiParser) escDispatch() error {
func (ap *AnsiParser) csiDispatch() error {
cmd, _ := parseCmd(*ap.context)
params, _ := parseParams(ap.context.paramBuffer)
ap.logf("Parsed params: %v with length: %d", params, len(params))

logger.Infof("csiDispatch: %v(%v)", cmd, params)
ap.logf("csiDispatch: %v(%v)", cmd, params)

switch cmd {
case "@":
Expand Down Expand Up @@ -102,7 +99,7 @@ func (ap *AnsiParser) csiDispatch() error {
top, bottom := ints[0], ints[1]
return ap.eventHandler.DECSTBM(top, bottom)
default:
logger.Errorf(fmt.Sprintf("Unsupported CSI command: '%s', with full context: %v", cmd, ap.context))
ap.logf("ERROR: Unsupported CSI command: '%s', with full context: %v", cmd, ap.context)
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion winterm/cursor_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL
if err != nil {
return err
}
logger.Infof("Cursor position set: (%d, %d)", position.X, position.Y)
h.logf("Cursor position set: (%d, %d)", position.X, position.Y)
return err
}

Expand Down
4 changes: 2 additions & 2 deletions winterm/scroll_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,8 @@ func (h *windowsAnsiEventHandler) insertLines(param int) error {

// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates.
func (h *windowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSOLE_SCREEN_BUFFER_INFO) error {
logger.Infof("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
logger.Infof("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)
h.logf("scroll: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
h.logf("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)

// Copy from and clip to the scroll region (full buffer width)
scrollRect := SMALL_RECT{
Expand Down
Loading

0 comments on commit 7fe486d

Please sign in to comment.