<commit_before>package stripe

import (
	"net/url"
	"strconv"
)

type Fund struct {
	Amount   int64  `json:"amount"`
	Currency string `json:"currency"`
}

type Balance struct {
	Object    string  `json:"object"`
	Livemode  bool    `json:"livemode"`
	Available []*Fund `json:"available"`
	Pending   []*Fund `json:"pending"`
}

type FeeDetails struct {
	Amount      int64  `json:"amount"`
	Currency    string `json:"currency"`
	Type        string `json:"type"`
	Description string `json:"description"`
	Application string `json:"application"`
}

type BalanceTransaction struct {
	Id          string        `json:"id"`
	Object      string        `json:"object"`
	Source      string        `json:"source"`
	Amount      int64         `json:"amount"`
	Currency    string        `json:"currency"`
	Net         int64         `json:"net"`
	Type        string        `json:"type"`
	Created     int64         `json:"created"`
	AvailableOn int64         `json:"available_on"`
	Status      string        `json:"status"`
	Fee         int64         `json:"fee"`
	FeeDetails  []*FeeDetails `json:"fee_details"`
}

type BalanceClient struct{}

// Retrieve loads a balance.
//
// For more information: https://stripe.com/docs/api#retrieve_balance
func (c *BalanceClient) Retrieve() (*Balance, error) {
	balance := Balance{}
	err := get("/balance", nil, &balance)
	return &balance, err
}

// RetrieveTransaction loads a balance transaction.
//
// For more information: https://stripe.com/docs/api#retrieve_balance_transaction
func (c *BalanceClient) RetrieveTransaction(id string) (*BalanceTransaction, error) {
	balanceTransaction := BalanceTransaction{}
	err := get("/balance/history/"+id, nil, &balanceTransaction)
	return &balanceTransaction, err
}

// History lists the first 10 balances in the balance history. It calls HistoryCount
// with 10 as the count and 0 as the offset, which are the defaults in the
// Stripe API.
//
// For more information: https://stripe.com/docs/api#balance_history
func (c *BalanceClient) History() ([]*BalanceTransaction, error) {
	return c.HistoryCount(10, 0)
}

// HistoryCount lists `count` balances in the balance history starting at `offset`.
//
// For more information: https://stripe.com/docs/api#balance_history
func (c *BalanceClient) HistoryCount(count, offset int) ([]*BalanceTransaction, error) {
	type balances struct{ Data []*BalanceTransaction }
	list := balances{}

	params := url.Values{
		"count":  {strconv.Itoa(count)},
		"offset": {strconv.Itoa(offset)},
	}

	err := get("/balance/history", params, &list)
	return list.Data, err
}
<commit_msg>updated balance from #HistoryCount to #HistoryWithFilters<commit_after>package stripe

import (
	"net/url"
)

type Fund struct {
	Amount   int64  `json:"amount"`
	Currency string `json:"currency"`
}

type Balance struct {
	Object    string  `json:"object"`
	Livemode  bool    `json:"livemode"`
	Available []*Fund `json:"available"`
	Pending   []*Fund `json:"pending"`
}

type FeeDetails struct {
	Amount      int64  `json:"amount"`
	Currency    string `json:"currency"`
	Type        string `json:"type"`
	Description string `json:"description"`
	Application string `json:"application"`
}

type BalanceTransaction struct {
	Id          string        `json:"id"`
	Object      string        `json:"object"`
	Source      string        `json:"source"`
	Amount      int64         `json:"amount"`
	Currency    string        `json:"currency"`
	Net         int64         `json:"net"`
	Type        string        `json:"type"`
	Created     int64         `json:"created"`
	AvailableOn int64         `json:"available_on"`
	Status      string        `json:"status"`
	Fee         int64         `json:"fee"`
	FeeDetails  []*FeeDetails `json:"fee_details"`
}

type BalanceTransactionListResponse struct {
	Object string  `json:"object"`
	Url    string  `json:"url"`
	Count  int     `json:"count"`
	Data   []*BalanceTransaction `json:"data"`
}

type BalanceClient struct{}

// Retrieve loads a balance.
//
// For more information: https://stripe.com/docs/api#retrieve_balance
func (c *BalanceClient) Retrieve() (*Balance, error) {
	balance := Balance{}
	err := get("/balance", nil, &balance)
	return &balance, err
}

// RetrieveTransaction loads a balance transaction.
//
// For more information: https://stripe.com/docs/api#retrieve_balance_transaction
func (c *BalanceClient) RetrieveTransaction(id string) (*BalanceTransaction, error) {
	balanceTransaction := BalanceTransaction{}
	err := get("/balance/history/"+id, nil, &balanceTransaction)
	return &balanceTransaction, err
}

// History lists the first 10 balances in the balance history. It calls
// HistoryWithFilters with a blank Filters so all defaults are used.
//
// For more information: https://stripe.com/docs/api#balance_history
func (c *BalanceClient) History() (*BalanceTransactionListResponse, error) {
  return c.HistoryWithFilters(Filters{})
}

// HistoryWithFilters takes a Filters and applies all valid filters for the action.
//
// For more information: https://stripe.com/docs/api#balance_history
func (c *BalanceClient) HistoryWithFilters(filters Filters) (*BalanceTransactionListResponse, error) {
  response := BalanceTransactionListResponse{}
  values := url.Values{}
  addFiltersToValues([]string{"count", "offset", "currency", "source", "transfer", "type"}, filters, &values)
	err := get("/balance/history", values, &response)
	return &response, err
}
<|endoftext|>


<commit_before>package logger

import (
	"sync"
	"testing"
)

type mock struct {
	lnCount map[LogLevel]int
	fCount  map[LogLevel]int
	level   LogLevel
	mu      sync.Mutex
}

var _ Logger = newMock()

func newMock() *mock {
	return &mock{
		lnCount: make(map[LogLevel]int),
		fCount:  make(map[LogLevel]int),
	}
}

func (m *mock) LnCount(level LogLevel) int {
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.lnCount[level]
}

func (m *mock) FCount(level LogLevel) int {
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.fCount[level]
}

func (m *mock) checkLnCount(t *testing.T, debug, verbose, info, ok, warn, fatal int) {
	if !(m.LnCount(LevelDebug) == debug &&
		m.LnCount(LevelVerbose) == verbose &&
		m.LnCount(LevelOK) == ok &&
		m.LnCount(LevelWarn) == warn &&
		m.LnCount(LevelFatal) == fatal) {
		t.Errorf("LnCount is wrong, should be %d,%d,%d,%d,%d,%d - is %d,%d,%d,%d,%d,%d", debug, verbose, info, ok, warn, fatal,
			m.LnCount(LevelDebug),
			m.LnCount(LevelVerbose),
			m.LnCount(LevelInfo),
			m.LnCount(LevelOK),
			m.LnCount(LevelWarn),
			m.LnCount(LevelFatal))
	}
}

func (m *mock) checkFCount(t *testing.T, debug, verbose, info, ok, warn, fatal int) {
	if !(m.FCount(LevelDebug) == debug &&
		m.FCount(LevelVerbose) == verbose &&
		m.FCount(LevelOK) == ok &&
		m.FCount(LevelWarn) == warn &&
		m.FCount(LevelFatal) == fatal) {
		t.Errorf("FCount is wrong, should be %d,%d,%d,%d,%d,%d - is %d,%d,%d,%d,%d,%d", debug, verbose, info, ok, warn, fatal,
			m.FCount(LevelDebug),
			m.FCount(LevelVerbose),
			m.FCount(LevelInfo),
			m.FCount(LevelOK),
			m.FCount(LevelWarn),
			m.FCount(LevelFatal))
	}
}

func (m *mock) Logs(level LogLevel) bool {
	return level >= m.level
}

func (m *mock) SetLevel(level LogLevel) {
	m.level = level
}

func (m *mock) Level() LogLevel { return m.level }

func (m *mock) Debugln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelDebug]++
}

func (m *mock) Debugf(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelDebug]++
}

func (m *mock) Verboseln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelVerbose]++
}

func (m *mock) Verbosef(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelVerbose]++
}

func (m *mock) Infoln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelInfo]++
}

func (m *mock) Infof(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelInfo]++
}

func (m *mock) Okln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelOK]++
}

func (m *mock) Okf(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelOK]++
}

func (m *mock) Warnln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelWarn]++
}

func (m *mock) Warnf(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelWarn]++
}

func (m *mock) Fatalln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelFatal]++
}

func (m *mock) Fatalf(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelFatal]++
}
<commit_msg>godoc<commit_after>package logger

import (
	"sync"
	"testing"
)

// mock is a mock logger that just counts how often <Level>(ln|f) was called
type mock struct {
	lnCount map[LogLevel]int
	fCount  map[LogLevel]int
	level   LogLevel
	mu      sync.Mutex
}

var _ Logger = newMock()

func newMock() *mock {
	return &mock{
		lnCount: make(map[LogLevel]int),
		fCount:  make(map[LogLevel]int),
	}
}

func (m *mock) LnCount(level LogLevel) int {
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.lnCount[level]
}

func (m *mock) FCount(level LogLevel) int {
	m.mu.Lock()
	defer m.mu.Unlock()
	return m.fCount[level]
}

func (m *mock) checkLnCount(t *testing.T, debug, verbose, info, ok, warn, fatal int) {
	if !(m.LnCount(LevelDebug) == debug &&
		m.LnCount(LevelVerbose) == verbose &&
		m.LnCount(LevelOK) == ok &&
		m.LnCount(LevelWarn) == warn &&
		m.LnCount(LevelFatal) == fatal) {
		t.Errorf("LnCount is wrong, should be %d,%d,%d,%d,%d,%d - is %d,%d,%d,%d,%d,%d", debug, verbose, info, ok, warn, fatal,
			m.LnCount(LevelDebug),
			m.LnCount(LevelVerbose),
			m.LnCount(LevelInfo),
			m.LnCount(LevelOK),
			m.LnCount(LevelWarn),
			m.LnCount(LevelFatal))
	}
}

func (m *mock) checkFCount(t *testing.T, debug, verbose, info, ok, warn, fatal int) {
	if !(m.FCount(LevelDebug) == debug &&
		m.FCount(LevelVerbose) == verbose &&
		m.FCount(LevelOK) == ok &&
		m.FCount(LevelWarn) == warn &&
		m.FCount(LevelFatal) == fatal) {
		t.Errorf("FCount is wrong, should be %d,%d,%d,%d,%d,%d - is %d,%d,%d,%d,%d,%d", debug, verbose, info, ok, warn, fatal,
			m.FCount(LevelDebug),
			m.FCount(LevelVerbose),
			m.FCount(LevelInfo),
			m.FCount(LevelOK),
			m.FCount(LevelWarn),
			m.FCount(LevelFatal))
	}
}

func (m *mock) Logs(level LogLevel) bool {
	return level >= m.level
}

func (m *mock) SetLevel(level LogLevel) {
	m.level = level
}

func (m *mock) Level() LogLevel { return m.level }

func (m *mock) Debugln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelDebug]++
}

func (m *mock) Debugf(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelDebug]++
}

func (m *mock) Verboseln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelVerbose]++
}

func (m *mock) Verbosef(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelVerbose]++
}

func (m *mock) Infoln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelInfo]++
}

func (m *mock) Infof(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelInfo]++
}

func (m *mock) Okln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelOK]++
}

func (m *mock) Okf(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelOK]++
}

func (m *mock) Warnln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelWarn]++
}

func (m *mock) Warnf(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelWarn]++
}

func (m *mock) Fatalln(val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.lnCount[LevelFatal]++
}

func (m *mock) Fatalf(format string, val ...interface{}) {
	m.mu.Lock()
	defer m.mu.Unlock()
	m.fCount[LevelFatal]++
}
<|endoftext|>


<commit_before>package mock

import (
	"fmt"
	"reflect"
	"runtime"
	"strings"
	"time"
)

// Mock should be embedded in the struct that we want to act as a Mock.
//
// Example:
// 		type MyClient struct {
//			mock.Mock
// 		}
type Mock struct {
	Functions []*MockFunction
	inorder   bool
	order     uint
}

type InOrder struct {
	functions []*MockFunction
	order     uint
}

type MockCountCheckType int

const (
	NONE MockCountCheckType = iota
	TIMES
	AT_LEAST
	AT_MOST
	BETWEEN
)

type MockFunction struct {
	Name              string
	Arguments         []interface{}
	ReturnValues      []interface{}
	ReturnToArguments []MockReturnToArgument
	PanicValue        interface{}
	count             int
	countCheck        MockCountCheckType
	times             [2]int
	order             uint
	timeout           time.Duration
}

type MockReturnToArgument struct {
	Argument int
	Value    interface{}
}

type MockResult struct {
	Result []interface{}
}

// The constant Any can be used to replace any kind of argument in the stub configuration.
type AnyType string

const (
	Any AnyType = "mock.any"
)

