<commit_before>// Copyright 2010  The "goheader" Authors
//
// Use of this source code is governed by the Simplified BSD License
// that can be found in the LICENSE file.
//
// This software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
// OR CONDITIONS OF ANY KIND, either express or implied. See the License
// for more details.

package main

import (
	"bufio"
	"bytes"
	"container/vector"
	"fmt"
	"regexp"
	"os"
	"strings"
)

// Translates C type declaration into Go type declaration.
func translateC(output *bytes.Buffer, file *os.File) (err os.Error) {
	var isMultipleComment, isDefineBlock, isStruct bool
	var extraType vector.StringVector // Types defined in the header file.

	// === Regular expressions
	reSkip := regexp.MustCompile(`^(\n|//)`) // Empty lines and comments.

	reType := regexp.MustCompile(`^(typedef)[ \t]+(.+)[ \t]+(.+)[;](.+)?`)

	reStruct := regexp.MustCompile(`^(struct)[ \t]+(.+)[ \t]*{`)
	reStructField := regexp.MustCompile(`^(.+)[ \t]+(.+)[;](.+)?`)
	reStructFieldName := regexp.MustCompile(`^([^_]*_)?(.+)`)

	reDefine := regexp.MustCompile(`^#[ \t]*(define|DEFINE)[ \t]+([^ \t]+)[ \t]+(.+)`)
	reDefineOnly := regexp.MustCompile(`^#[ \t]*(define|DEFINE)[ \t]+`)
	reDefineMacro := regexp.MustCompile(`^.*(\(.*\))`)

	reSingleComment := regexp.MustCompile(`^(.+)?/\*[ \t]*(.+)[ \t]*\*/`)
	reStartMultipleComment := regexp.MustCompile(`^/\*(.+)?`)
	reMiddleMultipleComment := regexp.MustCompile(`^[ \t*]*(.+)`)
	reEndMultipleComment := regexp.MustCompile(`^(.+)?\*/`)
	// ===

	if _, err = output.WriteString(goBase); err != nil {
		return
	}

	// === File to read
	fileBuf := bufio.NewReader(file)

	for {
		line, err := fileBuf.ReadString('\n')
		if err == os.EOF {
			break
		}
		line = strings.TrimSpace(line) + "\n"
		isSingleComment := false

		// === Translate comment of single line.
		if !isMultipleComment {
			if sub := reSingleComment.FindStringSubmatch(line); sub != nil {
				isSingleComment = true
				line = "// " + sub[2] + "\n"

				if sub[1] != "" {
					line = sub[1] + line
				}
			}
		}
		if !isSingleComment && !isMultipleComment && strings.HasPrefix(line, "/*") {
			isMultipleComment = true
		}

		// === Translate comments of multiple line.
		if isMultipleComment {
			if sub := reStartMultipleComment.FindStringSubmatch(line); sub != nil {
				if sub[1] != "\n" {
					line = "// " + sub[1]
					if _, err = output.WriteString(line); err != nil {
						return
					}
				}
				continue
			}
			if sub := reEndMultipleComment.FindStringSubmatch(line); sub != nil {
				if sub[1] != "" {
					line = "// " + sub[1] + "\n"
					if _, err = output.WriteString(line); err != nil {
						return
					}
				}
				isMultipleComment = false
				continue
			}
			if sub := reMiddleMultipleComment.FindStringSubmatch(line); sub != nil {
				line = "// " + sub[1]
				if _, err = output.WriteString(line); err != nil {
					return
				}
				continue
			}
		}

		// === Translate type definitions.
		if sub := reType.FindStringSubmatch(line); sub != nil {
			// Add the new type.
			extraType.Push(sub[3])

			gotype, ok := ctypeTogo(sub[2], &extraType)
			line = fmt.Sprintf("type %s %s", sub[3], gotype)

			if sub[4] != "\n" {
				line += sub[4]
			} else {
				line += "\n"
			}
			if !ok {
				line = COMMENT_LINE + line
			}

			if _, err = output.WriteString(line); err != nil {
				return
			}
			continue
		}

		// === Translate defines.
		if sub := reDefine.FindStringSubmatch(line); sub != nil {
			line = fmt.Sprintf("%s = %s", sub[2], sub[3])

			if !isDefineBlock {
				// Get characters of next line.
				startNextLine, err := fileBuf.Peek(10)
				if err != nil {
					return
				}

				// Constant in single line.
				if !reDefineOnly.Match(startNextLine) {
					line = "const " + line
				} else {
					isDefineBlock = true
					line = "const (\n" + line
				}
			}

			// Removes comment (if any) to ckeck if it is a macro.
			lastField := strings.Split(sub[3], "//", -1)[0]
			if reDefineMacro.MatchString(lastField) {
				line = COMMENT_LINE + line
			}

			if _, err = output.WriteString(line); err != nil {
				return
			}
			continue
		}

		if isDefineBlock && line == "\n" {
			if _, err = output.WriteString(")\n\n"); err != nil {
				return
			}
			isDefineBlock = false
			continue
		}

		// === Translate structs.
		if !isStruct {
			if sub := reStruct.FindStringSubmatch(line); sub != nil {
				isStruct = true

				if isDefineBlock {
					if _, err = output.WriteString(")\n"); err != nil {
						return
					}
					isDefineBlock = false
				}

				if _, err = output.WriteString(fmt.Sprintf(
					"type %s struct {\n", strings.Title(sub[2]))); err != nil {
					return
				}
				continue
			}
		} else {
			if sub := reStructField.FindStringSubmatch(line); sub != nil {
				// Translate the field type.
				gotype, ok := ctypeTogo(sub[1], &extraType)

				// === Translate the field name.
				fieldName := reStructFieldName.FindStringSubmatch(sub[2])
				_fieldName := ""

				if fieldName[1] != "" {
					_fieldName = fieldName[2]
				} else {
					_fieldName = fieldName[0]
				}
				// ===

				line = fmt.Sprintf("%s %s %s",
					strings.Title(_fieldName), gotype, sub[3])

				// C type not found.
				if !ok {
					line = COMMENT_LINE + line
				}

				if _, err = output.WriteString(line); err != nil {
					return
				}
				continue
			}
			if strings.HasPrefix(line, "}") {
				if _, err = output.WriteString(strings.Replace(line, ";", "", 1)); err != nil {
					return
				}
				isStruct = false
				continue
			}
		}

		// Comment another C lines.
		//if line != "\n" && !strings.HasPrefix(line, "//") {
		if !reSkip.MatchString(line) {
			line = COMMENT_LINE + line
		}

		if _, err = output.WriteString(line); err != nil {
			return
		}
	}

	return
}

// Translates a C type definition into Go definition. The C header could have
// defined new types so they're checked in the firs place.
func ctypeTogo(ctype string, extraCtype *vector.StringVector) (gotype string, ok bool) {
	for _, v := range *extraCtype {
		if v == ctype {
			return ctype, true
		}
	}

	switch ctype {
	case "char", "signed char", "signed short int", "short int", "short":
		return "int8", true
	case "unsigned char", "unsigned short int", "unsigned short":
		return "uint8", true
	case "int", "signed int":
		return "int16", true
	case "unsigned int", "unsigned":
		return "uint16", true
	case "signed long int", "long int", "long":
		return "int32", true
	case "unsigned long int", "unsigned long":
		return "uint32", true
	case "float":
		return "float32", true
	case "double", "long double":
		return "float64", true
	}
	return ctype, false
}

<commit_msg>Fixed spaces in line comments.<commit_after>// Copyright 2010  The "goheader" Authors
//
// Use of this source code is governed by the Simplified BSD License
// that can be found in the LICENSE file.
//
// This software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
// OR CONDITIONS OF ANY KIND, either express or implied. See the License
// for more details.

package main

import (
	"bufio"
	"bytes"
	"container/vector"
	"fmt"
	"regexp"
	"os"
	"strings"
)

// Translates C type declaration into Go type declaration.
//
// NOTE: the regular expression for single comments (reSingleComment) returns
// spaces before of "*/".
// The issue is that Go's regexp lib. doesn't support non greedy matches.
func translateC(output *bytes.Buffer, file *os.File) (err os.Error) {
	var isMultipleComment, isDefineBlock, isStruct bool
	var extraType vector.StringVector // Types defined in the header file.

	// === Regular expressions
	reSkip := regexp.MustCompile(`^(\n|//)`) // Empty lines and comments.

	reType := regexp.MustCompile(`^(typedef)[ \t]+(.+)[ \t]+(.+)[;](.+)?`)

	reStruct := regexp.MustCompile(`^(struct)[ \t]+(.+)[ \t]*{`)
	reStructField := regexp.MustCompile(`^(.+)[ \t]+(.+)[;](.+)?`)
	reStructFieldName := regexp.MustCompile(`^([^_]*_)?(.+)`)

	reDefine := regexp.MustCompile(`^#[ \t]*(define|DEFINE)[ \t]+([^ \t]+)[ \t]+(.+)`)
	reDefineOnly := regexp.MustCompile(`^#[ \t]*(define|DEFINE)[ \t]+`)
	reDefineMacro := regexp.MustCompile(`^.*(\(.*\))`)

	reSingleComment := regexp.MustCompile(`^(.+)?/\*[ \t]*(.+)[ \t]*\*/`)
	reStartMultipleComment := regexp.MustCompile(`^/\*(.+)?`)
	reMiddleMultipleComment := regexp.MustCompile(`^[ \t*]*(.+)`)
	reEndMultipleComment := regexp.MustCompile(`^(.+)?\*/`)
	// ===

	if _, err = output.WriteString(goBase); err != nil {
		return
	}

	// === File to read
	fileBuf := bufio.NewReader(file)

	for {
		line, err := fileBuf.ReadString('\n')
		if err == os.EOF {
			break
		}
		line = strings.TrimSpace(line) + "\n"
		isSingleComment := false

		// === Translate comment of single line.
		if !isMultipleComment {
			if sub := reSingleComment.FindStringSubmatch(line); sub != nil {
				isSingleComment = true
				line = "// " + strings.TrimRight(sub[2], " ") + "\n"

				if sub[1] != "" {
					line = sub[1] + line
				}
			}
		}
		if !isSingleComment && !isMultipleComment && strings.HasPrefix(line, "/*") {
			isMultipleComment = true
		}

		// === Translate comments of multiple line.
		if isMultipleComment {
			if sub := reStartMultipleComment.FindStringSubmatch(line); sub != nil {
				if sub[1] != "\n" {
					line = "// " + sub[1]
					if _, err = output.WriteString(line); err != nil {
						return
					}
				}
				continue
			}
			if sub := reEndMultipleComment.FindStringSubmatch(line); sub != nil {
				if sub[1] != "" {
					line = "// " + sub[1] + "\n"
					if _, err = output.WriteString(line); err != nil {
						return
					}
				}
				isMultipleComment = false
				continue
			}
			if sub := reMiddleMultipleComment.FindStringSubmatch(line); sub != nil {
				line = "// " + sub[1]
				if _, err = output.WriteString(line); err != nil {
					return
				}
				continue
			}
		}

		// === Translate type definitions.
		if sub := reType.FindStringSubmatch(line); sub != nil {
			// Add the new type.
			extraType.Push(sub[3])

			gotype, ok := ctypeTogo(sub[2], &extraType)
			line = fmt.Sprintf("type %s %s", sub[3], gotype)

			if sub[4] != "\n" {
				line += sub[4]
			} else {
				line += "\n"
			}
			if !ok {
				line = COMMENT_LINE + line
			}

			if _, err = output.WriteString(line); err != nil {
				return
			}
			continue
		}

		// === Translate defines.
		if sub := reDefine.FindStringSubmatch(line); sub != nil {
			line = fmt.Sprintf("%s = %s", sub[2], sub[3])

			if !isDefineBlock {
				// Get characters of next line.
				startNextLine, err := fileBuf.Peek(10)
				if err != nil {
					return
				}

				// Constant in single line.
				if !reDefineOnly.Match(startNextLine) {
					line = "const " + line
				} else {
					isDefineBlock = true
					line = "const (\n" + line
				}
			}

			// Removes comment (if any) to ckeck if it is a macro.
			lastField := strings.Split(sub[3], "//", -1)[0]
			if reDefineMacro.MatchString(lastField) {
				line = COMMENT_LINE + line
			}

			if _, err = output.WriteString(line); err != nil {
				return
			}
			continue
		}

		if isDefineBlock && line == "\n" {
			if _, err = output.WriteString(")\n\n"); err != nil {
				return
			}
			isDefineBlock = false
			continue
		}

		// === Translate structs.
		if !isStruct {
			if sub := reStruct.FindStringSubmatch(line); sub != nil {
				isStruct = true

				if isDefineBlock {
					if _, err = output.WriteString(")\n"); err != nil {
						return
					}
					isDefineBlock = false
				}

				if _, err = output.WriteString(fmt.Sprintf(
					"type %s struct {\n", strings.Title(sub[2]))); err != nil {
					return
				}
				continue
			}
		} else {
			if sub := reStructField.FindStringSubmatch(line); sub != nil {
				// Translate the field type.
				gotype, ok := ctypeTogo(sub[1], &extraType)

				// === Translate the field name.
				fieldName := reStructFieldName.FindStringSubmatch(sub[2])
				_fieldName := ""

				if fieldName[1] != "" {
					_fieldName = fieldName[2]
				} else {
					_fieldName = fieldName[0]
				}
				// ===

				line = fmt.Sprintf("%s %s %s",
					strings.Title(_fieldName), gotype, sub[3])

				// C type not found.
				if !ok {
					line = COMMENT_LINE + line
				}

				if _, err = output.WriteString(line); err != nil {
					return
				}
				continue
			}
			if strings.HasPrefix(line, "}") {
				if _, err = output.WriteString(strings.Replace(line, ";", "", 1)); err != nil {
					return
				}
				isStruct = false
				continue
			}
		}

		// Comment another C lines.
		//if line != "\n" && !strings.HasPrefix(line, "//") {
		if !reSkip.MatchString(line) {
			line = COMMENT_LINE + line
		}

		if _, err = output.WriteString(line); err != nil {
			return
		}
	}

	return
}

