1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

uprev docker/docker/pkg/reexec for libnetwork

Signed-off-by: Puneet Pruthi <puneetpruthi@gmail.com>
This commit is contained in:
Puneet Pruthi 2016-07-08 17:49:32 -07:00
parent f88765e4e6
commit 7fac070519
73 changed files with 811 additions and 1379 deletions

View file

@ -7,11 +7,11 @@
"Deps": [ "Deps": [
{ {
"ImportPath": "github.com/Azure/go-ansiterm", "ImportPath": "github.com/Azure/go-ansiterm",
"Rev": "70b2c90b260171e829f1ebd7c17f600c11858dbe" "Rev": "04b7f292a41fcb5da32dda536c0807fc13e8351c"
}, },
{ {
"ImportPath": "github.com/Azure/go-ansiterm/winterm", "ImportPath": "github.com/Azure/go-ansiterm/winterm",
"Rev": "70b2c90b260171e829f1ebd7c17f600c11858dbe" "Rev": "04b7f292a41fcb5da32dda536c0807fc13e8351c"
}, },
{ {
"ImportPath": "github.com/BurntSushi/toml", "ImportPath": "github.com/BurntSushi/toml",
@ -47,7 +47,7 @@
}, },
{ {
"ImportPath": "github.com/codegangsta/cli", "ImportPath": "github.com/codegangsta/cli",
"Comment": "1.2.0-143-ga65b733", "Comment": "v1.9.0",
"Rev": "a65b733b303f0055f8d324d805f393cd3e7a7904" "Rev": "a65b733b303f0055f8d324d805f393cd3e7a7904"
}, },
{ {
@ -82,119 +82,109 @@
}, },
{ {
"ImportPath": "github.com/docker/docker/opts", "ImportPath": "github.com/docker/docker/opts",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/discovery", "ImportPath": "github.com/docker/docker/pkg/discovery",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/discovery/kv", "ImportPath": "github.com/docker/docker/pkg/discovery/kv",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/homedir", "ImportPath": "github.com/docker/docker/pkg/homedir",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/ioutils", "ImportPath": "github.com/docker/docker/pkg/ioutils",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/longpath", "ImportPath": "github.com/docker/docker/pkg/longpath",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/mflag", "ImportPath": "github.com/docker/docker/pkg/mflag",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/mount", "ImportPath": "github.com/docker/docker/pkg/mount",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/parsers/kernel", "ImportPath": "github.com/docker/docker/pkg/parsers/kernel",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/plugins", "ImportPath": "github.com/docker/docker/pkg/plugins",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/plugins/transport", "ImportPath": "github.com/docker/docker/pkg/plugins/transport",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/random", "ImportPath": "github.com/docker/docker/pkg/random",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/reexec", "ImportPath": "github.com/docker/docker/pkg/reexec",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/signal", "ImportPath": "github.com/docker/docker/pkg/signal",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/stringid", "ImportPath": "github.com/docker/docker/pkg/stringid",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/symlink", "ImportPath": "github.com/docker/docker/pkg/symlink",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/system", "ImportPath": "github.com/docker/docker/pkg/system",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/term", "ImportPath": "github.com/docker/docker/pkg/term",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/term/windows", "ImportPath": "github.com/docker/docker/pkg/term/windows",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
}, },
{ {
"ImportPath": "github.com/docker/docker/pkg/tlsconfig", "ImportPath": "github.com/docker/docker/pkg/tlsconfig",
"Comment": "v1.4.1-11716-g24076ed", "Comment": "v1.4.1-12227-g86a7632",
"Rev": "24076ed4d9c82d387029b8a65e21873db5676f6a" "Rev": "86a7632d63bdddb95aaf1472648056a4fb737d38"
},
{
"ImportPath": "github.com/docker/engine-api/types/filters",
"Comment": "v0.3.1-210-g25941ec",
"Rev": "25941ecf6e8351810e8530c60de8dda7d5e1baba"
}, },
{ {
"ImportPath": "github.com/docker/engine-api/types/network", "ImportPath": "github.com/docker/engine-api/types/network",
"Comment": "v0.3.1-210-g25941ec", "Comment": "v0.3.1-210-g25941ec",
"Rev": "25941ecf6e8351810e8530c60de8dda7d5e1baba" "Rev": "25941ecf6e8351810e8530c60de8dda7d5e1baba"
}, },
{
"ImportPath": "github.com/docker/engine-api/types/versions",
"Comment": "v0.3.1-210-g25941ec",
"Rev": "25941ecf6e8351810e8530c60de8dda7d5e1baba"
},
{ {
"ImportPath": "github.com/docker/go-connections/sockets", "ImportPath": "github.com/docker/go-connections/sockets",
"Comment": "v0.2.0", "Comment": "v0.2.0",
@ -303,11 +293,6 @@
"Comment": "v0.7.0-47-g598c548", "Comment": "v0.7.0-47-g598c548",
"Rev": "598c54895cc5a7b1a24a398d635e8c0ea0959870" "Rev": "598c54895cc5a7b1a24a398d635e8c0ea0959870"
}, },
{
"ImportPath": "github.com/mattn/go-shellwords",
"Comment": "v1.0.0-1-g525bede",
"Rev": "525bedee691b5a8df547cb5cf9f86b7fb1883e24"
},
{ {
"ImportPath": "github.com/miekg/dns", "ImportPath": "github.com/miekg/dns",
"Rev": "d27455715200c7d3e321a1e5cadb27c9ee0b0f02" "Rev": "d27455715200c7d3e321a1e5cadb27c9ee0b0f02"

View file

@ -124,32 +124,32 @@ func getByteRange(start byte, end byte) []byte {
return bytes return bytes
} }
var ToGroundBytes = getToGroundBytes() var toGroundBytes = getToGroundBytes()
var Executors = getExecuteBytes() var executors = getExecuteBytes()
// SPACE 20+A0 hex Always and everywhere a blank space // SPACE 20+A0 hex Always and everywhere a blank space
// Intermediate 20-2F hex !"#$%&'()*+,-./ // Intermediate 20-2F hex !"#$%&'()*+,-./
var Intermeds = getByteRange(0x20, 0x2F) var intermeds = getByteRange(0x20, 0x2F)
// Parameters 30-3F hex 0123456789:;<=>? // Parameters 30-3F hex 0123456789:;<=>?
// CSI Parameters 30-39, 3B hex 0123456789; // CSI Parameters 30-39, 3B hex 0123456789;
var CsiParams = getByteRange(0x30, 0x3F) var csiParams = getByteRange(0x30, 0x3F)
var CsiCollectables = append(getByteRange(0x30, 0x39), getByteRange(0x3B, 0x3F)...) var csiCollectables = append(getByteRange(0x30, 0x39), getByteRange(0x3B, 0x3F)...)
// Uppercase 40-5F hex @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_ // Uppercase 40-5F hex @ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
var UpperCase = getByteRange(0x40, 0x5F) var upperCase = getByteRange(0x40, 0x5F)
// Lowercase 60-7E hex `abcdefghijlkmnopqrstuvwxyz{|}~ // Lowercase 60-7E hex `abcdefghijlkmnopqrstuvwxyz{|}~
var LowerCase = getByteRange(0x60, 0x7E) var lowerCase = getByteRange(0x60, 0x7E)
// Alphabetics 40-7E hex (all of upper and lower case) // Alphabetics 40-7E hex (all of upper and lower case)
var Alphabetics = append(UpperCase, LowerCase...) var alphabetics = append(upperCase, lowerCase...)
var Printables = getByteRange(0x20, 0x7F) var printables = getByteRange(0x20, 0x7F)
var EscapeIntermediateToGroundBytes = getByteRange(0x30, 0x7E) var escapeIntermediateToGroundBytes = getByteRange(0x30, 0x7E)
var EscapeToGroundBytes = getEscapeToGroundBytes() var escapeToGroundBytes = getEscapeToGroundBytes()
// See http://www.vt100.net/emu/vt500_parser.png for description of the complex // See http://www.vt100.net/emu/vt500_parser.png for description of the complex
// byte ranges below // byte ranges below

View file

@ -1,6 +1,6 @@
package ansiterm package ansiterm
type AnsiContext struct { type ansiContext struct {
currentChar byte currentChar byte
paramBuffer []byte paramBuffer []byte
interBuffer []byte interBuffer []byte

View file

@ -1,41 +1,41 @@
package ansiterm package ansiterm
type CsiEntryState struct { type csiEntryState struct {
BaseState baseState
} }
func (csiState CsiEntryState) Handle(b byte) (s State, e error) { func (csiState csiEntryState) Handle(b byte) (s state, e error) {
logger.Infof("CsiEntry::Handle %#x", b) logger.Infof("CsiEntry::Handle %#x", b)
nextState, err := csiState.BaseState.Handle(b) nextState, err := csiState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err
} }
switch { switch {
case sliceContains(Alphabetics, b): case sliceContains(alphabetics, b):
return csiState.parser.Ground, nil return csiState.parser.ground, nil
case sliceContains(CsiCollectables, b): case sliceContains(csiCollectables, b):
return csiState.parser.CsiParam, nil return csiState.parser.csiParam, nil
case sliceContains(Executors, b): case sliceContains(executors, b):
return csiState, csiState.parser.execute() return csiState, csiState.parser.execute()
} }
return csiState, nil return csiState, nil
} }
func (csiState CsiEntryState) Transition(s State) error { func (csiState csiEntryState) Transition(s state) error {
logger.Infof("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name()) logger.Infof("CsiEntry::Transition %s --> %s", csiState.Name(), s.Name())
csiState.BaseState.Transition(s) csiState.baseState.Transition(s)
switch s { switch s {
case csiState.parser.Ground: case csiState.parser.ground:
return csiState.parser.csiDispatch() return csiState.parser.csiDispatch()
case csiState.parser.CsiParam: case csiState.parser.csiParam:
switch { switch {
case sliceContains(CsiParams, csiState.parser.context.currentChar): case sliceContains(csiParams, csiState.parser.context.currentChar):
csiState.parser.collectParam() csiState.parser.collectParam()
case sliceContains(Intermeds, csiState.parser.context.currentChar): case sliceContains(intermeds, csiState.parser.context.currentChar):
csiState.parser.collectInter() csiState.parser.collectInter()
} }
} }
@ -43,7 +43,7 @@ func (csiState CsiEntryState) Transition(s State) error {
return nil return nil
} }
func (csiState CsiEntryState) Enter() error { func (csiState csiEntryState) Enter() error {
csiState.parser.clear() csiState.parser.clear()
return nil return nil
} }

View file

@ -1,36 +1,36 @@
package ansiterm package ansiterm
type CsiParamState struct { type csiParamState struct {
BaseState baseState
} }
func (csiState CsiParamState) Handle(b byte) (s State, e error) { func (csiState csiParamState) Handle(b byte) (s state, e error) {
logger.Infof("CsiParam::Handle %#x", b) logger.Infof("CsiParam::Handle %#x", b)
nextState, err := csiState.BaseState.Handle(b) nextState, err := csiState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err
} }
switch { switch {
case sliceContains(Alphabetics, b): case sliceContains(alphabetics, b):
return csiState.parser.Ground, nil return csiState.parser.ground, nil
case sliceContains(CsiCollectables, b): case sliceContains(csiCollectables, b):
csiState.parser.collectParam() csiState.parser.collectParam()
return csiState, nil return csiState, nil
case sliceContains(Executors, b): case sliceContains(executors, b):
return csiState, csiState.parser.execute() return csiState, csiState.parser.execute()
} }
return csiState, nil return csiState, nil
} }
func (csiState CsiParamState) Transition(s State) error { func (csiState csiParamState) Transition(s state) error {
logger.Infof("CsiParam::Transition %s --> %s", csiState.Name(), s.Name()) logger.Infof("CsiParam::Transition %s --> %s", csiState.Name(), s.Name())
csiState.BaseState.Transition(s) csiState.baseState.Transition(s)
switch s { switch s {
case csiState.parser.Ground: case csiState.parser.ground:
return csiState.parser.csiDispatch() return csiState.parser.csiDispatch()
} }

View file

@ -1,34 +1,34 @@
package ansiterm package ansiterm
type EscapeIntermediateState struct { type escapeIntermediateState struct {
BaseState baseState
} }
func (escState EscapeIntermediateState) Handle(b byte) (s State, e error) { func (escState escapeIntermediateState) Handle(b byte) (s state, e error) {
logger.Infof("EscapeIntermediateState::Handle %#x", b) logger.Infof("escapeIntermediateState::Handle %#x", b)
nextState, err := escState.BaseState.Handle(b) nextState, err := escState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err
} }
switch { switch {
case sliceContains(Intermeds, b): case sliceContains(intermeds, b):
return escState, escState.parser.collectInter() return escState, escState.parser.collectInter()
case sliceContains(Executors, b): case sliceContains(executors, b):
return escState, escState.parser.execute() return escState, escState.parser.execute()
case sliceContains(EscapeIntermediateToGroundBytes, b): case sliceContains(escapeIntermediateToGroundBytes, b):
return escState.parser.Ground, nil return escState.parser.ground, nil
} }
return escState, nil return escState, nil
} }
func (escState EscapeIntermediateState) Transition(s State) error { func (escState escapeIntermediateState) Transition(s state) error {
logger.Infof("EscapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name()) logger.Infof("escapeIntermediateState::Transition %s --> %s", escState.Name(), s.Name())
escState.BaseState.Transition(s) escState.baseState.Transition(s)
switch s { switch s {
case escState.parser.Ground: case escState.parser.ground:
return escState.parser.escDispatch() return escState.parser.escDispatch()
} }

View file

@ -1,47 +1,47 @@
package ansiterm package ansiterm
type EscapeState struct { type escapeState struct {
BaseState baseState
} }
func (escState EscapeState) Handle(b byte) (s State, e error) { func (escState escapeState) Handle(b byte) (s state, e error) {
logger.Infof("EscapeState::Handle %#x", b) logger.Infof("escapeState::Handle %#x", b)
nextState, err := escState.BaseState.Handle(b) nextState, err := escState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err
} }
switch { switch {
case b == ANSI_ESCAPE_SECONDARY: case b == ANSI_ESCAPE_SECONDARY:
return escState.parser.CsiEntry, nil return escState.parser.csiEntry, nil
case b == ANSI_OSC_STRING_ENTRY: case b == ANSI_OSC_STRING_ENTRY:
return escState.parser.OscString, nil return escState.parser.oscString, nil
case sliceContains(Executors, b): case sliceContains(executors, b):
return escState, escState.parser.execute() return escState, escState.parser.execute()
case sliceContains(EscapeToGroundBytes, b): case sliceContains(escapeToGroundBytes, b):
return escState.parser.Ground, nil return escState.parser.ground, nil
case sliceContains(Intermeds, b): case sliceContains(intermeds, b):
return escState.parser.EscapeIntermediate, nil return escState.parser.escapeIntermediate, nil
} }
return escState, nil return escState, nil
} }
func (escState EscapeState) Transition(s State) error { func (escState escapeState) Transition(s state) error {
logger.Infof("Escape::Transition %s --> %s", escState.Name(), s.Name()) logger.Infof("Escape::Transition %s --> %s", escState.Name(), s.Name())
escState.BaseState.Transition(s) escState.baseState.Transition(s)
switch s { switch s {
case escState.parser.Ground: case escState.parser.ground:
return escState.parser.escDispatch() return escState.parser.escDispatch()
case escState.parser.EscapeIntermediate: case escState.parser.escapeIntermediate:
return escState.parser.collectInter() return escState.parser.collectInter()
} }
return nil return nil
} }
func (escState EscapeState) Enter() error { func (escState escapeState) Enter() error {
escState.parser.clear() escState.parser.clear()
return nil return nil
} }

View file

@ -1,22 +1,22 @@
package ansiterm package ansiterm
type GroundState struct { type groundState struct {
BaseState baseState
} }
func (gs GroundState) Handle(b byte) (s State, e error) { func (gs groundState) Handle(b byte) (s state, e error) {
gs.parser.context.currentChar = b gs.parser.context.currentChar = b
nextState, err := gs.BaseState.Handle(b) nextState, err := gs.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err
} }
switch { switch {
case sliceContains(Printables, b): case sliceContains(printables, b):
return gs, gs.parser.print() return gs, gs.parser.print()
case sliceContains(Executors, b): case sliceContains(executors, b):
return gs, gs.parser.execute() return gs, gs.parser.execute()
} }

View file

@ -1,19 +1,19 @@
package ansiterm package ansiterm
type OscStringState struct { type oscStringState struct {
BaseState baseState
} }
func (oscState OscStringState) Handle(b byte) (s State, e error) { func (oscState oscStringState) Handle(b byte) (s state, e error) {
logger.Infof("OscString::Handle %#x", b) logger.Infof("OscString::Handle %#x", b)
nextState, err := oscState.BaseState.Handle(b) nextState, err := oscState.baseState.Handle(b)
if nextState != nil || err != nil { if nextState != nil || err != nil {
return nextState, err return nextState, err
} }
switch { switch {
case isOscStringTerminator(b): case isOscStringTerminator(b):
return oscState.parser.Ground, nil return oscState.parser.ground, nil
} }
return oscState, nil return oscState, nil

View file

@ -2,7 +2,6 @@ package ansiterm
import ( import (
"errors" "errors"
"fmt"
"io/ioutil" "io/ioutil"
"os" "os"
@ -12,18 +11,18 @@ import (
var logger *logrus.Logger var logger *logrus.Logger
type AnsiParser struct { type AnsiParser struct {
currState State currState state
eventHandler AnsiEventHandler eventHandler AnsiEventHandler
context *AnsiContext context *ansiContext
CsiEntry State csiEntry state
CsiParam State csiParam state
DcsEntry State dcsEntry state
Escape State escape state
EscapeIntermediate State escapeIntermediate state
Error State error state
Ground State ground state
OscString State oscString state
stateMap []State stateMap []state
} }
func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser { func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser {
@ -41,27 +40,27 @@ func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser
parser := &AnsiParser{ parser := &AnsiParser{
eventHandler: evtHandler, eventHandler: evtHandler,
context: &AnsiContext{}, context: &ansiContext{},
} }
parser.CsiEntry = CsiEntryState{BaseState{name: "CsiEntry", parser: parser}} parser.csiEntry = csiEntryState{baseState{name: "CsiEntry", parser: parser}}
parser.CsiParam = CsiParamState{BaseState{name: "CsiParam", parser: parser}} parser.csiParam = csiParamState{baseState{name: "CsiParam", parser: parser}}
parser.DcsEntry = DcsEntryState{BaseState{name: "DcsEntry", parser: parser}} parser.dcsEntry = dcsEntryState{baseState{name: "DcsEntry", parser: parser}}
parser.Escape = EscapeState{BaseState{name: "Escape", parser: parser}} parser.escape = escapeState{baseState{name: "Escape", parser: parser}}
parser.EscapeIntermediate = EscapeIntermediateState{BaseState{name: "EscapeIntermediate", parser: parser}} parser.escapeIntermediate = escapeIntermediateState{baseState{name: "EscapeIntermediate", parser: parser}}
parser.Error = ErrorState{BaseState{name: "Error", parser: parser}} parser.error = errorState{baseState{name: "Error", parser: parser}}
parser.Ground = GroundState{BaseState{name: "Ground", parser: parser}} parser.ground = groundState{baseState{name: "Ground", parser: parser}}
parser.OscString = OscStringState{BaseState{name: "OscString", parser: parser}} parser.oscString = oscStringState{baseState{name: "OscString", parser: parser}}
parser.stateMap = []State{ parser.stateMap = []state{
parser.CsiEntry, parser.csiEntry,
parser.CsiParam, parser.csiParam,
parser.DcsEntry, parser.dcsEntry,
parser.Escape, parser.escape,
parser.EscapeIntermediate, parser.escapeIntermediate,
parser.Error, parser.error,
parser.Ground, parser.ground,
parser.OscString, parser.oscString,
} }
parser.currState = getState(initialState, parser.stateMap) parser.currState = getState(initialState, parser.stateMap)
@ -70,7 +69,7 @@ func CreateParser(initialState string, evtHandler AnsiEventHandler) *AnsiParser
return parser return parser
} }
func getState(name string, states []State) State { func getState(name string, states []state) state {
for _, el := range states { for _, el := range states {
if el.Name() == name { if el.Name() == name {
return el return el
@ -99,7 +98,7 @@ func (ap *AnsiParser) handle(b byte) error {
if newState == nil { if newState == nil {
logger.Warning("newState is nil") logger.Warning("newState is nil")
return errors.New(fmt.Sprintf("New state of 'nil' is invalid.")) return errors.New("New state of 'nil' is invalid.")
} }
if newState != ap.currState { if newState != ap.currState {
@ -111,7 +110,7 @@ func (ap *AnsiParser) handle(b byte) error {
return nil return nil
} }
func (ap *AnsiParser) changeState(newState State) error { func (ap *AnsiParser) changeState(newState state) error {
logger.Infof("ChangeState %s --> %s", ap.currState.Name(), newState.Name()) logger.Infof("ChangeState %s --> %s", ap.currState.Name(), newState.Name())
// Exit old state // Exit old state

View file

@ -31,7 +31,7 @@ func parseParams(bytes []byte) ([]string, error) {
return params, nil return params, nil
} }
func parseCmd(context AnsiContext) (string, error) { func parseCmd(context ansiContext) (string, error) {
return string(context.currentChar), nil return string(context.currentChar), nil
} }

View file

@ -113,7 +113,7 @@ func (ap *AnsiParser) print() error {
} }
func (ap *AnsiParser) clear() error { func (ap *AnsiParser) clear() error {
ap.context = &AnsiContext{} ap.context = &ansiContext{}
return nil return nil
} }

View file

@ -1,114 +0,0 @@
package ansiterm
import (
"fmt"
"testing"
)
func getStateNames() []string {
parser, _ := createTestParser("Ground")
stateNames := []string{}
for _, state := range parser.stateMap {
stateNames = append(stateNames, state.Name())
}
return stateNames
}
func stateTransitionHelper(t *testing.T, start string, end string, bytes []byte) {
for _, b := range bytes {
bytes := []byte{byte(b)}
parser, _ := createTestParser(start)
parser.Parse(bytes)
validateState(t, parser.currState, end)
}
}
func anyToXHelper(t *testing.T, bytes []byte, expectedState string) {
for _, s := range getStateNames() {
stateTransitionHelper(t, s, expectedState, bytes)
}
}
func funcCallParamHelper(t *testing.T, bytes []byte, start string, expected string, expectedCalls []string) {
parser, evtHandler := createTestParser(start)
parser.Parse(bytes)
validateState(t, parser.currState, expected)
validateFuncCalls(t, evtHandler.FunctionCalls, expectedCalls)
}
func parseParamsHelper(t *testing.T, bytes []byte, expectedParams []string) {
params, err := parseParams(bytes)
if err != nil {
t.Errorf("Parameter parse error: %v", err)
return
}
if len(params) != len(expectedParams) {
t.Errorf("Parsed parameters: %v", params)
t.Errorf("Expected parameters: %v", expectedParams)
t.Errorf("Parameter length failure: %d != %d", len(params), len(expectedParams))
return
}
for i, v := range expectedParams {
if v != params[i] {
t.Errorf("Parsed parameters: %v", params)
t.Errorf("Expected parameters: %v", expectedParams)
t.Errorf("Parameter parse failure: %s != %s at position %d", v, params[i], i)
}
}
}
func cursorSingleParamHelper(t *testing.T, command byte, funcName string) {
funcCallParamHelper(t, []byte{command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
funcCallParamHelper(t, []byte{'0', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
funcCallParamHelper(t, []byte{'2', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2])", funcName)})
funcCallParamHelper(t, []byte{'2', '3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([23])", funcName)})
funcCallParamHelper(t, []byte{'2', ';', '3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2])", funcName)})
funcCallParamHelper(t, []byte{'2', ';', '3', ';', '4', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2])", funcName)})
}
func cursorTwoParamHelper(t *testing.T, command byte, funcName string) {
funcCallParamHelper(t, []byte{command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1 1])", funcName)})
funcCallParamHelper(t, []byte{'0', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1 1])", funcName)})
funcCallParamHelper(t, []byte{'2', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2 1])", funcName)})
funcCallParamHelper(t, []byte{'2', '3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([23 1])", funcName)})
funcCallParamHelper(t, []byte{'2', ';', '3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2 3])", funcName)})
funcCallParamHelper(t, []byte{'2', ';', '3', ';', '4', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2 3])", funcName)})
}
func eraseHelper(t *testing.T, command byte, funcName string) {
funcCallParamHelper(t, []byte{command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([0])", funcName)})
funcCallParamHelper(t, []byte{'0', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([0])", funcName)})
funcCallParamHelper(t, []byte{'1', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
funcCallParamHelper(t, []byte{'2', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([2])", funcName)})
funcCallParamHelper(t, []byte{'3', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([3])", funcName)})
funcCallParamHelper(t, []byte{'4', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([0])", funcName)})
funcCallParamHelper(t, []byte{'1', ';', '2', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
}
func scrollHelper(t *testing.T, command byte, funcName string) {
funcCallParamHelper(t, []byte{command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
funcCallParamHelper(t, []byte{'0', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
funcCallParamHelper(t, []byte{'1', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([1])", funcName)})
funcCallParamHelper(t, []byte{'5', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([5])", funcName)})
funcCallParamHelper(t, []byte{'4', ';', '6', command}, "CsiEntry", "Ground", []string{fmt.Sprintf("%s([4])", funcName)})
}
func clearOnStateChangeHelper(t *testing.T, start string, end string, bytes []byte) {
p, _ := createTestParser(start)
fillContext(p.context)
p.Parse(bytes)
validateState(t, p.currState, end)
validateEmptyContext(t, p.context)
}
func c0Helper(t *testing.T, bytes []byte, expectedState string, expectedCalls []string) {
parser, evtHandler := createTestParser("Ground")
parser.Parse(bytes)
validateState(t, parser.currState, expectedState)
validateFuncCalls(t, evtHandler.FunctionCalls, expectedCalls)
}

View file

@ -1,66 +0,0 @@
package ansiterm
import (
"testing"
)
func createTestParser(s string) (*AnsiParser, *TestAnsiEventHandler) {
evtHandler := CreateTestAnsiEventHandler()
parser := CreateParser(s, evtHandler)
return parser, evtHandler
}
func validateState(t *testing.T, actualState State, expectedStateName string) {
actualName := "Nil"
if actualState != nil {
actualName = actualState.Name()
}
if actualName != expectedStateName {
t.Errorf("Invalid State: '%s' != '%s'", actualName, expectedStateName)
}
}
func validateFuncCalls(t *testing.T, actualCalls []string, expectedCalls []string) {
actualCount := len(actualCalls)
expectedCount := len(expectedCalls)
if actualCount != expectedCount {
t.Errorf("Actual calls: %v", actualCalls)
t.Errorf("Expected calls: %v", expectedCalls)
t.Errorf("Call count error: %d != %d", actualCount, expectedCount)
return
}
for i, v := range actualCalls {
if v != expectedCalls[i] {
t.Errorf("Actual calls: %v", actualCalls)
t.Errorf("Expected calls: %v", expectedCalls)
t.Errorf("Mismatched calls: %s != %s with lengths %d and %d", v, expectedCalls[i], len(v), len(expectedCalls[i]))
}
}
}
func fillContext(context *AnsiContext) {
context.currentChar = 'A'
context.paramBuffer = []byte{'C', 'D', 'E'}
context.interBuffer = []byte{'F', 'G', 'H'}
}
func validateEmptyContext(t *testing.T, context *AnsiContext) {
var expectedCurrChar byte = 0x0
if context.currentChar != expectedCurrChar {
t.Errorf("Currentchar mismatch '%#x' != '%#x'", context.currentChar, expectedCurrChar)
}
if len(context.paramBuffer) != 0 {
t.Errorf("Non-empty parameter buffer: %v", context.paramBuffer)
}
if len(context.paramBuffer) != 0 {
t.Errorf("Non-empty intermediate buffer: %v", context.interBuffer)
}
}

View file

@ -1,52 +1,52 @@
package ansiterm package ansiterm
type StateId int type stateID int
type State interface { type state interface {
Enter() error Enter() error
Exit() error Exit() error
Handle(byte) (State, error) Handle(byte) (state, error)
Name() string Name() string
Transition(State) error Transition(state) error
} }
type BaseState struct { type baseState struct {
name string name string
parser *AnsiParser parser *AnsiParser
} }
func (base BaseState) Enter() error { func (base baseState) Enter() error {
return nil return nil
} }
func (base BaseState) Exit() error { func (base baseState) Exit() error {
return nil return nil
} }
func (base BaseState) Handle(b byte) (s State, e error) { func (base baseState) Handle(b byte) (s state, e error) {
switch { switch {
case b == CSI_ENTRY: case b == CSI_ENTRY:
return base.parser.CsiEntry, nil return base.parser.csiEntry, nil
case b == DCS_ENTRY: case b == DCS_ENTRY:
return base.parser.DcsEntry, nil return base.parser.dcsEntry, nil
case b == ANSI_ESCAPE_PRIMARY: case b == ANSI_ESCAPE_PRIMARY:
return base.parser.Escape, nil return base.parser.escape, nil
case b == OSC_STRING: case b == OSC_STRING:
return base.parser.OscString, nil return base.parser.oscString, nil
case sliceContains(ToGroundBytes, b): case sliceContains(toGroundBytes, b):
return base.parser.Ground, nil return base.parser.ground, nil
} }
return nil, nil return nil, nil
} }
func (base BaseState) Name() string { func (base baseState) Name() string {
return base.name return base.name
} }
func (base BaseState) Transition(s State) error { func (base baseState) Transition(s state) error {
if s == base.parser.Ground { if s == base.parser.ground {
execBytes := []byte{0x18} execBytes := []byte{0x18}
execBytes = append(execBytes, 0x1A) execBytes = append(execBytes, 0x1A)
execBytes = append(execBytes, getByteRange(0x80, 0x8F)...) execBytes = append(execBytes, getByteRange(0x80, 0x8F)...)
@ -62,10 +62,10 @@ func (base BaseState) Transition(s State) error {
return nil return nil
} }
type DcsEntryState struct { type dcsEntryState struct {
BaseState baseState
} }
type ErrorState struct { type errorState struct {
BaseState baseState
} }

View file

@ -1,173 +0,0 @@
package ansiterm
import (
"fmt"
"strconv"
)
type TestAnsiEventHandler struct {
FunctionCalls []string
}
func CreateTestAnsiEventHandler() *TestAnsiEventHandler {
evtHandler := TestAnsiEventHandler{}
evtHandler.FunctionCalls = make([]string, 0)
return &evtHandler
}
func (h *TestAnsiEventHandler) recordCall(call string, params []string) {
s := fmt.Sprintf("%s(%v)", call, params)
h.FunctionCalls = append(h.FunctionCalls, s)
}
func (h *TestAnsiEventHandler) Print(b byte) error {
h.recordCall("Print", []string{string(b)})
return nil
}
func (h *TestAnsiEventHandler) Execute(b byte) error {
h.recordCall("Execute", []string{string(b)})
return nil
}
func (h *TestAnsiEventHandler) CUU(param int) error {
h.recordCall("CUU", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) CUD(param int) error {
h.recordCall("CUD", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) CUF(param int) error {
h.recordCall("CUF", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) CUB(param int) error {
h.recordCall("CUB", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) CNL(param int) error {
h.recordCall("CNL", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) CPL(param int) error {
h.recordCall("CPL", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) CHA(param int) error {
h.recordCall("CHA", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) VPA(param int) error {
h.recordCall("VPA", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) CUP(x int, y int) error {
xS, yS := strconv.Itoa(x), strconv.Itoa(y)
h.recordCall("CUP", []string{xS, yS})
return nil
}
func (h *TestAnsiEventHandler) HVP(x int, y int) error {
xS, yS := strconv.Itoa(x), strconv.Itoa(y)
h.recordCall("HVP", []string{xS, yS})
return nil
}
func (h *TestAnsiEventHandler) DECTCEM(visible bool) error {
h.recordCall("DECTCEM", []string{strconv.FormatBool(visible)})
return nil
}
func (h *TestAnsiEventHandler) DECOM(visible bool) error {
h.recordCall("DECOM", []string{strconv.FormatBool(visible)})
return nil
}
func (h *TestAnsiEventHandler) DECCOLM(use132 bool) error {
h.recordCall("DECOLM", []string{strconv.FormatBool(use132)})
return nil
}
func (h *TestAnsiEventHandler) ED(param int) error {
h.recordCall("ED", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) EL(param int) error {
h.recordCall("EL", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) IL(param int) error {
h.recordCall("IL", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) DL(param int) error {
h.recordCall("DL", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) ICH(param int) error {
h.recordCall("ICH", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) DCH(param int) error {
h.recordCall("DCH", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) SGR(params []int) error {
strings := []string{}
for _, v := range params {
strings = append(strings, strconv.Itoa(v))
}
h.recordCall("SGR", strings)
return nil
}
func (h *TestAnsiEventHandler) SU(param int) error {
h.recordCall("SU", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) SD(param int) error {
h.recordCall("SD", []string{strconv.Itoa(param)})
return nil
}
func (h *TestAnsiEventHandler) DA(params []string) error {
h.recordCall("DA", params)
return nil
}
func (h *TestAnsiEventHandler) DECSTBM(top int, bottom int) error {
topS, bottomS := strconv.Itoa(top), strconv.Itoa(bottom)
h.recordCall("DECSTBM", []string{topS, bottomS})
return nil
}
func (h *TestAnsiEventHandler) RI() error {
h.recordCall("RI", nil)
return nil
}
func (h *TestAnsiEventHandler) IND() error {
h.recordCall("IND", nil)
return nil
}
func (h *TestAnsiEventHandler) Flush() error {
return nil
}

View file

@ -9,7 +9,7 @@ import (
"strings" "strings"
"syscall" "syscall"
. "github.com/Azure/go-ansiterm" "github.com/Azure/go-ansiterm"
) )
// Windows keyboard constants // Windows keyboard constants
@ -85,17 +85,17 @@ func newAnsiCommand(command []byte) *ansiCommand {
if lastCharIndex != 0 { if lastCharIndex != 0 {
start := 1 start := 1
// skip if double char escape sequence // skip if double char escape sequence
if command[0] == ANSI_ESCAPE_PRIMARY && command[1] == ANSI_ESCAPE_SECONDARY { if command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_ESCAPE_SECONDARY {
start++ start++
} }
// convert this to GetNextParam method // convert this to GetNextParam method
ac.Parameters = strings.Split(string(command[start:lastCharIndex]), ANSI_PARAMETER_SEP) ac.Parameters = strings.Split(string(command[start:lastCharIndex]), ansiterm.ANSI_PARAMETER_SEP)
} }
return ac return ac
} }
func (ac *ansiCommand) paramAsSHORT(index int, defaultValue SHORT) SHORT { func (ac *ansiCommand) paramAsSHORT(index int, defaultValue int16) int16 {
if index < 0 || index >= len(ac.Parameters) { if index < 0 || index >= len(ac.Parameters) {
return defaultValue return defaultValue
} }
@ -105,7 +105,7 @@ func (ac *ansiCommand) paramAsSHORT(index int, defaultValue SHORT) SHORT {
return defaultValue return defaultValue
} }
return SHORT(param) return int16(param)
} }
func (ac *ansiCommand) String() string { func (ac *ansiCommand) String() string {
@ -119,12 +119,12 @@ func (ac *ansiCommand) String() string {
// See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html. // See http://manpages.ubuntu.com/manpages/intrepid/man4/console_codes.4.html.
func isAnsiCommandChar(b byte) bool { func isAnsiCommandChar(b byte) bool {
switch { switch {
case ANSI_COMMAND_FIRST <= b && b <= ANSI_COMMAND_LAST && b != ANSI_ESCAPE_SECONDARY: case ansiterm.ANSI_COMMAND_FIRST <= b && b <= ansiterm.ANSI_COMMAND_LAST && b != ansiterm.ANSI_ESCAPE_SECONDARY:
return true return true
case b == ANSI_CMD_G1 || b == ANSI_CMD_OSC || b == ANSI_CMD_DECPAM || b == ANSI_CMD_DECPNM: case b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_OSC || b == ansiterm.ANSI_CMD_DECPAM || b == ansiterm.ANSI_CMD_DECPNM:
// non-CSI escape sequence terminator // non-CSI escape sequence terminator
return true return true
case b == ANSI_CMD_STR_TERM || b == ANSI_BEL: case b == ansiterm.ANSI_CMD_STR_TERM || b == ansiterm.ANSI_BEL:
// String escape sequence terminator // String escape sequence terminator
return true return true
} }
@ -132,11 +132,11 @@ func isAnsiCommandChar(b byte) bool {
} }
func isXtermOscSequence(command []byte, current byte) bool { func isXtermOscSequence(command []byte, current byte) bool {
return (len(command) >= 2 && command[0] == ANSI_ESCAPE_PRIMARY && command[1] == ANSI_CMD_OSC && current != ANSI_BEL) return (len(command) >= 2 && command[0] == ansiterm.ANSI_ESCAPE_PRIMARY && command[1] == ansiterm.ANSI_CMD_OSC && current != ansiterm.ANSI_BEL)
} }
func isCharacterSelectionCmdChar(b byte) bool { func isCharacterSelectionCmdChar(b byte) bool {
return (b == ANSI_CMD_G0 || b == ANSI_CMD_G1 || b == ANSI_CMD_G2 || b == ANSI_CMD_G3) return (b == ansiterm.ANSI_CMD_G0 || b == ansiterm.ANSI_CMD_G1 || b == ansiterm.ANSI_CMD_G2 || b == ansiterm.ANSI_CMD_G3)
} }
// bytesToHex converts a slice of bytes to a human-readable string. // bytesToHex converts a slice of bytes to a human-readable string.
@ -150,7 +150,7 @@ func bytesToHex(b []byte) string {
// ensureInRange adjusts the passed value, if necessary, to ensure it is within // ensureInRange adjusts the passed value, if necessary, to ensure it is within
// the passed min / max range. // the passed min / max range.
func ensureInRange(n SHORT, min SHORT, max SHORT) SHORT { func ensureInRange(n int16, min int16, max int16) int16 {
if n < min { if n < min {
return min return min
} else if n > max { } else if n > max {

View file

@ -66,21 +66,21 @@ const (
// -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan). // -- The attributes are combined to produce various colors (e.g., Blue + Green will create Cyan).
// Clearing all foreground or background colors results in black; setting all creates white. // Clearing all foreground or background colors results in black; setting all creates white.
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes. // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682088(v=vs.85).aspx#_win32_character_attributes.
FOREGROUND_BLUE WORD = 0x0001 FOREGROUND_BLUE uint16 = 0x0001
FOREGROUND_GREEN WORD = 0x0002 FOREGROUND_GREEN uint16 = 0x0002
FOREGROUND_RED WORD = 0x0004 FOREGROUND_RED uint16 = 0x0004
FOREGROUND_INTENSITY WORD = 0x0008 FOREGROUND_INTENSITY uint16 = 0x0008
FOREGROUND_MASK WORD = 0x000F FOREGROUND_MASK uint16 = 0x000F
BACKGROUND_BLUE WORD = 0x0010 BACKGROUND_BLUE uint16 = 0x0010
BACKGROUND_GREEN WORD = 0x0020 BACKGROUND_GREEN uint16 = 0x0020
BACKGROUND_RED WORD = 0x0040 BACKGROUND_RED uint16 = 0x0040
BACKGROUND_INTENSITY WORD = 0x0080 BACKGROUND_INTENSITY uint16 = 0x0080
BACKGROUND_MASK WORD = 0x00F0 BACKGROUND_MASK uint16 = 0x00F0
COMMON_LVB_MASK WORD = 0xFF00 COMMON_LVB_MASK uint16 = 0xFF00
COMMON_LVB_REVERSE_VIDEO WORD = 0x4000 COMMON_LVB_REVERSE_VIDEO uint16 = 0x4000
COMMON_LVB_UNDERSCORE WORD = 0x8000 COMMON_LVB_UNDERSCORE uint16 = 0x8000
// Input event types // Input event types
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx. // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.
@ -104,60 +104,53 @@ const (
) )
// Windows API Console types // Windows API Console types
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/aa383751(v=vs.85).aspx for core types (e.g., SHORT)
// -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682101(v=vs.85).aspx for Console specific types (e.g., COORD) // -- See https://msdn.microsoft.com/en-us/library/windows/desktop/ms682101(v=vs.85).aspx for Console specific types (e.g., COORD)
// -- See https://msdn.microsoft.com/en-us/library/aa296569(v=vs.60).aspx for comments on alignment // -- See https://msdn.microsoft.com/en-us/library/aa296569(v=vs.60).aspx for comments on alignment
type ( type (
SHORT int16
BOOL int32
WORD uint16
WCHAR uint16
DWORD uint32
CHAR_INFO struct { CHAR_INFO struct {
UnicodeChar WCHAR UnicodeChar uint16
Attributes WORD Attributes uint16
} }
CONSOLE_CURSOR_INFO struct { CONSOLE_CURSOR_INFO struct {
Size DWORD Size uint32
Visible BOOL Visible int32
} }
CONSOLE_SCREEN_BUFFER_INFO struct { CONSOLE_SCREEN_BUFFER_INFO struct {
Size COORD Size COORD
CursorPosition COORD CursorPosition COORD
Attributes WORD Attributes uint16
Window SMALL_RECT Window SMALL_RECT
MaximumWindowSize COORD MaximumWindowSize COORD
} }
COORD struct { COORD struct {
X SHORT X int16
Y SHORT Y int16
} }
SMALL_RECT struct { SMALL_RECT struct {
Left SHORT Left int16
Top SHORT Top int16
Right SHORT Right int16
Bottom SHORT Bottom int16
} }
// INPUT_RECORD is a C/C++ union of which KEY_EVENT_RECORD is one case, it is also the largest // INPUT_RECORD is a C/C++ union of which KEY_EVENT_RECORD is one case, it is also the largest
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx. // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms683499(v=vs.85).aspx.
INPUT_RECORD struct { INPUT_RECORD struct {
EventType WORD EventType uint16
KeyEvent KEY_EVENT_RECORD KeyEvent KEY_EVENT_RECORD
} }
KEY_EVENT_RECORD struct { KEY_EVENT_RECORD struct {
KeyDown BOOL KeyDown int32
RepeatCount WORD RepeatCount uint16
VirtualKeyCode WORD VirtualKeyCode uint16
VirtualScanCode WORD VirtualScanCode uint16
UnicodeChar WCHAR UnicodeChar uint16
ControlKeyState DWORD ControlKeyState uint32
} }
WINDOW_BUFFER_SIZE struct { WINDOW_BUFFER_SIZE struct {
@ -165,12 +158,12 @@ type (
} }
) )
// boolToBOOL converts a Go bool into a Windows BOOL. // boolToBOOL converts a Go bool into a Windows int32.
func boolToBOOL(f bool) BOOL { func boolToBOOL(f bool) int32 {
if f { if f {
return BOOL(1) return int32(1)
} else { } else {
return BOOL(0) return int32(0)
} }
} }
@ -242,7 +235,7 @@ func SetConsoleScreenBufferSize(handle uintptr, coord COORD) error {
// SetConsoleTextAttribute sets the attributes of characters written to the // SetConsoleTextAttribute sets the attributes of characters written to the
// console screen buffer by the WriteFile or WriteConsole function. // console screen buffer by the WriteFile or WriteConsole function.
// See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx. // See http://msdn.microsoft.com/en-us/library/windows/desktop/ms686047(v=vs.85).aspx.
func SetConsoleTextAttribute(handle uintptr, attribute WORD) error { func SetConsoleTextAttribute(handle uintptr, attribute uint16) error {
r1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0) r1, r2, err := setConsoleTextAttributeProc.Call(handle, uintptr(attribute), 0)
use(attribute) use(attribute)
return checkError(r1, r2, err) return checkError(r1, r2, err)
@ -280,7 +273,7 @@ func ReadConsoleInput(handle uintptr, buffer []INPUT_RECORD, count *uint32) erro
// It returns true if the handle was signaled; false otherwise. // It returns true if the handle was signaled; false otherwise.
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx. // See https://msdn.microsoft.com/en-us/library/windows/desktop/ms687032(v=vs.85).aspx.
func WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) { func WaitForSingleObject(handle uintptr, msWait uint32) (bool, error) {
r1, _, err := waitForSingleObjectProc.Call(handle, uintptr(DWORD(msWait))) r1, _, err := waitForSingleObjectProc.Call(handle, uintptr(uint32(msWait)))
switch r1 { switch r1 {
case WAIT_ABANDONED, WAIT_TIMEOUT: case WAIT_ABANDONED, WAIT_TIMEOUT:
return false, nil return false, nil
@ -320,8 +313,8 @@ func checkError(r1, r2 uintptr, err error) error {
// coordToPointer converts a COORD into a uintptr (by fooling the type system). // coordToPointer converts a COORD into a uintptr (by fooling the type system).
func coordToPointer(c COORD) uintptr { func coordToPointer(c COORD) uintptr {
// Note: This code assumes the two SHORTs are correctly laid out; the "cast" to DWORD is just to get a pointer to pass. // Note: This code assumes the two SHORTs are correctly laid out; the "cast" to uint32 is just to get a pointer to pass.
return uintptr(*((*DWORD)(unsafe.Pointer(&c)))) return uintptr(*((*uint32)(unsafe.Pointer(&c))))
} }
// use is a no-op, but the compiler cannot see that it is. // use is a no-op, but the compiler cannot see that it is.

View file

@ -2,9 +2,7 @@
package winterm package winterm
import ( import "github.com/Azure/go-ansiterm"
. "github.com/Azure/go-ansiterm"
)
const ( const (
FOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE FOREGROUND_COLOR_MASK = FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
@ -13,83 +11,83 @@ const (
// collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the // collectAnsiIntoWindowsAttributes modifies the passed Windows text mode flags to reflect the
// request represented by the passed ANSI mode. // request represented by the passed ANSI mode.
func collectAnsiIntoWindowsAttributes(windowsMode WORD, inverted bool, baseMode WORD, ansiMode SHORT) (WORD, bool) { func collectAnsiIntoWindowsAttributes(windowsMode uint16, inverted bool, baseMode uint16, ansiMode int16) (uint16, bool) {
switch ansiMode { switch ansiMode {
// Mode styles // Mode styles
case ANSI_SGR_BOLD: case ansiterm.ANSI_SGR_BOLD:
windowsMode = windowsMode | FOREGROUND_INTENSITY windowsMode = windowsMode | FOREGROUND_INTENSITY
case ANSI_SGR_DIM, ANSI_SGR_BOLD_DIM_OFF: case ansiterm.ANSI_SGR_DIM, ansiterm.ANSI_SGR_BOLD_DIM_OFF:
windowsMode &^= FOREGROUND_INTENSITY windowsMode &^= FOREGROUND_INTENSITY
case ANSI_SGR_UNDERLINE: case ansiterm.ANSI_SGR_UNDERLINE:
windowsMode = windowsMode | COMMON_LVB_UNDERSCORE windowsMode = windowsMode | COMMON_LVB_UNDERSCORE
case ANSI_SGR_REVERSE: case ansiterm.ANSI_SGR_REVERSE:
inverted = true inverted = true
case ANSI_SGR_REVERSE_OFF: case ansiterm.ANSI_SGR_REVERSE_OFF:
inverted = false inverted = false
case ANSI_SGR_UNDERLINE_OFF: case ansiterm.ANSI_SGR_UNDERLINE_OFF:
windowsMode &^= COMMON_LVB_UNDERSCORE windowsMode &^= COMMON_LVB_UNDERSCORE
// Foreground colors // Foreground colors
case ANSI_SGR_FOREGROUND_DEFAULT: case ansiterm.ANSI_SGR_FOREGROUND_DEFAULT:
windowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK) windowsMode = (windowsMode &^ FOREGROUND_MASK) | (baseMode & FOREGROUND_MASK)
case ANSI_SGR_FOREGROUND_BLACK: case ansiterm.ANSI_SGR_FOREGROUND_BLACK:
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK)
case ANSI_SGR_FOREGROUND_RED: case ansiterm.ANSI_SGR_FOREGROUND_RED:
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED
case ANSI_SGR_FOREGROUND_GREEN: case ansiterm.ANSI_SGR_FOREGROUND_GREEN:
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN
case ANSI_SGR_FOREGROUND_YELLOW: case ansiterm.ANSI_SGR_FOREGROUND_YELLOW:
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN
case ANSI_SGR_FOREGROUND_BLUE: case ansiterm.ANSI_SGR_FOREGROUND_BLUE:
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_BLUE
case ANSI_SGR_FOREGROUND_MAGENTA: case ansiterm.ANSI_SGR_FOREGROUND_MAGENTA:
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_BLUE
case ANSI_SGR_FOREGROUND_CYAN: case ansiterm.ANSI_SGR_FOREGROUND_CYAN:
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_GREEN | FOREGROUND_BLUE
case ANSI_SGR_FOREGROUND_WHITE: case ansiterm.ANSI_SGR_FOREGROUND_WHITE:
windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE windowsMode = (windowsMode &^ FOREGROUND_COLOR_MASK) | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE
// Background colors // Background colors
case ANSI_SGR_BACKGROUND_DEFAULT: case ansiterm.ANSI_SGR_BACKGROUND_DEFAULT:
// Black with no intensity // Black with no intensity
windowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK) windowsMode = (windowsMode &^ BACKGROUND_MASK) | (baseMode & BACKGROUND_MASK)
case ANSI_SGR_BACKGROUND_BLACK: case ansiterm.ANSI_SGR_BACKGROUND_BLACK:
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK)
case ANSI_SGR_BACKGROUND_RED: case ansiterm.ANSI_SGR_BACKGROUND_RED:
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED
case ANSI_SGR_BACKGROUND_GREEN: case ansiterm.ANSI_SGR_BACKGROUND_GREEN:
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN
case ANSI_SGR_BACKGROUND_YELLOW: case ansiterm.ANSI_SGR_BACKGROUND_YELLOW:
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN
case ANSI_SGR_BACKGROUND_BLUE: case ansiterm.ANSI_SGR_BACKGROUND_BLUE:
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_BLUE
case ANSI_SGR_BACKGROUND_MAGENTA: case ansiterm.ANSI_SGR_BACKGROUND_MAGENTA:
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_BLUE
case ANSI_SGR_BACKGROUND_CYAN: case ansiterm.ANSI_SGR_BACKGROUND_CYAN:
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_GREEN | BACKGROUND_BLUE
case ANSI_SGR_BACKGROUND_WHITE: case ansiterm.ANSI_SGR_BACKGROUND_WHITE:
windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE windowsMode = (windowsMode &^ BACKGROUND_COLOR_MASK) | BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE
} }
@ -97,6 +95,6 @@ func collectAnsiIntoWindowsAttributes(windowsMode WORD, inverted bool, baseMode
} }
// invertAttributes inverts the foreground and background colors of a Windows attributes value // invertAttributes inverts the foreground and background colors of a Windows attributes value
func invertAttributes(windowsMode WORD) WORD { func invertAttributes(windowsMode uint16) uint16 {
return (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4) return (COMMON_LVB_MASK & windowsMode) | ((FOREGROUND_MASK & windowsMode) << 4) | ((BACKGROUND_MASK & windowsMode) >> 4)
} }

View file

@ -3,11 +3,11 @@
package winterm package winterm
const ( const (
Horizontal = iota horizontal = iota
Vertical vertical
) )
func (h *WindowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT { func (h *windowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_INFO) SMALL_RECT {
if h.originMode { if h.originMode {
sr := h.effectiveSr(info.Window) sr := h.effectiveSr(info.Window)
return SMALL_RECT{ return SMALL_RECT{
@ -27,7 +27,7 @@ func (h *WindowsAnsiEventHandler) getCursorWindow(info *CONSOLE_SCREEN_BUFFER_IN
} }
// setCursorPosition sets the cursor to the specified position, bounded to the screen size // setCursorPosition sets the cursor to the specified position, bounded to the screen size
func (h *WindowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error { func (h *windowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL_RECT) error {
position.X = ensureInRange(position.X, window.Left, window.Right) position.X = ensureInRange(position.X, window.Left, window.Right)
position.Y = ensureInRange(position.Y, window.Top, window.Bottom) position.Y = ensureInRange(position.Y, window.Top, window.Bottom)
err := SetConsoleCursorPosition(h.fd, position) err := SetConsoleCursorPosition(h.fd, position)
@ -38,15 +38,15 @@ func (h *WindowsAnsiEventHandler) setCursorPosition(position COORD, window SMALL
return err return err
} }
func (h *WindowsAnsiEventHandler) moveCursorVertical(param int) error { func (h *windowsAnsiEventHandler) moveCursorVertical(param int) error {
return h.moveCursor(Vertical, param) return h.moveCursor(vertical, param)
} }
func (h *WindowsAnsiEventHandler) moveCursorHorizontal(param int) error { func (h *windowsAnsiEventHandler) moveCursorHorizontal(param int) error {
return h.moveCursor(Horizontal, param) return h.moveCursor(horizontal, param)
} }
func (h *WindowsAnsiEventHandler) moveCursor(moveMode int, param int) error { func (h *windowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
return err return err
@ -54,10 +54,10 @@ func (h *WindowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
position := info.CursorPosition position := info.CursorPosition
switch moveMode { switch moveMode {
case Horizontal: case horizontal:
position.X += SHORT(param) position.X += int16(param)
case Vertical: case vertical:
position.Y += SHORT(param) position.Y += int16(param)
} }
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
@ -67,7 +67,7 @@ func (h *WindowsAnsiEventHandler) moveCursor(moveMode int, param int) error {
return nil return nil
} }
func (h *WindowsAnsiEventHandler) moveCursorLine(param int) error { func (h *windowsAnsiEventHandler) moveCursorLine(param int) error {
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
return err return err
@ -75,7 +75,7 @@ func (h *WindowsAnsiEventHandler) moveCursorLine(param int) error {
position := info.CursorPosition position := info.CursorPosition
position.X = 0 position.X = 0
position.Y += SHORT(param) position.Y += int16(param)
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
return err return err
@ -84,14 +84,14 @@ func (h *WindowsAnsiEventHandler) moveCursorLine(param int) error {
return nil return nil
} }
func (h *WindowsAnsiEventHandler) moveCursorColumn(param int) error { func (h *windowsAnsiEventHandler) moveCursorColumn(param int) error {
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
return err return err
} }
position := info.CursorPosition position := info.CursorPosition
position.X = SHORT(param) - 1 position.X = int16(param) - 1
if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil { if err = h.setCursorPosition(position, h.getCursorWindow(info)); err != nil {
return err return err

View file

@ -2,11 +2,9 @@
package winterm package winterm
import ( import "github.com/Azure/go-ansiterm"
. "github.com/Azure/go-ansiterm"
)
func (h *WindowsAnsiEventHandler) clearRange(attributes WORD, fromCoord COORD, toCoord COORD) error { func (h *windowsAnsiEventHandler) clearRange(attributes uint16, fromCoord COORD, toCoord COORD) error {
// Ignore an invalid (negative area) request // Ignore an invalid (negative area) request
if toCoord.Y < fromCoord.Y { if toCoord.Y < fromCoord.Y {
return nil return nil
@ -60,7 +58,7 @@ func (h *WindowsAnsiEventHandler) clearRange(attributes WORD, fromCoord COORD, t
return nil return nil
} }
func (h *WindowsAnsiEventHandler) clearRect(attributes WORD, fromCoord COORD, toCoord COORD) error { func (h *windowsAnsiEventHandler) clearRect(attributes uint16, fromCoord COORD, toCoord COORD) error {
region := SMALL_RECT{Top: fromCoord.Y, Left: fromCoord.X, Bottom: toCoord.Y, Right: toCoord.X} region := SMALL_RECT{Top: fromCoord.Y, Left: fromCoord.X, Bottom: toCoord.Y, Right: toCoord.X}
width := toCoord.X - fromCoord.X + 1 width := toCoord.X - fromCoord.X + 1
height := toCoord.Y - fromCoord.Y + 1 height := toCoord.Y - fromCoord.Y + 1
@ -72,7 +70,7 @@ func (h *WindowsAnsiEventHandler) clearRect(attributes WORD, fromCoord COORD, to
buffer := make([]CHAR_INFO, size) buffer := make([]CHAR_INFO, size)
char := CHAR_INFO{WCHAR(FILL_CHARACTER), attributes} char := CHAR_INFO{ansiterm.FILL_CHARACTER, attributes}
for i := 0; i < int(size); i++ { for i := 0; i < int(size); i++ {
buffer[i] = char buffer[i] = char
} }

View file

@ -3,9 +3,9 @@
package winterm package winterm
// effectiveSr gets the current effective scroll region in buffer coordinates // effectiveSr gets the current effective scroll region in buffer coordinates
func (h *WindowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion { func (h *windowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {
top := AddInRange(window.Top, h.sr.top, window.Top, window.Bottom) top := addInRange(window.Top, h.sr.top, window.Top, window.Bottom)
bottom := AddInRange(window.Top, h.sr.bottom, window.Top, window.Bottom) bottom := addInRange(window.Top, h.sr.bottom, window.Top, window.Bottom)
if top >= bottom { if top >= bottom {
top = window.Top top = window.Top
bottom = window.Bottom bottom = window.Bottom
@ -13,7 +13,7 @@ func (h *WindowsAnsiEventHandler) effectiveSr(window SMALL_RECT) scrollRegion {
return scrollRegion{top: top, bottom: bottom} return scrollRegion{top: top, bottom: bottom}
} }
func (h *WindowsAnsiEventHandler) scrollUp(param int) error { func (h *windowsAnsiEventHandler) scrollUp(param int) error {
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
return err return err
@ -23,11 +23,11 @@ func (h *WindowsAnsiEventHandler) scrollUp(param int) error {
return h.scroll(param, sr, info) return h.scroll(param, sr, info)
} }
func (h *WindowsAnsiEventHandler) scrollDown(param int) error { func (h *windowsAnsiEventHandler) scrollDown(param int) error {
return h.scrollUp(-param) return h.scrollUp(-param)
} }
func (h *WindowsAnsiEventHandler) deleteLines(param int) error { func (h *windowsAnsiEventHandler) deleteLines(param int) error {
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
return err return err
@ -44,12 +44,12 @@ func (h *WindowsAnsiEventHandler) deleteLines(param int) error {
} }
} }
func (h *WindowsAnsiEventHandler) insertLines(param int) error { func (h *windowsAnsiEventHandler) insertLines(param int) error {
return h.deleteLines(-param) return h.deleteLines(-param)
} }
// scroll scrolls the provided scroll region by param lines. The scroll region is in buffer coordinates. // 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 { 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: scrollTop: %d, scrollBottom: %d", sr.top, sr.bottom)
logger.Infof("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom) logger.Infof("scroll: windowTop: %d, windowBottom: %d", info.Window.Top, info.Window.Bottom)
@ -64,7 +64,7 @@ func (h *WindowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSO
// Origin to which area should be copied // Origin to which area should be copied
destOrigin := COORD{ destOrigin := COORD{
X: 0, X: 0,
Y: sr.top - SHORT(param), Y: sr.top - int16(param),
} }
char := CHAR_INFO{ char := CHAR_INFO{
@ -78,7 +78,7 @@ func (h *WindowsAnsiEventHandler) scroll(param int, sr scrollRegion, info *CONSO
return nil return nil
} }
func (h *WindowsAnsiEventHandler) deleteCharacters(param int) error { func (h *windowsAnsiEventHandler) deleteCharacters(param int) error {
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
return err return err
@ -86,12 +86,12 @@ func (h *WindowsAnsiEventHandler) deleteCharacters(param int) error {
return h.scrollLine(param, info.CursorPosition, info) return h.scrollLine(param, info.CursorPosition, info)
} }
func (h *WindowsAnsiEventHandler) insertCharacters(param int) error { func (h *windowsAnsiEventHandler) insertCharacters(param int) error {
return h.deleteCharacters(-param) return h.deleteCharacters(-param)
} }
// scrollLine scrolls a line horizontally starting at the provided position by a number of columns. // scrollLine scrolls a line horizontally starting at the provided position by a number of columns.
func (h *WindowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error { func (h *windowsAnsiEventHandler) scrollLine(columns int, position COORD, info *CONSOLE_SCREEN_BUFFER_INFO) error {
// Copy from and clip to the scroll region (full buffer width) // Copy from and clip to the scroll region (full buffer width)
scrollRect := SMALL_RECT{ scrollRect := SMALL_RECT{
Top: position.Y, Top: position.Y,
@ -102,7 +102,7 @@ func (h *WindowsAnsiEventHandler) scrollLine(columns int, position COORD, info *
// Origin to which area should be copied // Origin to which area should be copied
destOrigin := COORD{ destOrigin := COORD{
X: position.X - SHORT(columns), X: position.X - int16(columns),
Y: position.Y, Y: position.Y,
} }

View file

@ -4,6 +4,6 @@ package winterm
// AddInRange increments a value by the passed quantity while ensuring the values // AddInRange increments a value by the passed quantity while ensuring the values
// always remain within the supplied min / max range. // always remain within the supplied min / max range.
func AddInRange(n SHORT, increment SHORT, min SHORT, max SHORT) SHORT { func addInRange(n int16, increment int16, min int16, max int16) int16 {
return ensureInRange(n+increment, min, max) return ensureInRange(n+increment, min, max)
} }

View file

@ -8,19 +8,19 @@ import (
"os" "os"
"strconv" "strconv"
. "github.com/Azure/go-ansiterm" "github.com/Azure/go-ansiterm"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
) )
var logger *logrus.Logger var logger *logrus.Logger
type WindowsAnsiEventHandler struct { type windowsAnsiEventHandler struct {
fd uintptr fd uintptr
file *os.File file *os.File
infoReset *CONSOLE_SCREEN_BUFFER_INFO infoReset *CONSOLE_SCREEN_BUFFER_INFO
sr scrollRegion sr scrollRegion
buffer bytes.Buffer buffer bytes.Buffer
attributes WORD attributes uint16
inverted bool inverted bool
wrapNext bool wrapNext bool
drewMarginByte bool drewMarginByte bool
@ -30,10 +30,10 @@ type WindowsAnsiEventHandler struct {
curPos COORD curPos COORD
} }
func CreateWinEventHandler(fd uintptr, file *os.File) AnsiEventHandler { func CreateWinEventHandler(fd uintptr, file *os.File) ansiterm.AnsiEventHandler {
logFile := ioutil.Discard logFile := ioutil.Discard
if isDebugEnv := os.Getenv(LogEnv); isDebugEnv == "1" { if isDebugEnv := os.Getenv(ansiterm.LogEnv); isDebugEnv == "1" {
logFile, _ = os.Create("winEventHandler.log") logFile, _ = os.Create("winEventHandler.log")
} }
@ -48,7 +48,7 @@ func CreateWinEventHandler(fd uintptr, file *os.File) AnsiEventHandler {
return nil return nil
} }
return &WindowsAnsiEventHandler{ return &windowsAnsiEventHandler{
fd: fd, fd: fd,
file: file, file: file,
infoReset: infoReset, infoReset: infoReset,
@ -57,8 +57,8 @@ func CreateWinEventHandler(fd uintptr, file *os.File) AnsiEventHandler {
} }
type scrollRegion struct { type scrollRegion struct {
top SHORT top int16
bottom SHORT bottom int16
} }
// simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the // simulateLF simulates a LF or CR+LF by scrolling if necessary to handle the
@ -68,7 +68,7 @@ type scrollRegion struct {
// //
// In the false case, the caller should ensure that a carriage return // In the false case, the caller should ensure that a carriage return
// and line feed are inserted or that the text is otherwise wrapped. // and line feed are inserted or that the text is otherwise wrapped.
func (h *WindowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) { func (h *windowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
if h.wrapNext { if h.wrapNext {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return false, err return false, err
@ -89,7 +89,8 @@ func (h *WindowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
h.updatePos(pos) h.updatePos(pos)
} }
return false, nil return false, nil
} else { }
// A custom scroll region is active. Scroll the window manually to simulate // A custom scroll region is active. Scroll the window manually to simulate
// the LF. // the LF.
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
@ -106,7 +107,7 @@ func (h *WindowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
} }
} }
return true, nil return true, nil
}
} else if pos.Y < info.Window.Bottom { } else if pos.Y < info.Window.Bottom {
// Let Windows handle the LF. // Let Windows handle the LF.
pos.Y++ pos.Y++
@ -133,7 +134,7 @@ func (h *WindowsAnsiEventHandler) simulateLF(includeCR bool) (bool, error) {
} }
// executeLF executes a LF without a CR. // executeLF executes a LF without a CR.
func (h *WindowsAnsiEventHandler) executeLF() error { func (h *windowsAnsiEventHandler) executeLF() error {
handled, err := h.simulateLF(false) handled, err := h.simulateLF(false)
if err != nil { if err != nil {
return err return err
@ -145,7 +146,7 @@ func (h *WindowsAnsiEventHandler) executeLF() error {
if err != nil { if err != nil {
return err return err
} }
h.buffer.WriteByte(ANSI_LINE_FEED) h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED)
if pos.X != 0 { if pos.X != 0 {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
@ -159,7 +160,7 @@ func (h *WindowsAnsiEventHandler) executeLF() error {
return nil return nil
} }
func (h *WindowsAnsiEventHandler) Print(b byte) error { func (h *windowsAnsiEventHandler) Print(b byte) error {
if h.wrapNext { if h.wrapNext {
h.buffer.WriteByte(h.marginByte) h.buffer.WriteByte(h.marginByte)
h.clearWrap() h.clearWrap()
@ -182,9 +183,9 @@ func (h *WindowsAnsiEventHandler) Print(b byte) error {
return nil return nil
} }
func (h *WindowsAnsiEventHandler) Execute(b byte) error { func (h *windowsAnsiEventHandler) Execute(b byte) error {
switch b { switch b {
case ANSI_TAB: case ansiterm.ANSI_TAB:
logger.Info("Execute(TAB)") logger.Info("Execute(TAB)")
// Move to the next tab stop, but preserve auto-wrap if already set. // Move to the next tab stop, but preserve auto-wrap if already set.
if !h.wrapNext { if !h.wrapNext {
@ -205,11 +206,11 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
} }
return nil return nil
case ANSI_BEL: case ansiterm.ANSI_BEL:
h.buffer.WriteByte(ANSI_BEL) h.buffer.WriteByte(ansiterm.ANSI_BEL)
return nil return nil
case ANSI_BACKSPACE: case ansiterm.ANSI_BACKSPACE:
if h.wrapNext { if h.wrapNext {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
@ -223,15 +224,15 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
if pos.X > 0 { if pos.X > 0 {
pos.X-- pos.X--
h.updatePos(pos) h.updatePos(pos)
h.buffer.WriteByte(ANSI_BACKSPACE) h.buffer.WriteByte(ansiterm.ANSI_BACKSPACE)
} }
return nil return nil
case ANSI_VERTICAL_TAB, ANSI_FORM_FEED: case ansiterm.ANSI_VERTICAL_TAB, ansiterm.ANSI_FORM_FEED:
// Treat as true LF. // Treat as true LF.
return h.executeLF() return h.executeLF()
case ANSI_LINE_FEED: case ansiterm.ANSI_LINE_FEED:
// Simulate a CR and LF for now since there is no way in go-ansiterm // Simulate a CR and LF for now since there is no way in go-ansiterm
// to tell if the LF should include CR (and more things break when it's // to tell if the LF should include CR (and more things break when it's
// missing than when it's incorrectly added). // missing than when it's incorrectly added).
@ -239,9 +240,9 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
if handled || err != nil { if handled || err != nil {
return err return err
} }
return h.buffer.WriteByte(ANSI_LINE_FEED) return h.buffer.WriteByte(ansiterm.ANSI_LINE_FEED)
case ANSI_CARRIAGE_RETURN: case ansiterm.ANSI_CARRIAGE_RETURN:
if h.wrapNext { if h.wrapNext {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
@ -255,7 +256,7 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
if pos.X != 0 { if pos.X != 0 {
pos.X = 0 pos.X = 0
h.updatePos(pos) h.updatePos(pos)
h.buffer.WriteByte(ANSI_CARRIAGE_RETURN) h.buffer.WriteByte(ansiterm.ANSI_CARRIAGE_RETURN)
} }
return nil return nil
@ -264,7 +265,7 @@ func (h *WindowsAnsiEventHandler) Execute(b byte) error {
} }
} }
func (h *WindowsAnsiEventHandler) CUU(param int) error { func (h *windowsAnsiEventHandler) CUU(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -273,7 +274,7 @@ func (h *WindowsAnsiEventHandler) CUU(param int) error {
return h.moveCursorVertical(-param) return h.moveCursorVertical(-param)
} }
func (h *WindowsAnsiEventHandler) CUD(param int) error { func (h *windowsAnsiEventHandler) CUD(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -282,7 +283,7 @@ func (h *WindowsAnsiEventHandler) CUD(param int) error {
return h.moveCursorVertical(param) return h.moveCursorVertical(param)
} }
func (h *WindowsAnsiEventHandler) CUF(param int) error { func (h *windowsAnsiEventHandler) CUF(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -291,7 +292,7 @@ func (h *WindowsAnsiEventHandler) CUF(param int) error {
return h.moveCursorHorizontal(param) return h.moveCursorHorizontal(param)
} }
func (h *WindowsAnsiEventHandler) CUB(param int) error { func (h *windowsAnsiEventHandler) CUB(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -300,7 +301,7 @@ func (h *WindowsAnsiEventHandler) CUB(param int) error {
return h.moveCursorHorizontal(-param) return h.moveCursorHorizontal(-param)
} }
func (h *WindowsAnsiEventHandler) CNL(param int) error { func (h *windowsAnsiEventHandler) CNL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -309,7 +310,7 @@ func (h *WindowsAnsiEventHandler) CNL(param int) error {
return h.moveCursorLine(param) return h.moveCursorLine(param)
} }
func (h *WindowsAnsiEventHandler) CPL(param int) error { func (h *windowsAnsiEventHandler) CPL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -318,7 +319,7 @@ func (h *WindowsAnsiEventHandler) CPL(param int) error {
return h.moveCursorLine(-param) return h.moveCursorLine(-param)
} }
func (h *WindowsAnsiEventHandler) CHA(param int) error { func (h *windowsAnsiEventHandler) CHA(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -327,7 +328,7 @@ func (h *WindowsAnsiEventHandler) CHA(param int) error {
return h.moveCursorColumn(param) return h.moveCursorColumn(param)
} }
func (h *WindowsAnsiEventHandler) VPA(param int) error { func (h *windowsAnsiEventHandler) VPA(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -339,11 +340,11 @@ func (h *WindowsAnsiEventHandler) VPA(param int) error {
} }
window := h.getCursorWindow(info) window := h.getCursorWindow(info)
position := info.CursorPosition position := info.CursorPosition
position.Y = window.Top + SHORT(param) - 1 position.Y = window.Top + int16(param) - 1
return h.setCursorPosition(position, window) return h.setCursorPosition(position, window)
} }
func (h *WindowsAnsiEventHandler) CUP(row int, col int) error { func (h *windowsAnsiEventHandler) CUP(row int, col int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -355,11 +356,11 @@ func (h *WindowsAnsiEventHandler) CUP(row int, col int) error {
} }
window := h.getCursorWindow(info) window := h.getCursorWindow(info)
position := COORD{window.Left + SHORT(col) - 1, window.Top + SHORT(row) - 1} position := COORD{window.Left + int16(col) - 1, window.Top + int16(row) - 1}
return h.setCursorPosition(position, window) return h.setCursorPosition(position, window)
} }
func (h *WindowsAnsiEventHandler) HVP(row int, col int) error { func (h *windowsAnsiEventHandler) HVP(row int, col int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -368,7 +369,7 @@ func (h *WindowsAnsiEventHandler) HVP(row int, col int) error {
return h.CUP(row, col) return h.CUP(row, col)
} }
func (h *WindowsAnsiEventHandler) DECTCEM(visible bool) error { func (h *windowsAnsiEventHandler) DECTCEM(visible bool) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -377,7 +378,7 @@ func (h *WindowsAnsiEventHandler) DECTCEM(visible bool) error {
return nil return nil
} }
func (h *WindowsAnsiEventHandler) DECOM(enable bool) error { func (h *windowsAnsiEventHandler) DECOM(enable bool) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -387,7 +388,7 @@ func (h *WindowsAnsiEventHandler) DECOM(enable bool) error {
return h.CUP(1, 1) return h.CUP(1, 1)
} }
func (h *WindowsAnsiEventHandler) DECCOLM(use132 bool) error { func (h *windowsAnsiEventHandler) DECCOLM(use132 bool) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -400,7 +401,7 @@ func (h *WindowsAnsiEventHandler) DECCOLM(use132 bool) error {
if err != nil { if err != nil {
return err return err
} }
targetWidth := SHORT(80) targetWidth := int16(80)
if use132 { if use132 {
targetWidth = 132 targetWidth = 132
} }
@ -426,7 +427,7 @@ func (h *WindowsAnsiEventHandler) DECCOLM(use132 bool) error {
return SetConsoleCursorPosition(h.fd, COORD{0, 0}) return SetConsoleCursorPosition(h.fd, COORD{0, 0})
} }
func (h *WindowsAnsiEventHandler) ED(param int) error { func (h *windowsAnsiEventHandler) ED(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -485,7 +486,7 @@ func (h *WindowsAnsiEventHandler) ED(param int) error {
return nil return nil
} }
func (h *WindowsAnsiEventHandler) EL(param int) error { func (h *windowsAnsiEventHandler) EL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -526,7 +527,7 @@ func (h *WindowsAnsiEventHandler) EL(param int) error {
return nil return nil
} }
func (h *WindowsAnsiEventHandler) IL(param int) error { func (h *windowsAnsiEventHandler) IL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -535,7 +536,7 @@ func (h *WindowsAnsiEventHandler) IL(param int) error {
return h.insertLines(param) return h.insertLines(param)
} }
func (h *WindowsAnsiEventHandler) DL(param int) error { func (h *windowsAnsiEventHandler) DL(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -544,7 +545,7 @@ func (h *WindowsAnsiEventHandler) DL(param int) error {
return h.deleteLines(param) return h.deleteLines(param)
} }
func (h *WindowsAnsiEventHandler) ICH(param int) error { func (h *windowsAnsiEventHandler) ICH(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -553,7 +554,7 @@ func (h *WindowsAnsiEventHandler) ICH(param int) error {
return h.insertCharacters(param) return h.insertCharacters(param)
} }
func (h *WindowsAnsiEventHandler) DCH(param int) error { func (h *windowsAnsiEventHandler) DCH(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -562,7 +563,7 @@ func (h *WindowsAnsiEventHandler) DCH(param int) error {
return h.deleteCharacters(param) return h.deleteCharacters(param)
} }
func (h *WindowsAnsiEventHandler) SGR(params []int) error { func (h *windowsAnsiEventHandler) SGR(params []int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -579,13 +580,13 @@ func (h *WindowsAnsiEventHandler) SGR(params []int) error {
} else { } else {
for _, attr := range params { for _, attr := range params {
if attr == ANSI_SGR_RESET { if attr == ansiterm.ANSI_SGR_RESET {
h.attributes = h.infoReset.Attributes h.attributes = h.infoReset.Attributes
h.inverted = false h.inverted = false
continue continue
} }
h.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, SHORT(attr)) h.attributes, h.inverted = collectAnsiIntoWindowsAttributes(h.attributes, h.inverted, h.infoReset.Attributes, int16(attr))
} }
} }
@ -601,7 +602,7 @@ func (h *WindowsAnsiEventHandler) SGR(params []int) error {
return nil return nil
} }
func (h *WindowsAnsiEventHandler) SU(param int) error { func (h *windowsAnsiEventHandler) SU(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -610,7 +611,7 @@ func (h *WindowsAnsiEventHandler) SU(param int) error {
return h.scrollUp(param) return h.scrollUp(param)
} }
func (h *WindowsAnsiEventHandler) SD(param int) error { func (h *windowsAnsiEventHandler) SD(param int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -619,29 +620,29 @@ func (h *WindowsAnsiEventHandler) SD(param int) error {
return h.scrollDown(param) return h.scrollDown(param)
} }
func (h *WindowsAnsiEventHandler) DA(params []string) error { func (h *windowsAnsiEventHandler) DA(params []string) error {
logger.Infof("DA: [%v]", params) logger.Infof("DA: [%v]", params)
// DA cannot be implemented because it must send data on the VT100 input stream, // DA cannot be implemented because it must send data on the VT100 input stream,
// which is not available to go-ansiterm. // which is not available to go-ansiterm.
return nil return nil
} }
func (h *WindowsAnsiEventHandler) DECSTBM(top int, bottom int) error { func (h *windowsAnsiEventHandler) DECSTBM(top int, bottom int) error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
logger.Infof("DECSTBM: [%d, %d]", top, bottom) logger.Infof("DECSTBM: [%d, %d]", top, bottom)
// Windows is 0 indexed, Linux is 1 indexed // Windows is 0 indexed, Linux is 1 indexed
h.sr.top = SHORT(top - 1) h.sr.top = int16(top - 1)
h.sr.bottom = SHORT(bottom - 1) h.sr.bottom = int16(bottom - 1)
// This command also moves the cursor to the origin. // This command also moves the cursor to the origin.
h.clearWrap() h.clearWrap()
return h.CUP(1, 1) return h.CUP(1, 1)
} }
func (h *WindowsAnsiEventHandler) RI() error { func (h *windowsAnsiEventHandler) RI() error {
if err := h.Flush(); err != nil { if err := h.Flush(); err != nil {
return err return err
} }
@ -656,17 +657,17 @@ func (h *WindowsAnsiEventHandler) RI() error {
sr := h.effectiveSr(info.Window) sr := h.effectiveSr(info.Window)
if info.CursorPosition.Y == sr.top { if info.CursorPosition.Y == sr.top {
return h.scrollDown(1) return h.scrollDown(1)
} else {
return h.moveCursorVertical(-1)
} }
return h.moveCursorVertical(-1)
} }
func (h *WindowsAnsiEventHandler) IND() error { func (h *windowsAnsiEventHandler) IND() error {
logger.Info("IND: []") logger.Info("IND: []")
return h.executeLF() return h.executeLF()
} }
func (h *WindowsAnsiEventHandler) Flush() error { func (h *windowsAnsiEventHandler) Flush() error {
h.curInfo = nil h.curInfo = nil
if h.buffer.Len() > 0 { if h.buffer.Len() > 0 {
logger.Infof("Flush: [%s]", h.buffer.Bytes()) logger.Infof("Flush: [%s]", h.buffer.Bytes())
@ -683,7 +684,7 @@ func (h *WindowsAnsiEventHandler) Flush() error {
return err return err
} }
charInfo := []CHAR_INFO{{UnicodeChar: WCHAR(h.marginByte), Attributes: info.Attributes}} charInfo := []CHAR_INFO{{UnicodeChar: uint16(h.marginByte), Attributes: info.Attributes}}
size := COORD{1, 1} size := COORD{1, 1}
position := COORD{0, 0} position := COORD{0, 0}
region := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y} region := SMALL_RECT{Left: info.CursorPosition.X, Top: info.CursorPosition.Y, Right: info.CursorPosition.X, Bottom: info.CursorPosition.Y}
@ -697,7 +698,7 @@ func (h *WindowsAnsiEventHandler) Flush() error {
// cacheConsoleInfo ensures that the current console screen information has been queried // cacheConsoleInfo ensures that the current console screen information has been queried
// since the last call to Flush(). It must be called before accessing h.curInfo or h.curPos. // since the last call to Flush(). It must be called before accessing h.curInfo or h.curPos.
func (h *WindowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) { func (h *windowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFER_INFO, error) {
if h.curInfo == nil { if h.curInfo == nil {
info, err := GetConsoleScreenBufferInfo(h.fd) info, err := GetConsoleScreenBufferInfo(h.fd)
if err != nil { if err != nil {
@ -709,7 +710,7 @@ func (h *WindowsAnsiEventHandler) getCurrentInfo() (COORD, *CONSOLE_SCREEN_BUFFE
return h.curPos, h.curInfo, nil return h.curPos, h.curInfo, nil
} }
func (h *WindowsAnsiEventHandler) updatePos(pos COORD) { func (h *windowsAnsiEventHandler) updatePos(pos COORD) {
if h.curInfo == nil { if h.curInfo == nil {
panic("failed to call getCurrentInfo before calling updatePos") panic("failed to call getCurrentInfo before calling updatePos")
} }
@ -719,7 +720,7 @@ func (h *WindowsAnsiEventHandler) updatePos(pos COORD) {
// clearWrap clears the state where the cursor is in the margin // clearWrap clears the state where the cursor is in the margin
// waiting for the next character before wrapping the line. This must // waiting for the next character before wrapping the line. This must
// be done before most operations that act on the cursor. // be done before most operations that act on the cursor.
func (h *WindowsAnsiEventHandler) clearWrap() { func (h *windowsAnsiEventHandler) clearWrap() {
h.wrapNext = false h.wrapNext = false
h.drewMarginByte = false h.drewMarginByte = false
} }

0
libnetwork/Godeps/_workspace/src/github.com/armon/go-metrics/.gitignore generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/github.com/armon/go-metrics/metrics.go generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/github.com/armon/go-metrics/sink.go generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/github.com/armon/go-metrics/start.go generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/github.com/armon/go-metrics/statsite.go generated vendored Normal file → Executable file
View file

View file

@ -21,6 +21,7 @@ var (
ErrClosed = errors.New("write to closed BytesPipe") ErrClosed = errors.New("write to closed BytesPipe")
bufPools = make(map[int]*sync.Pool) bufPools = make(map[int]*sync.Pool)
bufPoolsLock sync.Mutex
) )
// BytesPipe is io.ReadWriteCloser which works similarly to pipe(queue). // BytesPipe is io.ReadWriteCloser which works similarly to pipe(queue).
@ -164,17 +165,21 @@ func (bp *BytesPipe) Read(p []byte) (n int, err error) {
func returnBuffer(b *fixedBuffer) { func returnBuffer(b *fixedBuffer) {
b.Reset() b.Reset()
bufPoolsLock.Lock()
pool := bufPools[b.Cap()] pool := bufPools[b.Cap()]
bufPoolsLock.Unlock()
if pool != nil { if pool != nil {
pool.Put(b) pool.Put(b)
} }
} }
func getBuffer(size int) *fixedBuffer { func getBuffer(size int) *fixedBuffer {
bufPoolsLock.Lock()
pool, ok := bufPools[size] pool, ok := bufPools[size]
if !ok { if !ok {
pool = &sync.Pool{New: func() interface{} { return &fixedBuffer{buf: make([]byte, 0, size)} }} pool = &sync.Pool{New: func() interface{} { return &fixedBuffer{buf: make([]byte, 0, size)} }}
bufPools[size] = pool bufPools[size] = pool
} }
bufPoolsLock.Unlock()
return pool.Get().(*fixedBuffer) return pool.Get().(*fixedBuffer)
} }

View file

@ -0,0 +1,75 @@
package ioutils
import (
"io"
"io/ioutil"
"os"
"path/filepath"
)
// NewAtomicFileWriter returns WriteCloser so that writing to it writes to a
// temporary file and closing it atomically changes the temporary file to
// destination path. Writing and closing concurrently is not allowed.
func NewAtomicFileWriter(filename string, perm os.FileMode) (io.WriteCloser, error) {
f, err := ioutil.TempFile(filepath.Dir(filename), ".tmp-"+filepath.Base(filename))
if err != nil {
return nil, err
}
abspath, err := filepath.Abs(filename)
if err != nil {
return nil, err
}
return &atomicFileWriter{
f: f,
fn: abspath,
}, nil
}
// AtomicWriteFile atomically writes data to a file named by filename.
func AtomicWriteFile(filename string, data []byte, perm os.FileMode) error {
f, err := NewAtomicFileWriter(filename, perm)
if err != nil {
return err
}
n, err := f.Write(data)
if err == nil && n < len(data) {
err = io.ErrShortWrite
}
if err1 := f.Close(); err == nil {
err = err1
}
return err
}
type atomicFileWriter struct {
f *os.File
fn string
writeErr error
}
func (w *atomicFileWriter) Write(dt []byte) (int, error) {
n, err := w.f.Write(dt)
if err != nil {
w.writeErr = err
}
return n, err
}
func (w *atomicFileWriter) Close() (retErr error) {
defer func() {
if retErr != nil {
os.Remove(w.f.Name())
}
}()
if err := w.f.Sync(); err != nil {
w.f.Close()
return err
}
if err := w.f.Close(); err != nil {
return err
}
if w.writeErr == nil {
return os.Rename(w.f.Name(), w.fn)
}
return nil
}

View file

@ -1,4 +1,4 @@
// +build !linux,!freebsd freebsd,!cgo // +build !linux,!freebsd freebsd,!cgo solaris,!cgo
package mount package mount

View file

@ -9,8 +9,8 @@ func GetMounts() ([]*Info, error) {
return parseMountTable() return parseMountTable()
} }
// Mounted looks at /proc/self/mountinfo to determine of the specified // Mounted determines if a specified mountpoint has been mounted.
// mountpoint has been mounted // On Linux it looks at /proc/self/mountinfo and on Solaris at mnttab.
func Mounted(mountpoint string) (bool, error) { func Mounted(mountpoint string) (bool, error) {
entries, err := parseMountTable() entries, err := parseMountTable()
if err != nil { if err != nil {

View file

@ -0,0 +1,33 @@
// +build solaris,cgo
package mount
import (
"golang.org/x/sys/unix"
"unsafe"
)
// #include <stdlib.h>
// #include <stdio.h>
// #include <sys/mount.h>
// int Mount(const char *spec, const char *dir, int mflag,
// char *fstype, char *dataptr, int datalen, char *optptr, int optlen) {
// return mount(spec, dir, mflag, fstype, dataptr, datalen, optptr, optlen);
// }
import "C"
func mount(device, target, mType string, flag uintptr, data string) error {
spec := C.CString(device)
dir := C.CString(target)
fstype := C.CString(mType)
_, err := C.Mount(spec, dir, C.int(flag), fstype, nil, 0, nil, 0)
C.free(unsafe.Pointer(spec))
C.free(unsafe.Pointer(dir))
C.free(unsafe.Pointer(fstype))
return err
}
func unmount(target string, flag int) error {
err := unix.Unmount(target, flag)
return err
}

View file

@ -1,4 +1,4 @@
// +build !linux,!freebsd freebsd,!cgo // +build !linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
package mount package mount

View file

@ -0,0 +1,37 @@
// +build solaris,cgo
package mount
/*
#include <stdio.h>
#include <sys/mnttab.h>
*/
import "C"
import (
"fmt"
)
func parseMountTable() ([]*Info, error) {
mnttab := C.fopen(C.CString(C.MNTTAB), C.CString("r"))
if mnttab == nil {
return nil, fmt.Errorf("Failed to open %s", C.MNTTAB)
}
var out []*Info
var mp C.struct_mnttab
ret := C.getmntent(mnttab, &mp)
for ret == 0 {
var mountinfo Info
mountinfo.Mountpoint = C.GoString(mp.mnt_mountp)
mountinfo.Source = C.GoString(mp.mnt_special)
mountinfo.Fstype = C.GoString(mp.mnt_fstype)
mountinfo.Opts = C.GoString(mp.mnt_mntopts)
out = append(out, &mountinfo)
ret = C.getmntent(mnttab, &mp)
}
C.fclose(mnttab)
return out, nil
}

View file

@ -1,4 +1,4 @@
// +build !windows,!linux,!freebsd freebsd,!cgo // +build !windows,!linux,!freebsd,!solaris freebsd,!cgo solaris,!cgo
package mount package mount

View file

@ -0,0 +1,14 @@
package kernel
import (
"golang.org/x/sys/unix"
)
func uname() (*unix.Utsname, error) {
uts := &unix.Utsname{}
if err := unix.Uname(uts); err != nil {
return nil, err
}
return uts, nil
}

View file

@ -1,4 +1,4 @@
// +build !linux // +build !linux,!solaris
package kernel package kernel

View file

@ -1,4 +1,4 @@
// +build freebsd // +build freebsd solaris
package reexec package reexec

View file

@ -1,4 +1,4 @@
// +build !linux,!windows,!freebsd // +build !linux,!windows,!freebsd,!solaris
package reexec package reexec

View file

@ -0,0 +1,42 @@
package signal
import (
"syscall"
)
// SignalMap is a map of Solaris signals.
// SIGINFO and SIGTHR not defined for Solaris
var SignalMap = map[string]syscall.Signal{
"ABRT": syscall.SIGABRT,
"ALRM": syscall.SIGALRM,
"BUF": syscall.SIGBUS,
"CHLD": syscall.SIGCHLD,
"CONT": syscall.SIGCONT,
"EMT": syscall.SIGEMT,
"FPE": syscall.SIGFPE,
"HUP": syscall.SIGHUP,
"ILL": syscall.SIGILL,
"INT": syscall.SIGINT,
"IO": syscall.SIGIO,
"IOT": syscall.SIGIOT,
"KILL": syscall.SIGKILL,
"LWP": syscall.SIGLWP,
"PIPE": syscall.SIGPIPE,
"PROF": syscall.SIGPROF,
"QUIT": syscall.SIGQUIT,
"SEGV": syscall.SIGSEGV,
"STOP": syscall.SIGSTOP,
"SYS": syscall.SIGSYS,
"TERM": syscall.SIGTERM,
"TRAP": syscall.SIGTRAP,
"TSTP": syscall.SIGTSTP,
"TTIN": syscall.SIGTTIN,
"TTOU": syscall.SIGTTOU,
"URG": syscall.SIGURG,
"USR1": syscall.SIGUSR1,
"USR2": syscall.SIGUSR2,
"VTALRM": syscall.SIGVTALRM,
"WINCH": syscall.SIGWINCH,
"XCPU": syscall.SIGXCPU,
"XFSZ": syscall.SIGXFSZ,
}

View file

@ -1,4 +1,4 @@
// +build !linux,!darwin,!freebsd,!windows // +build !linux,!darwin,!freebsd,!windows,!solaris
package signal package signal

View file

@ -0,0 +1,128 @@
// +build solaris,cgo
package system
import (
"fmt"
"unsafe"
)
// #cgo LDFLAGS: -lkstat
// #include <unistd.h>
// #include <stdlib.h>
// #include <stdio.h>
// #include <kstat.h>
// #include <sys/swap.h>
// #include <sys/param.h>
// struct swaptable *allocSwaptable(int num) {
// struct swaptable *st;
// struct swapent *swapent;
// st = (struct swaptable *)malloc(num * sizeof(swapent_t) + sizeof (int));
// swapent = st->swt_ent;
// for (int i = 0; i < num; i++,swapent++) {
// swapent->ste_path = (char *)malloc(MAXPATHLEN * sizeof (char));
// }
// st->swt_n = num;
// return st;
//}
// void freeSwaptable (struct swaptable *st) {
// struct swapent *swapent = st->swt_ent;
// for (int i = 0; i < st->swt_n; i++,swapent++) {
// free(swapent->ste_path);
// }
// free(st);
// }
// swapent_t getSwapEnt(swapent_t *ent, int i) {
// return ent[i];
// }
// int64_t getPpKernel() {
// int64_t pp_kernel = 0;
// kstat_ctl_t *ksc;
// kstat_t *ks;
// kstat_named_t *knp;
// kid_t kid;
//
// if ((ksc = kstat_open()) == NULL) {
// return -1;
// }
// if ((ks = kstat_lookup(ksc, "unix", 0, "system_pages")) == NULL) {
// return -1;
// }
// if (((kid = kstat_read(ksc, ks, NULL)) == -1) ||
// ((knp = kstat_data_lookup(ks, "pp_kernel")) == NULL)) {
// return -1;
// }
// switch (knp->data_type) {
// case KSTAT_DATA_UINT64:
// pp_kernel = knp->value.ui64;
// break;
// case KSTAT_DATA_UINT32:
// pp_kernel = knp->value.ui32;
// break;
// }
// pp_kernel *= sysconf(_SC_PAGESIZE);
// return (pp_kernel > 0 ? pp_kernel : -1);
// }
import "C"
// Get the system memory info using sysconf same as prtconf
func getTotalMem() int64 {
pagesize := C.sysconf(C._SC_PAGESIZE)
npages := C.sysconf(C._SC_PHYS_PAGES)
return int64(pagesize * npages)
}
func getFreeMem() int64 {
pagesize := C.sysconf(C._SC_PAGESIZE)
npages := C.sysconf(C._SC_AVPHYS_PAGES)
return int64(pagesize * npages)
}
// ReadMemInfo retrieves memory statistics of the host system and returns a
// MemInfo type.
func ReadMemInfo() (*MemInfo, error) {
ppKernel := C.getPpKernel()
MemTotal := getTotalMem()
MemFree := getFreeMem()
SwapTotal, SwapFree, err := getSysSwap()
if ppKernel < 0 || MemTotal < 0 || MemFree < 0 || SwapTotal < 0 ||
SwapFree < 0 {
return nil, fmt.Errorf("Error getting system memory info %v\n", err)
}
meminfo := &MemInfo{}
// Total memory is total physical memory less than memory locked by kernel
meminfo.MemTotal = MemTotal - int64(ppKernel)
meminfo.MemFree = MemFree
meminfo.SwapTotal = SwapTotal
meminfo.SwapFree = SwapFree
return meminfo, nil
}
func getSysSwap() (int64, int64, error) {
var tSwap int64
var fSwap int64
var diskblksPerPage int64
num, err := C.swapctl(C.SC_GETNSWP, nil)
if err != nil {
return -1, -1, err
}
st := C.allocSwaptable(num)
_, err = C.swapctl(C.SC_LIST, unsafe.Pointer(st))
if err != nil {
C.freeSwaptable(st)
return -1, -1, err
}
diskblksPerPage = int64(C.sysconf(C._SC_PAGESIZE) >> C.DEV_BSHIFT)
for i := 0; i < int(num); i++ {
swapent := C.getSwapEnt(&st.swt_ent[0], C.int(i))
tSwap += int64(swapent.ste_pages) * diskblksPerPage
fSwap += int64(swapent.ste_free) * diskblksPerPage
}
C.freeSwaptable(st)
return tSwap, fSwap, nil
}

View file

@ -1,4 +1,4 @@
// +build !linux,!windows // +build !linux,!windows,!solaris
package system package system

View file

@ -6,3 +6,9 @@ package system
// executables. Each directory is separated from the next by a colon // executables. Each directory is separated from the next by a colon
// ':' character . // ':' character .
const DefaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" const DefaultPathEnv = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
// CheckSystemDriveAndRemoveDriveLetter verifies that a path, if it includes a drive letter,
// is the system drive. This is a no-op on Linux.
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
return path, nil
}

View file

@ -2,6 +2,36 @@
package system package system
import (
"fmt"
"path/filepath"
"strings"
)
// DefaultPathEnv is deliberately empty on Windows as the default path will be set by // DefaultPathEnv is deliberately empty on Windows as the default path will be set by
// the container. Docker has no context of what the default path should be. // the container. Docker has no context of what the default path should be.
const DefaultPathEnv = "" const DefaultPathEnv = ""
// CheckSystemDriveAndRemoveDriveLetter verifies and manipulates a Windows path.
// This is used, for example, when validating a user provided path in docker cp.
// If a drive letter is supplied, it must be the system drive. The drive letter
// is always removed. Also, it translates it to OS semantics (IOW / to \). We
// need the path in this syntax so that it can ultimately be contatenated with
// a Windows long-path which doesn't support drive-letters. Examples:
// C: --> Fail
// C:\ --> \
// a --> a
// /a --> \a
// d:\ --> Fail
func CheckSystemDriveAndRemoveDriveLetter(path string) (string, error) {
if len(path) == 2 && string(path[1]) == ":" {
return "", fmt.Errorf("No relative path specified in %q", path)
}
if !filepath.IsAbs(path) || len(path) < 2 {
return filepath.FromSlash(path), nil
}
if string(path[1]) == ":" && !strings.EqualFold(string(path[0]), "c") {
return "", fmt.Errorf("The specified path is not on the system drive (C:)")
}
return filepath.FromSlash(path[2:]), nil
}

View file

@ -15,3 +15,20 @@ func fromStatT(s *syscall.Stat_t) (*StatT, error) {
rdev: uint64(s.Rdev), rdev: uint64(s.Rdev),
mtim: s.Mtim}, nil mtim: s.Mtim}, nil
} }
// FromStatT loads a system.StatT from a syscal.Stat_t.
func FromStatT(s *syscall.Stat_t) (*StatT, error) {
return fromStatT(s)
}
// Stat takes a path to a file and returns
// a system.StatT type pertaining to that file.
//
// Throws an error if the file does not exist
func Stat(path string) (*StatT, error) {
s := &syscall.Stat_t{}
if err := syscall.Stat(path, s); err != nil {
return nil, err
}
return fromStatT(s)
}

View file

@ -3,10 +3,13 @@ package system
import ( import (
"syscall" "syscall"
"unsafe" "unsafe"
"github.com/Sirupsen/logrus"
) )
var ( var (
ntuserApiset = syscall.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0") ntuserApiset = syscall.NewLazyDLL("ext-ms-win-ntuser-window-l1-1-0")
procGetVersionExW = modkernel32.NewProc("GetVersionExW")
) )
// OSVersion is a wrapper for Windows version information // OSVersion is a wrapper for Windows version information
@ -18,6 +21,21 @@ type OSVersion struct {
Build uint16 Build uint16
} }
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms724833(v=vs.85).aspx
type osVersionInfoEx struct {
OSVersionInfoSize uint32
MajorVersion uint32
MinorVersion uint32
BuildNumber uint32
PlatformID uint32
CSDVersion [128]uint16
ServicePackMajor uint16
ServicePackMinor uint16
SuiteMask uint16
ProductType byte
Reserve byte
}
// GetOSVersion gets the operating system version on Windows. Note that // GetOSVersion gets the operating system version on Windows. Note that
// docker.exe must be manifested to get the correct version information. // docker.exe must be manifested to get the correct version information.
func GetOSVersion() OSVersion { func GetOSVersion() OSVersion {
@ -34,6 +52,18 @@ func GetOSVersion() OSVersion {
return osv return osv
} }
// IsWindowsClient returns true if the SKU is client
func IsWindowsClient() bool {
osviex := &osVersionInfoEx{OSVersionInfoSize: 284}
r1, _, err := procGetVersionExW.Call(uintptr(unsafe.Pointer(osviex)))
if r1 == 0 {
logrus.Warnf("GetVersionExW failed - assuming server SKU: %v", err)
return false
}
const verNTWorkstation = 0x00000001
return osviex.ProductType == verNTWorkstation
}
// Unmount is a platform-specific helper function to call // Unmount is a platform-specific helper function to call
// the unmount syscall. Not supported on Windows // the unmount syscall. Not supported on Windows
func Unmount(dest string) error { func Unmount(dest string) error {

View file

@ -83,11 +83,13 @@ func useNativeConsole() bool {
return false return false
} }
// TODO Windows. The native emulator still has issues which // Must have a post-TP5 RS1 build of Windows Server 2016/Windows 10 for
// mean it shouldn't be enabled for everyone. Change this next line to true // the native console to be usable.
// to change the default to "enable if available". In the meantime, users if osv.Build < 14350 {
// can still try it out by using USE_NATIVE_CONSOLE env variable.
return false return false
}
return true
} }
// getNativeConsole returns the console modes ('state') for the native Windows console // getNativeConsole returns the console modes ('state') for the native Windows console

View file

@ -136,14 +136,14 @@ func readInputEvents(fd uintptr, maxBytes int) ([]winterm.INPUT_RECORD, error) {
// KeyEvent Translation Helpers // KeyEvent Translation Helpers
var arrowKeyMapPrefix = map[winterm.WORD]string{ var arrowKeyMapPrefix = map[uint16]string{
winterm.VK_UP: "%s%sA", winterm.VK_UP: "%s%sA",
winterm.VK_DOWN: "%s%sB", winterm.VK_DOWN: "%s%sB",
winterm.VK_RIGHT: "%s%sC", winterm.VK_RIGHT: "%s%sC",
winterm.VK_LEFT: "%s%sD", winterm.VK_LEFT: "%s%sD",
} }
var keyMapPrefix = map[winterm.WORD]string{ var keyMapPrefix = map[uint16]string{
winterm.VK_UP: "\x1B[%sA", winterm.VK_UP: "\x1B[%sA",
winterm.VK_DOWN: "\x1B[%sB", winterm.VK_DOWN: "\x1B[%sB",
winterm.VK_RIGHT: "\x1B[%sC", winterm.VK_RIGHT: "\x1B[%sC",
@ -207,7 +207,7 @@ func keyToString(keyEvent *winterm.KEY_EVENT_RECORD, escapeSequence []byte) stri
} }
// formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string. // formatVirtualKey converts a virtual key (e.g., up arrow) into the appropriate ANSI string.
func formatVirtualKey(key winterm.WORD, controlState winterm.DWORD, escapeSequence []byte) string { func formatVirtualKey(key uint16, controlState uint32, escapeSequence []byte) string {
shift, alt, control := getControlKeys(controlState) shift, alt, control := getControlKeys(controlState)
modifier := getControlKeysModifier(shift, alt, control) modifier := getControlKeysModifier(shift, alt, control)
@ -223,7 +223,7 @@ func formatVirtualKey(key winterm.WORD, controlState winterm.DWORD, escapeSequen
} }
// getControlKeys extracts the shift, alt, and ctrl key states. // getControlKeys extracts the shift, alt, and ctrl key states.
func getControlKeys(controlState winterm.DWORD) (shift, alt, control bool) { func getControlKeys(controlState uint32) (shift, alt, control bool) {
shift = 0 != (controlState & winterm.SHIFT_PRESSED) shift = 0 != (controlState & winterm.SHIFT_PRESSED)
alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED)) alt = 0 != (controlState & (winterm.LEFT_ALT_PRESSED | winterm.RIGHT_ALT_PRESSED))
control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED)) control = 0 != (controlState & (winterm.LEFT_CTRL_PRESSED | winterm.RIGHT_CTRL_PRESSED))

View file

@ -1,307 +0,0 @@
// Package filters provides helper function to parse and handle command line
// filter, used for example in docker ps or docker images commands.
package filters
import (
"encoding/json"
"errors"
"fmt"
"regexp"
"strings"
"github.com/docker/engine-api/types/versions"
)
// Args stores filter arguments as map key:{map key: bool}.
// It contains an aggregation of the map of arguments (which are in the form
// of -f 'key=value') based on the key, and stores values for the same key
// in a map with string keys and boolean values.
// e.g given -f 'label=label1=1' -f 'label=label2=2' -f 'image.name=ubuntu'
// the args will be {"image.name":{"ubuntu":true},"label":{"label1=1":true,"label2=2":true}}
type Args struct {
fields map[string]map[string]bool
}
// NewArgs initializes a new Args struct.
func NewArgs() Args {
return Args{fields: map[string]map[string]bool{}}
}
// ParseFlag parses the argument to the filter flag. Like
//
// `docker ps -f 'created=today' -f 'image.name=ubuntu*'`
//
// If prev map is provided, then it is appended to, and returned. By default a new
// map is created.
func ParseFlag(arg string, prev Args) (Args, error) {
filters := prev
if len(arg) == 0 {
return filters, nil
}
if !strings.Contains(arg, "=") {
return filters, ErrBadFormat
}
f := strings.SplitN(arg, "=", 2)
name := strings.ToLower(strings.TrimSpace(f[0]))
value := strings.TrimSpace(f[1])
filters.Add(name, value)
return filters, nil
}
// ErrBadFormat is an error returned in case of bad format for a filter.
var ErrBadFormat = errors.New("bad format of filter (expected name=value)")
// ToParam packs the Args into a string for easy transport from client to server.
func ToParam(a Args) (string, error) {
// this way we don't URL encode {}, just empty space
if a.Len() == 0 {
return "", nil
}
buf, err := json.Marshal(a.fields)
if err != nil {
return "", err
}
return string(buf), nil
}
// ToParamWithVersion packs the Args into a string for easy transport from client to server.
// The generated string will depend on the specified version (corresponding to the API version).
func ToParamWithVersion(version string, a Args) (string, error) {
// this way we don't URL encode {}, just empty space
if a.Len() == 0 {
return "", nil
}
// for daemons older than v1.10, filter must be of the form map[string][]string
buf := []byte{}
err := errors.New("")
if version != "" && versions.LessThan(version, "1.22") {
buf, err = json.Marshal(convertArgsToSlice(a.fields))
} else {
buf, err = json.Marshal(a.fields)
}
if err != nil {
return "", err
}
return string(buf), nil
}
// FromParam unpacks the filter Args.
func FromParam(p string) (Args, error) {
if len(p) == 0 {
return NewArgs(), nil
}
r := strings.NewReader(p)
d := json.NewDecoder(r)
m := map[string]map[string]bool{}
if err := d.Decode(&m); err != nil {
r.Seek(0, 0)
// Allow parsing old arguments in slice format.
// Because other libraries might be sending them in this format.
deprecated := map[string][]string{}
if deprecatedErr := d.Decode(&deprecated); deprecatedErr == nil {
m = deprecatedArgs(deprecated)
} else {
return NewArgs(), err
}
}
return Args{m}, nil
}
// Get returns the list of values associates with a field.
// It returns a slice of strings to keep backwards compatibility with old code.
func (filters Args) Get(field string) []string {
values := filters.fields[field]
if values == nil {
return make([]string, 0)
}
slice := make([]string, 0, len(values))
for key := range values {
slice = append(slice, key)
}
return slice
}
// Add adds a new value to a filter field.
func (filters Args) Add(name, value string) {
if _, ok := filters.fields[name]; ok {
filters.fields[name][value] = true
} else {
filters.fields[name] = map[string]bool{value: true}
}
}
// Del removes a value from a filter field.
func (filters Args) Del(name, value string) {
if _, ok := filters.fields[name]; ok {
delete(filters.fields[name], value)
}
}
// Len returns the number of fields in the arguments.
func (filters Args) Len() int {
return len(filters.fields)
}
// MatchKVList returns true if the values for the specified field matches the ones
// from the sources.
// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}},
// field is 'label' and sources are {'label1': '1', 'label2': '2'}
// it returns true.
func (filters Args) MatchKVList(field string, sources map[string]string) bool {
fieldValues := filters.fields[field]
//do not filter if there is no filter set or cannot determine filter
if len(fieldValues) == 0 {
return true
}
if sources == nil || len(sources) == 0 {
return false
}
for name2match := range fieldValues {
testKV := strings.SplitN(name2match, "=", 2)
v, ok := sources[testKV[0]]
if !ok {
return false
}
if len(testKV) == 2 && testKV[1] != v {
return false
}
}
return true
}
// Match returns true if the values for the specified field matches the source string
// e.g. given Args are {'label': {'label1=1','label2=1'}, 'image.name', {'ubuntu'}},
// field is 'image.name' and source is 'ubuntu'
// it returns true.
func (filters Args) Match(field, source string) bool {
if filters.ExactMatch(field, source) {
return true
}
fieldValues := filters.fields[field]
for name2match := range fieldValues {
match, err := regexp.MatchString(name2match, source)
if err != nil {
continue
}
if match {
return true
}
}
return false
}
// ExactMatch returns true if the source matches exactly one of the filters.
func (filters Args) ExactMatch(field, source string) bool {
fieldValues, ok := filters.fields[field]
//do not filter if there is no filter set or cannot determine filter
if !ok || len(fieldValues) == 0 {
return true
}
// try to match full name value to avoid O(N) regular expression matching
return fieldValues[source]
}
// UniqueExactMatch returns true if there is only one filter and the source matches exactly this one.
func (filters Args) UniqueExactMatch(field, source string) bool {
fieldValues := filters.fields[field]
//do not filter if there is no filter set or cannot determine filter
if len(fieldValues) == 0 {
return true
}
if len(filters.fields[field]) != 1 {
return false
}
// try to match full name value to avoid O(N) regular expression matching
return fieldValues[source]
}
// FuzzyMatch returns true if the source matches exactly one of the filters,
// or the source has one of the filters as a prefix.
func (filters Args) FuzzyMatch(field, source string) bool {
if filters.ExactMatch(field, source) {
return true
}
fieldValues := filters.fields[field]
for prefix := range fieldValues {
if strings.HasPrefix(source, prefix) {
return true
}
}
return false
}
// Include returns true if the name of the field to filter is in the filters.
func (filters Args) Include(field string) bool {
_, ok := filters.fields[field]
return ok
}
// Validate ensures that all the fields in the filter are valid.
// It returns an error as soon as it finds an invalid field.
func (filters Args) Validate(accepted map[string]bool) error {
for name := range filters.fields {
if !accepted[name] {
return fmt.Errorf("Invalid filter '%s'", name)
}
}
return nil
}
// WalkValues iterates over the list of filtered values for a field.
// It stops the iteration if it finds an error and it returns that error.
func (filters Args) WalkValues(field string, op func(value string) error) error {
if _, ok := filters.fields[field]; !ok {
return nil
}
for v := range filters.fields[field] {
if err := op(v); err != nil {
return err
}
}
return nil
}
func deprecatedArgs(d map[string][]string) map[string]map[string]bool {
m := map[string]map[string]bool{}
for k, v := range d {
values := map[string]bool{}
for _, vv := range v {
values[vv] = true
}
m[k] = values
}
return m
}
func convertArgsToSlice(f map[string]map[string]bool) map[string][]string {
m := map[string][]string{}
for k, v := range f {
values := []string{}
for kk := range v {
if v[kk] {
values = append(values, kk)
}
}
m[k] = values
}
return m
}

View file

@ -1,14 +0,0 @@
## Legacy API type versions
This package includes types for legacy API versions. The stable version of the API types live in `api/types/*.go`.
Consider moving a type here when you need to keep backwards compatibility in the API. This legacy types are organized by the latest API version they appear in. For instance, types in the `v1p19` package are valid for API versions below or equal `1.19`. Types in the `v1p20` package are valid for the API version `1.20`, since the versions below that will use the legacy types in `v1p19`.
### Package name conventions
The package name convention is to use `v` as a prefix for the version number and `p`(patch) as a separator. We use this nomenclature due to a few restrictions in the Go package name convention:
1. We cannot use `.` because it's interpreted by the language, think of `v1.20.CallFunction`.
2. We cannot use `_` because golint complains about it. The code is actually valid, but it looks probably more weird: `v1_20.CallFunction`.
For instance, if you want to modify a type that was available in the version `1.21` of the API but it will have different fields in the version `1.22`, you want to create a new package under `api/types/versions/v1p21`.

View file

@ -1,62 +0,0 @@
package versions
import (
"strconv"
"strings"
)
// compare compares two version strings
// returns -1 if v1 < v2, 1 if v1 > v2, 0 otherwise.
func compare(v1, v2 string) int {
var (
currTab = strings.Split(v1, ".")
otherTab = strings.Split(v2, ".")
)
max := len(currTab)
if len(otherTab) > max {
max = len(otherTab)
}
for i := 0; i < max; i++ {
var currInt, otherInt int
if len(currTab) > i {
currInt, _ = strconv.Atoi(currTab[i])
}
if len(otherTab) > i {
otherInt, _ = strconv.Atoi(otherTab[i])
}
if currInt > otherInt {
return 1
}
if otherInt > currInt {
return -1
}
}
return 0
}
// LessThan checks if a version is less than another
func LessThan(v, other string) bool {
return compare(v, other) == -1
}
// LessThanOrEqualTo checks if a version is less than or equal to another
func LessThanOrEqualTo(v, other string) bool {
return compare(v, other) <= 0
}
// GreaterThan checks if a version is greater than another
func GreaterThan(v, other string) bool {
return compare(v, other) == 1
}
// GreaterThanOrEqualTo checks if a version is greater than or equal to another
func GreaterThanOrEqualTo(v, other string) bool {
return compare(v, other) >= 0
}
// Equal checks if a version is equal to another
func Equal(v, other string) bool {
return compare(v, other) == 0
}

View file

View file

@ -1,8 +0,0 @@
language: go
go:
- tip
before_install:
- go get github.com/mattn/goveralls
- go get golang.org/x/tools/cmd/cover
script:
- $HOME/gopath/bin/goveralls -repotoken 2FMhp57u8LcstKL9B190fLTcEnBtAAiEL

View file

@ -1,47 +0,0 @@
# go-shellwords
[![Coverage Status](https://coveralls.io/repos/mattn/go-shellwords/badge.png?branch=master)](https://coveralls.io/r/mattn/go-shellwords?branch=master)
[![Build Status](https://travis-ci.org/mattn/go-shellwords.svg?branch=master)](https://travis-ci.org/mattn/go-shellwords)
Parse line as shell words.
## Usage
```go
args, err := shellwords.Parse("./foo --bar=baz")
// args should be ["./foo", "--bar=baz"]
```
```go
os.Setenv("FOO", "bar")
p := shellwords.NewParser()
p.ParseEnv = true
args, err := p.Parse("./foo $FOO")
// args should be ["./foo", "bar"]
```
```go
p := shellwords.NewParser()
p.ParseBacktick = true
args, err := p.Parse("./foo `echo $SHELL`")
// args should be ["./foo", "/bin/bash"]
```
```go
shellwords.ParseBacktick = true
p := shellwords.NewParser()
args, err := p.Parse("./foo `echo $SHELL`")
// args should be ["./foo", "/bin/bash"]
```
# Thanks
This is based on cpan module [Parse::CommandLine](https://metacpan.org/pod/Parse::CommandLine).
# License
under the MIT License: http://mattn.mit-license.org/2014
# Author
Yasuhiro Matsumoto (a.k.a mattn)

View file

@ -1,134 +0,0 @@
package shellwords
import (
"errors"
"os"
"regexp"
"strings"
)
var (
ParseEnv bool = false
ParseBacktick bool = false
)
var envRe = regexp.MustCompile(`\$({[a-zA-Z0-9_]+}|[a-zA-Z0-9_]+)`)
func isSpace(r rune) bool {
switch r {
case ' ', '\t', '\r', '\n':
return true
}
return false
}
func replaceEnv(s string) string {
return envRe.ReplaceAllStringFunc(s, func(s string) string {
s = s[1:]
if s[0] == '{' {
s = s[1 : len(s)-1]
}
return os.Getenv(s)
})
}
type Parser struct {
ParseEnv bool
ParseBacktick bool
}
func NewParser() *Parser {
return &Parser{ParseEnv, ParseBacktick}
}
func (p *Parser) Parse(line string) ([]string, error) {
line = strings.TrimSpace(line)
args := []string{}
buf := ""
var escaped, doubleQuoted, singleQuoted, backQuote bool
backtick := ""
for _, r := range line {
if escaped {
buf += string(r)
escaped = false
continue
}
if r == '\\' {
if singleQuoted {
buf += string(r)
} else {
escaped = true
}
continue
}
if isSpace(r) {
if singleQuoted || doubleQuoted || backQuote {
buf += string(r)
backtick += string(r)
} else if buf != "" {
if p.ParseEnv {
buf = replaceEnv(buf)
}
args = append(args, buf)
buf = ""
}
continue
}
switch r {
case '`':
if !singleQuoted && !doubleQuoted {
if p.ParseBacktick {
if backQuote {
out, err := shellRun(backtick)
if err != nil {
return nil, err
}
buf = out
}
backtick = ""
backQuote = !backQuote
continue
}
backtick = ""
backQuote = !backQuote
}
case '"':
if !singleQuoted {
doubleQuoted = !doubleQuoted
continue
}
case '\'':
if !doubleQuoted {
singleQuoted = !singleQuoted
continue
}
}
buf += string(r)
if backQuote {
backtick += string(r)
}
}
if buf != "" {
if p.ParseEnv {
buf = replaceEnv(buf)
}
args = append(args, buf)
}
if escaped || singleQuoted || doubleQuoted || backQuote {
return nil, errors.New("invalid command line string")
}
return args, nil
}
func Parse(line string) ([]string, error) {
return NewParser().Parse(line)
}

View file

@ -1,19 +0,0 @@
// +build !windows
package shellwords
import (
"errors"
"os"
"os/exec"
"strings"
)
func shellRun(line string) (string, error) {
shell := os.Getenv("SHELL")
b, err := exec.Command(shell, "-c", line).Output()
if err != nil {
return "", errors.New(err.Error() + ":" + string(b))
}
return strings.TrimSpace(string(b)), nil
}

View file

@ -1,17 +0,0 @@
package shellwords
import (
"errors"
"os"
"os/exec"
"strings"
)
func shellRun(line string) (string, error) {
shell := os.Getenv("COMSPEC")
b, err := exec.Command(shell, "/c", line).Output()
if err != nil {
return "", errors.New(err.Error() + ":" + string(b))
}
return strings.TrimSpace(string(b)), nil
}

0
libnetwork/Godeps/_workspace/src/github.com/ugorji/go/codec/prebuild.sh generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/github.com/ugorji/go/codec/test.py generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mkall.sh generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mkerrors.sh generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksyscall.pl generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksyscall_solaris.pl generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksysctl_openbsd.pl generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksysnum_darwin.pl generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksysnum_dragonfly.pl generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksysnum_freebsd.pl generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksysnum_linux.pl generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksysnum_netbsd.pl generated vendored Normal file → Executable file
View file

0
libnetwork/Godeps/_workspace/src/golang.org/x/sys/unix/mksysnum_openbsd.pl generated vendored Normal file → Executable file
View file