<commit_before>package participle

import (
	"bytes"
	"fmt"
	"io"
	"reflect"
	"strings"

	"github.com/alecthomas/participle/v2/lexer"
)

type unionDef struct {
	typ     reflect.Type
	members []reflect.Type
}

type customDef struct {
	typ     reflect.Type
	parseFn reflect.Value
}

// A Parser for a particular grammar and lexer.
type Parser struct {
	root            node
	lex             lexer.Definition
	typ             reflect.Type
	useLookahead    int
	caseInsensitive map[string]bool
	mappers         []mapperByToken
	unionDefs       []unionDef
	customDefs      []customDef
	elide           []string
}

// MustBuild calls Build(grammar, options...) and panics if an error occurs.
func MustBuild(grammar interface{}, options ...Option) *Parser {
	parser, err := Build(grammar, options...)
	if err != nil {
		panic(err)
	}
	return parser
}

// Build constructs a parser for the given grammar.
//
// If "Lexer()" is not provided as an option, a default lexer based on text/scanner will be used. This scans typical Go-
// like tokens.
//
// See documentation for details
func Build(grammar interface{}, options ...Option) (parser *Parser, err error) {
	// Configure Parser struct with defaults + options.
	p := &Parser{
		lex:             lexer.TextScannerLexer,
		caseInsensitive: map[string]bool{},
		useLookahead:    1,
	}
	for _, option := range options {
		if err = option(p); err != nil {
			return nil, err
		}
	}

	symbols := p.lex.Symbols()
	if len(p.mappers) > 0 {
		mappers := map[lexer.TokenType][]Mapper{}
		for _, mapper := range p.mappers {
			if len(mapper.symbols) == 0 {
				mappers[lexer.EOF] = append(mappers[lexer.EOF], mapper.mapper)
			} else {
				for _, symbol := range mapper.symbols {
					if rn, ok := symbols[symbol]; !ok {
						return nil, fmt.Errorf("mapper %#v uses unknown token %q", mapper, symbol)
					} else { // nolint: golint
						mappers[rn] = append(mappers[rn], mapper.mapper)
					}
				}
			}
		}
		p.lex = &mappingLexerDef{p.lex, func(t lexer.Token) (lexer.Token, error) {
			combined := make([]Mapper, 0, len(mappers[t.Type])+len(mappers[lexer.EOF]))
			combined = append(combined, mappers[lexer.EOF]...)
			combined = append(combined, mappers[t.Type]...)

			var err error
			for _, m := range combined {
				t, err = m(t)
				if err != nil {
					return t, err
				}
			}
			return t, nil
		}}
	}

	context := newGeneratorContext(p.lex)
	if err := context.addCustomDefs(p.customDefs); err != nil {
		return nil, err
	}
	if err := context.addUnionDefs(p.unionDefs); err != nil {
		return nil, err
	}

	v := reflect.ValueOf(grammar)
	if v.Kind() == reflect.Interface {
		v = v.Elem()
	}
	p.typ = v.Type()
	p.root, err = context.parseType(p.typ)
	if err != nil {
		return nil, err
	}
	if err := validate(p.root); err != nil {
		return nil, err
	}
	return p, nil
}

// Lexer returns the parser's builtin lexer.
func (p *Parser) Lexer() lexer.Definition {
	return p.lex
}

// Lex uses the parser's lexer to tokenise input.
func (p *Parser) Lex(filename string, r io.Reader) ([]lexer.Token, error) {
	lex, err := p.lex.Lex(filename, r)
	if err != nil {
		return nil, err
	}
	tokens, err := lexer.ConsumeAll(lex)
	return tokens, err
}

// ParseFromLexer into grammar v which must be of the same type as the grammar passed to
// Build().
//
// This may return a Error.
func (p *Parser) ParseFromLexer(lex *lexer.PeekingLexer, v interface{}, options ...ParseOption) error {
	rv := reflect.ValueOf(v)
	if rv.Kind() == reflect.Interface {
		rv = rv.Elem()
	}
	rt := rv.Type()
	if rt != p.typ {
		return fmt.Errorf("must parse into value of type %s not %T", p.typ, v)
	}
	if rt.Kind() != reflect.Ptr || rt.Elem().Kind() != reflect.Struct {
		return fmt.Errorf("target must be a pointer to a struct, not %s", rt)
	}
	caseInsensitive := map[lexer.TokenType]bool{}
	for sym, tt := range p.lex.Symbols() {
		if p.caseInsensitive[sym] {
			caseInsensitive[tt] = true
		}
	}
	ctx := newParseContext(lex, p.useLookahead, caseInsensitive)
	defer func() { *lex = *ctx.PeekingLexer }()
	for _, option := range options {
		option(ctx)
	}
	// If the grammar implements Parseable, use it.
	if parseable, ok := v.(Parseable); ok {
		return p.rootParseable(ctx, parseable)
	}
	return p.parseOne(ctx, rv)
}

func (p *Parser) parse(lex lexer.Lexer, v interface{}, options ...ParseOption) (err error) {
	peeker, err := lexer.Upgrade(lex, p.getElidedTypes()...)
	if err != nil {
		return err
	}
	return p.ParseFromLexer(peeker, v, options...)
}

// Parse from r into grammar v which must be of the same type as the grammar passed to
// Build().
//
// This may return an Error.
func (p *Parser) Parse(filename string, r io.Reader, v interface{}, options ...ParseOption) (err error) {
	if filename == "" {
		filename = lexer.NameOfReader(r)
	}
	lex, err := p.lex.Lex(filename, r)
	if err != nil {
		return err
	}
	return p.parse(lex, v, options...)
}

// ParseString from s into grammar v which must be of the same type as the grammar passed to
// Build().
//
// This may return an Error.
func (p *Parser) ParseString(filename string, s string, v interface{}, options ...ParseOption) (err error) {
	var lex lexer.Lexer
	if sl, ok := p.lex.(lexer.StringDefinition); ok {
		lex, err = sl.LexString(filename, s)
	} else {
		lex, err = p.lex.Lex(filename, strings.NewReader(s))
	}
	if err != nil {
		return err
	}
	return p.parse(lex, v, options...)
}

// ParseBytes from b into grammar v which must be of the same type as the grammar passed to
// Build().
//
// This may return an Error.
func (p *Parser) ParseBytes(filename string, b []byte, v interface{}, options ...ParseOption) (err error) {
	var lex lexer.Lexer
	if sl, ok := p.lex.(lexer.BytesDefinition); ok {
		lex, err = sl.LexBytes(filename, b)
	} else {
		lex, err = p.lex.Lex(filename, bytes.NewReader(b))
	}
	if err != nil {
		return err
	}
	return p.parse(lex, v, options...)
}

func (p *Parser) parseOne(ctx *parseContext, rv reflect.Value) error {
	err := p.parseInto(ctx, rv)
	if err != nil {
		return err
	}
	token := ctx.Peek()
	if !token.EOF() && !ctx.allowTrailing {
		return ctx.DeepestError(UnexpectedTokenError{Unexpected: token})
	}
	return nil
}

func (p *Parser) parseInto(ctx *parseContext, rv reflect.Value) error {
	if rv.IsNil() {
		return fmt.Errorf("target must be a non-nil pointer to a struct, but is a nil %s", rv.Type())
	}
	pv, err := p.root.Parse(ctx, rv.Elem())
	if len(pv) > 0 && pv[0].Type() == rv.Elem().Type() {
		rv.Elem().Set(reflect.Indirect(pv[0]))
	}
	if err != nil {
		return err
	}
	if pv == nil {
		token := ctx.Peek()
		return ctx.DeepestError(UnexpectedTokenError{Unexpected: token})
	}
	return nil
}

func (p *Parser) rootParseable(ctx *parseContext, parseable Parseable) error {
	if err := parseable.Parse(ctx.PeekingLexer); err != nil {
		if err == NextMatch {
			err = UnexpectedTokenError{Unexpected: ctx.Peek()}
		} else {
			err = &ParseError{Msg: err.Error(), Pos: ctx.Peek().Pos}
		}
		return ctx.DeepestError(err)
	}
	peek := ctx.Peek()
	if !peek.EOF() && !ctx.allowTrailing {
		return ctx.DeepestError(UnexpectedTokenError{Unexpected: peek})
	}
	return nil
}

func (p *Parser) getElidedTypes() []lexer.TokenType {
	symbols := p.lex.Symbols()
	elideTypes := make([]lexer.TokenType, 0, len(p.elide))
	for _, elide := range p.elide {
		rn, ok := symbols[elide]
		if !ok {
			panic(fmt.Errorf("Elide() uses unknown token %q", elide))
		}
		elideTypes = append(elideTypes, rn)
	}
	return elideTypes
}
<commit_msg>document parameter "filename" for the Parser methods<commit_after>package participle

import (
	"bytes"
	"fmt"
	"io"
	"reflect"
	"strings"

	"github.com/alecthomas/participle/v2/lexer"
)

type unionDef struct {
	typ     reflect.Type
	members []reflect.Type
}

type customDef struct {
	typ     reflect.Type
	parseFn reflect.Value
}

// A Parser for a particular grammar and lexer.
type Parser struct {
	root            node
	lex             lexer.Definition
	typ             reflect.Type
	useLookahead    int
	caseInsensitive map[string]bool
	mappers         []mapperByToken
	unionDefs       []unionDef
	customDefs      []customDef
	elide           []string
}

// MustBuild calls Build(grammar, options...) and panics if an error occurs.
func MustBuild(grammar interface{}, options ...Option) *Parser {
	parser, err := Build(grammar, options...)
	if err != nil {
		panic(err)
	}
	return parser
}

// Build constructs a parser for the given grammar.
//
// If "Lexer()" is not provided as an option, a default lexer based on text/scanner will be used. This scans typical Go-
// like tokens.
//
// See documentation for details.
func Build(grammar interface{}, options ...Option) (parser *Parser, err error) {
	// Configure Parser struct with defaults + options.
	p := &Parser{
		lex:             lexer.TextScannerLexer,
		caseInsensitive: map[string]bool{},
		useLookahead:    1,
	}
	for _, option := range options {
		if err = option(p); err != nil {
			return nil, err
		}
	}

	symbols := p.lex.Symbols()
	if len(p.mappers) > 0 {
		mappers := map[lexer.TokenType][]Mapper{}
		for _, mapper := range p.mappers {
			if len(mapper.symbols) == 0 {
				mappers[lexer.EOF] = append(mappers[lexer.EOF], mapper.mapper)
			} else {
				for _, symbol := range mapper.symbols {
					if rn, ok := symbols[symbol]; !ok {
						return nil, fmt.Errorf("mapper %#v uses unknown token %q", mapper, symbol)
					} else { // nolint: golint
						mappers[rn] = append(mappers[rn], mapper.mapper)
					}
				}
			}
		}
		p.lex = &mappingLexerDef{p.lex, func(t lexer.Token) (lexer.Token, error) {
			combined := make([]Mapper, 0, len(mappers[t.Type])+len(mappers[lexer.EOF]))
			combined = append(combined, mappers[lexer.EOF]...)
			combined = append(combined, mappers[t.Type]...)

			var err error
			for _, m := range combined {
				t, err = m(t)
				if err != nil {
					return t, err
				}
			}
			return t, nil
		}}
	}

	context := newGeneratorContext(p.lex)
	if err := context.addCustomDefs(p.customDefs); err != nil {
		return nil, err
	}
	if err := context.addUnionDefs(p.unionDefs); err != nil {
		return nil, err
	}

	v := reflect.ValueOf(grammar)
	if v.Kind() == reflect.Interface {
		v = v.Elem()
	}
	p.typ = v.Type()
	p.root, err = context.parseType(p.typ)
	if err != nil {
		return nil, err
	}
	if err := validate(p.root); err != nil {
		return nil, err
	}
	return p, nil
}