// Translates a C type definition into Go definition. The C header could have
// defined new types so they're checked in the firs place.
func ctypeTogo(ctype string, extraCtype *vector.StringVector) (gotype string, ok bool) {
	for _, v := range *extraCtype {
		if v == ctype {
			return ctype, true
		}
	}

	switch ctype {
	case "char", "signed char", "signed short int", "short int", "short":
		return "int8", true
	case "unsigned char", "unsigned short int", "unsigned short":
		return "uint8", true
	case "int", "signed int":
		return "int16", true
	case "unsigned int", "unsigned":
		return "uint16", true
	case "signed long int", "long int", "long":
		return "int32", true
	case "unsigned long int", "unsigned long":
		return "uint32", true
	case "float":
		return "float32", true
	case "double", "long double":
		return "float64", true
	}
	return ctype, false
}

<|endoftext|>


<commit_before>/*
Copyright 2018 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package retrieval

import (
	"errors"
	"fmt"
	"sort"

	"github.com/gogo/protobuf/proto"
	dto "github.com/prometheus/client_model/go"
)

// The errors exposed.
var (
	ErrNotFound                    = errors.New("not found")
	ErrOutOfOrderSample            = errors.New("out of order sample")
	ErrDuplicateSampleForTimestamp = errors.New("duplicate sample for timestamp")
	ErrOutOfBounds                 = errors.New("out of bounds")
)

const (
	NoTimestamp = 0
)

type MetricFamily struct {
	*dto.MetricFamily
	// MetricResetTimestampMs must have one element for each
	// MetricFamily.Metric. Elements must be initialized to NoTimestamp if
	// the value is unknown.
	MetricResetTimestampMs []int64
}

// Clone returns a new object that is a deep copy of the target object.
func (f *MetricFamily) Clone() (o *MetricFamily) {
	o = &MetricFamily{
		MetricFamily:           proto.Clone(f.MetricFamily).(*dto.MetricFamily),
		MetricResetTimestampMs: make([]int64, len(f.MetricResetTimestampMs)),
	}
	o.MetricResetTimestampMs = f.MetricResetTimestampMs
	return
}

func (f *MetricFamily) String() string {
	return fmt.Sprintf("MetricFamily<dto.MetricFamily: %v MetricResetTimestampMs: %v>",
		f.MetricFamily, f.MetricResetTimestampMs)
}

// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is
// used to separate label names, label values, and other strings from each other
// when calculating their combined hash value (aka signature aka fingerprint).
const SeparatorByte byte = 255

// ByName implements sort.Interface for []*MetricFamily based on the Name field.
type LabelPairsByName []*dto.LabelPair

func (f LabelPairsByName) Len() int           { return len(f) }
func (f LabelPairsByName) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
func (f LabelPairsByName) Less(i, j int) bool { return f[i].GetName() < f[j].GetName() }

func (f *MetricFamily) Fingerprint() uint64 {
	h := hashNew()
	h = hashAdd(h, f.GetName())
	for _, metric := range f.GetMetric() {
		sort.Sort(LabelPairsByName(metric.GetLabel()))
		for _, label := range metric.GetLabel() {
			h = hashAddByte(h, SeparatorByte)
			h = hashAdd(h, label.GetName())
			h = hashAddByte(h, SeparatorByte)
			h = hashAdd(h, label.GetValue())
		}
	}
	return h
}

type Appender interface {
	Add(metricFamily *MetricFamily) error
}
<commit_msg>Dropped unused MetricFamily.Clone method.<commit_after>/*
Copyright 2018 Google Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package retrieval

import (
	"errors"
	"fmt"
	"sort"

	dto "github.com/prometheus/client_model/go"
)

// The errors exposed.
var (
	ErrNotFound                    = errors.New("not found")
	ErrOutOfOrderSample            = errors.New("out of order sample")
	ErrDuplicateSampleForTimestamp = errors.New("duplicate sample for timestamp")
	ErrOutOfBounds                 = errors.New("out of bounds")
)

const (
	NoTimestamp = 0
)

type MetricFamily struct {
	*dto.MetricFamily
	// MetricResetTimestampMs must have one element for each
	// MetricFamily.Metric. Elements must be initialized to NoTimestamp if
	// the value is unknown.
	MetricResetTimestampMs []int64
	//	TargetLabels           labels.Labels
}

func (f *MetricFamily) String() string {
	return fmt.Sprintf("MetricFamily<dto.MetricFamily: %v MetricResetTimestampMs: %v>",
		f.MetricFamily, f.MetricResetTimestampMs)
}

// SeparatorByte is a byte that cannot occur in valid UTF-8 sequences and is
// used to separate label names, label values, and other strings from each other
// when calculating their combined hash value (aka signature aka fingerprint).
const SeparatorByte byte = 255

// ByName implements sort.Interface for []*MetricFamily based on the Name field.
type LabelPairsByName []*dto.LabelPair

func (f LabelPairsByName) Len() int           { return len(f) }
func (f LabelPairsByName) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
func (f LabelPairsByName) Less(i, j int) bool { return f[i].GetName() < f[j].GetName() }

func (f *MetricFamily) Fingerprint() uint64 {
	h := hashNew()
	h = hashAdd(h, f.GetName())
	for _, metric := range f.GetMetric() {
		sort.Sort(LabelPairsByName(metric.GetLabel()))
		for _, label := range metric.GetLabel() {
			h = hashAddByte(h, SeparatorByte)
			h = hashAdd(h, label.GetName())
			h = hashAddByte(h, SeparatorByte)
			h = hashAdd(h, label.GetValue())
		}
	}
	return h
}

type Appender interface {
	Add(metricFamily *MetricFamily) error
}
<|endoftext|>


<commit_before>// Copyright 2016 Michal Witkowski. All Rights Reserved.
// See LICENSE for licensing terms.

package grpc_retry_test

import (
	"io"
	"time"

	"github.com/mwitkow/go-grpc-middleware/retry"
	pb_testproto "github.com/mwitkow/go-grpc-middleware/testing/testproto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"

	"context"

	"fmt"
)

var cc *grpc.ClientConn

func newCtx(timeout time.Duration) context.Context {
	ctx, _ := context.WithTimeout(context.TODO(), timeout)
	return ctx
}

// Simple example of using the default interceptor configuration.
func Example_dialsimple() {
	return grpc.Dial("myservice.example.com",
		grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor()),
		grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor()),
	)
}

// Complex example with a 100ms linear backoff interval, and retry only on NotFound and Unavailable.
func Example_dialcomplex() {
	opts := []grpc_retry.CallOption{
		grpc_retry.WithBackoff(100 * time.Millisecond),
		grpc_retry.WithCodes(codes.NotFound, codes.Aborted),
	}
	return grpc.Dial("myservice.example.com",
		grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(opts...)),
		grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(opts...)),
	)
}

// Simple example of an idempotent `ServerStream` call, that will be retried automatically 3 times.
func Example_simplecall() {
	client := pb_testproto.NewTestServiceClient(cc)
	stream, err := client.PingList(newCtx(1*time.Second), &pb_testproto.PingRequest{}, grpc_retry.WithMax(3))
	if err != nil {
		return err
	}
	for {
		pong, err := stream.Recv() // retries happen here
		if err == io.EOF {
			break
		} else if err != nil {
			return err
		}
		fmt.Printf("got pong: %v", pong)
	}
}

// This is an example of an `Unary` call that will also retry on deadlines.
//
// Because the passed in context has a `5s` timeout, the whole `Ping` invocation should finish
// within that time. However, by defauly all retried calls will use the parent context for their
// deadlines. This means, that unless you shorten the deadline of each call of the retry, you won't
// be able to retry the first call at all.
//
// `WithPerRetryTimeout` allows you to shorten the deadline of each retry call, allowing you to fit
// multiple retries in the single parent deadline.
func Example_deadlinecall() {
	client := pb_testproto.NewTestServiceClient(cc)
	pong, err := client.Ping(
		newCtx(5*time.Second),
		&pb_testproto.PingRequest{},
		grpc_retry.WithMax(3),
		grpc_retry.WithPerRetryTimeout(1*time.Second))
	if err != nil {
		return err
	}
	fmt.Printf("got pong: %v", pong)
}
<commit_msg>fixup examples<commit_after>// Copyright 2016 Michal Witkowski. All Rights Reserved.
// See LICENSE for licensing terms.

package grpc_retry_test

import (
	"io"
	"time"

	"github.com/mwitkow/go-grpc-middleware/retry"
	pb_testproto "github.com/mwitkow/go-grpc-middleware/testing/testproto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"

	"context"

	"fmt"
)

var cc *grpc.ClientConn

func newCtx(timeout time.Duration) context.Context {
	ctx, _ := context.WithTimeout(context.TODO(), timeout)
	return ctx
}

// Simple example of using the default interceptor configuration.
func Example_dialsimple() (*grpc.ClientConn, error) {
	return grpc.Dial("myservice.example.com",
		grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor()),
		grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor()),
	)
}

// Complex example with a 100ms linear backoff interval, and retry only on NotFound and Unavailable.
func Example_dialcomplex() (*grpc.ClientConn, error) {
	opts := []grpc_retry.CallOption{
		grpc_retry.WithBackoff(grpc_retry.BackoffLinear(100 * time.Millisecond)),
		grpc_retry.WithCodes(codes.NotFound, codes.Aborted),
	}
	return grpc.Dial("myservice.example.com",
		grpc.WithStreamInterceptor(grpc_retry.StreamClientInterceptor(opts...)),
		grpc.WithUnaryInterceptor(grpc_retry.UnaryClientInterceptor(opts...)),
	)
}

// Simple example of an idempotent `ServerStream` call, that will be retried automatically 3 times.
func Example_simplecall() error {
	client := pb_testproto.NewTestServiceClient(cc)
	stream, err := client.PingList(newCtx(1*time.Second), &pb_testproto.PingRequest{}, grpc_retry.WithMax(3))
	if err != nil {
		return err
	}
	for {
		pong, err := stream.Recv() // retries happen here
		if err == io.EOF {
			break
		} else if err != nil {
			return err
		}
		fmt.Printf("got pong: %v", pong)
	}
	return nil
}

// This is an example of an `Unary` call that will also retry on deadlines.
//
// Because the passed in context has a `5s` timeout, the whole `Ping` invocation should finish
// within that time. However, by defauly all retried calls will use the parent context for their
// deadlines. This means, that unless you shorten the deadline of each call of the retry, you won't
// be able to retry the first call at all.
//
// `WithPerRetryTimeout` allows you to shorten the deadline of each retry call, allowing you to fit
// multiple retries in the single parent deadline.
func Example_deadlinecall() error {
	client := pb_testproto.NewTestServiceClient(cc)
	pong, err := client.Ping(
		newCtx(5*time.Second),
		&pb_testproto.PingRequest{},
		grpc_retry.WithMax(3),
		grpc_retry.WithPerRetryTimeout(1*time.Second))
	if err != nil {
		return err
	}
	fmt.Printf("got pong: %v", pong)
	return nil
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2017 AlexRuzin (stan.ruzin@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package govfs

import (
    "testing"
    "time"
    "os"
    "io"
    "bytes"
    "runtime"
)

const FS_DATABASE_FILE string = "test_db"

func TestFSWriter(t *testing.T) {
    /*
     * This test will generate the raw fs stream file, along with some contents
     *  that will be later loaded by the TestFSReader() method
     */
    out("[+] Running Standard I/O Sanity Test...")

    /* Remove the test database if it exists */
    var filename = gen_raw_filename(FS_DATABASE_FILE)
    if _, err := os.Stat(filename); os.IsExist(err) {
        os.Remove(filename)
    }

    var header, err = CreateDatabase(filename, FLAG_DB_CREATE)
    if header == nil || err != nil {
        drive_fail(err.Error(), t)
    }
    if err := header.StartIOController(); err != nil {
        drive_fail("TEST1.1: Failed to start IOController", t)
    }
    out("[+] Test 1 PASS")

    // The root file "/" must at least exist
    if file, err := header.Create("/"); file != nil && err == nil {
        drive_fail("TEST2: Failed to return root handle", t)
    }
    out("[+] Test 2 PASS")

    /*
     * Try to delete the root file "/"
     */
    if header.Delete("/") == nil {
        drive_fail("TEST3: Cannot delete root -- critical", t)
    }
    out("[+] Test 3 PASS")

    /*
     * Attempt to write to a nonexistant file
     */
    var data = []byte{ 1, 2 }
    if header.Write("/folder5/folder5/file5", data) == nil {
        drive_fail("TEST4: Cannot write to a nonexistant file", t)
    }
    out("[+] Test 4 PASS")

    /*
     * Create empty file file9
     */
    if file, err := header.Create("/folder5/folder4/folder2/file9"); file == nil || err != nil {
        drive_fail("TEST4.1: file9 cannot be created", t)
    }
    out("[+] Test 4.1 PASS")

    /*
     * Attempt to create a new file0
     */
    if file, err := header.Create("/folder0/folder0/file0"); file == nil || err != nil {
        drive_fail("TEST5.0: file0 cannot be created", t)
    }
    out("[+] Test 5.0 PASS")

    /*
     * Attempt to create a new file0, this will fail since it should already exist
     */
    if file, err := header.Create("/folder0/folder0/file0"); file != nil && err == nil {
        drive_fail("TEST5.1: file0 cannot be created twice", t)
    }
    out("[+] Test 5.1 PASS")

    /*
     * Write some data into file0
     */
    data = []byte{ 1, 2, 3, 4 }
    if header.Write("/folder0/folder0/file0", data) != nil {
        drive_fail("TEST6: Failed to write data in file0", t)
    }
    out("[+] Test 6 PASS")

    /*
     * Check that the size of file0 is 4
     */
    if k, _ := header.get_file_size("/folder0/folder0/file0"); k != uint(len(data)) {
        drive_fail("TEST6.1: The size of data does not match", t)
    }
    out("[+] Test 6.1 PASS")

    /*
     * Attempt to create a new file3
     */
    if file, err := header.Create("/folder1/folder0/file3"); file == nil || err != nil {
        drive_fail("TEST7: file3 cannot be created", t)
    }
    out("[+] Test 7 PASS")

    /*
     * Write some data into file3
     */
    var data2 = []byte{ 1, 2, 3, 4, 5, 6, 7 }
    if header.Write("/folder1/folder0/file3", data2) != nil {
        drive_fail("TEST8: Failed to write data in file3", t)
    }
    out("[+] Test 8 PASS")

    /*
     * Write some data into file3
     */
    if header.Write("/folder1/folder0/file3", data2) != nil {
        drive_fail("TEST8.1: Failed to write data in file3", t)
    }
    out("[+] Test 8.1 PASS")

    /*
     * Read the written data from file0 and compare
     */
    output_data, _ := header.Read("/folder0/folder0/file0")
    if output_data == nil || len(output_data) != len(data) || header.t_size - 7 /* len(file3) */ != uint(len(data)) {
        drive_fail("TEST9: Failed to read data from file0", t)
    }
    out("[+] Test 9 PASS")

    /*
     * Read the written data from file3 and compare
     */
    output_data, _ = header.Read("/folder1/folder0/file3")
    if output_data == nil || len(output_data) != len(data2) || header.t_size - 4 /* len(file0) */ != uint(len(data2)) {
        drive_fail("TEST10: Failed to read data from file3", t)
    }
    out("[+] Test 10 PASS")

    /*
     * Write other data to file0
     */
    data = []byte{ 1, 2, 3 }
    if header.Write("/folder0/folder0/file0", data) != nil {
        drive_fail("TEST11: Failed to write data in file1", t)
    }
    out("[+] Test 11 PASS")

    /*
     * Read the new data from file0
     */
    output_data, _ = header.Read("/folder0/folder0/file0")
    if output_data == nil || len(output_data) != len(data) {
        drive_fail("TEST12: Failed to read data from file1", t)
    }
    out("[+] Test 12 PASS")

    /*
     * Attempt to create a new file5. This will be a blank file
     */
    if file, err := header.Create("/folder2/file7"); file == nil || err != nil {
        drive_fail("TEST13: file3 cannot be created", t)
    }
    out("[+] Test 13 PASS")

    /*
     * Delete file0 -- complete this
     */
    // FIXME/ADDME

    /*
     * Create just a folder
     */
    if file, err := header.Create("/folder2/file5/"); file == nil || err != nil {
        drive_fail("TEST15: folder file5 cannot be created", t)
    }
    out("[+] Test 15 PASS")

    /*
     * Tests the Reader interface
     */
    reader, err := header.NewReader("/folder0/folder0/file0")
    if err != nil {
        drive_fail("TEST15.1: Failed to create Reader", t)
    }

    file0data := make([]byte, 3)
    data_read, err := reader.Read(file0data)
    if data_read != len(data) || err != io.EOF || bytes.Compare(file0data, data) != 0 {
        drive_fail("TEST15.2: Failed to read from NewReader", t)
    }

    /* Test the reader interface again */
    file0data = make([]byte, 1)
    data_read, err = reader.Read(file0data)
    if data_read != 1 || err != nil || file0data[0] != 1 {
        drive_fail("TEST15.3: Invalid Reader interface behaviour", t)
    }
    out("[+] Test 15.1, 15.2, 15.3 PASS -- Reader interface")

    /*
     * Tests the Writer interface
     */
    file0data = []byte{1, 2, 3, 4, 5, 6, 7, 8}
    writer, err := header.NewWriter("/folder0/folder0/file0")
    if writer == nil || err != nil {
        drive_fail("TEST15.4: Invalid Writer object", t)
    }

    written, err := writer.Write(file0data)
    if written != len(file0data) || err != io.EOF {
        drive_fail("TEST15.4: Invalid Writer response", t)
    }

    file0data = make([]byte, 8)
    data_read, err = reader.Read(file0data)
    if data_read != 8 || err != io.EOF || file0data[0] != 1 || file0data[1] != 2 {
        drive_fail("TEST15.5: Invalid Reader data",t )
    }
    out("[+] Test 15.4, 15.5 PASS -- Writer interface")

    /*
     * Print out files
     */
    file_list := header.get_file_list()
    for _, e := range file_list {
        out(e)
    }

    /*
     * Unmount/commit database to file
     */
    if err := header.UnmountDB(0 /*FLAG_COMPRESS_FILES*/); err != nil {
        drive_fail("TEST16: Failed to commit database", t)
    }
    out("[+] Test 16 PASS. Raw FS stream written to: " + header.filename)
    out("Total File Content Size: " + string(header.get_total_filesizes()))

    time.Sleep(10000)
}