type AnythingOfType string

// AnyOfType can be used to replace any kind of argument of an specific type in the stub configuration.
func AnyOfType(t string) AnythingOfType {
	return AnythingOfType(t)
}

// Verifies the restrictions set in the stubbing.
func (m *Mock) Verify() (bool, error) {
	for _, f := range m.Functions {
		switch f.countCheck {
		case TIMES:
			if f.count != f.times[1] {
				return false, fmt.Errorf("Function %s executed %d times, expected: %d", f.Name, f.count, f.times[1])
			}
		case AT_LEAST:
			if f.count < f.times[1] {
				return false, fmt.Errorf("Function %s executed %d times, expected at least: %d", f.Name, f.count, f.times[1])
			}
		case AT_MOST:
			if f.count > f.times[1] {
				return false, fmt.Errorf("Function %s executed %d times, expected at most: %d", f.Name, f.count, f.times[1])
			}
		case BETWEEN:
			if f.count < f.times[0] || f.count > f.times[1] {
				return false, fmt.Errorf("Function %s executed %d times, expected between: [%d, %d]", f.Name, f.count, f.times[0], f.times[1])
			}
		}
	}
	return true, nil
}

// Defines an stub of one method with some specific arguments. It returns a *MockFunction
// that can be configured with Return, ReturnToArgument, Panic, ...
func (m *Mock) When(name string, arguments ...interface{}) *MockFunction {
	f := &MockFunction{
		Name:      name,
		Arguments: arguments,
	}

	m.Functions = append(m.Functions, f)
	return f
}

// Used in the mocks to replace the actual task.
//
// Example:
// 		func (m *MyClient) Request(url string) (int, string, error) {
// 			r := m.Called(url)
//			return r.Int(0), r.String(1), r.Error(2)
// 		}
func (m *Mock) Called(arguments ...interface{}) *MockResult {
	pc, _, _, ok := runtime.Caller(1)
	if !ok {
		panic("Couldn't get the caller information")
	}

	functionPath := runtime.FuncForPC(pc).Name()
	parts := strings.Split(functionPath, ".")
	functionName := parts[len(parts)-1]

	if f := m.find(functionName, arguments...); f != nil {
		// Increase the counter
		f.count++
		f.order = m.order
		m.order++

		if f.timeout > 0 {
			time.Sleep(f.timeout)
		}

		if f.PanicValue != nil {
			panic(f.PanicValue)
		}

		// Return to arguments
		for _, r := range f.ReturnToArguments {
			arg := arguments[r.Argument]
			argTyp := reflect.TypeOf(arg)
			argElem := reflect.ValueOf(arg).Elem()
			typ := reflect.TypeOf(r.Value)
			if typ.Kind() == reflect.Ptr {
				if typ == argTyp {
					// *type vs *type
					argElem.Set(reflect.ValueOf(r.Value).Elem())
				} else {
					// *type vs **type
					argElem.Set(reflect.ValueOf(r.Value))
				}
			} else {
				if typ == argTyp.Elem() {
					// type vs *type
					argElem.Set(reflect.ValueOf(r.Value))
				} else {
					// type vs **type
					value := reflect.New(typ).Elem()
					value.Set(reflect.ValueOf(r.Value))
					argElem.Set(value.Addr())
				}
			}
		}

		return &MockResult{f.ReturnValues}
	}

	panic(fmt.Sprintf("Mock call missing %s (%v)", functionName, arguments))
}

func (m *Mock) find(name string, arguments ...interface{}) *MockFunction {
	var ff *MockFunction

	for _, f := range m.Functions {
		if f.Name != name {
			continue
		}

		if len(f.Arguments) != len(arguments) {
			continue
		}

		found := true
		for i, arg := range f.Arguments {
			switch arg.(type) {
			case AnyType:
				continue
			case AnythingOfType:
				if string(arg.(AnythingOfType)) == reflect.TypeOf(arguments[i]).String() {
					continue
				} else {
					found = false
				}
			default:
				if reflect.DeepEqual(arg, arguments[i]) || reflect.ValueOf(arg) == reflect.ValueOf(arguments[i]) {
					continue
				} else {
					found = false
				}
			}
		}

		if !found {
			continue
		}

		// Check if the count check is valid.
		// If it's not try to match another function.
		if f.isMaxCountCheck() {
			if ff == nil {
				ff = f
			}
			continue
		}

		return f
	}

	return ff
}

// Defines the return values of a *MockFunction.
func (f *MockFunction) Return(v ...interface{}) *MockFunction {
	f.ReturnValues = append(f.ReturnValues, v...)
	return f
}

// Defines the values returned to a specific argument of a *MockFunction.
func (f *MockFunction) ReturnToArgument(n int, v interface{}) *MockFunction {
	f.ReturnToArguments = append(f.ReturnToArguments, MockReturnToArgument{n, v})
	return f
}

// Defines a panic for a specific *MockFunction.
func (f *MockFunction) Panic(v interface{}) *MockFunction {
	f.PanicValue = v
	return f
}

// Defines how many times a *MockFunction must be called.
// This is verified if mock.Verify is called.
func (f *MockFunction) Times(a int) *MockFunction {
	f.countCheck = TIMES
	f.times = [2]int{-1, a}
	return f
}

// Defines the number of times that a *MockFunction must be at least called.
// This is verified if mock.Verify is called.
func (f *MockFunction) AtLeast(a int) *MockFunction {
	f.countCheck = AT_LEAST
	f.times = [2]int{-1, a}
	return f
}

// Defines the number of times that a *MockFunction must be at most called.
// This is verified if mock.Verify is called.
func (f *MockFunction) AtMost(a int) *MockFunction {
	f.countCheck = AT_MOST
	f.times = [2]int{-1, a}
	return f
}

// Defines a range of times that a *MockFunction must be called.
// This is verified if mock.Verify is called.
func (f *MockFunction) Between(a, b int) *MockFunction {
	f.countCheck = BETWEEN
	f.times = [2]int{a, b}
	return f
}

// Defines a timeout to sleep before returning the value of a function.
func (f *MockFunction) Timeout(d time.Duration) *MockFunction {
	f.timeout = d
	return f
}

// Check if the number of times that a function has been called
// has reach the top range.
func (f *MockFunction) isMaxCountCheck() bool {
	switch f.countCheck {
	case TIMES:
		if f.count >= f.times[1] {
			return true
		}
	case AT_LEAST:
		// At least does not have a maximum
		return false
	case AT_MOST:
		if f.count >= f.times[1] {
			return true
		}
	case BETWEEN:
		if f.count >= f.times[1] {
			return true
		}
	}

	return false
}

// Returns true if the results have the index i, false otherwise.
func (r *MockResult) Contains(i int) bool {
	if len(r.Result) > i {
		return true
	} else {
		return false
	}
}

// Returns a specific return parameter.
// If a result has not been set, it returns nil,
func (r *MockResult) Get(i int) interface{} {
	if r.Contains(i) {
		return r.Result[i]
	} else {
		return nil
	}
}

// Returns a specific return parameter as a bool.
// If a result has not been set, it returns false.
func (r *MockResult) Bool(i int) bool {
	if r.Contains(i) {
		return r.Result[i].(bool)
	} else {
		return false
	}
}

// Returns a specific return parameter as an error.
// If a result has not been set, it returns nil.
func (r *MockResult) Error(i int) error {
	if r.Contains(i) && r.Result[i] != nil {
		return r.Result[i].(error)
	} else {
		return nil
	}
}

// Returns a specific return parameter as a float32.
// If a result has not been set, it returns 0.
func (r *MockResult) Float32(i int) float32 {
	if r.Contains(i) {
		return r.Result[i].(float32)
	} else {
		return 0
	}
}