// Lexer returns the parser's builtin lexer.
func (p *Parser) Lexer() lexer.Definition {
	return p.lex
}

// Lex uses the parser's lexer to tokenise input.
// Parameter filename is used as an opaque prefix in error messages.
func (p *Parser) Lex(filename string, r io.Reader) ([]lexer.Token, error) {
	lex, err := p.lex.Lex(filename, r)
	if err != nil {
		return nil, err
	}
	tokens, err := lexer.ConsumeAll(lex)
	return tokens, err
}

// ParseFromLexer into grammar v which must be of the same type as the grammar passed to
// Build().
//
// This may return a Error.
func (p *Parser) ParseFromLexer(lex *lexer.PeekingLexer, v interface{}, options ...ParseOption) error {
	rv := reflect.ValueOf(v)
	if rv.Kind() == reflect.Interface {
		rv = rv.Elem()
	}
	rt := rv.Type()
	if rt != p.typ {
		return fmt.Errorf("must parse into value of type %s not %T", p.typ, v)
	}
	if rt.Kind() != reflect.Ptr || rt.Elem().Kind() != reflect.Struct {
		return fmt.Errorf("target must be a pointer to a struct, not %s", rt)
	}
	caseInsensitive := map[lexer.TokenType]bool{}
	for sym, tt := range p.lex.Symbols() {
		if p.caseInsensitive[sym] {
			caseInsensitive[tt] = true
		}
	}
	ctx := newParseContext(lex, p.useLookahead, caseInsensitive)
	defer func() { *lex = *ctx.PeekingLexer }()
	for _, option := range options {
		option(ctx)
	}
	// If the grammar implements Parseable, use it.
	if parseable, ok := v.(Parseable); ok {
		return p.rootParseable(ctx, parseable)
	}
	return p.parseOne(ctx, rv)
}

func (p *Parser) parse(lex lexer.Lexer, v interface{}, options ...ParseOption) (err error) {
	peeker, err := lexer.Upgrade(lex, p.getElidedTypes()...)
	if err != nil {
		return err
	}
	return p.ParseFromLexer(peeker, v, options...)
}

// Parse from r into grammar v which must be of the same type as the grammar passed to
// Build(). Parameter filename is used as an opaque prefix in error messages.
//
// This may return an Error.
func (p *Parser) Parse(filename string, r io.Reader, v interface{}, options ...ParseOption) (err error) {
	if filename == "" {
		filename = lexer.NameOfReader(r)
	}
	lex, err := p.lex.Lex(filename, r)
	if err != nil {
		return err
	}
	return p.parse(lex, v, options...)
}

// ParseString from s into grammar v which must be of the same type as the grammar passed to
// Build(). Parameter filename is used as an opaque prefix in error messages.
//
// This may return an Error.
func (p *Parser) ParseString(filename string, s string, v interface{}, options ...ParseOption) (err error) {
	var lex lexer.Lexer
	if sl, ok := p.lex.(lexer.StringDefinition); ok {
		lex, err = sl.LexString(filename, s)
	} else {
		lex, err = p.lex.Lex(filename, strings.NewReader(s))
	}
	if err != nil {
		return err
	}
	return p.parse(lex, v, options...)
}

// ParseBytes from b into grammar v which must be of the same type as the grammar passed to
// Build(). Parameter filename is used as an opaque prefix in error messages.
//
// This may return an Error.
func (p *Parser) ParseBytes(filename string, b []byte, v interface{}, options ...ParseOption) (err error) {
	var lex lexer.Lexer
	if sl, ok := p.lex.(lexer.BytesDefinition); ok {
		lex, err = sl.LexBytes(filename, b)
	} else {
		lex, err = p.lex.Lex(filename, bytes.NewReader(b))
	}
	if err != nil {
		return err
	}
	return p.parse(lex, v, options...)
}

func (p *Parser) parseOne(ctx *parseContext, rv reflect.Value) error {
	err := p.parseInto(ctx, rv)
	if err != nil {
		return err
	}
	token := ctx.Peek()
	if !token.EOF() && !ctx.allowTrailing {
		return ctx.DeepestError(UnexpectedTokenError{Unexpected: token})
	}
	return nil
}

func (p *Parser) parseInto(ctx *parseContext, rv reflect.Value) error {
	if rv.IsNil() {
		return fmt.Errorf("target must be a non-nil pointer to a struct, but is a nil %s", rv.Type())
	}
	pv, err := p.root.Parse(ctx, rv.Elem())
	if len(pv) > 0 && pv[0].Type() == rv.Elem().Type() {
		rv.Elem().Set(reflect.Indirect(pv[0]))
	}
	if err != nil {
		return err
	}
	if pv == nil {
		token := ctx.Peek()
		return ctx.DeepestError(UnexpectedTokenError{Unexpected: token})
	}
	return nil
}

func (p *Parser) rootParseable(ctx *parseContext, parseable Parseable) error {
	if err := parseable.Parse(ctx.PeekingLexer); err != nil {
		if err == NextMatch {
			err = UnexpectedTokenError{Unexpected: ctx.Peek()}
		} else {
			err = &ParseError{Msg: err.Error(), Pos: ctx.Peek().Pos}
		}
		return ctx.DeepestError(err)
	}
	peek := ctx.Peek()
	if !peek.EOF() && !ctx.allowTrailing {
		return ctx.DeepestError(UnexpectedTokenError{Unexpected: peek})
	}
	return nil
}

func (p *Parser) getElidedTypes() []lexer.TokenType {
	symbols := p.lex.Symbols()
	elideTypes := make([]lexer.TokenType, 0, len(p.elide))
	for _, elide := range p.elide {
		rn, ok := symbols[elide]
		if !ok {
			panic(fmt.Errorf("Elide() uses unknown token %q", elide))
		}
		elideTypes = append(elideTypes, rn)
	}
	return elideTypes
}
<|endoftext|>


<commit_before>// Copyright (c) 2015 Arista Networks, Inc.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.

// Package monitor provides an embedded HTTP server to expose
// metrics for monitoring
package monitor

import (
	"expvar"
	"fmt"
	"net"
	"net/http"
	_ "net/http/pprof" // Go documentation recommended usage

	"github.com/aristanetworks/goarista/netns"

	"github.com/aristanetworks/glog"
)

// Server represents a monitoring server
type Server interface {
	Run()
}

// server contains information for the monitoring server
type server struct {
	vrfName string
	// Server name e.g. host[:port]
	serverName string
}

// NewServer creates a new server struct
func NewServer(address string) Server {
	vrfName, addr, err := netns.ParseAddress(address)
	if err != nil {
		glog.Errorf("Failed to parse address: %s", err)
	}
	return &server{
		vrfName:    vrfName,
		serverName: addr,
	}
}

func debugHandler(w http.ResponseWriter, r *http.Request) {
	indexTmpl := `

	<title>/debug</title>

/debug

vars

pprof

	`
	fmt.Fprintf(w, indexTmpl)
}

// PrintableHistogram represents a Histogram that can be printed as
// a chart.
type PrintableHistogram interface {
	Print() string
}

// Pretty prints the latency histograms
func histogramHandler(w http.ResponseWriter, r *http.Request) {
	expvar.Do(func(kv expvar.KeyValue) {
		if hist, ok := kv.Value.(PrintableHistogram); ok {
			w.Write([]byte(hist.Print()))
		}
	})
}

// Run sets up the HTTP server and any handlers
func (s *server) Run() {
	http.HandleFunc("/debug", debugHandler)
	http.HandleFunc("/debug/histograms", histogramHandler)

	var listener net.Listener
	err := netns.Do(s.vrfName, func() error {
		var err error
		listener, err = net.Listen("tcp", s.serverName)
		return err
	})
	if err != nil {
		glog.Fatalf("Could not start monitor server in VRF %q: %s", s.vrfName, err)
	}

	err = http.Serve(listener, nil)
	if err != nil {
		glog.Fatal("http serve returned with error:", err)
	}
}
<commit_msg>monitor: add serverMux handler to Run() parameter<commit_after>// Copyright (c) 2015 Arista Networks, Inc.
// Use of this source code is governed by the Apache License 2.0
// that can be found in the COPYING file.

// Package monitor provides an embedded HTTP server to expose
// metrics for monitoring
package monitor

import (
	"expvar"
	"fmt"
	"net"
	"net/http"
	_ "net/http/pprof" // Go documentation recommended usage

	"github.com/aristanetworks/goarista/netns"

	"github.com/aristanetworks/glog"
)

// Server represents a monitoring server
type Server interface {
	Run(serveMux *http.ServeMux)
}

// server contains information for the monitoring server
type server struct {
	vrfName string
	// Server name e.g. host[:port]
	serverName string
}

// NewServer creates a new server struct
func NewServer(address string) Server {
	vrfName, addr, err := netns.ParseAddress(address)
	if err != nil {
		glog.Errorf("Failed to parse address: %s", err)
	}
	return &server{
		vrfName:    vrfName,
		serverName: addr,
	}
}

func debugHandler(w http.ResponseWriter, r *http.Request) {
	indexTmpl := `

	<title>/debug</title>

/debug

vars

pprof

	`
	fmt.Fprintf(w, indexTmpl)
}

// PrintableHistogram represents a Histogram that can be printed as
// a chart.
type PrintableHistogram interface {
	Print() string
}

// Pretty prints the latency histograms
func histogramHandler(w http.ResponseWriter, r *http.Request) {
	expvar.Do(func(kv expvar.KeyValue) {
		if hist, ok := kv.Value.(PrintableHistogram); ok {
			w.Write([]byte(hist.Print()))
		}
	})
}

// Run sets up the HTTP server and any handlers
func (s *server) Run(serveMux *http.ServeMux) {
	serveMux.HandleFunc("/debug", debugHandler)
	serveMux.HandleFunc("/debug/histograms", histogramHandler)

	var listener net.Listener
	err := netns.Do(s.vrfName, func() error {
		var err error
		listener, err = net.Listen("tcp", s.serverName)
		return err
	})
	if err != nil {
		glog.Fatalf("Could not start monitor server in VRF %q: %s", s.vrfName, err)
	}

	err = http.Serve(listener, serveMux)
	if err != nil {
		glog.Fatal("http serve returned with error:", err)
	}
}
<|endoftext|>


<commit_before>// +build windows

package pb

import (
	"errors"
	"fmt"
	"os"
	"sync"
	"syscall"
	"unsafe"
)

var tty = os.Stdin

var (
	kernel32 = syscall.NewLazyDLL("kernel32.dll")

	// GetConsoleScreenBufferInfo retrieves information about the
	// specified console screen buffer.
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
	procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")

	// GetConsoleMode retrieves the current input mode of a console's
	// input buffer or the current output mode of a console screen buffer.
	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
	getConsoleMode = kernel32.NewProc("GetConsoleMode")

	// SetConsoleMode sets the input mode of a console's input buffer
	// or the output mode of a console screen buffer.
	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
	setConsoleMode = kernel32.NewProc("SetConsoleMode")

	// SetConsoleCursorPosition sets the cursor position in the
	// specified console screen buffer.
	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx
	setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
)

type (
	// Defines the coordinates of the upper left and lower right corners
	// of a rectangle.
	// See
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx
	smallRect struct {
		Left, Top, Right, Bottom int16
	}

	// Defines the coordinates of a character cell in a console screen
	// buffer. The origin of the coordinate system (0,0) is at the top, left cell
	// of the buffer.
	// See
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx
	coordinates struct {
		X, Y int16
	}

	word int16

	// Contains information about a console screen buffer.
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
	consoleScreenBufferInfo struct {
		dwSize              coordinates
		dwCursorPosition    coordinates
		wAttributes         word
		srWindow            smallRect
		dwMaximumWindowSize coordinates
	}
)

// terminalWidth returns width of the terminal.
func terminalWidth() (width int, err error) {
	var info consoleScreenBufferInfo
	_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
	if e != 0 {
		return 0, error(e)
	}
	return int(info.dwSize.X) - 1, nil
}