func TestFSReader(t *testing.T) {
    /*
     * Read in FS_DATABASE_FILE and do basic tests
     */
    var filename = gen_raw_filename(FS_DATABASE_FILE)
    out("[+] Loading Raw FS stream file: " + filename)

    /* Remove the test database if it exists */
    if _, err := os.Stat(filename); os.IsNotExist(err) {
        drive_fail("error: Standard raw fs stream " + filename + " does not exist", t)
    }

    header, err := CreateDatabase(filename, FLAG_DB_LOAD)
    if header == nil || err != nil {
        drive_fail("TEST1: Failed to obtain header", t)
    }

    if err := header.StartIOController(); err != nil {
        drive_fail("TEST1.1: Failed to start IOController", t)
    }
    out("[+] Test 1 PASS (Loaded FS stream)")

    /*
     * Tests the Writer interface
     */
    if file, err := header.Create("/NewestFolder/Subdirectory/GoodBoy.bin"); file == nil || err != nil {
        drive_fail("TEST2.1: folder file5 cannot be created", t)
    }

    file0data := []byte("whattttttt")
    writer, err := header.NewWriter("/NewestFolder/Subdirectory/GoodBoy.bin")
    if writer == nil || err != nil {
        drive_fail("TEST2.2: Invalid Writer object", t)
    }

    written, err := writer.Write(file0data)
    if written != len(file0data) || err != io.EOF {
        drive_fail("TEST2.3: Invalid Writer response", t)
    }
    out("[+] Test 2 PASS")

    /*
     * Print out files
     */
    file_list := header.get_file_list()
    for _, e := range file_list {
        out(e)
    }

    out("Total File Content Size: " + string(header.get_total_filesizes()))
}

func gen_raw_filename(suffix string) string {
    if runtime.GOOS == "windows" {
        return os.Getenv("TEMP") + "\\" + suffix + ".db"
    }

    if runtime.GOOS == "linux" {
        return suffix + ".db"
    }

    return suffix + ".db"
}