// Returns a specific return parameter as a float64.
// If a result has not been set, it returns 0.
func (r *MockResult) Float64(i int) float64 {
	if r.Contains(i) {
		return r.Result[i].(float64)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int.
// If a result has not been set, it returns 0.
func (r *MockResult) Int(i int) int {
	if r.Contains(i) {
		return r.Result[i].(int)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int8.
// If a result has not been set, it returns 0.
func (r *MockResult) Int8(i int) int8 {
	if r.Contains(i) {
		return r.Result[i].(int8)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int16.
// If a result has not been set, it returns 0.
func (r *MockResult) Int16(i int) int16 {
	if r.Contains(i) {
		return r.Result[i].(int16)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int32.
// If a result has not been set, it returns 0.
func (r *MockResult) Int32(i int) int32 {
	if r.Contains(i) {
		return r.Result[i].(int32)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int64.
// If a result has not been set, it returns 0.
func (r *MockResult) Int64(i int) int64 {
	if r.Contains(i) {
		return r.Result[i].(int64)
	} else {
		return 0
	}
}

// Returns a specific return parameter as a string.
// If a result has not been set, it returns "".
func (r *MockResult) String(i int) string {
	if r.Contains(i) {
		return r.Result[i].(string)
	} else {
		return ""
	}
}
<commit_msg>Add header.<commit_after>// Package mock provides a mocking framework.
//
// https://github.com/maraino/go-mock
package mock

import (
	"fmt"
	"reflect"
	"runtime"
	"strings"
	"time"
)

// Mock should be embedded in the struct that we want to act as a Mock.
//
// Example:
// 		type MyClient struct {
//			mock.Mock
// 		}
type Mock struct {
	Functions []*MockFunction
	inorder   bool
	order     uint
}

type InOrder struct {
	functions []*MockFunction
	order     uint
}

type MockCountCheckType int

const (
	NONE MockCountCheckType = iota
	TIMES
	AT_LEAST
	AT_MOST
	BETWEEN
)

type MockFunction struct {
	Name              string
	Arguments         []interface{}
	ReturnValues      []interface{}
	ReturnToArguments []MockReturnToArgument
	PanicValue        interface{}
	count             int
	countCheck        MockCountCheckType
	times             [2]int
	order             uint
	timeout           time.Duration
}

type MockReturnToArgument struct {
	Argument int
	Value    interface{}
}

type MockResult struct {
	Result []interface{}
}

// The constant Any can be used to replace any kind of argument in the stub configuration.
type AnyType string

const (
	Any AnyType = "mock.any"
)

type AnythingOfType string

// AnyOfType can be used to replace any kind of argument of an specific type in the stub configuration.
func AnyOfType(t string) AnythingOfType {
	return AnythingOfType(t)
}

// Verifies the restrictions set in the stubbing.
func (m *Mock) Verify() (bool, error) {
	for _, f := range m.Functions {
		switch f.countCheck {
		case TIMES:
			if f.count != f.times[1] {
				return false, fmt.Errorf("Function %s executed %d times, expected: %d", f.Name, f.count, f.times[1])
			}
		case AT_LEAST:
			if f.count < f.times[1] {
				return false, fmt.Errorf("Function %s executed %d times, expected at least: %d", f.Name, f.count, f.times[1])
			}
		case AT_MOST:
			if f.count > f.times[1] {
				return false, fmt.Errorf("Function %s executed %d times, expected at most: %d", f.Name, f.count, f.times[1])
			}
		case BETWEEN:
			if f.count < f.times[0] || f.count > f.times[1] {
				return false, fmt.Errorf("Function %s executed %d times, expected between: [%d, %d]", f.Name, f.count, f.times[0], f.times[1])
			}
		}
	}
	return true, nil
}

// Defines an stub of one method with some specific arguments. It returns a *MockFunction
// that can be configured with Return, ReturnToArgument, Panic, ...
func (m *Mock) When(name string, arguments ...interface{}) *MockFunction {
	f := &MockFunction{
		Name:      name,
		Arguments: arguments,
	}

	m.Functions = append(m.Functions, f)
	return f
}

// Used in the mocks to replace the actual task.
//
// Example:
// 		func (m *MyClient) Request(url string) (int, string, error) {
// 			r := m.Called(url)
//			return r.Int(0), r.String(1), r.Error(2)
// 		}
func (m *Mock) Called(arguments ...interface{}) *MockResult {
	pc, _, _, ok := runtime.Caller(1)
	if !ok {
		panic("Couldn't get the caller information")
	}

	functionPath := runtime.FuncForPC(pc).Name()
	parts := strings.Split(functionPath, ".")
	functionName := parts[len(parts)-1]

	if f := m.find(functionName, arguments...); f != nil {
		// Increase the counter
		f.count++
		f.order = m.order
		m.order++

		if f.timeout > 0 {
			time.Sleep(f.timeout)
		}

		if f.PanicValue != nil {
			panic(f.PanicValue)
		}

		// Return to arguments
		for _, r := range f.ReturnToArguments {
			arg := arguments[r.Argument]
			argTyp := reflect.TypeOf(arg)
			argElem := reflect.ValueOf(arg).Elem()
			typ := reflect.TypeOf(r.Value)
			if typ.Kind() == reflect.Ptr {
				if typ == argTyp {
					// *type vs *type
					argElem.Set(reflect.ValueOf(r.Value).Elem())
				} else {
					// *type vs **type
					argElem.Set(reflect.ValueOf(r.Value))
				}
			} else {
				if typ == argTyp.Elem() {
					// type vs *type
					argElem.Set(reflect.ValueOf(r.Value))
				} else {
					// type vs **type
					value := reflect.New(typ).Elem()
					value.Set(reflect.ValueOf(r.Value))
					argElem.Set(value.Addr())
				}
			}
		}

		return &MockResult{f.ReturnValues}
	}

	panic(fmt.Sprintf("Mock call missing %s (%v)", functionName, arguments))
}

func (m *Mock) find(name string, arguments ...interface{}) *MockFunction {
	var ff *MockFunction

	for _, f := range m.Functions {
		if f.Name != name {
			continue
		}

		if len(f.Arguments) != len(arguments) {
			continue
		}

		found := true
		for i, arg := range f.Arguments {
			switch arg.(type) {
			case AnyType:
				continue
			case AnythingOfType:
				if string(arg.(AnythingOfType)) == reflect.TypeOf(arguments[i]).String() {
					continue
				} else {
					found = false
				}
			default:
				if reflect.DeepEqual(arg, arguments[i]) || reflect.ValueOf(arg) == reflect.ValueOf(arguments[i]) {
					continue
				} else {
					found = false
				}
			}
		}

		if !found {
			continue
		}

		// Check if the count check is valid.
		// If it's not try to match another function.
		if f.isMaxCountCheck() {
			if ff == nil {
				ff = f
			}
			continue
		}

		return f
	}

	return ff
}

// Defines the return values of a *MockFunction.
func (f *MockFunction) Return(v ...interface{}) *MockFunction {
	f.ReturnValues = append(f.ReturnValues, v...)
	return f
}

// Defines the values returned to a specific argument of a *MockFunction.
func (f *MockFunction) ReturnToArgument(n int, v interface{}) *MockFunction {
	f.ReturnToArguments = append(f.ReturnToArguments, MockReturnToArgument{n, v})
	return f
}

// Defines a panic for a specific *MockFunction.
func (f *MockFunction) Panic(v interface{}) *MockFunction {
	f.PanicValue = v
	return f
}

// Defines how many times a *MockFunction must be called.
// This is verified if mock.Verify is called.
func (f *MockFunction) Times(a int) *MockFunction {
	f.countCheck = TIMES
	f.times = [2]int{-1, a}
	return f
}

// Defines the number of times that a *MockFunction must be at least called.
// This is verified if mock.Verify is called.
func (f *MockFunction) AtLeast(a int) *MockFunction {
	f.countCheck = AT_LEAST
	f.times = [2]int{-1, a}
	return f
}

// Defines the number of times that a *MockFunction must be at most called.
// This is verified if mock.Verify is called.
func (f *MockFunction) AtMost(a int) *MockFunction {
	f.countCheck = AT_MOST
	f.times = [2]int{-1, a}
	return f
}

// Defines a range of times that a *MockFunction must be called.
// This is verified if mock.Verify is called.
func (f *MockFunction) Between(a, b int) *MockFunction {
	f.countCheck = BETWEEN
	f.times = [2]int{a, b}
	return f
}

// Defines a timeout to sleep before returning the value of a function.
func (f *MockFunction) Timeout(d time.Duration) *MockFunction {
	f.timeout = d
	return f
}

// Check if the number of times that a function has been called
// has reach the top range.
func (f *MockFunction) isMaxCountCheck() bool {
	switch f.countCheck {
	case TIMES:
		if f.count >= f.times[1] {
			return true
		}
	case AT_LEAST:
		// At least does not have a maximum
		return false
	case AT_MOST:
		if f.count >= f.times[1] {
			return true
		}
	case BETWEEN:
		if f.count >= f.times[1] {
			return true
		}
	}

	return false
}

// Returns true if the results have the index i, false otherwise.
func (r *MockResult) Contains(i int) bool {
	if len(r.Result) > i {
		return true
	} else {
		return false
	}
}

// Returns a specific return parameter.
// If a result has not been set, it returns nil,
func (r *MockResult) Get(i int) interface{} {
	if r.Contains(i) {
		return r.Result[i]
	} else {
		return nil
	}
}

// Returns a specific return parameter as a bool.
// If a result has not been set, it returns false.
func (r *MockResult) Bool(i int) bool {
	if r.Contains(i) {
		return r.Result[i].(bool)
	} else {
		return false
	}
}

// Returns a specific return parameter as an error.
// If a result has not been set, it returns nil.
func (r *MockResult) Error(i int) error {
	if r.Contains(i) && r.Result[i] != nil {
		return r.Result[i].(error)
	} else {
		return nil
	}
}

// Returns a specific return parameter as a float32.
// If a result has not been set, it returns 0.
func (r *MockResult) Float32(i int) float32 {
	if r.Contains(i) {
		return r.Result[i].(float32)
	} else {
		return 0
	}
}

// Returns a specific return parameter as a float64.
// If a result has not been set, it returns 0.
func (r *MockResult) Float64(i int) float64 {
	if r.Contains(i) {
		return r.Result[i].(float64)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int.
// If a result has not been set, it returns 0.
func (r *MockResult) Int(i int) int {
	if r.Contains(i) {
		return r.Result[i].(int)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int8.
// If a result has not been set, it returns 0.
func (r *MockResult) Int8(i int) int8 {
	if r.Contains(i) {
		return r.Result[i].(int8)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int16.
// If a result has not been set, it returns 0.
func (r *MockResult) Int16(i int) int16 {
	if r.Contains(i) {
		return r.Result[i].(int16)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int32.
// If a result has not been set, it returns 0.
func (r *MockResult) Int32(i int) int32 {
	if r.Contains(i) {
		return r.Result[i].(int32)
	} else {
		return 0
	}
}

// Returns a specific return parameter as an int64.
// If a result has not been set, it returns 0.
func (r *MockResult) Int64(i int) int64 {
	if r.Contains(i) {
		return r.Result[i].(int64)
	} else {
		return 0
	}
}

// Returns a specific return parameter as a string.
// If a result has not been set, it returns "".
func (r *MockResult) String(i int) string {
	if r.Contains(i) {
		return r.Result[i].(string)
	} else {
		return ""
	}
}
<|endoftext|>


<commit_before>// fmt.go for sutff to format output in the stdoutt/terminal
package main

import (
	"fmt"
	"os"
	"sort"
	"strings"
	"unicode/utf8"

	isatty "github.com/mattn/go-isatty"
	c "github.com/mitchellh/colorstring"
)

const (
	dashesNumber = 2
)

var (
	terminalWidth   = 80
	columnSize      = 39 // characters in the filename column
	maxFileNameSize = columnSize - 5
)

// Defines Terminal Coloring Theme
var ColorScheme c.Colorize

// BlankScheme color scheme just deletes all the coloring tags
// this colorScheme is applied before fetching the string length
// so that color tags (or color decoding escape symbols )
// do not screw up column alignment and so on
var BlankScheme c.Colorize

func init() {
	ColorScheme = c.Colorize{
		Colors: map[string]string{
			"DEFAULT":     c.DefaultColors["default"],
			"FILENAME":    c.DefaultColors["light_green"],
			"META":        c.DefaultColors["red"],
			"DESCRIPTION": c.DefaultColors["light_yellow"],
			"HR":          c.DefaultColors["light_cyan"],
			"NUMBER":      c.DefaultColors["light_red"],
		},
		Reset:   true,
		Disable: !isatty.IsTerminal(os.Stdout.Fd()),
	}

	BlankScheme = ColorScheme
	BlankScheme.Disable = true

}

func render() {
	SetColumnSize()
	Traverse()
	renderSummary()
}

func renderSummary() {
	printHR()
	printCentered(fmt.Sprintf(ColorScheme.Color("[DEFAULT]lsp \"[NUMBER]%s[DEFAULT]\""), presentPath(mode.absolutePath)) + fmt.Sprintf(ColorScheme.Color(", [NUMBER]%v[DEFAULT] files, [NUMBER]%v[DEFAULT] directories"), len(FileList), len(Trie.Ch["dirs"].Fls)))
	for _, cm := range mode.comments {
		printCentered(cm)
	}
}

func renderFiles(fls []*FileInfo) {
	switch {
	case mode.size:
		sort.Sort(sizeSort(fls))
	case mode.time:
		sort.Sort(timeSort(fls))
	default:
		sort.Sort(alphabeticSort(fls))
	}
	for _, fl := range fls {
		if !fl.hidden {
			PrintColumns(fl.f.Name(), fl.Description())
		}
	}
}

// PrintColumns prints two-column table row, nicely formatted and shortened if needed
func PrintColumns(filename, description string) {

	if utf8.RuneCountInString(filename) > maxFileNameSize {
		filename = string([]rune(filename)[0:maxFileNameSize]) + "[META][...]"
	}

	indentSize := columnSize - utf8.RuneCountInString(BlankScheme.Color(filename))

	if mode.pyramid {
		fmt.Printf(ColorScheme.Color(fmt.Sprintf("[FILENAME]%s", filename)))
		fmt.Printf(strings.Repeat(" ", indentSize))
	} else {
		fmt.Printf(strings.Repeat(" ", indentSize))
		fmt.Printf(ColorScheme.Color(fmt.Sprintf("[FILENAME]%s", filename)))
	}
	// central dividing space
	fmt.Printf("  ")
	fmt.Printf(ColorScheme.Color(fmt.Sprintf("[DESCRIPTION]%s\n", description)))
}

func printHeader(o string) {
	length := utf8.RuneCountInString(o)
	sideburns := (6+2*columnSize-length)/2 - dashesNumber
	if sideburns < 0 {
		sideburns = 0
	}
	fmt.Printf(strings.Repeat(" ", sideburns))
	fmt.Printf(ColorScheme.Color("[DESCRIPTION]" + strings.Repeat("-", dashesNumber) + o + strings.Repeat("-", dashesNumber) + "[DEFAULT]\n"))
}

func printCentered(o string) {
	length := utf8.RuneCountInString(o)
	sideburns := (6 + 2*columnSize - length) / 2
	if sideburns < 0 {
		sideburns = 0
	}
	fmt.Printf(strings.Repeat(" ", sideburns))
	fmt.Printf(ColorScheme.Color(o + "\n"))
}

func printHR() {
	fmt.Printf(ColorScheme.Color("[HR]" + strings.Repeat("-", terminalWidth) + "\n"))
}
<commit_msg>Non pyramid mode to default<commit_after>// fmt.go for sutff to format output in the stdoutt/terminal
package main

import (
	"fmt"
	"os"
	"sort"
	"strings"
	"unicode/utf8"

	isatty "github.com/mattn/go-isatty"
	c "github.com/mitchellh/colorstring"
)

const (
	dashesNumber = 2
)

var (
	terminalWidth   = 80
	columnSize      = 39 // characters in the filename column
	maxFileNameSize = columnSize - 5
)

// Defines Terminal Coloring Theme
var ColorScheme c.Colorize

// BlankScheme color scheme just deletes all the coloring tags
// this colorScheme is applied before fetching the string length
// so that color tags (or color decoding escape symbols )
// do not screw up column alignment and so on
var BlankScheme c.Colorize

func init() {
	ColorScheme = c.Colorize{
		Colors: map[string]string{
			"DEFAULT":     c.DefaultColors["default"],
			"FILENAME":    c.DefaultColors["light_green"],
			"META":        c.DefaultColors["red"],
			"DESCRIPTION": c.DefaultColors["light_yellow"],
			"HR":          c.DefaultColors["light_cyan"],
			"NUMBER":      c.DefaultColors["light_red"],
		},
		Reset:   true,
		Disable: !isatty.IsTerminal(os.Stdout.Fd()),
	}

	BlankScheme = ColorScheme
	BlankScheme.Disable = true

}

func render() {
	SetColumnSize()
	Traverse()
	renderSummary()
}

func renderSummary() {
	printHR()
	printCentered(fmt.Sprintf(ColorScheme.Color("[DEFAULT]lsp \"[NUMBER]%s[DEFAULT]\""), presentPath(mode.absolutePath)) + fmt.Sprintf(ColorScheme.Color(", [NUMBER]%v[DEFAULT] files, [NUMBER]%v[DEFAULT] directories"), len(FileList), len(Trie.Ch["dirs"].Fls)))
	for _, cm := range mode.comments {
		printCentered(cm)
	}
}

func renderFiles(fls []*FileInfo) {
	switch {
	case mode.size:
		sort.Sort(sizeSort(fls))
	case mode.time:
		sort.Sort(timeSort(fls))
	default:
		sort.Sort(alphabeticSort(fls))
	}
	for _, fl := range fls {
		if !fl.hidden {
			PrintColumns(fl.f.Name(), fl.Description())
		}
	}
}

// PrintColumns prints two-column table row, nicely formatted and shortened if needed
func PrintColumns(filename, description string) {

	if utf8.RuneCountInString(filename) > maxFileNameSize {
		filename = string([]rune(filename)[0:maxFileNameSize]) + "[META][...]"
	}

	indentSize := columnSize - utf8.RuneCountInString(BlankScheme.Color(filename))

	if !mode.pyramid {
		fmt.Printf(ColorScheme.Color(fmt.Sprintf("[FILENAME]%s", filename)))
		fmt.Printf(strings.Repeat(" ", indentSize))
	} else {
		fmt.Printf(strings.Repeat(" ", indentSize))
		fmt.Printf(ColorScheme.Color(fmt.Sprintf("[FILENAME]%s", filename)))
	}
	// central dividing space
	fmt.Printf("  ")
	fmt.Printf(ColorScheme.Color(fmt.Sprintf("[DESCRIPTION]%s\n", description)))
}

func printHeader(o string) {
	length := utf8.RuneCountInString(o)
	sideburns := (6+2*columnSize-length)/2 - dashesNumber
	if sideburns < 0 {
		sideburns = 0
	}
	fmt.Printf(strings.Repeat(" ", sideburns))
	fmt.Printf(ColorScheme.Color("[DESCRIPTION]" + strings.Repeat("-", dashesNumber) + o + strings.Repeat("-", dashesNumber) + "[DEFAULT]\n"))
}

func printCentered(o string) {
	length := utf8.RuneCountInString(o)
	sideburns := (6 + 2*columnSize - length) / 2
	if sideburns < 0 {
		sideburns = 0
	}
	fmt.Printf(strings.Repeat(" ", sideburns))
	fmt.Printf(ColorScheme.Color(o + "\n"))
}

func printHR() {
	fmt.Printf(ColorScheme.Color("[HR]" + strings.Repeat("-", terminalWidth) + "\n"))
}
<|endoftext|>


<commit_before>// Package whitelist is a micro plugin for whitelisting service requests
package whitelist

import (
	"net/http"
	"strings"

	"github.com/micro/cli"
	"github.com/micro/go-micro/client"
	"github.com/micro/micro/plugin"
)

type whitelist struct {
	services map[string]bool
}

func (w *whitelist) Flags() []cli.Flag {
	return []cli.Flag{
		cli.StringFlag{
			Name:   "rpc_whitelist",
			Usage:  "Comma separated whitelist of allowed services for RPC calls",
			EnvVar: "MICRO_RPC_WHITELIST",
		},
	}
}

func (w *whitelist) Commands() []cli.Command {
	return nil
}

func (w *whitelist) Handler() plugin.Handler {
	return func(h http.Handler) http.Handler {
		return h
	}
}

func (w *whitelist) Init(ctx *cli.Context) error {
	if whitelist := ctx.String("rpc_whitelist"); len(whitelist) > 0 {
		client.DefaultClient = newClient(strings.Split(whitelist, ",")...)
	}
	return nil
}

func (w *whitelist) String() string {
	return "whitelist"
}

func NewRPCWhitelist(services ...string) plugin.Plugin {
	list := make(map[string]bool)

	for _, service := range services {
		list[service] = true
	}

	return &whitelist{
		services: list,
	}
}
<commit_msg>Env var same as flag<commit_after>// Package whitelist is a micro plugin for whitelisting service requests
package whitelist

import (
	"net/http"
	"strings"

	"github.com/micro/cli"
	"github.com/micro/go-micro/client"
	"github.com/micro/micro/plugin"
)

type whitelist struct {
	services map[string]bool
}

func (w *whitelist) Flags() []cli.Flag {
	return []cli.Flag{
		cli.StringFlag{
			Name:   "rpc_whitelist",
			Usage:  "Comma separated whitelist of allowed services for RPC calls",
			EnvVar: "RPC_WHITELIST",
		},
	}
}

func (w *whitelist) Commands() []cli.Command {
	return nil
}

func (w *whitelist) Handler() plugin.Handler {
	return func(h http.Handler) http.Handler {
		return h
	}
}

func (w *whitelist) Init(ctx *cli.Context) error {
	if whitelist := ctx.String("rpc_whitelist"); len(whitelist) > 0 {
		client.DefaultClient = newClient(strings.Split(whitelist, ",")...)
	}
	return nil
}

func (w *whitelist) String() string {
	return "whitelist"
}

func NewRPCWhitelist(services ...string) plugin.Plugin {
	list := make(map[string]bool)

	for _, service := range services {
		list[service] = true
	}

	return &whitelist{
		services: list,
	}
}
<|endoftext|>


<commit_before>package middlewares

import (
	"bytes"
	"compress/gzip"
	"fmt"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"
)

func Test_Compress(t *testing.T) {
	w := httptest.NewRecorder()
	compressedRequest(w, "gzip")
	if w.HeaderMap.Get("Content-Encoding") != "gzip" {
		t.Fatalf("wrong content encoding, got %d want %d", w.HeaderMap.Get("Content-Encoding"), "gzip")
	}
	if w.HeaderMap.Get("Content-Type") != "text/plain; charset=utf-8" {
		t.Fatalf("wrong content type, got %s want %s", w.HeaderMap.Get("Content-Type"), "text/plain; charset=utf-8")
	}
	reader, _ := gzip.NewReader(bytes.NewReader(w.Body.Bytes()))
	buf := make([]byte, 10000)
	n, _ := reader.Read(buf)
	if string(buf[:n]) != buffer {
		fmt.Printf("%#v\n", string(buf))
		t.Fatalf("wrong buffer")
	}
}

func compressedRequest(writer *httptest.ResponseRecorder, compression string) {
	handler := Chain(Compress()).Then(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		io.WriteString(writer, buffer)
		writer.(http.Flusher).Flush()
	}))

	handler.ServeHTTP(writer, &http.Request{
		Method: "GET",
		Header: http.Header{
			"Accept-Encoding": []string{compression},
		},
	})
}

const buffer = `
     1  // Copyright 2010 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4
     5  package gzip
     6
     7  import (
     8      "compress/flate"
     9      "errors"
    10      "fmt"
    11      "hash"
    12      "hash/crc32"
    13      "io"
    14  )
    15
    16  // These constants are copied from the flate package, so that code that imports
    17  // "compress/gzip" does not also have to import "compress/flate".
    18  const (
    19      NoCompression      = flate.NoCompression
    20      BestSpeed          = flate.BestSpeed
    21      BestCompression    = flate.BestCompression
    22      DefaultCompression = flate.DefaultCompression
    23  )
    24
    25  // A Writer is an io.WriteCloser.
    26  // Writes to a Writer are compressed and written to w.
    27  type Writer struct {
    28      Header
    29      w           io.Writer
    30      level       int
    31      wroteHeader bool
    32      compressor  *flate.Writer
    33      digest      hash.Hash32
    34      size        uint32
    35      closed      bool
    36      buf         [10]byte
    37      err         error
    38  }`
<commit_msg>compress unit test updated<commit_after>package middlewares

import (
	"bytes"
	"compress/flate"
	"compress/gzip"
	"io"
	"net/http"
	"net/http/httptest"
	"testing"
)

func Test_Compress_WhenGzipIsAccepted_ShouldUseGzip(t *testing.T) {
	ensureCompression(t, []string{"gzip"}, "gzip", gunzip)
}

func Test_Compress_WhenDeflateIsAccepted_ShouldUseDeflate(t *testing.T) {
	ensureCompression(t, []string{"deflate"}, "deflate", unflate)
}

func Test_Compress_WhenMultipleEncodingAccepted_ShouldUseFirst(t *testing.T) {
	ensureCompression(t, []string{"gzip", "deflate"}, "gzip", gunzip)
	ensureCompression(t, []string{"deflate", "gzip"}, "deflate", unflate)
}

func Test_Compress_WhenNoEncodingSpecified_ShouldNotCompress(t *testing.T) {
	ensureCompression(t, []string{}, "", raw)
}

func Test_Compress_WhenUnknownEncodingSpecified_ShouldNotCompress(t *testing.T) {
	ensureCompression(t, []string{"bzip"}, "", raw)
}

func Test_Compress_WhenCompression_ShouldDetectContentType(t *testing.T) {
	recorder := httptest.NewRecorder()
	compressedRequest(recorder, []string{"gzip"})
	if recorder.HeaderMap.Get("Content-Type") != "text/plain; charset=utf-8" {
		t.Errorf("Wrong content type, expected %#v, got %#v", "text/plain; charset=utf-8", recorder.HeaderMap.Get("Content-Type"))
	}
}

func ensureCompression(t *testing.T, acceptedEncoding []string, expectedEncoding string, decoder func([]byte) string) {
	recorder := httptest.NewRecorder()
	compressedRequest(recorder, acceptedEncoding)
	if recorder.HeaderMap.Get("Content-Encoding") != expectedEncoding {
		t.Errorf("Wrong content encoding, expected %#v, got %#v", expectedEncoding, recorder.HeaderMap.Get("Content-Encoding"))
	}
	data := decoder(recorder.Body.Bytes())
	if data != bodyContent {
		t.Errorf("Wrong content, expected %d chars, got %d chars", len(bodyContent), len(data))
	}
}

func compressedRequest(recorder *httptest.ResponseRecorder, acceptedEncoding []string) {
	handler := Chain(Compress()).Then(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
		io.WriteString(writer, bodyContent)
		writer.(http.Flusher).Flush()
	}))
	handler.ServeHTTP(recorder, &http.Request{
		Method: "GET",
		Header: http.Header{
			"Accept-Encoding": acceptedEncoding,
		},
	})
}

func gunzip(data []byte) string {
	buffer := new(bytes.Buffer)
	reader, _ := gzip.NewReader(bytes.NewReader(data))
	buffer.ReadFrom(reader)
	return buffer.String()
}

func unflate(data []byte) string {
	buffer := new(bytes.Buffer)
	buffer.ReadFrom(flate.NewReader(bytes.NewReader(data)))
	return buffer.String()
}

func raw(data []byte) string {
	return string(data)
}

const bodyContent = `Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed
in massa quis nisl vestibulum vehicula. Aenean a augue eu metus congue
placerat. Class aptent taciti sociosqu ad litora torquent per conubia nostra,
per inceptos himenaeos. Vivamus eleifend sodales facilisis. Mauris tempor
tempor condimentum. Curabitur ac lorem nec tortor imperdiet varius sodales
mollis nisi. Aliquam ut nisl ut dui blandit faucibus. Phasellus nec mauris
turpis. Suspendisse dapibus auctor est eget vulputate. Suspendisse maximus,
enim a vehicula rutrum, quam diam vehicula purus, ut fermentum leo augue sed
sapien.

Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac
turpis egestas. Fusce nec aliquam augue, nec vulputate ligula. Curabitur eget
tellus ipsum. Maecenas mattis lorem nec magna luctus, et rhoncus orci lacinia.
Vivamus lobortis ipsum at massa maximus pulvinar. Vivamus non ante et enim
congue aliquet a in arcu. Nunc sollicitudin purus leo, sed varius leo semper
quis. Mauris nulla sem, auctor volutpat condimentum a, pharetra posuere
lectus. Integer tempor lectus sit amet hendrerit pretium. Ut elementum mollis
tincidunt.

Etiam pellentesque sagittis turpis, non rutrum velit dapibus ultrices.
Praesent lobortis elit eget accumsan fermentum. Morbi rutrum imperdiet risus
sed efficitur. Morbi cursus sapien ac neque facilisis efficitur. Nulla aliquet
libero et quam auctor, blandit convallis lorem pellentesque. Curabitur
convallis finibus elit ut suscipit. Aenean sem augue, tempor sed odio quis,
pulvinar tincidunt turpis. Aliquam erat volutpat. Donec libero ipsum, posuere
pretium euismod non, lobortis ac leo. Nullam suscipit massa eu tristique
euismod. Praesent congue dictum egestas. Sed ac facilisis enim, a venenatis
purus. Vivamus pharetra venenatis odio, sit amet vehicula ex lacinia non.
Mauris congue risus diam, ut commodo leo lacinia id. Aenean consectetur, est
sit amet tristique ultricies, arcu orci rutrum velit, et auctor lectus mauris
eget risus.

Integer ornare nunc orci, a placerat diam convallis sit amet. Aenean augue
nisl, imperdiet vel faucibus eget, elementum id nunc. Aliquam facilisis lorem
ante, non elementum erat molestie at. Nulla dapibus pulvinar luctus. Curabitur
dignissim pretium eros, id vestibulum leo vulputate non. Phasellus lacinia,
arcu sed lobortis gravida, arcu velit viverra tellus, ullamcorper commodo quam
tellus et orci. Vivamus eget ultrices felis. Lorem ipsum dolor sit amet,
consectetur adipiscing elit. Duis feugiat volutpat turpis, nec sodales dui
fringilla in.

Integer id leo non justo finibus dictum id in dui. Vivamus sed finibus nisi.
Sed in diam in mauris dignissim molestie. Aliquam erat volutpat. Phasellus et
sollicitudin velit, vitae pharetra quam. Nunc vulputate varius massa, vitae
mattis turpis rutrum eget. Fusce velit justo, pharetra sit amet placerat at,
ultrices et magna. Nunc varius justo sit amet iaculis egestas. Integer in
lacus sit amet sem finibus mattis sit amet efficitur ante. Aliquam interdum
metus nec facilisis condimentum.

Proin eleifend non justo in varius. In iaculis ex lacus, vel volutpat lorem
ultricies id. Mauris interdum nulla rhoncus posuere tempus. Nulla nec eros sit
amet nibh blandit mattis. Integer elementum sem nec ligula posuere imperdiet.
Sed sagittis ipsum mi, sed lobortis urna congue ut. Phasellus eget sodales
velit. Fusce pellentesque ipsum non nibh luctus lobortis. Interdum et
malesuada fames ac ante ipsum primis in faucibus. Nam convallis massa vel
pretium euismod. Nulla aliquet faucibus massa, non finibus felis.

Ut id consequat tellus. Sed sagittis arcu in urna egestas, et gravida metus
tincidunt. Sed viverra lorem at libero vulputate tincidunt eget imperdiet
urna. Aenean semper, nunc tincidunt convallis sagittis, elit sapien vestibulum
dolor, sed maximus sapien arcu at risus. Aenean vitae diam sed nisl tincidunt
molestie. Donec sit amet pellentesque leo. Mauris semper magna vitae nunc
porttitor, ac pretium ipsum tincidunt. Nulla blandit ipsum quis magna varius,
nec rhoncus leo consequat. Integer consectetur a nisl et cursus. Suspendisse
ac dignissim cras amet.`
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"os"
)

const (
	DEFAULT_BUILD_FILE = "build.yml"
)

func ParseCommandLine() (*string, *bool, []string) {
	file := flag.String("file", DEFAULT_BUILD_FILE, "Build file to run")
	help := flag.Bool("build", false, "Print build help")
	flag.Parse()
	targets := flag.Args()
	return file, help, targets
}

func main() {
	file, help, targets := ParseCommandLine()
	build, err := NewBuild(*file)
	if err != nil {
		PrintError(err.Error())
		os.Exit(1)
	}
	if *help {
		err = build.Help()
		if err != nil {
			PrintError(err.Error())
			os.Exit(2)
		}
	} else {
		err = build.Run(targets)
		PrintOK()
		if err != nil {
			PrintError(err.Error())
			os.Exit(2)
		}
	}
}
<commit_msg>Fixed OK<commit_after>package main

import (
	"flag"
	"os"
)

const (
	DEFAULT_BUILD_FILE = "build.yml"
)

func ParseCommandLine() (*string, *bool, []string) {
	file := flag.String("file", DEFAULT_BUILD_FILE, "Build file to run")
	help := flag.Bool("build", false, "Print build help")
	flag.Parse()
	targets := flag.Args()
	return file, help, targets
}

func main() {
	file, help, targets := ParseCommandLine()
	build, err := NewBuild(*file)
	if err != nil {
		PrintError(err.Error())
		os.Exit(1)
	}
	if *help {
		err = build.Help()
		if err != nil {
			PrintError(err.Error())
			os.Exit(2)
		}
	} else {
		err = build.Run(targets)
		if err == nil {
			PrintOK()
		} else {
			PrintError(err.Error())
			os.Exit(2)
		}
	}
}
<|endoftext|>


<commit_before>package contour

// E versions, these return the error. Non-e versions are just wrapped calls to
// these functions with the error dropped.

// Config Get Methods

// E versions, these return the error. Non-e versions are just wrapped calls to
// these functions with the error dropped.

// GetE returns the setting Value as an interface{}. If its not a valid
// setting, an error is returned.
func (c *Cfg) GetE(k string) (interface{}, error) {
	_, ok := c.Settings[k]
	if !ok {
		return nil, notFoundErr(k)
	}

	return c.Settings[k].Value, nil
}

// GetBoolE returns the setting Value as a bool.
func (c *Cfg) GetBoolE(k string) (bool, error) {
	_, ok := c.Settings[k]
	if !ok {
		return false, notFoundErr(k)
	}

	return *c.Settings[k].Value.(*bool), nil
}

// GetIntE returns the setting Value as an int.
func (c *Cfg) GetIntE(k string) (int, error) {
	_, ok := c.Settings[k]
	if !ok {
		return 0, notFoundErr(k)
	}

	return c.Settings[k].Value.(int), nil
}

// GetStringE returns the setting Value as a string.
func (c *Cfg) GetStringE(k string) (string, error) {
	_, ok := c.Settings[k]
	if !ok {
		return "", notFoundErr(k)
	}

	return c.Settings[k].Value.(string), nil
}

// GetInterfaceE is a convenience wrapper function to Get
func (c *Cfg) GetInterfaceE(k string) (interface{}, error) {
	return c.GetE(k)
}

func (c *Cfg) Get(k string) interface{} {
	s, _ := c.GetE(k)
	return s
}

// GetBool returns the setting Value as a bool.
func (c *Cfg) GetBool(k string) bool {
	s, _ := c.GetBoolE(k)
	return s
}

// GetInt returns the setting Value as an int.
func (c *Cfg) GetInt(k string) int {
	s, _ := c.GetIntE(k)
	return s
}

// GetString returns the setting Value as a string.
func (c *Cfg) GetString(k string) string {
	s, _ := c.GetStringE(k)
	return s
}

// GetInterfac returns the setting Value as an interface
func (c *Cfg) GetInterface(k string) interface{} {
	return c.Get(k)
}

// Filter Methods obtain a list of flags of the filter type, e.g. boolFilter
// for bool flags, and returns them.
// GetBoolFilterNames returns a list of filter names (flags).
func (c *Cfg) GetBoolFilterNames() []string {
	var names []string

	for k, setting := range c.Settings {
		if setting.IsFlag && setting.Type == "bool" {
			names = append(names, k)
		}
	}

	return names
}

// GetIntFilterNames returns a list of filter names (flags).
func (c *Cfg) GetIntFilterNames() []string {
	var names []string

	for k, setting := range c.Settings {
		if setting.IsFlag && setting.Type == "int" {
			names = append(names, k)
		}
	}

	return names
}

// GetStringFilterNames returns a list of filter names (flags).
func (c *Cfg) GetStringFilterNames() []string {
	var names []string

	for k, setting := range c.Settings {
		if setting.IsFlag && setting.Type == "string" {
			names = append(names, k)
		}
	}

	return names
}

// Convenience functions for configs[app]
// Get returns the setting Value as an interface{}.
// GetE returns the setting Value as an interface{}.
func GetE(k string) (interface{}, error) {
	_, ok := configs[app].Settings[k]
	if !ok {
		return nil, notFoundErr(k)
	}

	return configs[app].Settings[k].Value, nil
}

// GetBoolE returns the setting Value as a bool.
func GetBoolE(k string) (bool, error) {
	_, ok := configs[app].Settings[k]
	if !ok {
		return false, notFoundErr(k)
	}

	return *configs[app].Settings[k].Value.(*bool), nil
}

// GetIntE returns the setting Value as an int.
func GetIntE(k string) (int, error) {
	_, ok := configs[app].Settings[k]
	if !ok {
		return 0, notFoundErr(k)
	}

	return *configs[app].Settings[k].Value.(*int), nil
}

// GetStringE returns the setting Value as a string.
func GetStringE(k string) (string, error) {
	_, ok := configs[app].Settings[k]
	if !ok {
		return "", notFoundErr(k)
	}

	return configs[app].Settings[k].Value.(string), nil
}

// GetInterfaceE is a convenience wrapper function to Get
func GetInterfaceE(k string) (interface{}, error) {
	return configs[app].GetE(k)
}

func Get(k string) interface{} {
	s, _ := configs[app].GetE(k)
	return s
}

// GetBool returns the setting Value as a bool.
func GetBool(k string) bool {
	s, _ := configs[app].GetBoolE(k)
	return s
}

// GetInt returns the setting Value as an int.
func GetInt(k string) int {
	s, _ := configs[app].GetIntE(k)
	return s
}

// GetString returns the setting Value as a string.
func GetString(k string) string {
	s, _ := configs[app].GetStringE(k)
	return s
}

// GetInterface is a convenience wrapper function to Get
func GetInterface(k string) interface{} {
	return configs[app].Get(k)
}

// GetBoolFilterNames returns a list of filter names (flags).
func GetBoolFilterNames() []string {
	var names []string

	for k, setting := range configs[app].Settings {
		if setting.IsFlag && setting.Type == "bool" {
			names = append(names, k)
		}
	}

	return names
}

// GetIntFilterNames returns a list of filter names (flags).
func GetIntFilterNames() []string {
	var names []string

	for k, setting := range configs[app].Settings {
		if setting.IsFlag && setting.Type == "int" {
			names = append(names, k)
		}
	}

	return names
}

// GetStringFilterNames returns a list of filter names (flags).
func GetStringFilterNames() []string {
	var names []string

	for k, setting := range configs[app].Settings {
		if setting.IsFlag && setting.Type == "string" {
			names = append(names, k)
		}
	}

	return names
}

<commit_msg>added handling for pointer versions<commit_after>package contour

// E versions, these return the error. Non-e versions are just wrapped calls to
// these functions with the error dropped.

// Config Get Methods

// E versions, these return the error. Non-e versions are just wrapped calls to
// these functions with the error dropped.

// GetE returns the setting Value as an interface{}. If its not a valid
// setting, an error is returned.
func (c *Cfg) GetE(k string) (interface{}, error) {
	_, ok := c.Settings[k]
	if !ok {
		return nil, notFoundErr(k)
	}

	return c.Settings[k].Value, nil
}

// GetBoolE returns the setting Value as a bool.
func (c *Cfg) GetBoolE(k string) (bool, error) {
	_, ok := c.Settings[k]
	if !ok {
		return false, notFoundErr(k)
	}

	switch c.Settings[k].Value.(type) {
	case bool:
		return c.Settings[k].Value.(bool), nil
	case *bool:
		return *c.Settings[k].Value.(*bool), nil
	}

	// Should never happen, but since we know the setting is there and we
	// expect it to be bool, given this method was called, we assume any
	// non-bool/*bool type == false.
	return false, nil
}

// GetIntE returns the setting Value as an int.
func (c *Cfg) GetIntE(k string) (int, error) {
	_, ok := c.Settings[k]
	if !ok {
		return 0, notFoundErr(k)
	}

	switch c.Settings[k].Value.(type) {
	case int:
		return c.Settings.k.Value.(int), nil
	case *int:
		return c.Settings[k].Value.(*int), nil
	}

	return 0, nil
}

// GetStringE returns the setting Value as a string.
func (c *Cfg) GetStringE(k string) (string, error) {
	_, ok := c.Settings[k]
	if !ok {
		return "", notFoundErr(k)
	}

	switch c.Settings[k].Value.(type) {
	case string:
		return c.Settings[k].Value.(string), nil
	case *string:
		return c.Settings[k].Value.(*string), nil
	}

	return "", nil
}

// GetInterfaceE is a convenience wrapper function to Get
func (c *Cfg) GetInterfaceE(k string) (interface{}, error) {
	return c.GetE(k)
}

func (c *Cfg) Get(k string) interface{} {
	s, _ := c.GetE(k)
	return s
}

// GetBool returns the setting Value as a bool.
func (c *Cfg) GetBool(k string) bool {
	s, _ := c.GetBoolE(k)
	return s
}

// GetInt returns the setting Value as an int.
func (c *Cfg) GetInt(k string) int {
	s, _ := c.GetIntE(k)
	return s
}

// GetString returns the setting Value as a string.
func (c *Cfg) GetString(k string) string {
	s, _ := c.GetStringE(k)
	return s
}

// GetInterfac returns the setting Value as an interface
func (c *Cfg) GetInterface(k string) interface{} {
	return c.Get(k)
}

// Filter Methods obtain a list of flags of the filter type, e.g. boolFilter
// for bool flags, and returns them.
// GetBoolFilterNames returns a list of filter names (flags).
func (c *Cfg) GetBoolFilterNames() []string {
	var names []string

	for k, setting := range c.Settings {
		if setting.IsFlag && setting.Type == "bool" {
			names = append(names, k)
		}
	}

	return names
}

// GetIntFilterNames returns a list of filter names (flags).
func (c *Cfg) GetIntFilterNames() []string {
	var names []string

	for k, setting := range c.Settings {
		if setting.IsFlag && setting.Type == "int" {
			names = append(names, k)
		}
	}

	return names
}

// GetStringFilterNames returns a list of filter names (flags).
func (c *Cfg) GetStringFilterNames() []string {
	var names []string

	for k, setting := range c.Settings {
		if setting.IsFlag && setting.Type == "string" {
			names = append(names, k)
		}
	}

	return names
}

// Convenience functions for configs[app]
// Get returns the setting Value as an interface{}.
// GetE returns the setting Value as an interface{}.
func GetE(k string) (interface{}, error) {
	_, ok := configs[app].Settings[k]
	if !ok {
		return nil, notFoundErr(k)
	}

	return configs[app].Settings[k].Value, nil
}

// GetBoolE returns the setting Value as a bool.
func GetBoolE(k string) (bool, error) {
	_, ok := configs[app].Settings[k]
	if !ok {
		return false, notFoundErr(k)
	}

	return *configs[app].Settings[k].Value.(*bool), nil
}

// GetIntE returns the setting Value as an int.
func GetIntE(k string) (int, error) {
	_, ok := configs[app].Settings[k]
	if !ok {
		return 0, notFoundErr(k)
	}

	return *configs[app].Settings[k].Value.(*int), nil
}

// GetStringE returns the setting Value as a string.
func GetStringE(k string) (string, error) {
	_, ok := configs[app].Settings[k]
	if !ok {
		return "", notFoundErr(k)
	}

	return configs[app].Settings[k].Value.(string), nil
}

// GetInterfaceE is a convenience wrapper function to Get
func GetInterfaceE(k string) (interface{}, error) {
	return configs[app].GetE(k)
}

func Get(k string) interface{} {
	s, _ := configs[app].GetE(k)
	return s
}

// GetBool returns the setting Value as a bool.
func GetBool(k string) bool {
	s, _ := configs[app].GetBoolE(k)
	return s
}

// GetInt returns the setting Value as an int.
func GetInt(k string) int {
	s, _ := configs[app].GetIntE(k)
	return s
}

// GetString returns the setting Value as a string.
func GetString(k string) string {
	s, _ := configs[app].GetStringE(k)
	return s
}

// GetInterface is a convenience wrapper function to Get
func GetInterface(k string) interface{} {
	return configs[app].Get(k)
}

// GetBoolFilterNames returns a list of filter names (flags).
func GetBoolFilterNames() []string {
	var names []string

	for k, setting := range configs[app].Settings {
		if setting.IsFlag && setting.Type == "bool" {
			names = append(names, k)
		}
	}

	return names
}

// GetIntFilterNames returns a list of filter names (flags).
func GetIntFilterNames() []string {
	var names []string

	for k, setting := range configs[app].Settings {
		if setting.IsFlag && setting.Type == "int" {
			names = append(names, k)
		}
	}

	return names
}

// GetStringFilterNames returns a list of filter names (flags).
func GetStringFilterNames() []string {
	var names []string

	for k, setting := range configs[app].Settings {
		if setting.IsFlag && setting.Type == "string" {
			names = append(names, k)
		}
	}

	return names
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"sync"

	"github.com/FreekKalter/ansi/color"
	"github.com/FreekKalter/text/columnswriter"
	"github.com/FreekKalter/text/tabwriter"
	Optarg "github.com/jteeuwen/go-pkg-optarg"
)

type colorFunc func(interface{}) *color.Escape

var colorMap map[string]colorFunc = map[string]colorFunc{
	"ok":                 func(i interface{}) *color.Escape { return color.BgDefault(color.Default(i)) },
	"file":               func(i interface{}) *color.Escape { return color.BgDefault(color.Default(i)) },
	"no_version_control": func(i interface{}) *color.Escape { return color.Bold(color.Blue(i)) },                  // Blue
	"dirty":              func(i interface{}) *color.Escape { return color.Bold(color.Red(i)) },                   // Red
	"no_remote":          func(i interface{}) *color.Escape { return color.BgBlue(color.Bold(color.Red(i))) },     // Red on Blue
	"fetch_failed":       func(i interface{}) *color.Escape { return color.BgRed(color.Bold(color.Blue(i))) },     // Blue on Red
	"branch_ahead":       func(i interface{}) *color.Escape { return color.BgYellow(color.Bold(color.Green(i))) }, // Green on Yellow
	"branch_behind":      func(i interface{}) *color.Escape { return color.BgYellow(color.Bold(color.Red(i))) },   // Red on Yellow
}

// Struct passed between gls and main
type Project struct {
	Name, State string
	Info        os.FileInfo
}
type Projects []*Project

func (projects Projects) Len() int      { return len(projects) }
func (projects Projects) Swap(i, j int) { projects[i], projects[j] = projects[j], projects[i] }

type ByName struct{ Projects }
type ByState struct{ Projects }

func (s ByName) Less(i, j int) bool {
	return strings.ToLower(s.Projects[i].Name) < strings.ToLower(s.Projects[j].Name)
}
func (s ByState) Less(i, j int) bool {
	return sortOrderStates[s.Projects[i].State] < sortOrderStates[s.Projects[j].State]
}

var (
	cleanGitRegex = regexp.MustCompile("nothing to commit")
	fetchErrors   = regexp.MustCompile("^fatal")
	branchAhead   = regexp.MustCompile("branch is ahead of")
	branchBehind  = regexp.MustCompile("branch is behind")
)

var help, list, onlyDirty, sortByState, all bool
var sortOrderStates = map[string]int{"ok": 0, "no_version_control": 1, "dirty": 2, "no_remote": 3, "fetch_failed": 4, "branch_ahead": 5, "branch_behind": 6}
var TimeFormat = "Jan 02,2006 15:04"
var wg sync.WaitGroup

func main() {
	//flag.BoolVar(&help, "help", false, "print help message")
	//flag.BoolVar(&list, "list", false, "display results in 1 long list")
	//flag.BoolVar(&all, "all", false, "display files and folders staring with a dot")
	//flag.BoolVar(&onlyDirty, "dirty", false, "only show diry dirs, this is very fast because it does not check remotes")
	//flag.BoolVar(&sortByState, "statesort", false, "sort output by state")
	//flag.Parse()
	Optarg.Add("h", "help", "print help message", false)
	Optarg.Add("l", "list", "display results in 1 long list", false)
	Optarg.Add("a", "all", "display files and folders staring with a dot", false)
	Optarg.Add("d", "dirty", "only show diry dirs, this is very fast because it does not check remotes", false)
	Optarg.Add("s", "statesort", "sort output by state", false)
	for opt := range Optarg.Parse() {
		switch opt.ShortName {
		case "h":
			Optarg.Usage()
			fmt.Println("")
			fmt.Println("Color codes:")
			for k, v := range colorMap {
				fmt.Println(v(k))
			}
			return
		case "l":
			list = true
		case "a":
			all = true
		case "d":
			onlyDirty = true
		case "s":
			sortByState = true
		}
	}

	// Sort out path and files in that dir
	var path string
	if len(flag.Args()) > 0 {
		path = flag.Arg(0)
	} else {
		path = "."
	}
	var files []string
	var err error
	if all {
		files, err = filepath.Glob(filepath.Join(path, "*"))
	} else {
		files, err = filepath.Glob(filepath.Join(path, "[^.]*"))
	}
	if err != nil {
		panic(err)
	}

	// Start goroutine for every dir found
	glsResults := make(chan *Project, 1000)
	var projects Projects
	for _, file := range files {
		file_info, _ := os.Stat(file)
		if file_info.IsDir() {
			wg.Add(1)
			go gls(&Project{Name: file, Info: file_info}, glsResults)
		} else {
			projects = append(projects, &Project{Name: file, State: "file", Info: file_info})
		}
	}
	wg.Wait()
	close(glsResults)

	// Gather results and process them
	for res := range glsResults {
		// make a copy to add to []projects, because res always points to the same address space
		toAppend := res
		toAppend.Name = filepath.Base(res.Name)
		projects = append(projects, toAppend)
	}
	if sortByState {
		sort.Sort(ByState{projects})
	} else {
		sort.Sort(ByName{projects})
	}

	if list {
		w := new(tabwriter.Writer)
		w.Init(os.Stdout, 0, 8, 0, '\t', tabwriter.StripEscape)
		for _, p := range projects {
			fmt.Fprintf(w, "%s\t%s\t%s\n", colorMap[p.State](p.Name), humanReadable(p.Info.Size()), p.Info.ModTime().Format(TimeFormat))
		}
		w.Flush()
	} else {

		var projectsString string
		for _, p := range projects {
			projectsString = fmt.Sprintf("%s\t%s", projectsString, colorMap[p.State](p.Name))
		}

		w := columnswriter.New(os.Stdout, '\t', 0, 2)
		fmt.Fprint(w, projectsString)
		w.Flush()
	}
}

func gls(project *Project /*dirName string*/, result chan *Project) {
	defer wg.Done()

	// First chek, is the directory under (git) version control
	if ok, _ := exists(filepath.Join(project.Name, ".git")); !ok {
		if !onlyDirty {
			project.State = "no_version_control"
			result <- project
		}
		return
	}

	gitDir := fmt.Sprintf("--git-dir=%s", filepath.Join(project.Name, ".git"))
	gitTree := fmt.Sprintf("--work-tree=%s", project.Name)
	output, err := exec.Command("git", gitDir, gitTree, "status").Output() //, gitDir, gitTree, "status")
	if err != nil {
		panic(err)
	}
	// Are there uncommitted changes is the directory (dirty)
	if !cleanGitRegex.MatchString(strings.TrimSpace(string(output))) {
		project.State = "dirty"
		result <- project
		return
	} else if onlyDirty {
		return
	}

	// Check if the repo has a remote
	output, err = exec.Command("git", gitDir, gitTree, "remote", "-v").Output()
	if err != nil {
		panic(err)
	}
	if len(output) == 0 {
		project.State = "no_remote"
		result <- project
		return
	}

	// Fetch latest changes from remote
	output, err = exec.Command("git", gitDir, gitTree, "fetch").Output()
	if err != nil {
		project.State = "fetch_failed"
		result <- project
		return
	}
	outputStr := strings.TrimSpace(string(output))
	if fetchErrors.MatchString(outputStr) {
		project.State = "fetch_failed"
		result <- project
		return
	}

	output, err = exec.Command("git", gitDir, gitTree, "status").Output()
	if err != nil {
		panic(err)
	}
	outputStr = strings.TrimSpace(string(output))

	// Is branch ahead of behind of remote
	if branchAhead.MatchString(outputStr) {
		project.State = "branch_ahead"
		result <- project
		return
	} else if branchBehind.MatchString(outputStr) {
		project.State = "branch_behind"
		result <- project
		return
	}

	project.State = "ok"
	result <- project
}

func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func humanReadable(filesize int64) string {
	fs := float64(filesize)
	for _, x := range []string{"b", "kb", "mb", "gb", "tb"} {
		if fs < 1024 {
			return fmt.Sprintf("%3.1f % s", fs, x)
		}
		fs /= 1024
	}
	return ""
}
<commit_msg>Added errorhandling in humanreadable()<commit_after>package main

import (
	"errors"
	"flag"
	"fmt"
	"os"
	"os/exec"
	"path/filepath"
	"regexp"
	"sort"
	"strings"
	"sync"

	"github.com/FreekKalter/ansi/color"
	"github.com/FreekKalter/text/columnswriter"
	"github.com/FreekKalter/text/tabwriter"
	Optarg "github.com/jteeuwen/go-pkg-optarg"
)

type colorFunc func(interface{}) *color.Escape

var colorMap map[string]colorFunc = map[string]colorFunc{
	"ok":                 func(i interface{}) *color.Escape { return color.BgDefault(color.Default(i)) },
	"file":               func(i interface{}) *color.Escape { return color.BgDefault(color.Default(i)) },
	"no_version_control": func(i interface{}) *color.Escape { return color.Bold(color.Blue(i)) },                  // Blue
	"dirty":              func(i interface{}) *color.Escape { return color.Bold(color.Red(i)) },                   // Red
	"no_remote":          func(i interface{}) *color.Escape { return color.BgBlue(color.Bold(color.Red(i))) },     // Red on Blue
	"fetch_failed":       func(i interface{}) *color.Escape { return color.BgRed(color.Bold(color.Blue(i))) },     // Blue on Red
	"branch_ahead":       func(i interface{}) *color.Escape { return color.BgYellow(color.Bold(color.Green(i))) }, // Green on Yellow
	"branch_behind":      func(i interface{}) *color.Escape { return color.BgYellow(color.Bold(color.Red(i))) },   // Red on Yellow
}

// Struct passed between gls and main
type Project struct {
	Name, State string
	Info        os.FileInfo
}
type Projects []*Project

func (projects Projects) Len() int      { return len(projects) }
func (projects Projects) Swap(i, j int) { projects[i], projects[j] = projects[j], projects[i] }

type ByName struct{ Projects }
type ByState struct{ Projects }

func (s ByName) Less(i, j int) bool {
	return strings.ToLower(s.Projects[i].Name) < strings.ToLower(s.Projects[j].Name)
}
func (s ByState) Less(i, j int) bool {
	return sortOrderStates[s.Projects[i].State] < sortOrderStates[s.Projects[j].State]
}

var (
	cleanGitRegex = regexp.MustCompile("nothing to commit")
	fetchErrors   = regexp.MustCompile("^fatal")
	branchAhead   = regexp.MustCompile("branch is ahead of")
	branchBehind  = regexp.MustCompile("branch is behind")
)

var help, list, onlyDirty, sortByState, all bool
var sortOrderStates = map[string]int{"ok": 0, "no_version_control": 1, "dirty": 2, "no_remote": 3, "fetch_failed": 4, "branch_ahead": 5, "branch_behind": 6}
var TimeFormat = "Jan 02,2006 15:04"
var wg sync.WaitGroup

func main() {
	//flag.BoolVar(&help, "help", false, "print help message")
	//flag.BoolVar(&list, "list", false, "display results in 1 long list")
	//flag.BoolVar(&all, "all", false, "display files and folders staring with a dot")
	//flag.BoolVar(&onlyDirty, "dirty", false, "only show diry dirs, this is very fast because it does not check remotes")
	//flag.BoolVar(&sortByState, "statesort", false, "sort output by state")
	//flag.Parse()
	Optarg.Add("h", "help", "print help message", false)
	Optarg.Add("l", "list", "display results in 1 long list", false)
	Optarg.Add("a", "all", "display files and folders staring with a dot", false)
	Optarg.Add("d", "dirty", "only show diry dirs, this is very fast because it does not check remotes", false)
	Optarg.Add("s", "statesort", "sort output by state", false)
	for opt := range Optarg.Parse() {
		switch opt.ShortName {
		case "h":
			Optarg.Usage()
			fmt.Println("")
			fmt.Println("Color codes:")
			for k, v := range colorMap {
				fmt.Println(v(k))
			}
			return
		case "l":
			list = true
		case "a":
			all = true
		case "d":
			onlyDirty = true
		case "s":
			sortByState = true
		}
	}

	// Sort out path and files in that dir
	var path string
	if len(flag.Args()) > 0 {
		path = flag.Arg(0)
	} else {
		path = "."
	}
	var files []string
	var err error
	if all {
		files, err = filepath.Glob(filepath.Join(path, "*"))
	} else {
		files, err = filepath.Glob(filepath.Join(path, "[^.]*"))
	}
	if err != nil {
		panic(err)
	}

	// Start goroutine for every dir found
	glsResults := make(chan *Project, 1000)
	var projects Projects
	for _, file := range files {
		file_info, _ := os.Stat(file)
		if file_info.IsDir() {
			wg.Add(1)
			go gls(&Project{Name: file, Info: file_info}, glsResults)
		} else {
			projects = append(projects, &Project{Name: file, State: "file", Info: file_info})
		}
	}
	wg.Wait()
	close(glsResults)

	// Gather results and process them
	for res := range glsResults {
		// make a copy to add to []projects, because res always points to the same address space
		toAppend := res
		toAppend.Name = filepath.Base(res.Name)
		projects = append(projects, toAppend)
	}
	if sortByState {
		sort.Sort(ByState{projects})
	} else {
		sort.Sort(ByName{projects})
	}

	if list {
		w := new(tabwriter.Writer)
		w.Init(os.Stdout, 0, 8, 0, '\t', tabwriter.StripEscape)
		for _, p := range projects {
            hm, err := humanReadable(p.Info.Size())
            if err != nil {
                panic(err)
            }
			fmt.Fprintf(w, "%s\t%s\t%s\n", colorMap[p.State](p.Name),hm , p.Info.ModTime().Format(TimeFormat))
		}
		w.Flush()
	} else {

		var projectsString string
		for _, p := range projects {
			projectsString = fmt.Sprintf("%s\t%s", projectsString, colorMap[p.State](p.Name))
		}

		w := columnswriter.New(os.Stdout, '\t', 0, 2)
		fmt.Fprint(w, projectsString)
		w.Flush()
	}
}

func gls(project *Project /*dirName string*/, result chan *Project) {
	defer wg.Done()

	// First chek, is the directory under (git) version control
	if ok, _ := exists(filepath.Join(project.Name, ".git")); !ok {
		if !onlyDirty {
			project.State = "no_version_control"
			result <- project
		}
		return
	}

	gitDir := fmt.Sprintf("--git-dir=%s", filepath.Join(project.Name, ".git"))
	gitTree := fmt.Sprintf("--work-tree=%s", project.Name)
	output, err := exec.Command("git", gitDir, gitTree, "status").Output() //, gitDir, gitTree, "status")
	if err != nil {
		panic(err)
	}
	// Are there uncommitted changes is the directory (dirty)
	if !cleanGitRegex.MatchString(strings.TrimSpace(string(output))) {
		project.State = "dirty"
		result <- project
		return
	} else if onlyDirty {
		return
	}

	// Check if the repo has a remote
	output, err = exec.Command("git", gitDir, gitTree, "remote", "-v").Output()
	if err != nil {
		panic(err)
	}
	if len(output) == 0 {
		project.State = "no_remote"
		result <- project
		return
	}

	// Fetch latest changes from remote
	output, err = exec.Command("git", gitDir, gitTree, "fetch").Output()
	if err != nil {
		project.State = "fetch_failed"
		result <- project
		return
	}
	outputStr := strings.TrimSpace(string(output))
	if fetchErrors.MatchString(outputStr) {
		project.State = "fetch_failed"
		result <- project
		return
	}

	output, err = exec.Command("git", gitDir, gitTree, "status").Output()
	if err != nil {
		panic(err)
	}
	outputStr = strings.TrimSpace(string(output))

	// Is branch ahead of behind of remote
	if branchAhead.MatchString(outputStr) {
		project.State = "branch_ahead"
		result <- project
		return
	} else if branchBehind.MatchString(outputStr) {
		project.State = "branch_behind"
		result <- project
		return
	}

	project.State = "ok"
	result <- project
}

func exists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}

func humanReadable(filesize int64) (string , error){
    if filesize < 0 {
        return "", errors.New("negative input")
    }
	fs := float64(filesize)
	for _, x := range []string{"b", "kb", "mb", "gb", "tb"} {
		if fs < 1024 {
			return fmt.Sprintf("%3.1f % s", fs, x), nil
		}
		fs /= 1024
	}
	return "",nil
}
<|endoftext|>


<commit_before>// Copyright 2010 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.

package runtime

// The Error interface identifies a run time error.
type Error interface {
	error

	// RuntimeError is a no-op function but
	// serves to distinguish types that are runtime
	// errors from ordinary errors: a type is a
	// runtime error if it has a RuntimeError method.
	RuntimeError()
}

// A TypeAssertionError explains a failed type assertion.
type TypeAssertionError struct {
	interfaceString string
	concreteString  string
	assertedString  string
	missingMethod   string // one method needed by Interface, missing from Concrete
}

func (*TypeAssertionError) RuntimeError() {}

func (e *TypeAssertionError) Error() string {
	inter := e.interfaceString
	if inter == "" {
		inter = "interface"
	}
	if e.concreteString == "" {
		return "interface conversion: " + inter + " is nil, not " + e.assertedString
	}
	if e.missingMethod == "" {
		return "interface conversion: " + inter + " is " + e.concreteString +
			", not " + e.assertedString
	}
	return "interface conversion: " + e.concreteString + " is not " + e.assertedString +
		": missing method " + e.missingMethod
}

// For calling from C.
func newTypeAssertionError(ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) {
	var s1, s2, s3, meth string

	if ps1 != nil {
		s1 = *ps1
	}
	if ps2 != nil {
		s2 = *ps2
	}
	if ps3 != nil {
		s3 = *ps3
	}
	if pmeth != nil {
		meth = *pmeth
	}
	*ret = &TypeAssertionError{s1, s2, s3, meth}
}

// An errorString represents a runtime error described by a single string.
type errorString string

func (e errorString) RuntimeError() {}

func (e errorString) Error() string {
	return "runtime error: " + string(e)
}

// For calling from C.
func newErrorString(s string, ret *interface{}) {
	*ret = errorString(s)
}

// An errorCString represents a runtime error described by a single C string.
// Not "type errorCString uintptr" because of http://golang.org/issue/7084.
type errorCString struct{ cstr uintptr }

func (e errorCString) RuntimeError() {}

func (e errorCString) Error() string {
	return "runtime error: " + cstringToGo(e.cstr)
}

// For calling from C.
func newErrorCString(s uintptr, ret *interface{}) {
	*ret = errorCString{s}
}

type stringer interface {
	String() string
}

func typestring(interface{}) string

// For calling from C.
// Prints an argument passed to panic.
// There's room for arbitrary complexity here, but we keep it
// simple and handle just a few important cases: int, string, and Stringer.
func printany(i interface{}) {
	switch v := i.(type) {
	case nil:
		print("nil")
	case stringer:
		print(v.String())
	case error:
		print(v.Error())
	case int:
		print(v)
	case string:
		print(v)
	default:
		print("(", typestring(i), ") ", i)
	}
}

// called from generated code
func panicwrap(pkg, typ, meth string) {
	panic("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer")
}
<commit_msg>runtime: adjust errorCString definition to avoid allocation<commit_after>// Copyright 2010 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.

package runtime

import "unsafe"

// The Error interface identifies a run time error.
type Error interface {
	error

	// RuntimeError is a no-op function but
	// serves to distinguish types that are runtime
	// errors from ordinary errors: a type is a
	// runtime error if it has a RuntimeError method.
	RuntimeError()
}

// A TypeAssertionError explains a failed type assertion.
type TypeAssertionError struct {
	interfaceString string
	concreteString  string
	assertedString  string
	missingMethod   string // one method needed by Interface, missing from Concrete
}

func (*TypeAssertionError) RuntimeError() {}

func (e *TypeAssertionError) Error() string {
	inter := e.interfaceString
	if inter == "" {
		inter = "interface"
	}
	if e.concreteString == "" {
		return "interface conversion: " + inter + " is nil, not " + e.assertedString
	}
	if e.missingMethod == "" {
		return "interface conversion: " + inter + " is " + e.concreteString +
			", not " + e.assertedString
	}
	return "interface conversion: " + e.concreteString + " is not " + e.assertedString +
		": missing method " + e.missingMethod
}

// For calling from C.
func newTypeAssertionError(ps1, ps2, ps3 *string, pmeth *string, ret *interface{}) {
	var s1, s2, s3, meth string

	if ps1 != nil {
		s1 = *ps1
	}
	if ps2 != nil {
		s2 = *ps2
	}
	if ps3 != nil {
		s3 = *ps3
	}
	if pmeth != nil {
		meth = *pmeth
	}
	*ret = &TypeAssertionError{s1, s2, s3, meth}
}

// An errorString represents a runtime error described by a single string.
type errorString string

func (e errorString) RuntimeError() {}

func (e errorString) Error() string {
	return "runtime error: " + string(e)
}

// For calling from C.
func newErrorString(s string, ret *interface{}) {
	*ret = errorString(s)
}

// An errorCString represents a runtime error described by a single C string.
// Not "type errorCString unsafe.Pointer" because of http://golang.org/issue/7084.
// Not uintptr because we want to avoid an allocation if interfaces can't hold
// uintptrs directly (and cstr _is_ a pointer).
type errorCString struct{ cstr unsafe.Pointer }

func (e errorCString) RuntimeError() {}

func (e errorCString) Error() string {
	return "runtime error: " + cstringToGo(uintptr(e.cstr))
}

// For calling from C.
func newErrorCString(s unsafe.Pointer, ret *interface{}) {
	*ret = errorCString{s}
}

type stringer interface {
	String() string
}

func typestring(interface{}) string

// For calling from C.
// Prints an argument passed to panic.
// There's room for arbitrary complexity here, but we keep it
// simple and handle just a few important cases: int, string, and Stringer.
func printany(i interface{}) {
	switch v := i.(type) {
	case nil:
		print("nil")
	case stringer:
		print(v.String())
	case error:
		print(v.Error())
	case int:
		print(v)
	case string:
		print(v)
	default:
		print("(", typestring(i), ") ", i)
	}
}

// called from generated code
func panicwrap(pkg, typ, meth string) {
	panic("value method " + pkg + "." + typ + "." + meth + " called using nil *" + typ + " pointer")
}
<|endoftext|>


<commit_before>// Copyright 2009 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.

package strconv

import (
	"bytes"
	"os"
	"strings"
	"unicode"
	"utf8"
)

const lowerhex = "0123456789abcdef"

// Quote returns a double-quoted Go string literal
// representing s.  The returned string s uses Go escape
// sequences (\t, \n, \xFF, \u0100) for control characters
// and non-ASCII characters.
func Quote(s string) string {
	var buf bytes.Buffer
	buf.WriteByte('"')
	for ; len(s) > 0; s = s[1:] {
		switch c := s[0]; {
		case c == '"':
			buf.WriteString(`\"`)
		case c == '\\':
			buf.WriteString(`\\`)
		case ' ' <= c && c <= '~':
			buf.WriteString(string(c))
		case c == '\a':
			buf.WriteString(`\a`)
		case c == '\b':
			buf.WriteString(`\b`)
		case c == '\f':
			buf.WriteString(`\f`)
		case c == '\n':
			buf.WriteString(`\n`)
		case c == '\r':
			buf.WriteString(`\r`)
		case c == '\t':
			buf.WriteString(`\t`)
		case c == '\v':
			buf.WriteString(`\v`)

		case c >= utf8.RuneSelf && utf8.FullRuneInString(s):
			r, size := utf8.DecodeRuneInString(s)
			if r == utf8.RuneError && size == 1 {
				goto EscX
			}
			s = s[size-1:] // next iteration will slice off 1 more
			if r < 0x10000 {
				buf.WriteString(`\u`)
				for j := uint(0); j < 4; j++ {
					buf.WriteByte(lowerhex[(r>>(12-4*j))&0xF])
				}
			} else {
				buf.WriteString(`\U`)
				for j := uint(0); j < 8; j++ {
					buf.WriteByte(lowerhex[(r>>(28-4*j))&0xF])
				}
			}

		default:
		EscX:
			buf.WriteString(`\x`)
			buf.WriteByte(lowerhex[c>>4])
			buf.WriteByte(lowerhex[c&0xF])
		}
	}
	buf.WriteByte('"')
	return buf.String()
}

// CanBackquote returns whether the string s would be
// a valid Go string literal if enclosed in backquotes.
func CanBackquote(s string) bool {
	for i := 0; i < len(s); i++ {
		if (s[i] < ' ' && s[i] != '\t') || s[i] == '`' {
			return false
		}
	}
	return true
}

func unhex(b byte) (v int, ok bool) {
	c := int(b)
	switch {
	case '0' <= c && c <= '9':
		return c - '0', true
	case 'a' <= c && c <= 'f':
		return c - 'a' + 10, true
	case 'A' <= c && c <= 'F':
		return c - 'A' + 10, true
	}
	return
}

// UnquoteChar decodes the first character or byte in the escaped string
// or character literal represented by the string s.
// It returns four values:
// 1) value, the decoded Unicode code point or byte value;
// 2) multibyte, a boolean indicating whether the decoded character
//    requires a multibyte UTF-8 representation;
// 3) tail, the remainder of the string after the character; and
// 4) an error that will be nil if the character is syntactically valid.
// The second argument, quote, specifies the type of literal being parsed
// and therefore which escaped quote character is permitted.
// If set to a single quote, it permits the sequence \' and disallows unescaped '.
// If set to a double quote, it permits \" and disallows unescaped ".
// If set to zero, it does not permit either escape and allows both quote characters to appear unescaped.
func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string, err os.Error) {
	// easy cases
	switch c := s[0]; {
	case c == quote && (quote == '\'' || quote == '"'):
		err = os.EINVAL
		return
	case c >= utf8.RuneSelf:
		r, size := utf8.DecodeRuneInString(s)
		return r, true, s[size:], nil
	case c != '\\':
		return int(s[0]), false, s[1:], nil
	}

	// hard case: c is backslash
	if len(s) <= 1 {
		err = os.EINVAL
		return
	}
	c := s[1]
	s = s[2:]

	switch c {
	case 'a':
		value = '\a'
	case 'b':
		value = '\b'
	case 'f':
		value = '\f'
	case 'n':
		value = '\n'
	case 'r':
		value = '\r'
	case 't':
		value = '\t'
	case 'v':
		value = '\v'
	case 'x', 'u', 'U':
		n := 0
		switch c {
		case 'x':
			n = 2
		case 'u':
			n = 4
		case 'U':
			n = 8
		}
		v := 0
		if len(s) < n {
			err = os.EINVAL
			return
		}
		for j := 0; j < n; j++ {
			x, ok := unhex(s[j])
			if !ok {
				err = os.EINVAL
				return
			}
			v = v<<4 | x
		}
		s = s[n:]
		if c == 'x' {
			// single-byte string, possibly not UTF-8
			value = v
			break
		}
		if v > unicode.MaxRune {
			err = os.EINVAL
			return
		}
		value = v
		multibyte = true
	case '0', '1', '2', '3', '4', '5', '6', '7':
		v := int(c) - '0'
		if len(s) < 2 {
			err = os.EINVAL
			return
		}
		for j := 0; j < 2; j++ { // one digit already; two more
			x := int(s[j]) - '0'
			if x < 0 || x > 7 {
				return
			}
			v = (v << 3) | x
		}
		s = s[2:]
		if v > 255 {
			err = os.EINVAL
			return
		}
		value = v
	case '\\':
		value = '\\'
	case '\'', '"':
		if c != quote {
			err = os.EINVAL
			return
		}
		value = int(c)
	default:
		err = os.EINVAL
		return
	}
	tail = s
	return
}

// Unquote interprets s as a single-quoted, double-quoted,
// or backquoted Go string literal, returning the string value
// that s quotes.  (If s is single-quoted, it would be a Go
// character literal; Unquote returns the corresponding
// one-character string.)
func Unquote(s string) (t string, err os.Error) {
	n := len(s)
	if n < 2 {
		return "", os.EINVAL
	}
	quote := s[0]
	if quote != s[n-1] {
		return "", os.EINVAL
	}
	s = s[1 : n-1]

	if quote == '`' {
		if strings.Index(s, "`") >= 0 {
			return "", os.EINVAL
		}
		return s, nil
	}
	if quote != '"' && quote != '\'' {
		return "", err
	}

	var buf bytes.Buffer
	for len(s) > 0 {
		c, multibyte, ss, err := UnquoteChar(s, quote)
		if err != nil {
			return "", err
		}
		s = ss
		if c < utf8.RuneSelf || !multibyte {
			buf.WriteByte(byte(c))
		} else {
			buf.WriteString(string(c))
		}
		if quote == '\'' && len(s) != 0 {
			// single-quoted must be single character
			return "", os.EINVAL
		}
	}
	return buf.String(), nil
}
<commit_msg>strconv.Unquote could wrongly return a nil error on error.<commit_after>// Copyright 2009 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.

package strconv

import (
	"bytes"
	"os"
	"strings"
	"unicode"
	"utf8"
)

const lowerhex = "0123456789abcdef"

// Quote returns a double-quoted Go string literal
// representing s.  The returned string s uses Go escape
// sequences (\t, \n, \xFF, \u0100) for control characters
// and non-ASCII characters.
func Quote(s string) string {
	var buf bytes.Buffer
	buf.WriteByte('"')
	for ; len(s) > 0; s = s[1:] {
		switch c := s[0]; {
		case c == '"':
			buf.WriteString(`\"`)
		case c == '\\':
			buf.WriteString(`\\`)
		case ' ' <= c && c <= '~':
			buf.WriteString(string(c))
		case c == '\a':
			buf.WriteString(`\a`)
		case c == '\b':
			buf.WriteString(`\b`)
		case c == '\f':
			buf.WriteString(`\f`)
		case c == '\n':
			buf.WriteString(`\n`)
		case c == '\r':
			buf.WriteString(`\r`)
		case c == '\t':
			buf.WriteString(`\t`)
		case c == '\v':
			buf.WriteString(`\v`)

		case c >= utf8.RuneSelf && utf8.FullRuneInString(s):
			r, size := utf8.DecodeRuneInString(s)
			if r == utf8.RuneError && size == 1 {
				goto EscX
			}
			s = s[size-1:] // next iteration will slice off 1 more
			if r < 0x10000 {
				buf.WriteString(`\u`)
				for j := uint(0); j < 4; j++ {
					buf.WriteByte(lowerhex[(r>>(12-4*j))&0xF])
				}
			} else {
				buf.WriteString(`\U`)
				for j := uint(0); j < 8; j++ {
					buf.WriteByte(lowerhex[(r>>(28-4*j))&0xF])
				}
			}

		default:
		EscX:
			buf.WriteString(`\x`)
			buf.WriteByte(lowerhex[c>>4])
			buf.WriteByte(lowerhex[c&0xF])
		}
	}
	buf.WriteByte('"')
	return buf.String()
}

// CanBackquote returns whether the string s would be
// a valid Go string literal if enclosed in backquotes.
func CanBackquote(s string) bool {
	for i := 0; i < len(s); i++ {
		if (s[i] < ' ' && s[i] != '\t') || s[i] == '`' {
			return false
		}
	}
	return true
}

func unhex(b byte) (v int, ok bool) {
	c := int(b)
	switch {
	case '0' <= c && c <= '9':
		return c - '0', true
	case 'a' <= c && c <= 'f':
		return c - 'a' + 10, true
	case 'A' <= c && c <= 'F':
		return c - 'A' + 10, true
	}
	return
}

// UnquoteChar decodes the first character or byte in the escaped string
// or character literal represented by the string s.
// It returns four values:
// 1) value, the decoded Unicode code point or byte value;
// 2) multibyte, a boolean indicating whether the decoded character
//    requires a multibyte UTF-8 representation;
// 3) tail, the remainder of the string after the character; and
// 4) an error that will be nil if the character is syntactically valid.
// The second argument, quote, specifies the type of literal being parsed
// and therefore which escaped quote character is permitted.
// If set to a single quote, it permits the sequence \' and disallows unescaped '.
// If set to a double quote, it permits \" and disallows unescaped ".
// If set to zero, it does not permit either escape and allows both quote characters to appear unescaped.
func UnquoteChar(s string, quote byte) (value int, multibyte bool, tail string, err os.Error) {
	// easy cases
	switch c := s[0]; {
	case c == quote && (quote == '\'' || quote == '"'):
		err = os.EINVAL
		return
	case c >= utf8.RuneSelf:
		r, size := utf8.DecodeRuneInString(s)
		return r, true, s[size:], nil
	case c != '\\':
		return int(s[0]), false, s[1:], nil
	}

	// hard case: c is backslash
	if len(s) <= 1 {
		err = os.EINVAL
		return
	}
	c := s[1]
	s = s[2:]

	switch c {
	case 'a':
		value = '\a'
	case 'b':
		value = '\b'
	case 'f':
		value = '\f'
	case 'n':
		value = '\n'
	case 'r':
		value = '\r'
	case 't':
		value = '\t'
	case 'v':
		value = '\v'
	case 'x', 'u', 'U':
		n := 0
		switch c {
		case 'x':
			n = 2
		case 'u':
			n = 4
		case 'U':
			n = 8
		}
		v := 0
		if len(s) < n {
			err = os.EINVAL
			return
		}
		for j := 0; j < n; j++ {
			x, ok := unhex(s[j])
			if !ok {
				err = os.EINVAL
				return
			}
			v = v<<4 | x
		}
		s = s[n:]
		if c == 'x' {
			// single-byte string, possibly not UTF-8
			value = v
			break
		}
		if v > unicode.MaxRune {
			err = os.EINVAL
			return
		}
		value = v
		multibyte = true
	case '0', '1', '2', '3', '4', '5', '6', '7':
		v := int(c) - '0'
		if len(s) < 2 {
			err = os.EINVAL
			return
		}
		for j := 0; j < 2; j++ { // one digit already; two more
			x := int(s[j]) - '0'
			if x < 0 || x > 7 {
				return
			}
			v = (v << 3) | x
		}
		s = s[2:]
		if v > 255 {
			err = os.EINVAL
			return
		}
		value = v
	case '\\':
		value = '\\'
	case '\'', '"':
		if c != quote {
			err = os.EINVAL
			return
		}
		value = int(c)
	default:
		err = os.EINVAL
		return
	}
	tail = s
	return
}

// Unquote interprets s as a single-quoted, double-quoted,
// or backquoted Go string literal, returning the string value
// that s quotes.  (If s is single-quoted, it would be a Go
// character literal; Unquote returns the corresponding
// one-character string.)
func Unquote(s string) (t string, err os.Error) {
	n := len(s)
	if n < 2 {
		return "", os.EINVAL
	}
	quote := s[0]
	if quote != s[n-1] {
		return "", os.EINVAL
	}
	s = s[1 : n-1]

	if quote == '`' {
		if strings.Index(s, "`") >= 0 {
			return "", os.EINVAL
		}
		return s, nil
	}
	if quote != '"' && quote != '\'' {
		return "", os.EINVAL
	}

	var buf bytes.Buffer
	for len(s) > 0 {
		c, multibyte, ss, err := UnquoteChar(s, quote)
		if err != nil {
			return "", err
		}
		s = ss
		if c < utf8.RuneSelf || !multibyte {
			buf.WriteByte(byte(c))
		} else {
			buf.WriteString(string(c))
		}
		if quote == '\'' && len(s) != 0 {
			// single-quoted must be single character
			return "", os.EINVAL
		}
	}
	return buf.String(), nil
}
<|endoftext|>