func getCursorPos() (pos coordinates, err error) {
	var info consoleScreenBufferInfo
	_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
	if e != 0 {
		return info.dwCursorPosition, error(e)
	}
	return info.dwCursorPosition, nil
}

func setCursorPos(pos coordinates) error {
	_, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0)
	if e != 0 {
		return error(e)
	}
	return nil
}

var ErrPoolWasStarted = errors.New("Bar pool was started")

var echoLocked bool
var echoLockMutex sync.Mutex

var oldState word

func lockEcho() (shutdownCh chan struct{}, err error) {
	echoLockMutex.Lock()
	defer echoLockMutex.Unlock()
	if echoLocked {
		err = ErrPoolWasStarted
		return
	}
	echoLocked = true

	if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 {
		err = fmt.Errorf("Can't get terminal settings: %v", e)
		return
	}

	newState := oldState
	const ENABLE_ECHO_INPUT = 0x0004
	const ENABLE_LINE_INPUT = 0x0002
	newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))
	if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 {
		err = fmt.Errorf("Can't set terminal settings: %v", e)
		return
	}
	return
}

func unlockEcho() (err error) {
	echoLockMutex.Lock()
	defer echoLockMutex.Unlock()
	if !echoLocked {
		return
	}
	echoLocked = false
	if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 {
		err = fmt.Errorf("Can't set terminal settings")
	}
	return
}
<commit_msg>Fix panic with multiple bars in Windows<commit_after>// +build windows

package pb

import (
	"errors"
	"fmt"
	"os"
	"sync"
	"syscall"
	"unsafe"
)

var tty = os.Stdin

var (
	kernel32 = syscall.NewLazyDLL("kernel32.dll")

	// GetConsoleScreenBufferInfo retrieves information about the
	// specified console screen buffer.
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms683171(v=vs.85).aspx
	procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")

	// GetConsoleMode retrieves the current input mode of a console's
	// input buffer or the current output mode of a console screen buffer.
	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms683167(v=vs.85).aspx
	getConsoleMode = kernel32.NewProc("GetConsoleMode")

	// SetConsoleMode sets the input mode of a console's input buffer
	// or the output mode of a console screen buffer.
	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686033(v=vs.85).aspx
	setConsoleMode = kernel32.NewProc("SetConsoleMode")

	// SetConsoleCursorPosition sets the cursor position in the
	// specified console screen buffer.
	// https://msdn.microsoft.com/en-us/library/windows/desktop/ms686025(v=vs.85).aspx
	setConsoleCursorPosition = kernel32.NewProc("SetConsoleCursorPosition")
)

type (
	// Defines the coordinates of the upper left and lower right corners
	// of a rectangle.
	// See
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms686311(v=vs.85).aspx
	smallRect struct {
		Left, Top, Right, Bottom int16
	}

	// Defines the coordinates of a character cell in a console screen
	// buffer. The origin of the coordinate system (0,0) is at the top, left cell
	// of the buffer.
	// See
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682119(v=vs.85).aspx
	coordinates struct {
		X, Y int16
	}

	word int16

	// Contains information about a console screen buffer.
	// http://msdn.microsoft.com/en-us/library/windows/desktop/ms682093(v=vs.85).aspx
	consoleScreenBufferInfo struct {
		dwSize              coordinates
		dwCursorPosition    coordinates
		wAttributes         word
		srWindow            smallRect
		dwMaximumWindowSize coordinates
	}
)

// terminalWidth returns width of the terminal.
func terminalWidth() (width int, err error) {
	var info consoleScreenBufferInfo
	_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
	if e != 0 {
		return 0, error(e)
	}
	return int(info.dwSize.X) - 1, nil
}

func getCursorPos() (pos coordinates, err error) {
	var info consoleScreenBufferInfo
	_, _, e := syscall.Syscall(procGetConsoleScreenBufferInfo.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&info)), 0)
	if e != 0 {
		return info.dwCursorPosition, error(e)
	}
	return info.dwCursorPosition, nil
}

func setCursorPos(pos coordinates) error {
	_, _, e := syscall.Syscall(setConsoleCursorPosition.Addr(), 2, uintptr(syscall.Stdout), uintptr(uint32(uint16(pos.Y))<<16|uint32(uint16(pos.X))), 0)
	if e != 0 {
		return error(e)
	}
	return nil
}

var ErrPoolWasStarted = errors.New("Bar pool was started")

var echoLocked bool
var echoLockMutex sync.Mutex

var oldState word

func lockEcho() (shutdownCh chan struct{}, err error) {
	echoLockMutex.Lock()
	defer echoLockMutex.Unlock()
	if echoLocked {
		err = ErrPoolWasStarted
		return
	}
	echoLocked = true

	if _, _, e := syscall.Syscall(getConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(unsafe.Pointer(&oldState)), 0); e != 0 {
		err = fmt.Errorf("Can't get terminal settings: %v", e)
		return
	}

	newState := oldState
	const ENABLE_ECHO_INPUT = 0x0004
	const ENABLE_LINE_INPUT = 0x0002
	newState = newState & (^(ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT))
	if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(newState), 0); e != 0 {
		err = fmt.Errorf("Can't set terminal settings: %v", e)
		return
	}

	shutdownCh = make(chan struct{})
	return
}

func unlockEcho() (err error) {
	echoLockMutex.Lock()
	defer echoLockMutex.Unlock()
	if !echoLocked {
		return
	}
	echoLocked = false
	if _, _, e := syscall.Syscall(setConsoleMode.Addr(), 2, uintptr(syscall.Stdout), uintptr(oldState), 0); e != 0 {
		err = fmt.Errorf("Can't set terminal settings")
	}
	return
}
<|endoftext|>


<commit_before>// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package rafthttp

import (
	"bytes"
	"io"
	"io/ioutil"
	"net/http"
	"time"

	"github.com/coreos/etcd/pkg/httputil"
	pioutil "github.com/coreos/etcd/pkg/ioutil"
	"github.com/coreos/etcd/pkg/types"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/snap"
)

var (
	// timeout for reading snapshot response body
	snapResponseReadTimeout = 5 * time.Second
)

type snapshotSender struct {
	from, to types.ID
	cid      types.ID

	tr     http.RoundTripper
	picker *urlPicker
	status *peerStatus
	r      Raft
	errorc chan error

	stopc chan struct{}
}

func newSnapshotSender(tr http.RoundTripper, picker *urlPicker, from, to, cid types.ID, status *peerStatus, r Raft, errorc chan error) *snapshotSender {
	return &snapshotSender{
		from:   from,
		to:     to,
		cid:    cid,
		tr:     tr,
		picker: picker,
		status: status,
		r:      r,
		errorc: errorc,
		stopc:  make(chan struct{}),
	}
}

func (s *snapshotSender) stop() { close(s.stopc) }

func (s *snapshotSender) send(merged snap.Message) {
	m := merged.Message

	start := time.Now()

	body := createSnapBody(merged)
	defer body.Close()

	u := s.picker.pick()
	req := createPostRequest(u, RaftSnapshotPrefix, body, "application/octet-stream", s.from, s.cid)

	err := s.post(req)
	if err != nil {
		// errMemberRemoved is a critical error since a removed member should
		// always be stopped. So we use reportCriticalError to report it to errorc.
		if err == errMemberRemoved {
			reportCriticalError(err, s.errorc)
		}
		s.picker.unreachable(u)
		reportSentFailure(sendSnap, m)
		s.status.deactivate(failureType{source: sendSnap, action: "post"}, err.Error())
		s.r.ReportUnreachable(m.To)
		// report SnapshotFailure to raft state machine. After raft state
		// machine knows about it, it would pause a while and retry sending
		// new snapshot message.
		s.r.ReportSnapshot(m.To, raft.SnapshotFailure)
		if s.status.isActive() {
			plog.Warningf("snapshot [index: %d, to: %s] failed to be sent out (%v)", m.Snapshot.Metadata.Index, types.ID(m.To), err)
		} else {
			plog.Debugf("snapshot [index: %d, to: %s] failed to be sent out (%v)", m.Snapshot.Metadata.Index, types.ID(m.To), err)
		}
		return
	}
	reportSentDuration(sendSnap, m, time.Since(start))
	s.status.activate()
	s.r.ReportSnapshot(m.To, raft.SnapshotFinish)
	plog.Infof("snapshot [index: %d, to: %s] sent out successfully", m.Snapshot.Metadata.Index, types.ID(m.To))
}

// post posts the given request.
// It returns nil when request is sent out and processed successfully.
func (s *snapshotSender) post(req *http.Request) (err error) {
	cancel := httputil.RequestCanceler(s.tr, req)

	type responseAndError struct {
		resp *http.Response
		body []byte
		err  error
	}
	result := make(chan responseAndError, 1)

	go func() {
		// TODO: the snapshot could be large and eat up all resources when writing
		// it out. Send it block by block and rest some time between to give the
		// time for main loop to run.
		resp, err := s.tr.RoundTrip(req)
		if err != nil {
			result <- responseAndError{resp, nil, err}
			return
		}

		// close the response body when timeouts.
		// prevents from reading the body forever when the other side dies right after
		// successfully receives the request body.
		time.AfterFunc(snapResponseReadTimeout, func() { resp.Body.Close() })
		body, err := ioutil.ReadAll(resp.Body)
		result <- responseAndError{resp, body, err}
	}()

	select {
	case <-s.stopc:
		cancel()
		return errStopped
	case r := <-result:
		if r.err != nil {
			return r.err
		}
		return checkPostResponse(r.resp, r.body, req, s.to)
	}
}

func createSnapBody(merged snap.Message) io.ReadCloser {
	buf := new(bytes.Buffer)
	enc := &messageEncoder{w: buf}
	// encode raft message
	if err := enc.encode(merged.Message); err != nil {
		plog.Panicf("encode message error (%v)", err)
	}

	return &pioutil.ReaderAndCloser{
		Reader: io.MultiReader(buf, merged.ReadCloser),
		Closer: merged.ReadCloser,
	}
}
<commit_msg>rafthttp: remove the unncessary TODO<commit_after>// Copyright 2015 CoreOS, Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package rafthttp

import (
	"bytes"
	"io"
	"io/ioutil"
	"net/http"
	"time"

	"github.com/coreos/etcd/pkg/httputil"
	pioutil "github.com/coreos/etcd/pkg/ioutil"
	"github.com/coreos/etcd/pkg/types"
	"github.com/coreos/etcd/raft"
	"github.com/coreos/etcd/snap"
)

var (
	// timeout for reading snapshot response body
	snapResponseReadTimeout = 5 * time.Second
)

type snapshotSender struct {
	from, to types.ID
	cid      types.ID

	tr     http.RoundTripper
	picker *urlPicker
	status *peerStatus
	r      Raft
	errorc chan error

	stopc chan struct{}
}

func newSnapshotSender(tr http.RoundTripper, picker *urlPicker, from, to, cid types.ID, status *peerStatus, r Raft, errorc chan error) *snapshotSender {
	return &snapshotSender{
		from:   from,
		to:     to,
		cid:    cid,
		tr:     tr,
		picker: picker,
		status: status,
		r:      r,
		errorc: errorc,
		stopc:  make(chan struct{}),
	}
}

func (s *snapshotSender) stop() { close(s.stopc) }