func drive_fail(output string, t *testing.T) {
    t.Errorf(output)
    t.FailNow()
}
<commit_msg>Using util.DebugOut instead of out(). Importing util<commit_after>/*
 * Copyright (c) 2017 AlexRuzin (stan.ruzin@gmail.com)
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

package govfs

import (
    "testing"
    "time"
    "os"
    "io"
    "bytes"
    "runtime"
    "github.com/AlexRuzin/util"
)

const FS_DATABASE_FILE string = "test_db"

func TestFSWriter(t *testing.T) {
    /*
     * This test will generate the raw fs stream file, along with some contents
     *  that will be later loaded by the TestFSReader() method
     */
    util.DebugOut("[+] Running Standard I/O Sanity Test...")

    /* Remove the test database if it exists */
    var filename = gen_raw_filename(FS_DATABASE_FILE)
    if _, err := os.Stat(filename); os.IsExist(err) {
        os.Remove(filename)
    }

    var header, err = CreateDatabase(filename, FLAG_DB_CREATE)
    if header == nil || err != nil {
        drive_fail(err.Error(), t)
    }
    if err := header.StartIOController(); err != nil {
        drive_fail("TEST1.1: Failed to start IOController", t)
    }
    util.DebugOut("[+] Test 1 PASS")

    // The root file "/" must at least exist
    if file, err := header.Create("/"); file != nil && err == nil {
        drive_fail("TEST2: Failed to return root handle", t)
    }
    util.DebugOut("[+] Test 2 PASS")

    /*
     * Try to delete the root file "/"
     */
    if header.Delete("/") == nil {
        drive_fail("TEST3: Cannot delete root -- critical", t)
    }
    util.DebugOut("[+] Test 3 PASS")

    /*
     * Attempt to write to a nonexistant file
     */
    var data = []byte{ 1, 2 }
    if header.Write("/folder5/folder5/file5", data) == nil {
        drive_fail("TEST4: Cannot write to a nonexistant file", t)
    }
    util.DebugOut("[+] Test 4 PASS")

    /*
     * Create empty file file9
     */
    if file, err := header.Create("/folder5/folder4/folder2/file9"); file == nil || err != nil {
        drive_fail("TEST4.1: file9 cannot be created", t)
    }
    util.DebugOut("[+] Test 4.1 PASS")

    /*
     * Attempt to create a new file0
     */
    if file, err := header.Create("/folder0/folder0/file0"); file == nil || err != nil {
        drive_fail("TEST5.0: file0 cannot be created", t)
    }
    util.DebugOut("[+] Test 5.0 PASS")

    /*
     * Attempt to create a new file0, this will fail since it should already exist
     */
    if file, err := header.Create("/folder0/folder0/file0"); file != nil && err == nil {
        drive_fail("TEST5.1: file0 cannot be created twice", t)
    }
    util.DebugOut("[+] Test 5.1 PASS")

    /*
     * Write some data into file0
     */
    data = []byte{ 1, 2, 3, 4 }
    if header.Write("/folder0/folder0/file0", data) != nil {
        drive_fail("TEST6: Failed to write data in file0", t)
    }
    util.DebugOut("[+] Test 6 PASS")

    /*
     * Check that the size of file0 is 4
     */
    if k, _ := header.get_file_size("/folder0/folder0/file0"); k != uint(len(data)) {
        drive_fail("TEST6.1: The size of data does not match", t)
    }
    util.DebugOut("[+] Test 6.1 PASS")

    /*
     * Attempt to create a new file3
     */
    if file, err := header.Create("/folder1/folder0/file3"); file == nil || err != nil {
        drive_fail("TEST7: file3 cannot be created", t)
    }
    util.DebugOut("[+] Test 7 PASS")

    /*
     * Write some data into file3
     */
    var data2 = []byte{ 1, 2, 3, 4, 5, 6, 7 }
    if header.Write("/folder1/folder0/file3", data2) != nil {
        drive_fail("TEST8: Failed to write data in file3", t)
    }
    util.DebugOut("[+] Test 8 PASS")

    /*
     * Write some data into file3
     */
    if header.Write("/folder1/folder0/file3", data2) != nil {
        drive_fail("TEST8.1: Failed to write data in file3", t)
    }
    util.DebugOut("[+] Test 8.1 PASS")

    /*
     * Read the written data from file0 and compare
     */
    output_data, _ := header.Read("/folder0/folder0/file0")
    if output_data == nil || len(output_data) != len(data) || header.t_size - 7 /* len(file3) */ != uint(len(data)) {
        drive_fail("TEST9: Failed to read data from file0", t)
    }
    util.DebugOut("[+] Test 9 PASS")

    /*
     * Read the written data from file3 and compare
     */
    output_data, _ = header.Read("/folder1/folder0/file3")
    if output_data == nil || len(output_data) != len(data2) || header.t_size - 4 /* len(file0) */ != uint(len(data2)) {
        drive_fail("TEST10: Failed to read data from file3", t)
    }
    util.DebugOut("[+] Test 10 PASS")

    /*
     * Write other data to file0
     */
    data = []byte{ 1, 2, 3 }
    if header.Write("/folder0/folder0/file0", data) != nil {
        drive_fail("TEST11: Failed to write data in file1", t)
    }
    util.DebugOut("[+] Test 11 PASS")

    /*
     * Read the new data from file0
     */
    output_data, _ = header.Read("/folder0/folder0/file0")
    if output_data == nil || len(output_data) != len(data) {
        drive_fail("TEST12: Failed to read data from file1", t)
    }
    util.DebugOut("[+] Test 12 PASS")

    /*
     * Attempt to create a new file5. This will be a blank file
     */
    if file, err := header.Create("/folder2/file7"); file == nil || err != nil {
        drive_fail("TEST13: file3 cannot be created", t)
    }
    util.DebugOut("[+] Test 13 PASS")

    /*
     * Delete file0 -- complete this
     */
    // FIXME/ADDME

    /*
     * Create just a folder
     */
    if file, err := header.Create("/folder2/file5/"); file == nil || err != nil {
        drive_fail("TEST15: folder file5 cannot be created", t)
    }
    util.DebugOut("[+] Test 15 PASS")

    /*
     * Tests the Reader interface
     */
    reader, err := header.NewReader("/folder0/folder0/file0")
    if err != nil {
        drive_fail("TEST15.1: Failed to create Reader", t)
    }

    file0data := make([]byte, 3)
    data_read, err := reader.Read(file0data)
    if data_read != len(data) || err != io.EOF || bytes.Compare(file0data, data) != 0 {
        drive_fail("TEST15.2: Failed to read from NewReader", t)
    }

    /* Test the reader interface again */
    file0data = make([]byte, 1)
    data_read, err = reader.Read(file0data)
    if data_read != 1 || err != nil || file0data[0] != 1 {
        drive_fail("TEST15.3: Invalid Reader interface behaviour", t)
    }
    util.DebugOut("[+] Test 15.1, 15.2, 15.3 PASS -- Reader interface")

    /*
     * Tests the Writer interface
     */
    file0data = []byte{1, 2, 3, 4, 5, 6, 7, 8}
    writer, err := header.NewWriter("/folder0/folder0/file0")
    if writer == nil || err != nil {
        drive_fail("TEST15.4: Invalid Writer object", t)
    }

    written, err := writer.Write(file0data)
    if written != len(file0data) || err != io.EOF {
        drive_fail("TEST15.4: Invalid Writer response", t)
    }

    file0data = make([]byte, 8)
    data_read, err = reader.Read(file0data)
    if data_read != 8 || err != io.EOF || file0data[0] != 1 || file0data[1] != 2 {
        drive_fail("TEST15.5: Invalid Reader data",t )
    }
    util.DebugOut("[+] Test 15.4, 15.5 PASS -- Writer interface")

    /*
     * Print out files
     */
    file_list := header.get_file_list()
    for _, e := range file_list {
        util.DebugOut(e)
    }

    /*
     * Unmount/commit database to file
     */
    if err := header.UnmountDB(0 /*FLAG_COMPRESS_FILES*/); err != nil {
        drive_fail("TEST16: Failed to commit database", t)
    }
    util.DebugOut("[+] Test 16 PASS. Raw FS stream written to: " + header.filename)
    util.DebugOut("Total File Content Size: " + string(header.get_total_filesizes()))

    time.Sleep(10000)
}

func TestFSReader(t *testing.T) {
    /*
     * Read in FS_DATABASE_FILE and do basic tests
     */
    var filename = gen_raw_filename(FS_DATABASE_FILE)
    util.DebugOut("[+] Loading Raw FS stream file: " + filename)

    /* Remove the test database if it exists */
    if _, err := os.Stat(filename); os.IsNotExist(err) {
        drive_fail("error: Standard raw fs stream " + filename + " does not exist", t)
    }

    header, err := CreateDatabase(filename, FLAG_DB_LOAD)
    if header == nil || err != nil {
        drive_fail("TEST1: Failed to obtain header", t)
    }

    if err := header.StartIOController(); err != nil {
        drive_fail("TEST1.1: Failed to start IOController", t)
    }
    util.DebugOut("[+] Test 1 PASS (Loaded FS stream)")

    /*
     * Tests the Writer interface
     */
    if file, err := header.Create("/NewestFolder/Subdirectory/GoodBoy.bin"); file == nil || err != nil {
        drive_fail("TEST2.1: folder file5 cannot be created", t)
    }

    file0data := []byte("whattttttt")
    writer, err := header.NewWriter("/NewestFolder/Subdirectory/GoodBoy.bin")
    if writer == nil || err != nil {
        drive_fail("TEST2.2: Invalid Writer object", t)
    }

    written, err := writer.Write(file0data)
    if written != len(file0data) || err != io.EOF {
        drive_fail("TEST2.3: Invalid Writer response", t)
    }
    util.DebugOut("[+] Test 2 PASS")

    /*
     * Print out files
     */
    file_list := header.get_file_list()
    for _, e := range file_list {
        util.DebugOut(e)
    }

    util.DebugOut("Total File Content Size: " + string(header.get_total_filesizes()))
}

func gen_raw_filename(suffix string) string {
    if runtime.GOOS == "windows" {
        return os.Getenv("TEMP") + "\\" + suffix + ".db"
    }

    if runtime.GOOS == "linux" {
        return suffix + ".db"
    }

    return suffix + ".db"
}

func drive_fail(output string, t *testing.T) {
    t.Errorf(output)
    t.FailNow()
}
<|endoftext|>


<commit_before>/*

Type describing the tracker events.

*/

package rep

import (
	"math"

	"github.com/icza/s2prot"
)

const (
	// TrackerEvtIDPlayerStats is the ID of the Player Stats tracker event
	TrackerEvtIDPlayerStats = 0
	// TrackerEvtIDUnitBorn is the ID of the Unit Born tracker event
	TrackerEvtIDUnitBorn = 1
)

// TrackerEvts contains tracker events and some metrics and data calculated from them.
type TrackerEvts struct {
	// Evts contains the tracker events
	Evts []s2prot.Event

	// PIDPlayerDescMap is a PlayerDesc map mapped from player ID.
	PIDPlayerDescMap map[int64]*PlayerDesc
}

// PlayerDesc contains calculated, derived data from tracker events.
type PlayerDesc struct {
	// PlayerID is the ID of the player this PlayerDesc belongs to.
	PlayerID int64

	// Start location of the player
	StartLocX, StartLocY int64

	// StartDir is the start direction of the player, expressed in clock,
	// e.g. 1 o'clock, 3 o'clock etcc, in range of 1..12
	StartDir int
}

// init initializes / preprocesses the tracker events.
func (t *TrackerEvts) init(rep *Rep) {
	pidPlayerDescMap := make(map[int64]*PlayerDesc)
	t.PIDPlayerDescMap = pidPlayerDescMap

	getPD := func(pid int64) *PlayerDesc {
		pd := pidPlayerDescMap[pid]
		if pd == nil {
			pd = &PlayerDesc{PlayerID: pid}
			pidPlayerDescMap[pid] = pd
		}
		return pd
	}

	cx := rep.InitData.GameDescription.MapSizeX()
	cy := rep.InitData.GameDescription.MapSizeY()

	for _, e := range t.Evts {
		eid := e.Int("ID")
		if e.Loop() == 0 && eid == TrackerEvtIDUnitBorn {
			if isMainBuilding(e.Stringv("unitTypeName")) {
				pd := getPD(e.Int("controlPlayerId"))
				pd.StartLocX = e.Int("x")
				pd.StartLocX = e.Int("x")
				pd.StartDir = angleToClock(math.Atan2(float64(pd.StartLocY-cy), float64(pd.StartLocX-cx)))
			}
		}

		if eid == TrackerEvtIDPlayerStats {
			// TODO
		}
	}
}

// isMainBuilding tells if the unit type name denots a main building, that is
// one of Nexus, Command Center and Hatchery.
func isMainBuilding(unitTypeName string) bool {
	return unitTypeName == "Nexus" || unitTypeName == "CommandCenter" || unitTypeName == "Hatchery"
}

// angleToClock converts an angle given in radian to an hour clock value
// in the range of 1..12.
//
// Examples:
//  - PI/2 => 12 (o'clock)
//  - 0 => 3 (o'clock)
//  - PI => 9 (o'clock)
func angleToClock(angle float64) int {
	// The algorithm below computes clock value in the range of 0..11 where
	// 0 corresponds to 12.

	// 1 hour is PI/6 angle range
	const oneHour = math.Pi / 6

	// Shift by 3:30 (0 or 12 o-clock starts at 11:30)
	// and invert direction (clockwise):
	angle = -angle + oneHour*3.5

	// Put in range of 0..2*PI
	for angle < 0 {
		angle += oneHour * 12
	}
	for angle >= oneHour*12 {
		angle -= oneHour * 12
	}

	// And convert to a clock value:
	hour := int(angle / oneHour)
	if hour == 0 {
		return 12
	}
	return hour
}
<commit_msg>Added and filled fields to PlayerDesc: SlotID, UserID, SQ, SupplyCappedPercent.<commit_after>/*

Type describing the tracker events.

*/

package rep

import (
	"math"

	"github.com/icza/s2prot"
)

const (
	// TrackerEvtIDPlayerStats is the ID of the Player Stats tracker event
	TrackerEvtIDPlayerStats = 0

	// TrackerEvtIDUnitBorn is the ID of the Unit Born tracker event
	TrackerEvtIDUnitBorn = 1

	// TrackerEvtIDPlayerSetup is the ID of the Player Setup tracker event
	TrackerEvtIDPlayerSetup = 9
)

// TrackerEvts contains tracker events and some metrics and data calculated from them.
type TrackerEvts struct {
	// Evts contains the tracker events
	Evts []s2prot.Event

	// PIDPlayerDescMap is a PlayerDesc map mapped from player ID.
	PIDPlayerDescMap map[int64]*PlayerDesc
}

// PlayerDesc contains calculated, derived data from tracker events.
type PlayerDesc struct {
	// PlayerID is the ID of the player this PlayerDesc belongs to.
	PlayerID int64

	// SlotID is the slot ID of the player
	SlotID int64

	// UserID is the user ID of the player
	UserID int64

	// Start location of the player
	StartLocX, StartLocY int64

	// StartDir is the start direction of the player, expressed in clock,
	// e.g. 1 o'clock, 3 o'clock etcc, in range of 1..12
	StartDir int

	// SQ (Spending Quotient) of the player
	SQ int

	// SupplyCappedPercent is the supply-capped percent of the player
	SupplyCappedPercent int
}