func (s *snapshotSender) send(merged snap.Message) {
	m := merged.Message

	start := time.Now()

	body := createSnapBody(merged)
	defer body.Close()

	u := s.picker.pick()
	req := createPostRequest(u, RaftSnapshotPrefix, body, "application/octet-stream", s.from, s.cid)

	err := s.post(req)
	if err != nil {
		// errMemberRemoved is a critical error since a removed member should
		// always be stopped. So we use reportCriticalError to report it to errorc.
		if err == errMemberRemoved {
			reportCriticalError(err, s.errorc)
		}
		s.picker.unreachable(u)
		reportSentFailure(sendSnap, m)
		s.status.deactivate(failureType{source: sendSnap, action: "post"}, err.Error())
		s.r.ReportUnreachable(m.To)
		// report SnapshotFailure to raft state machine. After raft state
		// machine knows about it, it would pause a while and retry sending
		// new snapshot message.
		s.r.ReportSnapshot(m.To, raft.SnapshotFailure)
		if s.status.isActive() {
			plog.Warningf("snapshot [index: %d, to: %s] failed to be sent out (%v)", m.Snapshot.Metadata.Index, types.ID(m.To), err)
		} else {
			plog.Debugf("snapshot [index: %d, to: %s] failed to be sent out (%v)", m.Snapshot.Metadata.Index, types.ID(m.To), err)
		}
		return
	}
	reportSentDuration(sendSnap, m, time.Since(start))
	s.status.activate()
	s.r.ReportSnapshot(m.To, raft.SnapshotFinish)
	plog.Infof("snapshot [index: %d, to: %s] sent out successfully", m.Snapshot.Metadata.Index, types.ID(m.To))
}

// post posts the given request.
// It returns nil when request is sent out and processed successfully.
func (s *snapshotSender) post(req *http.Request) (err error) {
	cancel := httputil.RequestCanceler(s.tr, req)

	type responseAndError struct {
		resp *http.Response
		body []byte
		err  error
	}
	result := make(chan responseAndError, 1)

	go func() {
		resp, err := s.tr.RoundTrip(req)
		if err != nil {
			result <- responseAndError{resp, nil, err}
			return
		}

		// close the response body when timeouts.
		// prevents from reading the body forever when the other side dies right after
		// successfully receives the request body.
		time.AfterFunc(snapResponseReadTimeout, func() { resp.Body.Close() })
		body, err := ioutil.ReadAll(resp.Body)
		result <- responseAndError{resp, body, err}
	}()

	select {
	case <-s.stopc:
		cancel()
		return errStopped
	case r := <-result:
		if r.err != nil {
			return r.err
		}
		return checkPostResponse(r.resp, r.body, req, s.to)
	}
}

func createSnapBody(merged snap.Message) io.ReadCloser {
	buf := new(bytes.Buffer)
	enc := &messageEncoder{w: buf}
	// encode raft message
	if err := enc.encode(merged.Message); err != nil {
		plog.Panicf("encode message error (%v)", err)
	}

	return &pioutil.ReaderAndCloser{
		Reader: io.MultiReader(buf, merged.ReadCloser),
		Closer: merged.ReadCloser,
	}
}
<|endoftext|>


<commit_before>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// ------
// This file is copied from the standard golang library
// in order to change the MaxScanTokenSize const

package myqlib

import (
	"bytes"
	"errors"
	"io"
	"unicode/utf8"
)

// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
	r            io.Reader // The reader provided by the client.
	split        SplitFunc // The function to split the tokens.
	maxTokenSize int       // Maximum size of a token; modified by tests.
	token        []byte    // Last token returned by split.
	buf          []byte    // Buffer used as argument to split.
	start        int       // First non-processed byte in buf.
	end          int       // End of data in buf.
	err          error     // Sticky error.
	empties      int       // Count of successive empty tokens.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
	ErrTooLong         = errors.New("bufio.Scanner: token too long")
	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
	// MaxScanTokenSize is the maximum size used to buffer a token.
	// The actual maximum token size may be smaller as the buffer
	// may need to include, for instance, a newline.
	MaxScanTokenSize = 256 * 1024
	maxConsecutiveEmptyReads = 100
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        ScanLines,
		maxTokenSize: MaxScanTokenSize,
		buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
	}
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
	if s.err == io.EOF {
		return nil
	}
	return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
	return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
	return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
// Split panics if the split function returns 100 empty tokens without
// advancing the input. This is a common error mode for scanners.
func (s *Scanner) Scan() bool {
	// Loop until we have a token.
	for {
		// See if we can get a token with what we already have.
		// If we've run out of data but have an error, give the split function
		// a chance to recover any remaining, possibly empty token.
		if s.end > s.start || s.err != nil {
			advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
			if err != nil {
				s.setErr(err)
				return false
			}
			if !s.advance(advance) {
				return false
			}
			s.token = token
			if token != nil {
				if s.err == nil || advance > 0 {
					s.empties = 0
				} else {
					// Returning tokens not advancing input at EOF.
					s.empties++
					if s.empties > 100 {
						panic("bufio.Scan: 100 empty tokens without progressing")
					}
				}
				return true
			}
		}
		// We cannot generate a token with what we are holding.
		// If we've already hit EOF or an I/O error, we are done.
		if s.err != nil {
			// Shut it down.
			s.start = 0
			s.end = 0
			return false
		}
		// Must read more data.
		// First, shift data to beginning of buffer if there's lots of empty space
		// or space is needed.
		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
			copy(s.buf, s.buf[s.start:s.end])
			s.end -= s.start
			s.start = 0
		}
		// Is the buffer full? If so, resize.
		if s.end == len(s.buf) {
			if len(s.buf) >= s.maxTokenSize {
				s.setErr(ErrTooLong)
				return false
			}
			newSize := len(s.buf) * 2
			if newSize > s.maxTokenSize {
				newSize = s.maxTokenSize
			}
			newBuf := make([]byte, newSize)
			copy(newBuf, s.buf[s.start:s.end])
			s.buf = newBuf
			s.end -= s.start
			s.start = 0
			continue
		}
		// Finally we can read some input. Make sure we don't get stuck with
		// a misbehaving Reader. Officially we don't need to do this, but let's
		// be extra careful: Scanner is for safe, simple jobs.
		for loop := 0; ; {
			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
			s.end += n
			if err != nil {
				s.setErr(err)
				break
			}
			if n > 0 {
				s.empties = 0
				break
			}
			loop++
			if loop > maxConsecutiveEmptyReads {
				s.setErr(io.ErrNoProgress)
				break
			}
		}
	}
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
	if n < 0 {
		s.setErr(ErrNegativeAdvance)
		return false
	}
	if n > s.end-s.start {
		s.setErr(ErrAdvanceTooFar)
		return false
	}
	s.start += n
	return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
	if s.err == nil || s.err == io.EOF {
		s.err = err
	}
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
	s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}

	// Fast path 1: ASCII.
	if data[0] < utf8.RuneSelf {
		return 1, data[0:1], nil
	}

	// Fast path 2: Correct UTF-8 decode without error.
	_, width := utf8.DecodeRune(data)
	if width > 1 {
		// It's a valid encoding. Width cannot be one for a correctly encoded
		// non-ASCII rune.
		return width, data[0:width], nil
	}

	// We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
	// Is the error because there wasn't a full rune to be decoded?
	// FullRune distinguishes correctly between erroneous and incomplete encodings.
	if !atEOF && !utf8.FullRune(data) {
		// Incomplete; get more bytes.
		return 0, nil, nil
	}

	// We have a real UTF-8 encoding error. Return a properly encoded error rune
	// but advance only one byte. This matches the behavior of a range loop over
	// an incorrectly encoded string.
	return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
	if len(data) > 0 && data[len(data)-1] == '\r' {
		return data[0 : len(data)-1]
	}
	return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	if i := bytes.IndexByte(data, '\n'); i >= 0 {
		// We have a full newline-terminated line.
		return i + 1, dropCR(data[0:i]), nil
	}
	// If we're at EOF, we have a final, non-terminated line. Return it.
	if atEOF {
		return len(data), dropCR(data), nil
	}
	// Request more data.
	return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
	if r <= '\u00FF' {
		// Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
		switch r {
		case ' ', '\t', '\n', '\v', '\f', '\r':
			return true
		case '\u0085', '\u00A0':
			return true
		}
		return false
	}
	// High-valued ones.
	if '\u2000' <= r && r <= '\u200a' {
		return true
	}
	switch r {
	case '\u1680', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
		return true
	}
	return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
	// Skip leading spaces.
	start := 0
	for width := 0; start < len(data); start += width {
		var r rune
		r, width = utf8.DecodeRune(data[start:])
		if !isSpace(r) {
			break
		}
	}
	// Scan until space, marking end of word.
	for width, i := 0, start; i < len(data); i += width {
		var r rune
		r, width = utf8.DecodeRune(data[i:])
		if isSpace(r) {
			return i + width, data[start:i], nil
		}
	}
	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
	if atEOF && len(data) > start {
		return len(data), data[start:], nil
	}
	// Request more data.
	return start, nil, nil
}<commit_msg>go fmt<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// ------
// This file is copied from the standard golang library
// in order to change the MaxScanTokenSize const

package myqlib

import (
	"bytes"
	"errors"
	"io"
	"unicode/utf8"
)

// Scanner provides a convenient interface for reading data such as
// a file of newline-delimited lines of text. Successive calls to
// the Scan method will step through the 'tokens' of a file, skipping
// the bytes between the tokens. The specification of a token is
// defined by a split function of type SplitFunc; the default split
// function breaks the input into lines with line termination stripped. Split
// functions are defined in this package for scanning a file into
// lines, bytes, UTF-8-encoded runes, and space-delimited words. The
// client may instead provide a custom split function.
//
// Scanning stops unrecoverably at EOF, the first I/O error, or a token too
// large to fit in the buffer. When a scan stops, the reader may have
// advanced arbitrarily far past the last token. Programs that need more
// control over error handling or large tokens, or must run sequential scans
// on a reader, should use bufio.Reader instead.
//
type Scanner struct {
	r            io.Reader // The reader provided by the client.
	split        SplitFunc // The function to split the tokens.
	maxTokenSize int       // Maximum size of a token; modified by tests.
	token        []byte    // Last token returned by split.
	buf          []byte    // Buffer used as argument to split.
	start        int       // First non-processed byte in buf.
	end          int       // End of data in buf.
	err          error     // Sticky error.
	empties      int       // Count of successive empty tokens.
}

// SplitFunc is the signature of the split function used to tokenize the
// input. The arguments are an initial substring of the remaining unprocessed
// data and a flag, atEOF, that reports whether the Reader has no more data
// to give. The return values are the number of bytes to advance the input
// and the next token to return to the user, plus an error, if any. If the
// data does not yet hold a complete token, for instance if it has no newline
// while scanning lines, SplitFunc can return (0, nil, nil) to signal the
// Scanner to read more data into the slice and try again with a longer slice
// starting at the same point in the input.
//
// If the returned error is non-nil, scanning stops and the error
// is returned to the client.
//
// The function is never called with an empty data slice unless atEOF
// is true. If atEOF is true, however, data may be non-empty and,
// as always, holds unprocessed text.
type SplitFunc func(data []byte, atEOF bool) (advance int, token []byte, err error)

// Errors returned by Scanner.
var (
	ErrTooLong         = errors.New("bufio.Scanner: token too long")
	ErrNegativeAdvance = errors.New("bufio.Scanner: SplitFunc returns negative advance count")
	ErrAdvanceTooFar   = errors.New("bufio.Scanner: SplitFunc returns advance count beyond input")
)

const (
	// MaxScanTokenSize is the maximum size used to buffer a token.
	// The actual maximum token size may be smaller as the buffer
	// may need to include, for instance, a newline.
	MaxScanTokenSize         = 256 * 1024
	maxConsecutiveEmptyReads = 100
)

// NewScanner returns a new Scanner to read from r.
// The split function defaults to ScanLines.
func NewScanner(r io.Reader) *Scanner {
	return &Scanner{
		r:            r,
		split:        ScanLines,
		maxTokenSize: MaxScanTokenSize,
		buf:          make([]byte, 4096), // Plausible starting size; needn't be large.
	}
}

// Err returns the first non-EOF error that was encountered by the Scanner.
func (s *Scanner) Err() error {
	if s.err == io.EOF {
		return nil
	}
	return s.err
}

// Bytes returns the most recent token generated by a call to Scan.
// The underlying array may point to data that will be overwritten
// by a subsequent call to Scan. It does no allocation.
func (s *Scanner) Bytes() []byte {
	return s.token
}

// Text returns the most recent token generated by a call to Scan
// as a newly allocated string holding its bytes.
func (s *Scanner) Text() string {
	return string(s.token)
}

// Scan advances the Scanner to the next token, which will then be
// available through the Bytes or Text method. It returns false when the
// scan stops, either by reaching the end of the input or an error.
// After Scan returns false, the Err method will return any error that
// occurred during scanning, except that if it was io.EOF, Err
// will return nil.
// Split panics if the split function returns 100 empty tokens without
// advancing the input. This is a common error mode for scanners.
func (s *Scanner) Scan() bool {
	// Loop until we have a token.
	for {
		// See if we can get a token with what we already have.
		// If we've run out of data but have an error, give the split function
		// a chance to recover any remaining, possibly empty token.
		if s.end > s.start || s.err != nil {
			advance, token, err := s.split(s.buf[s.start:s.end], s.err != nil)
			if err != nil {
				s.setErr(err)
				return false
			}
			if !s.advance(advance) {
				return false
			}
			s.token = token
			if token != nil {
				if s.err == nil || advance > 0 {
					s.empties = 0
				} else {
					// Returning tokens not advancing input at EOF.
					s.empties++
					if s.empties > 100 {
						panic("bufio.Scan: 100 empty tokens without progressing")
					}
				}
				return true
			}
		}
		// We cannot generate a token with what we are holding.
		// If we've already hit EOF or an I/O error, we are done.
		if s.err != nil {
			// Shut it down.
			s.start = 0
			s.end = 0
			return false
		}
		// Must read more data.
		// First, shift data to beginning of buffer if there's lots of empty space
		// or space is needed.
		if s.start > 0 && (s.end == len(s.buf) || s.start > len(s.buf)/2) {
			copy(s.buf, s.buf[s.start:s.end])
			s.end -= s.start
			s.start = 0
		}
		// Is the buffer full? If so, resize.
		if s.end == len(s.buf) {
			if len(s.buf) >= s.maxTokenSize {
				s.setErr(ErrTooLong)
				return false
			}
			newSize := len(s.buf) * 2
			if newSize > s.maxTokenSize {
				newSize = s.maxTokenSize
			}
			newBuf := make([]byte, newSize)
			copy(newBuf, s.buf[s.start:s.end])
			s.buf = newBuf
			s.end -= s.start
			s.start = 0
			continue
		}
		// Finally we can read some input. Make sure we don't get stuck with
		// a misbehaving Reader. Officially we don't need to do this, but let's
		// be extra careful: Scanner is for safe, simple jobs.
		for loop := 0; ; {
			n, err := s.r.Read(s.buf[s.end:len(s.buf)])
			s.end += n
			if err != nil {
				s.setErr(err)
				break
			}
			if n > 0 {
				s.empties = 0
				break
			}
			loop++
			if loop > maxConsecutiveEmptyReads {
				s.setErr(io.ErrNoProgress)
				break
			}
		}
	}
}

// advance consumes n bytes of the buffer. It reports whether the advance was legal.
func (s *Scanner) advance(n int) bool {
	if n < 0 {
		s.setErr(ErrNegativeAdvance)
		return false
	}
	if n > s.end-s.start {
		s.setErr(ErrAdvanceTooFar)
		return false
	}
	s.start += n
	return true
}

// setErr records the first error encountered.
func (s *Scanner) setErr(err error) {
	if s.err == nil || s.err == io.EOF {
		s.err = err
	}
}

// Split sets the split function for the Scanner. If called, it must be
// called before Scan. The default split function is ScanLines.
func (s *Scanner) Split(split SplitFunc) {
	s.split = split
}

// Split functions

// ScanBytes is a split function for a Scanner that returns each byte as a token.
func ScanBytes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	return 1, data[0:1], nil
}

var errorRune = []byte(string(utf8.RuneError))

// ScanRunes is a split function for a Scanner that returns each
// UTF-8-encoded rune as a token. The sequence of runes returned is
// equivalent to that from a range loop over the input as a string, which
// means that erroneous UTF-8 encodings translate to U+FFFD = "\xef\xbf\xbd".
// Because of the Scan interface, this makes it impossible for the client to
// distinguish correctly encoded replacement runes from encoding errors.
func ScanRunes(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}

	// Fast path 1: ASCII.
	if data[0] < utf8.RuneSelf {
		return 1, data[0:1], nil
	}

	// Fast path 2: Correct UTF-8 decode without error.
	_, width := utf8.DecodeRune(data)
	if width > 1 {
		// It's a valid encoding. Width cannot be one for a correctly encoded
		// non-ASCII rune.
		return width, data[0:width], nil
	}

	// We know it's an error: we have width==1 and implicitly r==utf8.RuneError.
	// Is the error because there wasn't a full rune to be decoded?
	// FullRune distinguishes correctly between erroneous and incomplete encodings.
	if !atEOF && !utf8.FullRune(data) {
		// Incomplete; get more bytes.
		return 0, nil, nil
	}

	// We have a real UTF-8 encoding error. Return a properly encoded error rune
	// but advance only one byte. This matches the behavior of a range loop over
	// an incorrectly encoded string.
	return 1, errorRune, nil
}

// dropCR drops a terminal \r from the data.
func dropCR(data []byte) []byte {
	if len(data) > 0 && data[len(data)-1] == '\r' {
		return data[0 : len(data)-1]
	}
	return data
}

// ScanLines is a split function for a Scanner that returns each line of
// text, stripped of any trailing end-of-line marker. The returned line may
// be empty. The end-of-line marker is one optional carriage return followed
// by one mandatory newline. In regular expression notation, it is `\r?\n`.
// The last non-empty line of input will be returned even if it has no
// newline.
func ScanLines(data []byte, atEOF bool) (advance int, token []byte, err error) {
	if atEOF && len(data) == 0 {
		return 0, nil, nil
	}
	if i := bytes.IndexByte(data, '\n'); i >= 0 {
		// We have a full newline-terminated line.
		return i + 1, dropCR(data[0:i]), nil
	}
	// If we're at EOF, we have a final, non-terminated line. Return it.
	if atEOF {
		return len(data), dropCR(data), nil
	}
	// Request more data.
	return 0, nil, nil
}

// isSpace reports whether the character is a Unicode white space character.
// We avoid dependency on the unicode package, but check validity of the implementation
// in the tests.
func isSpace(r rune) bool {
	if r <= '\u00FF' {
		// Obvious ASCII ones: \t through \r plus space. Plus two Latin-1 oddballs.
		switch r {
		case ' ', '\t', '\n', '\v', '\f', '\r':
			return true
		case '\u0085', '\u00A0':
			return true
		}
		return false
	}
	// High-valued ones.
	if '\u2000' <= r && r <= '\u200a' {
		return true
	}
	switch r {
	case '\u1680', '\u2028', '\u2029', '\u202f', '\u205f', '\u3000':
		return true
	}
	return false
}

// ScanWords is a split function for a Scanner that returns each
// space-separated word of text, with surrounding spaces deleted. It will
// never return an empty string. The definition of space is set by
// unicode.IsSpace.
func ScanWords(data []byte, atEOF bool) (advance int, token []byte, err error) {
	// Skip leading spaces.
	start := 0
	for width := 0; start < len(data); start += width {
		var r rune
		r, width = utf8.DecodeRune(data[start:])
		if !isSpace(r) {
			break
		}
	}
	// Scan until space, marking end of word.
	for width, i := 0, start; i < len(data); i += width {
		var r rune
		r, width = utf8.DecodeRune(data[i:])
		if isSpace(r) {
			return i + width, data[start:i], nil
		}
	}
	// If we're at EOF, we have a final, non-empty, non-terminated word. Return it.
	if atEOF && len(data) > start {
		return len(data), data[start:], nil
	}
	// Request more data.
	return start, nil, nil
}
<|endoftext|>


<commit_before>package netpkg

import (
	"encoding/json"
	"time"
	"encoding/base64"
	"bytes"
	"github.com/emersion/go-kdeconnect/crypto"
)

const ProtocolVersion = 5

type Type string

const (
	IdentityType Type = "kdeconnect.identity"
	PairType = "kdeconnect.pair"
	EncryptedType = "kdeconnect.encrypted"

	// TODO: move all of these to plugins
	PingType = "kdeconnect.ping"
	TelephonyType = "kdeconnect.telephony"
	BatteryType = "kdeconnect.battery"
	SftpType = "kdeconnect.sftp"
	NotificationType = "kdeconnect.notification"
	ClipboardType = "kdeconnect.clipboard"
	MprisType = "kdeconnect.mpris"
	MousepadType = "kdeconnect.mousepad"
	ShareType = "kdeconnect.share"
	Capabilities = "kdeconnect.capabilities"
	FindMyPhoneType = "kdeconnect.findmyphone"
	RunCommandType = "kdeconnect.runcommand"
)

type Package struct {
	Id int64 `json:"id"`
	Type Type `json:"type"`
	RawBody json.RawMessage `json:"body"`
	Body interface{} `json:"-"`
}

func (p *Package) Serialize() []byte {
	p.Id = time.Now().UnixNano()

	p.RawBody, _ = json.Marshal(p.Body)
	output, _ := json.Marshal(p)
	output = append(output, byte('\n'))
	return output
}

func (p *Package) Encrypt(pub *crypto.PublicKey) (output *Package, err error) {
	raw := p.Serialize()

	encrypted, err := pub.Encrypt(raw)
	if err != nil {
		return
	}

	output = &Package{
		Type: EncryptedType,
		Body: &Encrypted{
			Data: []string{base64.StdEncoding.EncodeToString(encrypted)},
		},
	}
	return
}

func Unserialize(input []byte) (pkg *Package, err error) {
	if len(input) == 0 {
		return
	}

	err = json.Unmarshal(input, &pkg)
	if err != nil {
		return
	}

	switch pkg.Type {
	case IdentityType:
		pkg.Body = new(Identity)
	case PairType:
		pkg.Body = new(Pair)
	case EncryptedType:
		pkg.Body = new(Encrypted)
	}

	if pkg.Body != nil {
		err = json.Unmarshal(pkg.RawBody, pkg.Body)
	}
	return
}

type Identity struct {
	DeviceId string `json:"deviceId"`
	DeviceName string `json:"deviceName"`
	DeviceType string `json:"deviceType"`
	ProtocolVersion int `json:"protocolVersion"`
	TcpPort int `json:"tcpPort,omitempty"`
}

type Pair struct {
	PublicKey string `json:"publicKey"`
	Pair bool `json:"pair"`
}

type Encrypted struct {
	Data []string `json:"data"`
}

func (b *Encrypted) Decrypt(priv *crypto.PrivateKey) (pkg *Package, err error) {
	buffer := new(bytes.Buffer)
	var encrypted []byte
	var raw []byte
	for _, chunk := range b.Data {
		encrypted, err = base64.StdEncoding.DecodeString(chunk)
		if err != nil {
			return
		}

		raw, err = priv.Decrypt(encrypted)
		if err != nil {
			return
		}

		buffer.Write(raw)
	}

	pkg, err = Unserialize(buffer.Bytes())
	return
}
<commit_msg>Removes plugin message types from netpkg<commit_after>package netpkg

import (
	"encoding/json"
	"time"
	"encoding/base64"
	"bytes"
	"github.com/emersion/go-kdeconnect/crypto"
)

const ProtocolVersion = 5

type Type string

const (
	IdentityType Type = "kdeconnect.identity"
	PairType = "kdeconnect.pair"
	EncryptedType = "kdeconnect.encrypted"
)