// init initializes / preprocesses the tracker events.
func (t *TrackerEvts) init(rep *Rep) {
	pidPlayerDescMap := make(map[int64]*PlayerDesc)
	t.PIDPlayerDescMap = pidPlayerDescMap

	// stats per player
	type stats struct {
		samples   int64 // stats samples count
		unspents  int64 // Unspent resources
		incomes   int64 // Resource income
		supCapped int64 // supply capped
	}

	pidStats := make(map[int64]*stats)

	// first read Player setup events:
	for _, e := range t.Evts {
		if e.Loop() > 0 {
			break
		}
		if e.Int("ID") != TrackerEvtIDPlayerSetup {
			continue
		}
		pid := e.Int("playerId")
		pd := pidPlayerDescMap[pid]
		if pd == nil {
			pd = &PlayerDesc{PlayerID: pid}
			pidPlayerDescMap[pid] = pd
			pidStats[pid] = &stats{}
		}
		pd.SlotID = e.Int("slotId")
		pd.UserID = e.Int("userId")
	}

	// Read start locations and player stats

	cx := rep.InitData.GameDescription.MapSizeX()
	cy := rep.InitData.GameDescription.MapSizeY()

	for _, e := range t.Evts {
		eid := e.Int("ID")
		if e.Loop() == 0 && eid == TrackerEvtIDUnitBorn {
			if isMainBuilding(e.Stringv("unitTypeName")) {
				pd := pidPlayerDescMap[e.Int("controlPlayerId")]
				if pd != nil {
					pd.StartLocX = e.Int("x")
					pd.StartLocY = e.Int("y")
					pd.StartDir = angleToClock(math.Atan2(float64(pd.StartLocY-cy), float64(pd.StartLocX-cx)))
				}
			}
		}

		if eid != TrackerEvtIDPlayerStats {
			pid := e.Int("playerId")
			st := pidStats[pid]
			if st != nil {
				ss := e.Structv("stats")
				st.samples++
				st.unspents += ss.Int("scoreValueMineralsCurrent") + ss.Int("scoreValueVespeneCurrent")
				st.incomes += ss.Int("scoreValueMineralsCollectionRate") + ss.Int("scoreValueVespeneCollectionRate")
				if ss.Int("scoreValueFoodUsed") >= ss.Int("scoreValueFoodMade") {
					st.supCapped++
				}
			}
		}
	}

	// Finish SQ and supply-capped calculations
	for pid, pd := range pidPlayerDescMap {
		st := pidStats[pid]
		if st == nil || st.samples == 0 {
			continue
		}
		pd.SQ = calcSQ(st.unspents/st.samples, st.incomes/st.samples)
		pd.SupplyCappedPercent = int(st.supCapped * 100 / st.samples)
	}
}

// isMainBuilding tells if the unit type name denots a main building, that is
// one of Nexus, Command Center and Hatchery.
func isMainBuilding(unitTypeName string) bool {
	return unitTypeName == "Nexus" || unitTypeName == "CommandCenter" || unitTypeName == "Hatchery"
}

// angleToClock converts an angle given in radian to an hour clock value
// in the range of 1..12.
//
// Examples:
//  - PI/2 => 12 (o'clock)
//  - 0 => 3 (o'clock)
//  - PI => 9 (o'clock)
func angleToClock(angle float64) int {
	// The algorithm below computes clock value in the range of 0..11 where
	// 0 corresponds to 12.

	// 1 hour is PI/6 angle range
	const oneHour = math.Pi / 6

	// Shift by 3:30 (0 or 12 o-clock starts at 11:30)
	// and invert direction (clockwise):
	angle = -angle + oneHour*3.5

	// Put in range of 0..2*PI
	for angle < 0 {
		angle += oneHour * 12
	}
	for angle >= oneHour*12 {
		angle -= oneHour * 12
	}

	// And convert to a clock value:
	hour := int(angle / oneHour)
	if hour == 0 {
		return 12
	}
	return hour
}

// calcSQ calculates the SQ (Spending Quotient).
//
// Algorithm:
// SQ = 35 * ( 0.00137 * I - ln( U ) ) + 240
// Where U is the average unspent resources (Resources Current; including minerals and vespene)
// and I is the average income (Resource Colleciton Rate; including minerals and vespene);
// and samples are taken up to the loop of the last cmd game event of the user.
//
// Source: Do you macro like a pro? http://www.teamliquid.net/forum/viewmessage.php?topic_id=266019
func calcSQ(unspentResources, income int64) int {
	return int(35*(0.00137*float64(income)-math.Log(float64(unspentResources))) + 240 + 0.5)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"

	"github.com/spf13/cobra"

	"github.com/coreos/coreos-kubernetes/multi-node/aws/pkg/cluster"
	"github.com/coreos/coreos-kubernetes/multi-node/aws/pkg/config"
)

var (
	cmdDestroy = &cobra.Command{
		Use:          "destroy",
		Short:        "Destroy an existing Kubernetes cluster",
		Long:         ``,
		RunE:         runCmdDestroy,
		SilenceUsage: true,
	}
	destroyOpts = struct {
		awsDebug bool
	}{}
)

func init() {
	cmdRoot.AddCommand(cmdDestroy)
	cmdDestroy.Flags().BoolVar(&destroyOpts.awsDebug, "aws-debug", false, "Log debug information from aws-sdk-go library")
}

func runCmdDestroy(cmd *cobra.Command, args []string) error {
	cfg, err := config.ClusterFromFile(configPath)
	if err != nil {
		return fmt.Errorf("Error parsing config: %v", err)
	}

	c := cluster.New(cfg, destroyOpts.awsDebug)
	if err := c.Destroy(); err != nil {
		return fmt.Errorf("Failed destroying cluster: %v", err)
	}

	fmt.Println("Destroyed cluster")
	return nil
}
<commit_msg>kube-aws: Print clearer message on `kube-aws destroy`<commit_after>package main

import (
	"fmt"

	"github.com/spf13/cobra"

	"github.com/coreos/coreos-kubernetes/multi-node/aws/pkg/cluster"
	"github.com/coreos/coreos-kubernetes/multi-node/aws/pkg/config"
)

var (
	cmdDestroy = &cobra.Command{
		Use:          "destroy",
		Short:        "Destroy an existing Kubernetes cluster",
		Long:         ``,
		RunE:         runCmdDestroy,
		SilenceUsage: true,
	}
	destroyOpts = struct {
		awsDebug bool
	}{}
)

func init() {
	cmdRoot.AddCommand(cmdDestroy)
	cmdDestroy.Flags().BoolVar(&destroyOpts.awsDebug, "aws-debug", false, "Log debug information from aws-sdk-go library")
}

func runCmdDestroy(cmd *cobra.Command, args []string) error {
	cfg, err := config.ClusterFromFile(configPath)
	if err != nil {
		return fmt.Errorf("Error parsing config: %v", err)
	}

	c := cluster.New(cfg, destroyOpts.awsDebug)
	if err := c.Destroy(); err != nil {
		return fmt.Errorf("Failed destroying cluster: %v", err)
	}

	fmt.Println("CloudFormation stack is being destroyed. This will take several minutes")
	return nil
}
<|endoftext|>


<commit_before>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package util

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"regexp"
	"strings"

	netutil "k8s.io/apimachinery/pkg/util/net"
)

var (
	kubeReleaseBucketURL  = "https://dl.k8s.io"
	kubeReleaseRegex      = regexp.MustCompile(`^v?(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)([-0-9a-zA-Z_\.+]*)?$`)
	kubeReleaseLabelRegex = regexp.MustCompile(`^[[:lower:]]+(-[-\w_\.]+)?$`)
	kubeBucketPrefixes    = regexp.MustCompile(`^((release|ci|ci-cross)/)?([-\w_\.+]+)$`)
)

// KubernetesReleaseVersion is helper function that can fetch
// available version information from release servers based on
// label names, like "stable" or "latest".
//
// If argument is already semantic version string, it
// will return same string.
//
// In case of labels, it tries to fetch from release
// servers and then return actual semantic version.
//
// Available names on release servers:
//  stable      (latest stable release)
//  stable-1    (latest stable release in 1.x)
//  stable-1.0  (and similarly 1.1, 1.2, 1.3, ...)
//  latest      (latest release, including alpha/beta)
//  latest-1    (latest release in 1.x, including alpha/beta)
//  latest-1.0  (and similarly 1.1, 1.2, 1.3, ...)
func KubernetesReleaseVersion(version string) (string, error) {
	ver := normalizedBuildVersion(version)
	if len(ver) != 0 {
		return ver, nil
	}

	bucketURL, versionLabel, err := splitVersion(version)
	if err != nil {
		return "", err
	}

	// revalidate, if exact build from e.g. CI bucket requested.
	ver = normalizedBuildVersion(versionLabel)
	if len(ver) != 0 {
		return ver, nil
	}

	if kubeReleaseLabelRegex.MatchString(versionLabel) {
		url := fmt.Sprintf("%s/%s.txt", bucketURL, versionLabel)
		body, err := fetchFromURL(url)
		if err != nil {
			return "", err
		}
		// Re-validate received version and return.
		return KubernetesReleaseVersion(body)
	}
	return "", fmt.Errorf("version %q doesn't match patterns for neither semantic version nor labels (stable, latest, ...)", version)
}

// KubernetesVersionToImageTag is helper function that replaces all
// non-allowed symbols in tag strings with underscores.
// Image tag can only contain lowercase and uppercase letters, digits,
// underscores, periods and dashes.
// Current usage is for CI images where all of symbols except '+' are valid,
// but function is for generic usage where input can't be always pre-validated.
func KubernetesVersionToImageTag(version string) string {
	allowed := regexp.MustCompile(`[^-a-zA-Z0-9_\.]`)
	return allowed.ReplaceAllString(version, "_")
}

// KubernetesIsCIVersion checks if user requested CI version
func KubernetesIsCIVersion(version string) bool {
	subs := kubeBucketPrefixes.FindAllStringSubmatch(version, 1)
	if len(subs) == 1 && len(subs[0]) == 4 && strings.HasPrefix(subs[0][2], "ci") {
		return true
	}
	return false
}

// Internal helper: returns normalized build version (with "v" prefix if needed)
// If input doesn't match known version pattern, returns empty string.
func normalizedBuildVersion(version string) string {
	if kubeReleaseRegex.MatchString(version) {
		if strings.HasPrefix(version, "v") {
			return version
		}
		return "v" + version
	}
	return ""
}

// Internal helper: split version parts,
// Return base URL and cleaned-up version
func splitVersion(version string) (string, string, error) {
	var urlSuffix string
	subs := kubeBucketPrefixes.FindAllStringSubmatch(version, 1)
	if len(subs) != 1 || len(subs[0]) != 4 {
		return "", "", fmt.Errorf("invalid version %q", version)
	}

	switch {
	case strings.HasPrefix(subs[0][2], "ci"):
		// Just use whichever the user specified
		urlSuffix = subs[0][2]
	default:
		urlSuffix = "release"
	}
	url := fmt.Sprintf("%s/%s", kubeReleaseBucketURL, urlSuffix)
	return url, subs[0][3], nil
}