type Package struct {
	Id int64 `json:"id"`
	Type Type `json:"type"`
	RawBody json.RawMessage `json:"body"`
	Body interface{} `json:"-"`
}

func (p *Package) Serialize() []byte {
	p.Id = time.Now().UnixNano()

	p.RawBody, _ = json.Marshal(p.Body)
	output, _ := json.Marshal(p)
	output = append(output, byte('\n'))
	return output
}

func (p *Package) Encrypt(pub *crypto.PublicKey) (output *Package, err error) {
	raw := p.Serialize()

	encrypted, err := pub.Encrypt(raw)
	if err != nil {
		return
	}

	output = &Package{
		Type: EncryptedType,
		Body: &Encrypted{
			Data: []string{base64.StdEncoding.EncodeToString(encrypted)},
		},
	}
	return
}

func Unserialize(input []byte) (pkg *Package, err error) {
	if len(input) == 0 {
		return
	}

	err = json.Unmarshal(input, &pkg)
	if err != nil {
		return
	}

	switch pkg.Type {
	case IdentityType:
		pkg.Body = new(Identity)
	case PairType:
		pkg.Body = new(Pair)
	case EncryptedType:
		pkg.Body = new(Encrypted)
	}

	if pkg.Body != nil {
		err = json.Unmarshal(pkg.RawBody, pkg.Body)
	}
	return
}

type Identity struct {
	DeviceId string `json:"deviceId"`
	DeviceName string `json:"deviceName"`
	DeviceType string `json:"deviceType"`
	ProtocolVersion int `json:"protocolVersion"`
	TcpPort int `json:"tcpPort,omitempty"`
}

type Pair struct {
	PublicKey string `json:"publicKey"`
	Pair bool `json:"pair"`
}

type Encrypted struct {
	Data []string `json:"data"`
}

func (b *Encrypted) Decrypt(priv *crypto.PrivateKey) (pkg *Package, err error) {
	buffer := new(bytes.Buffer)
	var encrypted []byte
	var raw []byte
	for _, chunk := range b.Data {
		encrypted, err = base64.StdEncoding.DecodeString(chunk)
		if err != nil {
			return
		}

		raw, err = priv.Decrypt(encrypted)
		if err != nil {
			return
		}

		buffer.Write(raw)
	}

	pkg, err = Unserialize(buffer.Bytes())
	return
}
<|endoftext|>


<commit_before>package omxplayer

import (
	log "github.com/Sirupsen/logrus"
	"github.com/guelfey/go.dbus"
	"os/exec"
	"time"
)

const (
	ifaceProps     = "org.freedesktop.DBus.Properties"
	ifaceOmxRoot   = ifaceMpris
	ifaceOmxPlayer = ifaceOmxRoot + ".Player"

	cmdQuit                 = ifaceOmxRoot + ".Quit"
	propCanQuit             = ifaceProps + ".CanQuit"
	propFullscreen          = ifaceProps + ".Fullscreen"
	propCanSetFullscreen    = ifaceProps + ".CanSetFullscreen"
	propCanRaise            = ifaceProps + ".CanRaise"
	propHasTrackList        = ifaceProps + ".HasTrackList"
	propIdentity            = ifaceProps + ".Identity"
	propSupportedUriSchemes = ifaceProps + ".SupportedUriSchemes"
	propSupportedMimeTypes  = ifaceProps + ".SupportedMimeTypes"
	propCanGoNext           = ifaceProps + ".CanGoNext"
	propCanGoPrevious       = ifaceProps + ".CanGoPrevious"
	propCanSeek             = ifaceProps + ".CanSeek"
	propCanControl          = ifaceProps + ".CanControl"
	propCanPlay             = ifaceProps + ".CanPlay"
	propCanPause            = ifaceProps + ".CanPause"
	cmdNext                 = ifaceOmxPlayer + ".Next"
	cmdPrevious             = ifaceOmxPlayer + ".Previous"
	cmdPause                = ifaceOmxPlayer + ".Pause"
	cmdPlayPause            = ifaceOmxPlayer + ".PlayPause"
	cmdStop                 = ifaceOmxPlayer + ".Stop"
	cmdSeek                 = ifaceOmxPlayer + ".Seek"
	cmdSetPosition          = ifaceOmxPlayer + ".SetPosition"
	propPlaybackStatus      = ifaceProps + ".PlaybackStatus"
	cmdVolume               = ifaceProps + ".Volume"
	cmdMute                 = ifaceProps + ".Mute"
	cmdUnmute               = ifaceProps + ".Unmute"
	propPosition            = ifaceProps + ".Position"
	propAspect              = ifaceProps + ".Aspect"
	propVideoStreamCount    = ifaceProps + ".VideoStreamCount"
	propResWidth            = ifaceProps + ".ResWidth"
	propResHeight           = ifaceProps + ".ResHeight"
	propDuration            = ifaceProps + ".Duration"
	propMinimumRate         = ifaceProps + ".MinimumRate"
	propMaximumRate         = ifaceProps + ".MaximumRate"
	cmdListSubtitles        = ifaceOmxPlayer + ".ListSubtitles"
	cmdHideVideo            = ifaceOmxPlayer + ".HideVideo"
	cmdUnHideVideo          = ifaceOmxPlayer + ".UnHideVideo"
	cmdListAudio            = ifaceOmxPlayer + ".ListAudio"
	cmdListVideo            = ifaceOmxPlayer + ".ListVideo"
	cmdSelectSubtitle       = ifaceOmxPlayer + ".SelectSubtitle"
	cmdSelectAudio          = ifaceOmxPlayer + ".SelectAudio"
	cmdShowSubtitles        = ifaceOmxPlayer + ".ShowSubtitles"
	cmdHideSubtitles        = ifaceOmxPlayer + ".HideSubtitles"
	cmdAction               = ifaceOmxPlayer + ".Action"
)

type Player struct {
	command    *exec.Cmd
	connection *dbus.Conn
	bus        *dbus.Object
	ready      bool
}

// IsReady checks to see if the Player instance is ready to accept D-Bus
// commands. If the player is ready and can accept commands, the function
// returns true, otherwise it returns false.
func (p *Player) IsReady() bool {
	if p.ready {
		return true
	}

	_, err := p.CanQuit()
	p.ready = err != nil
	return p.ready
}

// WaitForReady waits until the Player instance is ready to accept D-Bus
// commands and then returns.
func (p *Player) WaitForReady() {
	for !p.IsReady() {
		time.Sleep(50 * time.Millisecond)
	}
}

func (p *Player) Quit() error {
	return dbusCall(p.bus, cmdQuit)
}

func (p *Player) CanQuit() (bool, error) {
	return dbusGetBool(p.bus, propCanQuit)
}

func (p *Player) Fullscreen() (bool, error) {
	return dbusGetBool(p.bus, propFullscreen)
}

func (p *Player) CanSetFullscreen() (bool, error) {
	return dbusGetBool(p.bus, propCanSetFullscreen)
}

func (p *Player) CanRaise() (bool, error) {
	return dbusGetBool(p.bus, propCanRaise)
}

func (p *Player) HasTrackList() (bool, error) {
	return dbusGetBool(p.bus, propHasTrackList)
}

func (p *Player) Identity() (string, error) {
	return dbusGetString(p.bus, propIdentity)
}

func (p *Player) SupportedUriSchemes() ([]string, error) {
	return dbusGetStringArray(p.bus, propSupportedUriSchemes)
}

func (p *Player) SupportedMimeTypes() ([]string, error) {
	return dbusGetStringArray(p.bus, propSupportedMimeTypes)
}

func (p *Player) CanGoNext() (bool, error) {
	return dbusGetBool(p.bus, propCanGoNext)
}

func (p *Player) CanGoPrevious() (bool, error) {
	return dbusGetBool(p.bus, propCanGoPrevious)
}

func (p *Player) CanSeek() (bool, error) {
	return dbusGetBool(p.bus, cmdSeek)
}

func (p *Player) CanControl() (bool, error) {
	return dbusGetBool(p.bus, propCanControl)
}

func (p *Player) CanPlay() (bool, error) {
	return dbusGetBool(p.bus, propCanPlay)
}

func (p *Player) CanPause() (bool, error) {
	return dbusGetBool(p.bus, propCanPause)
}

func (p *Player) Next() error {
	return dbusCall(p.bus, cmdNext)
}

func (p *Player) Previous() error {
	return dbusCall(p.bus, cmdPrevious)
}

func (p *Player) Pause() error {
	return dbusCall(p.bus, cmdPause)
}

func (p *Player) PlayPause() error {
	return dbusCall(p.bus, cmdPlayPause)
}

func (p *Player) Stop() error {
	return dbusCall(p.bus, cmdStop)
}

func (p *Player) Seek(amount int64) (int64, error) {
	log.WithFields(log.Fields{
		"path":        cmdSeek,
		"paramAmount": amount,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSeek, 0, amount)
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(int64), nil
}

func (p *Player) SetPosition(path string, position int64) (int64, error) {
	log.WithFields(log.Fields{
		"path":          cmdSetPosition,
		"paramPath":     path,
		"paramPosition": position,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSetPosition, 0, path, position)
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(int64), nil
}

func (p *Player) PlaybackStatus() (string, error) {
	return dbusGetString(p.bus, propPlaybackStatus)
}

func (p *Player) Volume(volume ...float64) (float64, error) {
	log.WithFields(log.Fields{
		"path":        cmdVolume,
		"paramVolume": volume,
	}).Debug("omxplayer: dbus call")
	if len(volume) == 0 {
		return dbusGetFloat64(p.bus, cmdVolume)
	}
	call := p.bus.Call(cmdVolume, 0, volume[0])
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(float64), nil
}

func (p *Player) Mute() error {
	return dbusCall(p.bus, cmdMute)
}

func (p *Player) Unmute() error {
	return dbusCall(p.bus, cmdUnmute)
}

func (p *Player) Position() (int64, error) {
	return dbusGetInt64(p.bus, propPosition)
}

func (p *Player) Aspect() (float64, error) {
	return dbusGetFloat64(p.bus, propAspect)
}

func (p *Player) VideoStreamCount() (int64, error) {
	return dbusGetInt64(p.bus, propVideoStreamCount)
}

func (p *Player) ResWidth() (int64, error) {
	return dbusGetInt64(p.bus, propResWidth)
}

func (p *Player) ResHeight() (int64, error) {
	return dbusGetInt64(p.bus, propResHeight)
}

func (p *Player) Duration() (int64, error) {
	return dbusGetInt64(p.bus, propDuration)
}

func (p *Player) MinimumRate() (float64, error) {
	return dbusGetFloat64(p.bus, propMinimumRate)
}

func (p *Player) MaximumRate() (float64, error) {
	return dbusGetFloat64(p.bus, propMaximumRate)
}

func (p *Player) ListSubtitles() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListSubtitles)
}

func (p *Player) HideVideo() error {
	return dbusCall(p.bus, cmdHideVideo)
}

func (p *Player) UnHideVideo() error {
	return dbusCall(p.bus, cmdUnHideVideo)
}

func (p *Player) ListAudio() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListAudio)
}

func (p *Player) ListVideo() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListVideo)
}

func (p *Player) SelectSubtitle(index int32) (bool, error) {
	log.WithFields(log.Fields{
		"path":       cmdSelectSubtitle,
		"paramIndex": index,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSelectSubtitle, 0, index)
	if call.Err != nil {
		return false, call.Err
	}
	return call.Body[0].(bool), nil
}

func (p *Player) SelectAudio(index int32) (bool, error) {
	log.WithFields(log.Fields{
		"path":       cmdSelectAudio,
		"paramIndex": index,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSelectAudio, 0, index)
	if call.Err != nil {
		return false, call.Err
	}
	return call.Body[0].(bool), nil
}

func (p *Player) ShowSubtitles() error {
	return dbusCall(p.bus, cmdShowSubtitles)
}

func (p *Player) HideSubtitles() error {
	return dbusCall(p.bus, cmdHideSubtitles)
}

func (p *Player) Action(action int32) error {
	log.WithFields(log.Fields{
		"path":        cmdAction,
		"paramAction": action,
	}).Debug("omxplayer: dbus call")
	return p.bus.Call(cmdAction, 0, action).Err
}
<commit_msg>Add IsRunning method.<commit_after>package omxplayer

import (
	log "github.com/Sirupsen/logrus"
	"github.com/guelfey/go.dbus"
	"os"
	"os/exec"
	"syscall"
	"time"
)

const (
	ifaceProps     = "org.freedesktop.DBus.Properties"
	ifaceOmxRoot   = ifaceMpris
	ifaceOmxPlayer = ifaceOmxRoot + ".Player"

	cmdQuit                 = ifaceOmxRoot + ".Quit"
	propCanQuit             = ifaceProps + ".CanQuit"
	propFullscreen          = ifaceProps + ".Fullscreen"
	propCanSetFullscreen    = ifaceProps + ".CanSetFullscreen"
	propCanRaise            = ifaceProps + ".CanRaise"
	propHasTrackList        = ifaceProps + ".HasTrackList"
	propIdentity            = ifaceProps + ".Identity"
	propSupportedUriSchemes = ifaceProps + ".SupportedUriSchemes"
	propSupportedMimeTypes  = ifaceProps + ".SupportedMimeTypes"
	propCanGoNext           = ifaceProps + ".CanGoNext"
	propCanGoPrevious       = ifaceProps + ".CanGoPrevious"
	propCanSeek             = ifaceProps + ".CanSeek"
	propCanControl          = ifaceProps + ".CanControl"
	propCanPlay             = ifaceProps + ".CanPlay"
	propCanPause            = ifaceProps + ".CanPause"
	cmdNext                 = ifaceOmxPlayer + ".Next"
	cmdPrevious             = ifaceOmxPlayer + ".Previous"
	cmdPause                = ifaceOmxPlayer + ".Pause"
	cmdPlayPause            = ifaceOmxPlayer + ".PlayPause"
	cmdStop                 = ifaceOmxPlayer + ".Stop"
	cmdSeek                 = ifaceOmxPlayer + ".Seek"
	cmdSetPosition          = ifaceOmxPlayer + ".SetPosition"
	propPlaybackStatus      = ifaceProps + ".PlaybackStatus"
	cmdVolume               = ifaceProps + ".Volume"
	cmdMute                 = ifaceProps + ".Mute"
	cmdUnmute               = ifaceProps + ".Unmute"
	propPosition            = ifaceProps + ".Position"
	propAspect              = ifaceProps + ".Aspect"
	propVideoStreamCount    = ifaceProps + ".VideoStreamCount"
	propResWidth            = ifaceProps + ".ResWidth"
	propResHeight           = ifaceProps + ".ResHeight"
	propDuration            = ifaceProps + ".Duration"
	propMinimumRate         = ifaceProps + ".MinimumRate"
	propMaximumRate         = ifaceProps + ".MaximumRate"
	cmdListSubtitles        = ifaceOmxPlayer + ".ListSubtitles"
	cmdHideVideo            = ifaceOmxPlayer + ".HideVideo"
	cmdUnHideVideo          = ifaceOmxPlayer + ".UnHideVideo"
	cmdListAudio            = ifaceOmxPlayer + ".ListAudio"
	cmdListVideo            = ifaceOmxPlayer + ".ListVideo"
	cmdSelectSubtitle       = ifaceOmxPlayer + ".SelectSubtitle"
	cmdSelectAudio          = ifaceOmxPlayer + ".SelectAudio"
	cmdShowSubtitles        = ifaceOmxPlayer + ".ShowSubtitles"
	cmdHideSubtitles        = ifaceOmxPlayer + ".HideSubtitles"
	cmdAction               = ifaceOmxPlayer + ".Action"
)

type Player struct {
	command    *exec.Cmd
	connection *dbus.Conn
	bus        *dbus.Object
	ready      bool
}

// IsRunning checks to see if the OMXPlayer process is running. If it is, the
// function returns true, otherwise it returns false.
func (p *Player) IsRunning() bool {
	pid := p.command.Process.Pid
	process, err := os.FindProcess(pid)
	if err != nil {
		return false
	} else {
		err = process.Signal(syscall.Signal(0))
		return err != nil
	}
}

// IsReady checks to see if the Player instance is ready to accept D-Bus
// commands. If the player is ready and can accept commands, the function
// returns true, otherwise it returns false.
func (p *Player) IsReady() bool {
	if p.ready {
		return true
	}

	_, err := p.CanQuit()
	p.ready = err != nil
	return p.ready
}

// WaitForReady waits until the Player instance is ready to accept D-Bus
// commands and then returns.
func (p *Player) WaitForReady() {
	for !p.IsReady() {
		time.Sleep(50 * time.Millisecond)
	}
}

func (p *Player) Quit() error {
	return dbusCall(p.bus, cmdQuit)
}

func (p *Player) CanQuit() (bool, error) {
	return dbusGetBool(p.bus, propCanQuit)
}

func (p *Player) Fullscreen() (bool, error) {
	return dbusGetBool(p.bus, propFullscreen)
}

func (p *Player) CanSetFullscreen() (bool, error) {
	return dbusGetBool(p.bus, propCanSetFullscreen)
}

func (p *Player) CanRaise() (bool, error) {
	return dbusGetBool(p.bus, propCanRaise)
}

func (p *Player) HasTrackList() (bool, error) {
	return dbusGetBool(p.bus, propHasTrackList)
}

func (p *Player) Identity() (string, error) {
	return dbusGetString(p.bus, propIdentity)
}

func (p *Player) SupportedUriSchemes() ([]string, error) {
	return dbusGetStringArray(p.bus, propSupportedUriSchemes)
}

func (p *Player) SupportedMimeTypes() ([]string, error) {
	return dbusGetStringArray(p.bus, propSupportedMimeTypes)
}

func (p *Player) CanGoNext() (bool, error) {
	return dbusGetBool(p.bus, propCanGoNext)
}

func (p *Player) CanGoPrevious() (bool, error) {
	return dbusGetBool(p.bus, propCanGoPrevious)
}

func (p *Player) CanSeek() (bool, error) {
	return dbusGetBool(p.bus, cmdSeek)
}

func (p *Player) CanControl() (bool, error) {
	return dbusGetBool(p.bus, propCanControl)
}

func (p *Player) CanPlay() (bool, error) {
	return dbusGetBool(p.bus, propCanPlay)
}

func (p *Player) CanPause() (bool, error) {
	return dbusGetBool(p.bus, propCanPause)
}

func (p *Player) Next() error {
	return dbusCall(p.bus, cmdNext)
}

func (p *Player) Previous() error {
	return dbusCall(p.bus, cmdPrevious)
}

func (p *Player) Pause() error {
	return dbusCall(p.bus, cmdPause)
}

func (p *Player) PlayPause() error {
	return dbusCall(p.bus, cmdPlayPause)
}

func (p *Player) Stop() error {
	return dbusCall(p.bus, cmdStop)
}

func (p *Player) Seek(amount int64) (int64, error) {
	log.WithFields(log.Fields{
		"path":        cmdSeek,
		"paramAmount": amount,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSeek, 0, amount)
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(int64), nil
}

func (p *Player) SetPosition(path string, position int64) (int64, error) {
	log.WithFields(log.Fields{
		"path":          cmdSetPosition,
		"paramPath":     path,
		"paramPosition": position,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSetPosition, 0, path, position)
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(int64), nil
}

func (p *Player) PlaybackStatus() (string, error) {
	return dbusGetString(p.bus, propPlaybackStatus)
}

func (p *Player) Volume(volume ...float64) (float64, error) {
	log.WithFields(log.Fields{
		"path":        cmdVolume,
		"paramVolume": volume,
	}).Debug("omxplayer: dbus call")
	if len(volume) == 0 {
		return dbusGetFloat64(p.bus, cmdVolume)
	}
	call := p.bus.Call(cmdVolume, 0, volume[0])
	if call.Err != nil {
		return 0, call.Err
	}
	return call.Body[0].(float64), nil
}

func (p *Player) Mute() error {
	return dbusCall(p.bus, cmdMute)
}

func (p *Player) Unmute() error {
	return dbusCall(p.bus, cmdUnmute)
}

func (p *Player) Position() (int64, error) {
	return dbusGetInt64(p.bus, propPosition)
}

func (p *Player) Aspect() (float64, error) {
	return dbusGetFloat64(p.bus, propAspect)
}

func (p *Player) VideoStreamCount() (int64, error) {
	return dbusGetInt64(p.bus, propVideoStreamCount)
}

func (p *Player) ResWidth() (int64, error) {
	return dbusGetInt64(p.bus, propResWidth)
}

func (p *Player) ResHeight() (int64, error) {
	return dbusGetInt64(p.bus, propResHeight)
}

func (p *Player) Duration() (int64, error) {
	return dbusGetInt64(p.bus, propDuration)
}

func (p *Player) MinimumRate() (float64, error) {
	return dbusGetFloat64(p.bus, propMinimumRate)
}

func (p *Player) MaximumRate() (float64, error) {
	return dbusGetFloat64(p.bus, propMaximumRate)
}

func (p *Player) ListSubtitles() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListSubtitles)
}

func (p *Player) HideVideo() error {
	return dbusCall(p.bus, cmdHideVideo)
}

func (p *Player) UnHideVideo() error {
	return dbusCall(p.bus, cmdUnHideVideo)
}

func (p *Player) ListAudio() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListAudio)
}

func (p *Player) ListVideo() ([]string, error) {
	return dbusGetStringArray(p.bus, cmdListVideo)
}