// Internal helper: return content of URL
func fetchFromURL(url string) (string, error) {
	client := &http.Client{Transport: netutil.SetOldTransportDefaults(&http.Transport{})}
	resp, err := client.Get(url)
	if err != nil {
		return "", fmt.Errorf("unable to get URL %q: %s", url, err.Error())
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("unable to fetch file. URL: %q Status: %v", url, resp.Status)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("unable to read content of URL %q: %s", url, err.Error())
	}
	return strings.TrimSpace(string(body)), nil
}
<commit_msg>Add a timeout when fetching latest version<commit_after>/*
Copyright 2016 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package util

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"regexp"
	"strings"
	"time"

	netutil "k8s.io/apimachinery/pkg/util/net"
)

const (
	getReleaseVersionTimeout = time.Duration(10 * time.Second)
)

var (
	kubeReleaseBucketURL  = "https://dl.k8s.io"
	kubeReleaseRegex      = regexp.MustCompile(`^v?(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)\.(0|[1-9][0-9]*)([-0-9a-zA-Z_\.+]*)?$`)
	kubeReleaseLabelRegex = regexp.MustCompile(`^[[:lower:]]+(-[-\w_\.]+)?$`)
	kubeBucketPrefixes    = regexp.MustCompile(`^((release|ci|ci-cross)/)?([-\w_\.+]+)$`)
)

// KubernetesReleaseVersion is helper function that can fetch
// available version information from release servers based on
// label names, like "stable" or "latest".
//
// If argument is already semantic version string, it
// will return same string.
//
// In case of labels, it tries to fetch from release
// servers and then return actual semantic version.
//
// Available names on release servers:
//  stable      (latest stable release)
//  stable-1    (latest stable release in 1.x)
//  stable-1.0  (and similarly 1.1, 1.2, 1.3, ...)
//  latest      (latest release, including alpha/beta)
//  latest-1    (latest release in 1.x, including alpha/beta)
//  latest-1.0  (and similarly 1.1, 1.2, 1.3, ...)
func KubernetesReleaseVersion(version string) (string, error) {
	ver := normalizedBuildVersion(version)
	if len(ver) != 0 {
		return ver, nil
	}

	bucketURL, versionLabel, err := splitVersion(version)
	if err != nil {
		return "", err
	}

	// revalidate, if exact build from e.g. CI bucket requested.
	ver = normalizedBuildVersion(versionLabel)
	if len(ver) != 0 {
		return ver, nil
	}

	if kubeReleaseLabelRegex.MatchString(versionLabel) {
		url := fmt.Sprintf("%s/%s.txt", bucketURL, versionLabel)
		body, err := fetchFromURL(url, getReleaseVersionTimeout)
		if err != nil {
			return "", err
		}
		// Re-validate received version and return.
		return KubernetesReleaseVersion(body)
	}
	return "", fmt.Errorf("version %q doesn't match patterns for neither semantic version nor labels (stable, latest, ...)", version)
}

// KubernetesVersionToImageTag is helper function that replaces all
// non-allowed symbols in tag strings with underscores.
// Image tag can only contain lowercase and uppercase letters, digits,
// underscores, periods and dashes.
// Current usage is for CI images where all of symbols except '+' are valid,
// but function is for generic usage where input can't be always pre-validated.
func KubernetesVersionToImageTag(version string) string {
	allowed := regexp.MustCompile(`[^-a-zA-Z0-9_\.]`)
	return allowed.ReplaceAllString(version, "_")
}

// KubernetesIsCIVersion checks if user requested CI version
func KubernetesIsCIVersion(version string) bool {
	subs := kubeBucketPrefixes.FindAllStringSubmatch(version, 1)
	if len(subs) == 1 && len(subs[0]) == 4 && strings.HasPrefix(subs[0][2], "ci") {
		return true
	}
	return false
}

// Internal helper: returns normalized build version (with "v" prefix if needed)
// If input doesn't match known version pattern, returns empty string.
func normalizedBuildVersion(version string) string {
	if kubeReleaseRegex.MatchString(version) {
		if strings.HasPrefix(version, "v") {
			return version
		}
		return "v" + version
	}
	return ""
}

// Internal helper: split version parts,
// Return base URL and cleaned-up version
func splitVersion(version string) (string, string, error) {
	var urlSuffix string
	subs := kubeBucketPrefixes.FindAllStringSubmatch(version, 1)
	if len(subs) != 1 || len(subs[0]) != 4 {
		return "", "", fmt.Errorf("invalid version %q", version)
	}

	switch {
	case strings.HasPrefix(subs[0][2], "ci"):
		// Just use whichever the user specified
		urlSuffix = subs[0][2]
	default:
		urlSuffix = "release"
	}
	url := fmt.Sprintf("%s/%s", kubeReleaseBucketURL, urlSuffix)
	return url, subs[0][3], nil
}

// Internal helper: return content of URL
func fetchFromURL(url string, timeout time.Duration) (string, error) {
	client := &http.Client{Timeout: timeout, Transport: netutil.SetOldTransportDefaults(&http.Transport{})}
	resp, err := client.Get(url)
	if err != nil {
		return "", fmt.Errorf("unable to get URL %q: %s", url, err.Error())
	}
	defer resp.Body.Close()
	if resp.StatusCode != http.StatusOK {
		return "", fmt.Errorf("unable to fetch file. URL: %q Status: %v", url, resp.Status)
	}
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return "", fmt.Errorf("unable to read content of URL %q: %s", url, err.Error())
	}
	return strings.TrimSpace(string(body)), nil
}
<|endoftext|>


<commit_before>package main

import (
	"context"
	"errors"
	"log"
	"os"
	"os/signal"
)

func main() {
	lgr := log.New(os.Stderr, "grace: ", 0)

	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	<-ctx.Done()

	err := ctx.Err()
	if err != nil {
		if errors.Is(err, context.Canceled) {
			return
		}

		lgr.Printf("%v", err)

		stop()

		os.Exit(1)
	}

}
<commit_msg>grace: add run func<commit_after>package main

import (
	"context"
	"errors"
	"log"
	"os"
	"os/signal"
)

func main() {
	lgr := log.New(os.Stderr, "grace: ", 0)

	err := run()
	if err != nil {
		if errors.Is(err, context.Canceled) {
			return
		}

		lgr.Printf("%v", err)
		os.Exit(1)
	}

}

func run() error {
	ctx, stop := signal.NotifyContext(context.Background(), os.Interrupt)
	defer stop()

	<-ctx.Done()

	return ctx.Err()
}
<|endoftext|>


<commit_before>package app

import (
	"fmt"
	"os"
	"reflect"
	"strings"
	"text/tabwriter"
	"text/template"
	"unicode/utf8"

	"github.com/cloudfoundry/cli/cf/configuration/plugin_config"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/codegangsta/cli"
)

type groupedCommands struct {
	Name             string
	CommandSubGroups [][]cmdPresenter
}

func (c groupedCommands) SubTitle(name string) string {
	return terminal.HeaderColor(name + ":")
}

type cmdPresenter struct {
	Name        string
	Description string
}

func presentCmdName(cmd cli.Command) (name string) {
	name = cmd.Name
	if cmd.ShortName != "" {
		name = name + ", " + cmd.ShortName
	}
	return
}

type appPresenter struct {
	cli.App
	Commands []groupedCommands
}

func (p appPresenter) Title(name string) string {
	return terminal.HeaderColor(name)
}

func newAppPresenter(app *cli.App) (presenter appPresenter) {
	maxNameLen := 0
	for _, cmd := range app.Commands {
		name := presentCmdName(cmd)
		if utf8.RuneCountInString(name) > maxNameLen {
			maxNameLen = len(name)
		}
	}

	presentCommand := func(commandName string) (presenter cmdPresenter) {
		cmd := app.Command(commandName)
		presenter.Name = presentCmdName(*cmd)
		padding := strings.Repeat(" ", maxNameLen-utf8.RuneCountInString(presenter.Name))
		presenter.Name = presenter.Name + padding
		presenter.Description = cmd.Description
		return
	}

	presentPluginCommands := func() []cmdPresenter {
		pluginConfig := plugin_config.NewPluginConfig(func(err error) {
			//fail silently when running help?
		})

		plugins := pluginConfig.Plugins()
		var presenters []cmdPresenter
		var pluginPresenter cmdPresenter

		for _, pluginMetadata := range plugins {
			for _, cmd := range pluginMetadata.Commands {
				pluginPresenter.Name = cmd.Name
				padding := strings.Repeat(" ", maxNameLen-utf8.RuneCountInString(pluginPresenter.Name))
				pluginPresenter.Name = pluginPresenter.Name + padding
				pluginPresenter.Description = cmd.HelpText
				presenters = append(presenters, pluginPresenter)
			}
		}

		return presenters
	}
	presenter.Name = app.Name
	presenter.Flags = app.Flags
	presenter.Usage = app.Usage
	presenter.Version = app.Version
	presenter.Compiled = app.Compiled
	presenter.Commands = []groupedCommands{
		{
			Name: T("GETTING STARTED"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("login"),
					presentCommand("logout"),
					presentCommand("passwd"),
					presentCommand("target"),
				}, {
					presentCommand("api"),
					presentCommand("auth"),
				},
			},
		}, {
			Name: T("APPS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("apps"),
					presentCommand("app"),
				}, {
					presentCommand("push"),
					presentCommand("scale"),
					presentCommand("delete"),
					presentCommand("rename"),
				}, {
					presentCommand("start"),
					presentCommand("stop"),
					presentCommand("restart"),
					presentCommand("restage"),
				}, {
					presentCommand("events"),
					presentCommand("files"),
					presentCommand("logs"),
				}, {
					presentCommand("env"),
					presentCommand("set-env"),
					presentCommand("unset-env"),
				}, {
					presentCommand("stacks"),
				}, {
					presentCommand("copy-source"),
				},
			},
		}, {
			Name: T("SERVICES"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("marketplace"),
					presentCommand("services"),
					presentCommand("service"),
				}, {
					presentCommand("create-service"),
					presentCommand("update-service"),
					presentCommand("delete-service"),
					presentCommand("rename-service"),
				}, {
					presentCommand("bind-service"),
					presentCommand("unbind-service"),
				}, {
					presentCommand("create-user-provided-service"),
					presentCommand("update-user-provided-service"),
				},
			},
		}, {
			Name: T("ORGS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("orgs"),
					presentCommand("org"),
				}, {
					presentCommand("create-org"),
					presentCommand("delete-org"),
					presentCommand("rename-org"),
				},
			},
		}, {
			Name: T("SPACES"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("spaces"),
					presentCommand("space"),
				}, {
					presentCommand("create-space"),
					presentCommand("delete-space"),
					presentCommand("rename-space"),
				},
			},
		}, {
			Name: T("DOMAINS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("domains"),
					presentCommand("create-domain"),
					presentCommand("delete-domain"),
					presentCommand("create-shared-domain"),
					presentCommand("delete-shared-domain"),
				},
			},
		}, {
			Name: T("ROUTES"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("routes"),
					presentCommand("create-route"),
					presentCommand("check-route"),
					presentCommand("map-route"),
					presentCommand("unmap-route"),
					presentCommand("delete-route"),
					presentCommand("delete-orphaned-routes"),
				},
			},
		}, {
			Name: T("BUILDPACKS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("buildpacks"),
					presentCommand("create-buildpack"),
					presentCommand("update-buildpack"),
					presentCommand("rename-buildpack"),
					presentCommand("delete-buildpack"),
				},
			},
		}, {
			Name: T("USER ADMIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("create-user"),
					presentCommand("delete-user"),
				}, {
					presentCommand("org-users"),
					presentCommand("set-org-role"),
					presentCommand("unset-org-role"),
				}, {
					presentCommand("space-users"),
					presentCommand("set-space-role"),
					presentCommand("unset-space-role"),
				},
			},
		}, {
			Name: T("ORG ADMIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("quotas"),
					presentCommand("quota"),
					presentCommand("set-quota"),
				}, {
					presentCommand("create-quota"),
					presentCommand("delete-quota"),
					presentCommand("update-quota"),
				},
			},
		}, {
			Name: T("SPACE ADMIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("space-quota"),
					presentCommand("space-quotas"),
					presentCommand("create-space-quota"),
					presentCommand("update-space-quota"),
					presentCommand("delete-space-quota"),
					presentCommand("set-space-quota"),
					presentCommand("unset-space-quota"),
				},
			},
		}, {
			Name: T("SERVICE ADMIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("service-auth-tokens"),
					presentCommand("create-service-auth-token"),
					presentCommand("update-service-auth-token"),
					presentCommand("delete-service-auth-token"),
				}, {
					presentCommand("service-brokers"),
					presentCommand("create-service-broker"),
					presentCommand("update-service-broker"),
					presentCommand("delete-service-broker"),
					presentCommand("rename-service-broker"),
				}, {
					presentCommand("migrate-service-instances"),
					presentCommand("purge-service-offering"),
				}, {
					presentCommand("service-access"),
					presentCommand("enable-service-access"),
					presentCommand("disable-service-access"),
				},
			},
		}, {
			Name: T("SECURITY GROUP"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("security-group"),
					presentCommand("security-groups"),
					presentCommand("create-security-group"),
					presentCommand("update-security-group"),
					presentCommand("delete-security-group"),
					presentCommand("bind-security-group"),
					presentCommand("unbind-security-group"),
				}, {
					presentCommand("bind-staging-security-group"),
					presentCommand("staging-security-groups"),
					presentCommand("unbind-staging-security-group"),
				}, {
					presentCommand("bind-running-security-group"),
					presentCommand("running-security-groups"),
					presentCommand("unbind-running-security-group"),
				},
			},
		}, {
			Name: T("ENVIRONMENT VARIABLE GROUPS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("running-environment-variable-group"),
					presentCommand("staging-environment-variable-group"),
					presentCommand("set-staging-environment-variable-group"),
					presentCommand("set-running-environment-variable-group"),
				},
			},
		},
		{
			Name: T("FEATURE FLAGS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("feature-flags"),
					presentCommand("feature-flag"),
					presentCommand("enable-feature-flag"),
					presentCommand("disable-feature-flag"),
				},
			},
		}, {
			Name: T("ADVANCED"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("curl"),
					presentCommand("config"),
					presentCommand("oauth-token"),
				},
			},
		}, {
			Name: T("PLUGIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("plugins"),
					presentCommand("install-plugin"),
					presentCommand("uninstall-plugin"),
				},
			},
		}, {
			Name: T("PLUGIN COMMANDS"),
			CommandSubGroups: [][]cmdPresenter{
				presentPluginCommands(),
			},
		},
	}

	return
}

func ShowHelp(helpTemplate string, thingToPrint interface{}) {
	translatedTemplatedHelp := T(strings.Replace(helpTemplate, "{{", "[[", -1))
	translatedTemplatedHelp = strings.Replace(translatedTemplatedHelp, "[[", "{{", -1)

	switch thing := thingToPrint.(type) {
	case *cli.App:
		showAppHelp(translatedTemplatedHelp, thing)
	case cli.Command:
		showCommandHelp(translatedTemplatedHelp, thing)
	default:
		panic(fmt.Sprintf("Help printer has received something that is neither app nor command! The beast (%s) looks like this: %s", reflect.TypeOf(thing), thing))
	}
}

var CodeGangstaHelpPrinter = cli.HelpPrinter

func showCommandHelp(helpTemplate string, commandToPrint cli.Command) {
	CodeGangstaHelpPrinter(helpTemplate, commandToPrint)
}

func showAppHelp(helpTemplate string, appToPrint *cli.App) {
	presenter := newAppPresenter(appToPrint)

	w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
	t := template.Must(template.New("help").Parse(helpTemplate))
	t.Execute(w, presenter)
	w.Flush()
}
<commit_msg>correct display order in space admin help section<commit_after>package app

import (
	"fmt"
	"os"
	"reflect"
	"strings"
	"text/tabwriter"
	"text/template"
	"unicode/utf8"

	"github.com/cloudfoundry/cli/cf/configuration/plugin_config"
	. "github.com/cloudfoundry/cli/cf/i18n"
	"github.com/cloudfoundry/cli/cf/terminal"
	"github.com/codegangsta/cli"
)

type groupedCommands struct {
	Name             string
	CommandSubGroups [][]cmdPresenter
}

func (c groupedCommands) SubTitle(name string) string {
	return terminal.HeaderColor(name + ":")
}

type cmdPresenter struct {
	Name        string
	Description string
}

func presentCmdName(cmd cli.Command) (name string) {
	name = cmd.Name
	if cmd.ShortName != "" {
		name = name + ", " + cmd.ShortName
	}
	return
}

type appPresenter struct {
	cli.App
	Commands []groupedCommands
}

func (p appPresenter) Title(name string) string {
	return terminal.HeaderColor(name)
}

func newAppPresenter(app *cli.App) (presenter appPresenter) {
	maxNameLen := 0
	for _, cmd := range app.Commands {
		name := presentCmdName(cmd)
		if utf8.RuneCountInString(name) > maxNameLen {
			maxNameLen = len(name)
		}
	}

	presentCommand := func(commandName string) (presenter cmdPresenter) {
		cmd := app.Command(commandName)
		presenter.Name = presentCmdName(*cmd)
		padding := strings.Repeat(" ", maxNameLen-utf8.RuneCountInString(presenter.Name))
		presenter.Name = presenter.Name + padding
		presenter.Description = cmd.Description
		return
	}

	presentPluginCommands := func() []cmdPresenter {
		pluginConfig := plugin_config.NewPluginConfig(func(err error) {
			//fail silently when running help?
		})

		plugins := pluginConfig.Plugins()
		var presenters []cmdPresenter
		var pluginPresenter cmdPresenter

		for _, pluginMetadata := range plugins {
			for _, cmd := range pluginMetadata.Commands {
				pluginPresenter.Name = cmd.Name
				padding := strings.Repeat(" ", maxNameLen-utf8.RuneCountInString(pluginPresenter.Name))
				pluginPresenter.Name = pluginPresenter.Name + padding
				pluginPresenter.Description = cmd.HelpText
				presenters = append(presenters, pluginPresenter)
			}
		}

		return presenters
	}
	presenter.Name = app.Name
	presenter.Flags = app.Flags
	presenter.Usage = app.Usage
	presenter.Version = app.Version
	presenter.Compiled = app.Compiled
	presenter.Commands = []groupedCommands{
		{
			Name: T("GETTING STARTED"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("login"),
					presentCommand("logout"),
					presentCommand("passwd"),
					presentCommand("target"),
				}, {
					presentCommand("api"),
					presentCommand("auth"),
				},
			},
		}, {
			Name: T("APPS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("apps"),
					presentCommand("app"),
				}, {
					presentCommand("push"),
					presentCommand("scale"),
					presentCommand("delete"),
					presentCommand("rename"),
				}, {
					presentCommand("start"),
					presentCommand("stop"),
					presentCommand("restart"),
					presentCommand("restage"),
				}, {
					presentCommand("events"),
					presentCommand("files"),
					presentCommand("logs"),
				}, {
					presentCommand("env"),
					presentCommand("set-env"),
					presentCommand("unset-env"),
				}, {
					presentCommand("stacks"),
				}, {
					presentCommand("copy-source"),
				},
			},
		}, {
			Name: T("SERVICES"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("marketplace"),
					presentCommand("services"),
					presentCommand("service"),
				}, {
					presentCommand("create-service"),
					presentCommand("update-service"),
					presentCommand("delete-service"),
					presentCommand("rename-service"),
				}, {
					presentCommand("bind-service"),
					presentCommand("unbind-service"),
				}, {
					presentCommand("create-user-provided-service"),
					presentCommand("update-user-provided-service"),
				},
			},
		}, {
			Name: T("ORGS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("orgs"),
					presentCommand("org"),
				}, {
					presentCommand("create-org"),
					presentCommand("delete-org"),
					presentCommand("rename-org"),
				},
			},
		}, {
			Name: T("SPACES"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("spaces"),
					presentCommand("space"),
				}, {
					presentCommand("create-space"),
					presentCommand("delete-space"),
					presentCommand("rename-space"),
				},
			},
		}, {
			Name: T("DOMAINS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("domains"),
					presentCommand("create-domain"),
					presentCommand("delete-domain"),
					presentCommand("create-shared-domain"),
					presentCommand("delete-shared-domain"),
				},
			},
		}, {
			Name: T("ROUTES"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("routes"),
					presentCommand("create-route"),
					presentCommand("check-route"),
					presentCommand("map-route"),
					presentCommand("unmap-route"),
					presentCommand("delete-route"),
					presentCommand("delete-orphaned-routes"),
				},
			},
		}, {
			Name: T("BUILDPACKS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("buildpacks"),
					presentCommand("create-buildpack"),
					presentCommand("update-buildpack"),
					presentCommand("rename-buildpack"),
					presentCommand("delete-buildpack"),
				},
			},
		}, {
			Name: T("USER ADMIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("create-user"),
					presentCommand("delete-user"),
				}, {
					presentCommand("org-users"),
					presentCommand("set-org-role"),
					presentCommand("unset-org-role"),
				}, {
					presentCommand("space-users"),
					presentCommand("set-space-role"),
					presentCommand("unset-space-role"),
				},
			},
		}, {
			Name: T("ORG ADMIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("quotas"),
					presentCommand("quota"),
					presentCommand("set-quota"),
				}, {
					presentCommand("create-quota"),
					presentCommand("delete-quota"),
					presentCommand("update-quota"),
				},
			},
		}, {
			Name: T("SPACE ADMIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("space-quotas"),
					presentCommand("space-quota"),
					presentCommand("create-space-quota"),
					presentCommand("update-space-quota"),
					presentCommand("delete-space-quota"),
					presentCommand("set-space-quota"),
					presentCommand("unset-space-quota"),
				},
			},
		}, {
			Name: T("SERVICE ADMIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("service-auth-tokens"),
					presentCommand("create-service-auth-token"),
					presentCommand("update-service-auth-token"),
					presentCommand("delete-service-auth-token"),
				}, {
					presentCommand("service-brokers"),
					presentCommand("create-service-broker"),
					presentCommand("update-service-broker"),
					presentCommand("delete-service-broker"),
					presentCommand("rename-service-broker"),
				}, {
					presentCommand("migrate-service-instances"),
					presentCommand("purge-service-offering"),
				}, {
					presentCommand("service-access"),
					presentCommand("enable-service-access"),
					presentCommand("disable-service-access"),
				},
			},
		}, {
			Name: T("SECURITY GROUP"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("security-group"),
					presentCommand("security-groups"),
					presentCommand("create-security-group"),
					presentCommand("update-security-group"),
					presentCommand("delete-security-group"),
					presentCommand("bind-security-group"),
					presentCommand("unbind-security-group"),
				}, {
					presentCommand("bind-staging-security-group"),
					presentCommand("staging-security-groups"),
					presentCommand("unbind-staging-security-group"),
				}, {
					presentCommand("bind-running-security-group"),
					presentCommand("running-security-groups"),
					presentCommand("unbind-running-security-group"),
				},
			},
		}, {
			Name: T("ENVIRONMENT VARIABLE GROUPS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("running-environment-variable-group"),
					presentCommand("staging-environment-variable-group"),
					presentCommand("set-staging-environment-variable-group"),
					presentCommand("set-running-environment-variable-group"),
				},
			},
		},
		{
			Name: T("FEATURE FLAGS"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("feature-flags"),
					presentCommand("feature-flag"),
					presentCommand("enable-feature-flag"),
					presentCommand("disable-feature-flag"),
				},
			},
		}, {
			Name: T("ADVANCED"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("curl"),
					presentCommand("config"),
					presentCommand("oauth-token"),
				},
			},
		}, {
			Name: T("PLUGIN"),
			CommandSubGroups: [][]cmdPresenter{
				{
					presentCommand("plugins"),
					presentCommand("install-plugin"),
					presentCommand("uninstall-plugin"),
				},
			},
		}, {
			Name: T("PLUGIN COMMANDS"),
			CommandSubGroups: [][]cmdPresenter{
				presentPluginCommands(),
			},
		},
	}

	return
}

func ShowHelp(helpTemplate string, thingToPrint interface{}) {
	translatedTemplatedHelp := T(strings.Replace(helpTemplate, "{{", "[[", -1))
	translatedTemplatedHelp = strings.Replace(translatedTemplatedHelp, "[[", "{{", -1)

	switch thing := thingToPrint.(type) {
	case *cli.App:
		showAppHelp(translatedTemplatedHelp, thing)
	case cli.Command:
		showCommandHelp(translatedTemplatedHelp, thing)
	default:
		panic(fmt.Sprintf("Help printer has received something that is neither app nor command! The beast (%s) looks like this: %s", reflect.TypeOf(thing), thing))
	}
}

var CodeGangstaHelpPrinter = cli.HelpPrinter

func showCommandHelp(helpTemplate string, commandToPrint cli.Command) {
	CodeGangstaHelpPrinter(helpTemplate, commandToPrint)
}

func showAppHelp(helpTemplate string, appToPrint *cli.App) {
	presenter := newAppPresenter(appToPrint)

	w := tabwriter.NewWriter(os.Stdout, 0, 8, 1, '\t', 0)
	t := template.Must(template.New("help").Parse(helpTemplate))
	t.Execute(w, presenter)
	w.Flush()
}
<|endoftext|>


<commit_before>// Package term manages POSIX terminals. As POSIX terminals are connected to, or emulate,
// a UART, this package provides control over the various UART and serial line parameters.
package term

import (
	"io"
	"os"
	"syscall"
	"unsafe"
)

// Term represents an asynchronous communications port.
type Term struct {
	name string
	fd   int
}

// Open opens an asynchronous communications port.
func Open(name string) (*Term, error) {
	fd, e := syscall.Open(name, syscall.O_NOCTTY|syscall.O_CLOEXEC|syscall.O_RDWR, 0666)
	if e != nil {
		return nil, &os.PathError{"open", name, e}
	}
	return &Term{name: name, fd: fd}, nil
}

// Read reads up to len(b) bytes from the terminal. It returns the number of
// bytes read and an error, if any. EOF is signaled by a zero count with
// err set to io.EOF.
func (t *Term) Read(b []byte) (int, error) {
	n, e := syscall.Read(t.fd, b)
	if n < 0 {
		n = 0
	}
	if n == 0 && len(b) > 0 && e == nil {
		return 0, io.EOF
	}
	if e != nil {
		return n, &os.PathError{"read", t.name, e}
	}
	return n, nil
}

// Write writes len(b) bytes to the terminal. It returns the number of bytes
// written and an error, if any. Write returns a non-nil error when n !=
// len(b).
func (t *Term) Write(b []byte) (int, error) {
	n, e := syscall.Write(t.fd, b)
	if n < 0 {
		n = 0
	}
	if n != len(b) {
		return n, io.ErrShortWrite
	}
	if e != nil {
		return n, &os.PathError{"write", t.name, e}
	}
	return n, nil
}

// Close releases any associated resources.
func (t *Term) Close() error {
	err := syscall.Close(t.fd)
	t.fd = -1
	return err
}

// Speed returns the current input and output baud rates for device.
func (t *Term) Speed() (int, int, error) {
	termios, err := t.tcgetattr()
	if err != nil {
		return -1, -1, err
	}
	return int(termios.Ispeed), int(termios.Ospeed), nil
}

// SetSpeed sets the receive and transmit baud rates.
func (t *Term) SetSpeed(baud int) error {
	attr, err := t.tcgetattr()
	if err != nil {
		return err
	}
	cfsetspeed(attr, baud)
	return t.tcsetattr(attr)
}

// Flush flushes both data received but not read, and data written but not transmitted.
func (t *Term) Flush() error {
	const TCFLSH = 0x540B
	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(t.fd), TCFLSH, syscall.TCIOFLUSH, 0, 0, 0); e != 0 {
		return e
	}
	return nil
}

// SendBreak sends a break signal.
func (t *Term) SendBreak() error {
	const TCSBRK = 0x5409 // not POSIX TCSBRKP
	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(t.fd), TCSBRK, 0, 0, 0, 0); e != 0 {
		return e
	}
	return nil
}

func (t *Term) tcgetattr() (*syscall.Termios, error) {
	var attr syscall.Termios
	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(t.fd), syscall.TCGETS, uintptr(unsafe.Pointer(&attr)), 0, 0, 0); e != 0 {
		return nil, e
	}
	return &attr, nil
}

func (t *Term) tcsetattr(attr *syscall.Termios) error {
	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(t.fd), syscall.TCSETS, uintptr(unsafe.Pointer(attr)), 0, 0, 0); e != 0 {
		return e
	}
	return nil
}
<commit_msg>removed Speed()<commit_after>// Package term manages POSIX terminals. As POSIX terminals are connected to, or emulate,
// a UART, this package provides control over the various UART and serial line parameters.
package term

import (
	"io"
	"os"
	"syscall"
	"unsafe"
)

// Term represents an asynchronous communications port.
type Term struct {
	name string
	fd   int
}

// Open opens an asynchronous communications port.
func Open(name string) (*Term, error) {
	fd, e := syscall.Open(name, syscall.O_NOCTTY|syscall.O_CLOEXEC|syscall.O_RDWR, 0666)
	if e != nil {
		return nil, &os.PathError{"open", name, e}
	}
	return &Term{name: name, fd: fd}, nil
}

// Read reads up to len(b) bytes from the terminal. It returns the number of
// bytes read and an error, if any. EOF is signaled by a zero count with
// err set to io.EOF.
func (t *Term) Read(b []byte) (int, error) {
	n, e := syscall.Read(t.fd, b)
	if n < 0 {
		n = 0
	}
	if n == 0 && len(b) > 0 && e == nil {
		return 0, io.EOF
	}
	if e != nil {
		return n, &os.PathError{"read", t.name, e}
	}
	return n, nil
}

// Write writes len(b) bytes to the terminal. It returns the number of bytes
// written and an error, if any. Write returns a non-nil error when n !=
// len(b).
func (t *Term) Write(b []byte) (int, error) {
	n, e := syscall.Write(t.fd, b)
	if n < 0 {
		n = 0
	}
	if n != len(b) {
		return n, io.ErrShortWrite
	}
	if e != nil {
		return n, &os.PathError{"write", t.name, e}
	}
	return n, nil
}

// Close releases any associated resources.
func (t *Term) Close() error {
	err := syscall.Close(t.fd)
	t.fd = -1
	return err
}

// SetSpeed sets the receive and transmit baud rates.
func (t *Term) SetSpeed(baud int) error {
	attr, err := t.tcgetattr()
	if err != nil {
		return err
	}
	cfsetspeed(attr, baud)
	return t.tcsetattr(attr)
}

// Flush flushes both data received but not read, and data written but not transmitted.
func (t *Term) Flush() error {
	const TCFLSH = 0x540B
	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(t.fd), TCFLSH, syscall.TCIOFLUSH, 0, 0, 0); e != 0 {
		return e
	}
	return nil
}

// SendBreak sends a break signal.
func (t *Term) SendBreak() error {
	const TCSBRK = 0x5409 // not POSIX TCSBRKP
	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(t.fd), TCSBRK, 0, 0, 0, 0); e != 0 {
		return e
	}
	return nil
}

func (t *Term) tcgetattr() (*syscall.Termios, error) {
	var attr syscall.Termios
	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(t.fd), syscall.TCGETS, uintptr(unsafe.Pointer(&attr)), 0, 0, 0); e != 0 {
		return nil, e
	}
	return &attr, nil
}

func (t *Term) tcsetattr(attr *syscall.Termios) error {
	if _, _, e := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(t.fd), syscall.TCSETS, uintptr(unsafe.Pointer(attr)), 0, 0, 0); e != 0 {
		return e
	}
	return nil
}
<|endoftext|>


<commit_before>package leakybucket

import (
	"math"
	"sync"
	"testing"
	"time"
)

// CreateTest returns a test of bucket creation for a given storage backend.
// It is meant to be used by leakybucket implementers who wish to test this.
func CreateTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		now := time.Now()
		bucket, err := s.Create("testbucket", 100, time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		if capacity := bucket.Capacity(); capacity != 100 {
			t.Fatalf("expected capacity of %d, got %d", 100, capacity)
		}
		e := float64(1 * time.Second) // margin of error
		if error := float64(bucket.Reset().Sub(now.Add(time.Minute))); math.Abs(error) > e {
			t.Fatalf("expected reset time close to %s, got %s", now.Add(time.Minute),
				bucket.Reset())
		}
	}
}

// AddTest returns a test that adding to a single bucket works.
// It is meant to be used by leakybucket implementers who wish to test this.
func AddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		bucket, err := s.Create("testbucket", 10, time.Minute)
		if err != nil {
			t.Fatal(err)
		}

		addAndTestRemaining := func(add, remaining uint) {
			if state, err := bucket.Add(add); err != nil {
				t.Fatal(err)
			} else if bucket.Remaining() != state.Remaining {
				t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
					bucket.Remaining(), state.Remaining)
			} else if state.Remaining != remaining {
				t.Fatalf("expected %d remaining, got %d", remaining, state.Remaining)
			}
		}

		addAndTestRemaining(1, 9)
		addAndTestRemaining(3, 6)
		addAndTestRemaining(6, 0)

		if _, err := bucket.Add(1); err == nil {
			t.Fatalf("expected ErrorFull, received no error")
		} else if err != ErrorFull {
			t.Fatalf("expected ErrorFull, received %v", err)
		}
	}
}

// ThreadSafeAddTest returns a test that adding to a single bucket is thread-safe.
// It is meant to be used by leakybucket implementers who wish to test this.
func ThreadSafeAddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		// Make a bucket of size `n`. Spawn `n+1` goroutines that each try to take one token.
		// We should see the bucket transition through having `n-1`, `n-2`, ... 0 remaining capacity.
		// We should also witness one error when the bucket has reached capacity.
		n := 100
		bucket, err := s.Create("testbucket", uint(n), time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		remaining := map[uint]bool{}     // record observed "remaining" counts. (ab)using map as set here
		remainingMutex := sync.RWMutex{} // maps are not threadsafe
		errors := []error{}              // record observed errors
		var wg sync.WaitGroup
		for i := 0; i < n+1; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()
				state, err := bucket.Add(1)
				if err != nil {
					errors = append(errors, err)
				} else {
					remainingMutex.Lock()
					defer remainingMutex.Unlock()
					remaining[state.Remaining] = true
				}
			}()
		}
		wg.Wait()
		if len(remaining) != n {
			t.Fatalf("Did not observe correct bucket states: %#v, %#v", remaining, errors)
		}
		if len(errors) != 1 && errors[0] != ErrorFull {
			t.Fatalf("Did not observe one full error: %#v", errors)
		}
	}
}
<commit_msg>test: ThreadSafeAdd: clearer error reporting<commit_after>package leakybucket

import (
	"math"
	"reflect"
	"sync"
	"testing"
	"time"
)

// CreateTest returns a test of bucket creation for a given storage backend.
// It is meant to be used by leakybucket implementers who wish to test this.
func CreateTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		now := time.Now()
		bucket, err := s.Create("testbucket", 100, time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		if capacity := bucket.Capacity(); capacity != 100 {
			t.Fatalf("expected capacity of %d, got %d", 100, capacity)
		}
		e := float64(1 * time.Second) // margin of error
		if error := float64(bucket.Reset().Sub(now.Add(time.Minute))); math.Abs(error) > e {
			t.Fatalf("expected reset time close to %s, got %s", now.Add(time.Minute),
				bucket.Reset())
		}
	}
}

// AddTest returns a test that adding to a single bucket works.
// It is meant to be used by leakybucket implementers who wish to test this.
func AddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		bucket, err := s.Create("testbucket", 10, time.Minute)
		if err != nil {
			t.Fatal(err)
		}

		addAndTestRemaining := func(add, remaining uint) {
			if state, err := bucket.Add(add); err != nil {
				t.Fatal(err)
			} else if bucket.Remaining() != state.Remaining {
				t.Fatalf("expected bucket and state remaining to match, bucket is %d, state is %d",
					bucket.Remaining(), state.Remaining)
			} else if state.Remaining != remaining {
				t.Fatalf("expected %d remaining, got %d", remaining, state.Remaining)
			}
		}

		addAndTestRemaining(1, 9)
		addAndTestRemaining(3, 6)
		addAndTestRemaining(6, 0)

		if _, err := bucket.Add(1); err == nil {
			t.Fatalf("expected ErrorFull, received no error")
		} else if err != ErrorFull {
			t.Fatalf("expected ErrorFull, received %v", err)
		}
	}
}

// ThreadSafeAddTest returns a test that adding to a single bucket is thread-safe.
// It is meant to be used by leakybucket implementers who wish to test this.
func ThreadSafeAddTest(s Storage) func(*testing.T) {
	return func(t *testing.T) {
		// Make a bucket of size `n`. Spawn `n+1` goroutines that each try to take one token.
		// We should see the bucket transition through having `n-1`, `n-2`, ... 0 remaining capacity.
		// We should also witness one error when the bucket has reached capacity.
		n := 100
		bucket, err := s.Create("testbucket", uint(n), time.Minute)
		if err != nil {
			t.Fatal(err)
		}
		remaining := map[uint]bool{}     // record observed "remaining" counts. (ab)using map as set here
		remainingMutex := sync.RWMutex{} // maps are not threadsafe
		errors := []error{}              // record observed errors
		var wg sync.WaitGroup
		for i := 0; i < n+1; i++ {
			wg.Add(1)
			go func() {
				defer wg.Done()
				state, err := bucket.Add(1)
				if err != nil {
					errors = append(errors, err)
				} else {
					remainingMutex.Lock()
					defer remainingMutex.Unlock()
					remaining[state.Remaining] = true
				}
			}()
		}
		wg.Wait()
		keys := reflect.ValueOf(remaining).MapKeys()
		if len(remaining) != n {
			string_keys := []int{}
			for key := range keys {
				string_keys = append(string_keys, key)
			}
			t.Fatalf("Did not observe correct bucket states. Saw %d distinct remaining values instead of %d: %#v",
				len(remaining), n, string_keys)
		}
		if len(errors) != 1 && errors[0] != ErrorFull {
			t.Fatalf("Did not observe one full error: %#v", errors)
		}
	}
}
<|endoftext|>


<commit_before>package main

import (
     "io/ioutil"
     "fmt"
     "net/http"
     "net/url"
)

func main() {
     /*resp, _ := http.Get("http://localhost:8080/")
     defer resp.Body.Close()
     body, _ := ioutil.ReadAll(resp.Body)
     fmt.Printf(string(body))*/

     resp2, _ := http.PostForm("http://localhost:8080/braille",
               url.Values{"input":{"hello"}, "lang": {"en"}})
     defer resp2.Body.Close()
     body2, _ := ioutil.ReadAll(resp2.Body)
     fmt.Printf(string(body2))
}
<commit_msg>reformat test.go<commit_after>package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
)

func main() {
	/*resp, _ := http.Get("http://localhost:8080/")
	  defer resp.Body.Close()
	  body, _ := ioutil.ReadAll(resp.Body)
	  fmt.Printf(string(body))*/

	resp2, _ := http.PostForm("http://localhost:8080/braille",
		url.Values{"input": {"hello"}, "lang": {"en"}})
	defer resp2.Body.Close()
	body2, _ := ioutil.ReadAll(resp2.Body)
	fmt.Printf(string(body2))
}
<|endoftext|>