func (p *Player) SelectSubtitle(index int32) (bool, error) {
	log.WithFields(log.Fields{
		"path":       cmdSelectSubtitle,
		"paramIndex": index,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSelectSubtitle, 0, index)
	if call.Err != nil {
		return false, call.Err
	}
	return call.Body[0].(bool), nil
}

func (p *Player) SelectAudio(index int32) (bool, error) {
	log.WithFields(log.Fields{
		"path":       cmdSelectAudio,
		"paramIndex": index,
	}).Debug("omxplayer: dbus call")
	call := p.bus.Call(cmdSelectAudio, 0, index)
	if call.Err != nil {
		return false, call.Err
	}
	return call.Body[0].(bool), nil
}

func (p *Player) ShowSubtitles() error {
	return dbusCall(p.bus, cmdShowSubtitles)
}

func (p *Player) HideSubtitles() error {
	return dbusCall(p.bus, cmdHideSubtitles)
}

func (p *Player) Action(action int32) error {
	log.WithFields(log.Fields{
		"path":        cmdAction,
		"paramAction": action,
	}).Debug("omxplayer: dbus call")
	return p.bus.Call(cmdAction, 0, action).Err
}
<|endoftext|>


<commit_before>// Copyright ©2013 The rivet Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package nlptoken

// Following Rob Pike's discussion of building a lexer that
// "Executes an action, returns the next state—as a state function."
// something like:

/*
	// lexer holds the state of the scanner.
	type lexer struct {
		name  string    // used only for error reports.
		input string    // the string being scanned.
		start int       // start position of this item.
		pos   int       // current position in the input.
		width int       // width of last rune read from input.
		items chan item // channel of scanned items.
	}
	// stateFn represents the state of the scanner
	// as a function that returns the next state.
	type stateFn func(*lexer) stateFn

	// run lexes the input by executing state functions
	// until the state is nil.
	func run() {
		for state := startState; state != nil; {
			state = state(lexer)
		}
	}

	// run lexes the input by executing state functions until
	// the state is nil.
	func (l *lexer) run() {
		for state := lexText; state != nil; {
			state = state(l)
		}
		close(l.items) // No more tokens will be delivered.
	}

	func lex(name, input string) (*lexer, chan item) {
		l := &lexer{
			name:  name,
			input: input,
			items: make(chan item),
		}
		go l.run()  // Concurrently run state machine.
		return l, l.items
	}
*/
<commit_msg>more fake code for the nlp token lexer<commit_after>// Copyright ©2013 The rivet Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package nlptoken

/*
// Following Rob Pike's discussion of building a lexer that
// "Executes an action, returns the next state—as a state function."
// http://cuddle.googlecode.com/hg/talk/lex.html#landing-slide
// something like:

SEE https://groups.google.com/forum/#!topic/golang-nuts/DcONCTJUDhY for discussion
NOTE: as of Go 1 we can use goroutines with init() functions

LEXER IN http://weekly.golang.org/src/pkg/text/template/parse/lex.go

	// lexer holds the state of the scanner.
	type lexer struct {
		name  string    // used only for error reports.
		input string    // the string being scanned.
		start int       // start position of this item.
		pos   int       // current position in the input.
		width int       // width of last rune read from input.
		items chan item // channel of scanned items.
	}
	// stateFn represents the state of the scanner
	// as a function that returns the next state.
	type stateFn func(*lexer) stateFn

	// run lexes the input by executing state functions
	// until the state is nil.
	func run() {
		for state := startState; state != nil; {
			state = state(lexer)
		}
	}

	// run lexes the input by executing state functions until
	// the state is nil.
	func (l *lexer) run() {
		for state := lexText; state != nil; {
			state = state(l)
		}
		close(l.items) // No more tokens will be delivered.
	}

	func lex(name, input string) (*lexer, chan item) {
		l := &lexer{
			name:  name,
			input: input,
			items: make(chan item),
		}
		go l.run()  // Concurrently run state machine.
		return l, l.items
	}

	// emit passes an item back to the client.
	func (l *lexer) emit(t itemType) {
		l.items <- item{t, l.input[l.start:l.pos]}
		l.start = l.pos
	}
	const leftMeta = "{{"

	func lexText(l *lexer) stateFn {
		for {
			if strings.HasPrefix(l.input[l.pos:], leftMeta) {
				if l.pos > l.start {
					l.emit(itemText)
				}
				return lexLeftMeta    // Next state.
			}
			if l.next() == eof { break }
		}
		// Correctly reached EOF.
		if l.pos > l.start {
			l.emit(itemText)
		}
		l.emit(itemEOF)  // Useful to make EOF a token.
		return nil       // Stop the run loop.
	}

	func lexLeftMeta(l *lexer) stateFn {
		l.pos += len(leftMeta)
		l.emit(itemLeftMeta)
		return lexInsideAction    // Now inside {{ }}.
	}

	func lexInsideAction(l *lexer) stateFn {
		// Either number, quoted string, or identifier.
		// Spaces separate and are ignored.
		// Pipe symbols separate and are emitted.
		for {
			if strings.HasPrefix(l.input[l.pos:], rightMeta) {
				return lexRightMeta
			}
			switch r := l.next(); {
			case r == eof || r == '\n':
				return l.errorf("unclosed action")
			case isSpace(r):
				l.ignore()
			case r == '|':
				l.emit(itemPipe)
			case r == '"':
				return lexQuote
			case r == '`':
				return lexRawQuote
			case r == '+' || r == '-' || '0' <= r && r <= '9':
				l.backup()
				return lexNumber
			case isAlphaNumeric(r):
				l.backup()
				return lexIdentifier
			}
		}
	}

	// next returns the next rune in the input.
	func (l *lexer) next() (rune int) {
		if l.pos >= len(l.input) {
			l.width = 0
			return eof
		}
		rune, l.width =
			utf8.DecodeRuneInString(l.input[l.pos:])
		l.pos += l.width
		return rune
	}

	// ignore skips over the pending input before this point.
	func (l *lexer) ignore() {
		l.start = l.pos
	}

	// backup steps back one rune.
	// Can be called only once per call of next.
	func (l *lexer) backup() {
		l.pos -= l.width
	}

	// peek returns but does not consume
	// the next rune in the input.
	func (l *lexer) peek() int {
		rune := l.next()
		l.backup()
		return rune
	}

	// accept consumes the next rune
	// if it's from the valid set.
	func (l *lexer) accept(valid string) bool {
		if strings.IndexRune(valid, l.next()) >= 0 {
			return true
		}
		l.backup()
		return false
	}

	// acceptRun consumes a run of runes from the valid set.
	func (l *lexer) acceptRun(valid string) {
		for strings.IndexRune(valid, l.next()) >= 0 {
		}
		l.backup()
	}

	func lexNumber(l *lexer) stateFn {
		// Optional leading sign.
		l.accept("+-")
		// Is it hex?
		digits := "0123456789"
		if l.accept("0") && l.accept("xX") {
			digits = "0123456789abcdefABCDEF"
		}
		l.acceptRun(digits)
		if l.accept(".") {
			l.acceptRun(digits)
		}
		if l.accept("eE") {
			l.accept("+-")
			l.acceptRun("0123456789")
		}
		// Is it imaginary?
		l.accept("i")
		// Next thing mustn't be alphanumeric.
		if isAlphaNumeric(l.peek()) {
			l.next()
			return l.errorf("bad number syntax: %q",
				l.input[l.start:l.pos])
		}
		l.emit(itemNumber)
		return lexInsideAction
	}

	// error returns an error token and terminates the scan
	// by passing back a nil pointer that will be the next
	// state, terminating l.run.
	func (l *lexer) errorf(format string, args ...interface{})
	  stateFn {
		l.items <- item{
			itemError,
			fmt.Sprintf(format, args...),
		}
		return nil
	}

!!!!!*******************************
	With Go 1, the lexer can go back to using a goroutine. I should
probably make that change.
-rob
!!!!!*******************************

	// lex creates a new scanner for the input string.
	func lex(name, input string) *lexer {
		l := &lexer{
			name:  name,
			input: input,
			state: lexText,
			items: make(chan item, 2), // Two items sufficient.
		}
		return l
	}

	// nextItem returns the next item from the input.
	func (l *lexer) nextItem() item {
		for {
			select {
			case item := <-l.items:
				return item
			default:
				l.state = l.state(l)
			}
		}
		panic("not reached")
	}
*/
<|endoftext|>


<commit_before>package main

import (
	"log"
	"net/url"
	"os"
	"os/exec"
	"syscall"
)

func execPlugin(path string, args []string) error {
	u, err := url.Parse(apiURL)
	if err != nil {
		log.Fatal(err)
	}

	hkuser, hkpass := getCreds(u)
	hkapp, _ := app()
	env := []string{
		"HKAPP=" + hkapp,
		"HKUSER=" + hkuser,
		"HKPASS=" + hkpass,
		"HKHOST=" + u.Host,
		"HKVERSION=" + Version,
	}

	return syscall.Exec(path, args, append(env, os.Environ()...))
}

func findPlugin(name string) (path string) {
	path = lookupPlugin(name)
	if path == "" {
		path = lookupPlugin("default")
	}
	return path
}

// NOTE: lookupPlugin is not threadsafe for anything needing the PATH env var.
func lookupPlugin(name string) string {
	const defaultPluginPath = "/usr/local/lib/hk/plugin"

	opath := os.Getenv("PATH")
	defer os.Setenv("PATH", opath)

	os.Setenv("PATH", os.Getenv("HKPATH")+":"+defaultPluginPath)
	path, err := exec.LookPath(name)
	if err != nil {
		if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound {
			return ""
		}
		log.Fatal(err)
	}
	return path
}
<commit_msg>export HEROKU_API_URL to plugins<commit_after>package main

import (
	"log"
	"net/url"
	"os"
	"os/exec"
	"syscall"
)

func execPlugin(path string, args []string) error {
	u, err := url.Parse(apiURL)
	if err != nil {
		log.Fatal(err)
	}

	hkuser, hkpass := getCreds(u)
	hkapp, _ := app()
	env := []string{
		"HEROKU_API_URL="+apiURL,
		"HKAPP=" + hkapp,
		"HKUSER=" + hkuser,
		"HKPASS=" + hkpass,
		"HKHOST=" + u.Host,
		"HKVERSION=" + Version,
	}

	return syscall.Exec(path, args, append(env, os.Environ()...))
}

func findPlugin(name string) (path string) {
	path = lookupPlugin(name)
	if path == "" {
		path = lookupPlugin("default")
	}
	return path
}

// NOTE: lookupPlugin is not threadsafe for anything needing the PATH env var.
func lookupPlugin(name string) string {
	const defaultPluginPath = "/usr/local/lib/hk/plugin"

	opath := os.Getenv("PATH")
	defer os.Setenv("PATH", opath)

	os.Setenv("PATH", os.Getenv("HKPATH")+":"+defaultPluginPath)
	path, err := exec.LookPath(name)
	if err != nil {
		if e, ok := err.(*exec.Error); ok && e.Err == exec.ErrNotFound {
			return ""
		}
		log.Fatal(err)
	}
	return path
}
<|endoftext|>


<commit_before>// Copyright 2012 Kevin Gillette. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package polish

import "strconv"

type Runner interface {
	Run([]float64) []float64
}

type Program []Runner

func (p Program) Run(stack []float64) []float64 {
	for _, s := range p {
		stack = s.Run(stack)
	}
	return stack
}

type Constant float64

func (c Constant) Run(stack []float64) []float64 {
	return append(stack, float64(c))
}

type BinOp func(float64, float64) float64

func (f BinOp) Run(stack []float64) []float64 {
	l := len(stack)
	x, y, stack := stack[l-2], stack[l-1], stack[:l-2]
	return append(stack, f(x, y))
}

func Add(x, y float64) float64 { return x + y }
func Sub(x, y float64) float64 { return x - y }
func Mul(x, y float64) float64 { return x * y }
func Div(x, y float64) float64 { return x / y }

func Parse(args []string) (p Program, err error) {
	p = make(Program, len(args))
	for i, str := range args {
		switch str {
		case "+":
			p[i] = BinOp(Add)
		case "-":
			p[i] = BinOp(Sub)
		case "*":
			p[i] = BinOp(Mul)
		case "/":
			p[i] = BinOp(Div)
		default:
			n, err := strconv.ParseFloat(str, 64)
			if err != nil {
				return p, err
			}
			p[i] = Constant(n)
		}
	}
	return p, nil
}
<commit_msg>Parse is now extensible by adding words to Dict<commit_after>// Copyright 2012 Kevin Gillette. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package polish

import "strconv"

type Runner interface {
	Run([]float64) []float64
}

type Program []Runner

func (p Program) Run(stack []float64) []float64 {
	for _, s := range p {
		stack = s.Run(stack)
	}
	return stack
}

type Constant float64

func (c Constant) Run(stack []float64) []float64 {
	return append(stack, float64(c))
}

type BinOp func(float64, float64) float64

func (f BinOp) Run(stack []float64) []float64 {
	l := len(stack)
	x, y, stack := stack[l-2], stack[l-1], stack[:l-2]
	return append(stack, f(x, y))
}

func Add(x, y float64) float64 { return x + y }
func Sub(x, y float64) float64 { return x - y }
func Mul(x, y float64) float64 { return x * y }
func Div(x, y float64) float64 { return x / y }

var Dict = map[string]Runner{
	"+": BinOp(Add),
	"-": BinOp(Sub),
	"*": BinOp(Mul),
	"/": BinOp(Div),
}

func Parse(args []string) (p Program, err error) {
	p = make(Program, len(args))
	for i, arg := range args {
		word, ok := Dict[arg]
		if !ok {
			n, err := strconv.ParseFloat(arg, 64)
			if err != nil {
				return nil, err
			}
			word = Constant(n)
		}
		p[i] = word
	}
	return p, nil
}
<|endoftext|>