<commit_before>// +build windows

/*
   Copyright The containerd 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 runhcs

import (
	"context"
	"os"
	"os/exec"
	"sync"
	"sync/atomic"
	"syscall"
	"time"

	eventstypes "github.com/containerd/containerd/api/events"
	"github.com/containerd/containerd/runtime"
)

type processExit struct {
	pid        uint32
	exitStatus uint32
	exitedAt   time.Time
	exitErr    error
}

func newProcess(ctx context.Context, s *service, id string, pid uint32, pr *pipeRelay, bundle, stdin, stdout, stderr string, terminal bool) (*process, error) {
	p, err := os.FindProcess(int(pid))
	if err != nil {
		return nil, err
	}
	process := &process{
		cid:       id,
		id:        id,
		bundle:    bundle,
		stdin:     stdin,
		stdout:    stdout,
		stderr:    stderr,
		terminal:  terminal,
		relay:     pr,
		waitBlock: make(chan struct{}),
	}
	go waitForProcess(ctx, process, p, s)
	return process, nil
}

func waitForProcess(ctx context.Context, process *process, p *os.Process, s *service) {
	pid := uint32(p.Pid)
	// Store the default non-exited value for calls to stat
	process.exit.Store(&processExit{
		pid:        pid,
		exitStatus: 255,
		exitedAt:   time.Time{},
		exitErr:    nil,
	})

	var status int
	_, eerr := p.Wait()
	if eerr != nil {
		status = 255
		if exitErr, ok := eerr.(*exec.ExitError); ok {
			if ws, ok := exitErr.Sys().(syscall.WaitStatus); ok {
				status = ws.ExitStatus()
			}
		}
	}
	now := time.Now()
	process.exit.Store(&processExit{
		pid:        pid,
		exitStatus: uint32(status),
		exitedAt:   now,
		exitErr:    eerr,
	})

	// Wait for the relay
	process.relay.wait()

	// close the client io, and free upstream waiters
	process.close()

	s.publisher.Publish(
		ctx,
		runtime.TaskExitEventTopic,
		&eventstypes.TaskExit{
			ContainerID: process.cid,
			ID:          process.id,
			Pid:         pid,
			ExitStatus:  uint32(status),
			ExitedAt:    now,
		})
}

func newExecProcess(ctx context.Context, s *service, cid, id string, pr *pipeRelay, bundle, stdin, stdout, stderr string, terminal bool) (*process, error) {
	process := &process{
		cid:       cid,
		id:        id,
		bundle:    bundle,
		stdin:     stdin,
		stdout:    stdout,
		stderr:    stderr,
		terminal:  terminal,
		relay:     pr,
		waitBlock: make(chan struct{}),
	}
	// Store the default non-exited value for calls to stat
	process.exit.Store(&processExit{
		pid:        0, // This is updated when the call to Start happens and the state is overwritten in waitForProcess.
		exitStatus: 255,
		exitedAt:   time.Time{},
		exitErr:    nil,
	})
	return process, nil
}

type process struct {
	sync.Mutex

	cid string
	id  string

	bundle   string
	stdin    string
	stdout   string
	stderr   string
	terminal bool
	relay    *pipeRelay

	// started track if the process has ever been started and will not be reset
	// for the lifetime of the process object.
	started bool

	waitBlock chan struct{}
	// exit holds the exit value for all calls to `stat`. By default a
	// non-exited value is stored of status: 255, at: time 0.
	exit atomic.Value

	// closeOnce is responsible for closing waitBlock and any io.
	closeOnce sync.Once
}

// closeIO closes the stdin of the executing process to unblock any waiters
func (p *process) closeIO() {
	p.Lock()
	defer p.Unlock()

	p.relay.closeIO()
}

// close closes all stdio and frees any waiters. This is safe to call multiple
// times.
func (p *process) close() {
	p.closeOnce.Do(func() {
		p.relay.close()

		// Free any waiters
		close(p.waitBlock)
	})
}

// stat is a non-blocking query of the current process state.
func (p *process) stat() *processExit {
	er := p.exit.Load()
	return er.(*processExit)
}

// wait waits for the container process to exit and returns the exit status. If
// the process failed post start the processExit will contain the exitErr. This
// is safe to call previous to calling start().
func (p *process) wait() *processExit {
	<-p.waitBlock
	return p.stat()
}
<commit_msg>Windows: Publish exit status correctly in TaskExit<commit_after>// +build windows

/*
   Copyright The containerd 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 runhcs

import (
	"context"
	"os"
	"sync"
	"sync/atomic"
	"syscall"
	"time"

	eventstypes "github.com/containerd/containerd/api/events"
	"github.com/containerd/containerd/runtime"
)

type processExit struct {
	pid        uint32
	exitStatus uint32
	exitedAt   time.Time
	exitErr    error
}

func newProcess(ctx context.Context, s *service, id string, pid uint32, pr *pipeRelay, bundle, stdin, stdout, stderr string, terminal bool) (*process, error) {
	p, err := os.FindProcess(int(pid))
	if err != nil {
		return nil, err
	}
	process := &process{
		cid:       id,
		id:        id,
		bundle:    bundle,
		stdin:     stdin,
		stdout:    stdout,
		stderr:    stderr,
		terminal:  terminal,
		relay:     pr,
		waitBlock: make(chan struct{}),
	}
	go waitForProcess(ctx, process, p, s)
	return process, nil
}

func waitForProcess(ctx context.Context, process *process, p *os.Process, s *service) {
	pid := uint32(p.Pid)
	// Store the default non-exited value for calls to stat
	process.exit.Store(&processExit{
		pid:        pid,
		exitStatus: 255,
		exitedAt:   time.Time{},
		exitErr:    nil,
	})

	var status int
	processState, eerr := p.Wait()
	if eerr != nil {
		status = 255
		p.Kill()
	} else {
		status = processState.Sys().(syscall.WaitStatus).ExitStatus()
	}

	now := time.Now()
	process.exit.Store(&processExit{
		pid:        pid,
		exitStatus: uint32(status),
		exitedAt:   now,
		exitErr:    eerr,
	})

	// Wait for the relay
	process.relay.wait()

	// close the client io, and free upstream waiters
	process.close()

	s.publisher.Publish(
		ctx,
		runtime.TaskExitEventTopic,
		&eventstypes.TaskExit{
			ContainerID: process.cid,
			ID:          process.id,
			Pid:         pid,
			ExitStatus:  uint32(status),
			ExitedAt:    now,
		})
}

func newExecProcess(ctx context.Context, s *service, cid, id string, pr *pipeRelay, bundle, stdin, stdout, stderr string, terminal bool) (*process, error) {
	process := &process{
		cid:       cid,
		id:        id,
		bundle:    bundle,
		stdin:     stdin,
		stdout:    stdout,
		stderr:    stderr,
		terminal:  terminal,
		relay:     pr,
		waitBlock: make(chan struct{}),
	}
	// Store the default non-exited value for calls to stat
	process.exit.Store(&processExit{
		pid:        0, // This is updated when the call to Start happens and the state is overwritten in waitForProcess.
		exitStatus: 255,
		exitedAt:   time.Time{},
		exitErr:    nil,
	})
	return process, nil
}

type process struct {
	sync.Mutex

	cid string
	id  string

	bundle   string
	stdin    string
	stdout   string
	stderr   string
	terminal bool
	relay    *pipeRelay

	// started track if the process has ever been started and will not be reset
	// for the lifetime of the process object.
	started bool

	waitBlock chan struct{}
	// exit holds the exit value for all calls to `stat`. By default a
	// non-exited value is stored of status: 255, at: time 0.
	exit atomic.Value

	// closeOnce is responsible for closing waitBlock and any io.
	closeOnce sync.Once
}

// closeIO closes the stdin of the executing process to unblock any waiters
func (p *process) closeIO() {
	p.Lock()
	defer p.Unlock()

	p.relay.closeIO()
}

// close closes all stdio and frees any waiters. This is safe to call multiple
// times.
func (p *process) close() {
	p.closeOnce.Do(func() {
		p.relay.close()

		// Free any waiters
		close(p.waitBlock)
	})
}

// stat is a non-blocking query of the current process state.
func (p *process) stat() *processExit {
	er := p.exit.Load()
	return er.(*processExit)
}

// wait waits for the container process to exit and returns the exit status. If
// the process failed post start the processExit will contain the exitErr. This
// is safe to call previous to calling start().
func (p *process) wait() *processExit {
	<-p.waitBlock
	return p.stat()
}
<|endoftext|>


<commit_before>package main

import (
	"flag"
	"log"
	"net/http"

	"github.com/billhathaway/webcounter"
)

const (
	defaultPort = "8080"
)

func main() {
	port := flag.String("p", defaultPort, "listen port")
	flag.Parse()
	counter, err := webcounter.New()
	if err != nil {
		log.Fatal(err)
	}
	http.ListenAndServe(":"+*port, counter)
}
<commit_msg>Add -pprof flag to enable profiling<commit_after>package main

import (
	"flag"
	"log"
	"net/http"
	_ "net/http/pprof"

	"github.com/billhathaway/webcounter"
)

const (
	defaultPort = "8080"
)

func main() {
	port := flag.String("p", defaultPort, "listen port")
	pprofPort := flag.String("pprof", "", "listen port for profiling")
	flag.Parse()
	counter, err := webcounter.New()
	if err != nil {
		log.Fatal(err)
	}
	if *pprofPort != "" {
		go func() {
			log.Fatal(http.ListenAndServe(":"+*pprofPort, nil))
		}()
	}
	log.Fatal(http.ListenAndServe(":"+*port, counter))
}
<|endoftext|>


<commit_before>package dd

import (
	"image"
	"image/png"
	"io/ioutil"
	"os"

	"github.com/golang/freetype/truetype"

	"golang.org/x/image/font"
	"golang.org/x/image/math/fixed"
)

func writeToPNG(path string, im image.Image) error {
	file, err := os.Create(path)
	if err != nil {
		return err
	}
	defer file.Close()
	return png.Encode(file, im)
}

func fp(x, y float64) fixed.Point26_6 {
	return fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)}
}

func fi(x float64) fixed.Int26_6 {
	return fixed.Int26_6(x * 64)
}

func loadFontFace(path string, size float64) font.Face {
	fontBytes, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}
	f, err := truetype.Parse(fontBytes)
	if err != nil {
		panic(err)
	}
	return truetype.NewFace(f, &truetype.Options{
		Size:    size,
		DPI:     96,
		Hinting: font.HintingFull,
	})
}
<commit_msg>don't specify dpi<commit_after>package dd

import (
	"image"
	"image/png"
	"io/ioutil"
	"os"

	"github.com/golang/freetype/truetype"

	"golang.org/x/image/font"
	"golang.org/x/image/math/fixed"
)

func writeToPNG(path string, im image.Image) error {
	file, err := os.Create(path)
	if err != nil {
		return err
	}
	defer file.Close()
	return png.Encode(file, im)
}

func fp(x, y float64) fixed.Point26_6 {
	return fixed.Point26_6{fixed.Int26_6(x * 64), fixed.Int26_6(y * 64)}
}

func fi(x float64) fixed.Int26_6 {
	return fixed.Int26_6(x * 64)
}

func loadFontFace(path string, size float64) font.Face {
	fontBytes, err := ioutil.ReadFile(path)
	if err != nil {
		panic(err)
	}
	f, err := truetype.Parse(fontBytes)
	if err != nil {
		panic(err)
	}
	return truetype.NewFace(f, &truetype.Options{
		Size:    size,
		Hinting: font.HintingFull,
	})
}
<|endoftext|>


<commit_before>// Copyright 2015 go-swagger maintainers
//
// 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 swag

import (
	"math"
	"reflect"
	"regexp"
	"sort"
	"strings"
)

// Taken from https://github.com/golang/lint/blob/1fab560e16097e5b69afb66eb93aab843ef77845/lint.go#L663-L698
var commonInitialisms = map[string]bool{
	"API":   true,
	"ASCII": true,
	"CPU":   true,
	"CSS":   true,
	"DNS":   true,
	"EOF":   true,
	"GUID":  true,
	"HTML":  true,
	"HTTPS": true,
	"HTTP":  true,
	"ID":    true,
	"IP":    true,
	"JSON":  true,
	"LHS":   true,
	"QPS":   true,
	"RAM":   true,
	"RHS":   true,
	"RPC":   true,
	"SLA":   true,
	"SMTP":  true,
	"SSH":   true,
	"TCP":   true,
	"TLS":   true,
	"TTL":   true,
	"UDP":   true,
	"UUID":  true,
	"UID":   true,
	"UI":    true,
	"URI":   true,
	"URL":   true,
	"UTF8":  true,
	"VM":    true,
	"XML":   true,
	"XSRF":  true,
	"XSS":   true,
}
var initialisms []string

func init() {
	for k := range commonInitialisms {
		initialisms = append(initialisms, k)
	}
	sort.Sort(sort.Reverse(byLength(initialisms)))
}

// JoinByFormat joins a string array by a known format:
//		ssv: space separated value
//		tsv: tab separated value
//		pipes: pipe (|) separated value
//		csv: comma separated value (default)
func JoinByFormat(data []string, format string) []string {
	if len(data) == 0 {
		return data
	}
	var sep string
	switch format {
	case "ssv":
		sep = " "
	case "tsv":
		sep = "\t"
	case "pipes":
		sep = "|"
	case "multi":
		return data
	default:
		sep = ","
	}
	return []string{strings.Join(data, sep)}
}

// SplitByFormat splits a string by a known format:
//		ssv: space separated value
//		tsv: tab separated value
//		pipes: pipe (|) separated value
//		csv: comma separated value (default)
func SplitByFormat(data, format string) []string {
	if data == "" {
		return nil
	}
	var sep string
	switch format {
	case "ssv":
		sep = " "
	case "tsv":
		sep = "\t"
	case "pipes":
		sep = "|"
	case "multi":
		return nil
	default:
		sep = ","
	}
	var result []string
	for _, s := range strings.Split(data, sep) {
		if ts := strings.TrimSpace(s); ts != "" {
			result = append(result, ts)
		}
	}
	return result
}

type byLength []string

func (s byLength) Len() int {
	return len(s)
}
func (s byLength) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}
func (s byLength) Less(i, j int) bool {
	return len(s[i]) < len(s[j])
}

// Prepares strings by splitting by caps, spaces, dashes, and underscore
func split(str string) (words []string) {
	repl := strings.NewReplacer("@", "At ", "&", "And ", "|", "Or ", "$", "Dollar ", "-", " ", "_", " ")

	rex1 := regexp.MustCompile(`(\p{Lu})`)
	rex2 := regexp.MustCompile(`(\pL|\pM|\pN|\p{Pc})+`)

	str = trim(str)

	// Convert dash and underscore to spaces
	str = repl.Replace(str)

	// Split when uppercase is found (needed for Snake)
	str = rex1.ReplaceAllString(str, " $1")
	// check if consecutive single char things make up an initialism

	for _, k := range initialisms {
		str = strings.Replace(str, rex1.ReplaceAllString(k, " $1"), " "+k, -1)
	}
	// Get the final list of words
	words = rex2.FindAllString(str, -1)

	return
}

// Removes leading whitespaces
func trim(str string) string {
	return strings.Trim(str, " ")
}

// Shortcut to strings.ToUpper()
func upper(str string) string {
	return strings.ToUpper(trim(str))
}

// Shortcut to strings.ToLower()
func lower(str string) string {
	return strings.ToLower(trim(str))
}

// ToFileName lowercases and underscores a go type name
func ToFileName(name string) string {
	var out []string
	for _, w := range split(name) {
		out = append(out, lower(w))
	}
	return strings.Join(out, "_")
}

// ToCommandName lowercases and underscores a go type name
func ToCommandName(name string) string {
	var out []string
	for _, w := range split(name) {
		out = append(out, lower(w))
	}
	return strings.Join(out, "-")
}

// ToHumanNameLower represents a code name as a human series of words
func ToHumanNameLower(name string) string {
	var out []string
	for _, w := range split(name) {
		if !commonInitialisms[w] {
			out = append(out, lower(w))
		} else {
			out = append(out, w)
		}
	}
	return strings.Join(out, " ")
}

// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
func ToHumanNameTitle(name string) string {
	var out []string
	for _, w := range split(name) {
		if !commonInitialisms[w] {
			out = append(out, upper(w[:1])+lower(w[1:]))
		} else {
			out = append(out, w)
		}
	}
	return strings.Join(out, " ")
}

// ToJSONName camelcases a name which can be underscored or pascal cased
func ToJSONName(name string) string {
	var out []string
	for i, w := range split(name) {
		if i == 0 {
			out = append(out, lower(w))
			continue
		}
		out = append(out, upper(w[:1])+lower(w[1:]))
	}
	return strings.Join(out, "")
}

// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
func ToGoName(name string) string {
	var out []string
	for _, w := range split(name) {
		uw := upper(w)
		mod := int(math.Min(float64(len(uw)), 2))
		if !commonInitialisms[uw] && !commonInitialisms[uw[:len(uw)-mod]] {
			uw = upper(w[:1]) + lower(w[1:])
		}
		out = append(out, uw)
	}
	return strings.Join(out, "")
}

// ContainsStringsCI searches a slice of strings for a case-insensitive match
func ContainsStringsCI(coll []string, item string) bool {
	for _, a := range coll {
		if strings.EqualFold(a, item) {
			return true
		}
	}
	return false
}

type zeroable interface {
	IsZero() bool
}

// IsZero returns true when the value passed into the function is a zero value.
// This allows for safer checking of interface values.
func IsZero(data interface{}) bool {
	// check for things that have an IsZero method instead
	if vv, ok := data.(zeroable); ok {
		return vv.IsZero()
	}
	// continue with slightly more complex reflection
	v := reflect.ValueOf(data)
	switch v.Kind() {
	case reflect.String:
		return v.Len() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return v.IsNil()
	case reflect.Struct, reflect.Array:
		return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface())
	case reflect.Invalid:
		return true
	}
	return false
}

// CommandLineOptionsGroup represents a group of user-defined command line options
type CommandLineOptionsGroup struct {
	ShortDescription string
	LongDescription  string
	Options          interface{}
}
<commit_msg>also add ! and / as transliterated<commit_after>// Copyright 2015 go-swagger maintainers
//
// 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 swag

import (
	"math"
	"reflect"
	"regexp"
	"sort"
	"strings"
)

// Taken from https://github.com/golang/lint/blob/1fab560e16097e5b69afb66eb93aab843ef77845/lint.go#L663-L698
var commonInitialisms = map[string]bool{
	"API":   true,
	"ASCII": true,
	"CPU":   true,
	"CSS":   true,
	"DNS":   true,
	"EOF":   true,
	"GUID":  true,
	"HTML":  true,
	"HTTPS": true,
	"HTTP":  true,
	"ID":    true,
	"IP":    true,
	"JSON":  true,
	"LHS":   true,
	"QPS":   true,
	"RAM":   true,
	"RHS":   true,
	"RPC":   true,
	"SLA":   true,
	"SMTP":  true,
	"SSH":   true,
	"TCP":   true,
	"TLS":   true,
	"TTL":   true,
	"UDP":   true,
	"UUID":  true,
	"UID":   true,
	"UI":    true,
	"URI":   true,
	"URL":   true,
	"UTF8":  true,
	"VM":    true,
	"XML":   true,
	"XSRF":  true,
	"XSS":   true,
}
var initialisms []string

func init() {
	for k := range commonInitialisms {
		initialisms = append(initialisms, k)
	}
	sort.Sort(sort.Reverse(byLength(initialisms)))
}

// JoinByFormat joins a string array by a known format:
//		ssv: space separated value
//		tsv: tab separated value
//		pipes: pipe (|) separated value
//		csv: comma separated value (default)
func JoinByFormat(data []string, format string) []string {
	if len(data) == 0 {
		return data
	}
	var sep string
	switch format {
	case "ssv":
		sep = " "
	case "tsv":
		sep = "\t"
	case "pipes":
		sep = "|"
	case "multi":
		return data
	default:
		sep = ","
	}
	return []string{strings.Join(data, sep)}
}

// SplitByFormat splits a string by a known format:
//		ssv: space separated value
//		tsv: tab separated value
//		pipes: pipe (|) separated value
//		csv: comma separated value (default)
func SplitByFormat(data, format string) []string {
	if data == "" {
		return nil
	}
	var sep string
	switch format {
	case "ssv":
		sep = " "
	case "tsv":
		sep = "\t"
	case "pipes":
		sep = "|"
	case "multi":
		return nil
	default:
		sep = ","
	}
	var result []string
	for _, s := range strings.Split(data, sep) {
		if ts := strings.TrimSpace(s); ts != "" {
			result = append(result, ts)
		}
	}
	return result
}

type byLength []string

func (s byLength) Len() int {
	return len(s)
}
func (s byLength) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}
func (s byLength) Less(i, j int) bool {
	return len(s[i]) < len(s[j])
}

// Prepares strings by splitting by caps, spaces, dashes, and underscore
func split(str string) (words []string) {
	repl := strings.NewReplacer(
		"@", "At ",
		"&", "And ",
		"|", "Pipe ",
		"$", "Dollar ",
		"!", "Bang ",
		"/", "Slash ",
		"-", " ",
		"_", " ",
	)

	rex1 := regexp.MustCompile(`(\p{Lu})`)
	rex2 := regexp.MustCompile(`(\pL|\pM|\pN|\p{Pc})+`)

	str = trim(str)

	// Convert dash and underscore to spaces
	str = repl.Replace(str)

	// Split when uppercase is found (needed for Snake)
	str = rex1.ReplaceAllString(str, " $1")
	// check if consecutive single char things make up an initialism

	for _, k := range initialisms {
		str = strings.Replace(str, rex1.ReplaceAllString(k, " $1"), " "+k, -1)
	}
	// Get the final list of words
	words = rex2.FindAllString(str, -1)

	return
}

// Removes leading whitespaces
func trim(str string) string {
	return strings.Trim(str, " ")
}

// Shortcut to strings.ToUpper()
func upper(str string) string {
	return strings.ToUpper(trim(str))
}

// Shortcut to strings.ToLower()
func lower(str string) string {
	return strings.ToLower(trim(str))
}

// ToFileName lowercases and underscores a go type name
func ToFileName(name string) string {
	var out []string
	for _, w := range split(name) {
		out = append(out, lower(w))
	}
	return strings.Join(out, "_")
}

// ToCommandName lowercases and underscores a go type name
func ToCommandName(name string) string {
	var out []string
	for _, w := range split(name) {
		out = append(out, lower(w))
	}
	return strings.Join(out, "-")
}

// ToHumanNameLower represents a code name as a human series of words
func ToHumanNameLower(name string) string {
	var out []string
	for _, w := range split(name) {
		if !commonInitialisms[w] {
			out = append(out, lower(w))
		} else {
			out = append(out, w)
		}
	}
	return strings.Join(out, " ")
}

// ToHumanNameTitle represents a code name as a human series of words with the first letters titleized
func ToHumanNameTitle(name string) string {
	var out []string
	for _, w := range split(name) {
		if !commonInitialisms[w] {
			out = append(out, upper(w[:1])+lower(w[1:]))
		} else {
			out = append(out, w)
		}
	}
	return strings.Join(out, " ")
}

// ToJSONName camelcases a name which can be underscored or pascal cased
func ToJSONName(name string) string {
	var out []string
	for i, w := range split(name) {
		if i == 0 {
			out = append(out, lower(w))
			continue
		}
		out = append(out, upper(w[:1])+lower(w[1:]))
	}
	return strings.Join(out, "")
}

// ToGoName translates a swagger name which can be underscored or camel cased to a name that golint likes
func ToGoName(name string) string {
	var out []string
	for _, w := range split(name) {
		uw := upper(w)
		mod := int(math.Min(float64(len(uw)), 2))
		if !commonInitialisms[uw] && !commonInitialisms[uw[:len(uw)-mod]] {
			uw = upper(w[:1]) + lower(w[1:])
		}
		out = append(out, uw)
	}
	return strings.Join(out, "")
}

// ContainsStringsCI searches a slice of strings for a case-insensitive match
func ContainsStringsCI(coll []string, item string) bool {
	for _, a := range coll {
		if strings.EqualFold(a, item) {
			return true
		}
	}
	return false
}

type zeroable interface {
	IsZero() bool
}

// IsZero returns true when the value passed into the function is a zero value.
// This allows for safer checking of interface values.
func IsZero(data interface{}) bool {
	// check for things that have an IsZero method instead
	if vv, ok := data.(zeroable); ok {
		return vv.IsZero()
	}
	// continue with slightly more complex reflection
	v := reflect.ValueOf(data)
	switch v.Kind() {
	case reflect.String:
		return v.Len() == 0
	case reflect.Bool:
		return !v.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return v.Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return v.Uint() == 0
	case reflect.Float32, reflect.Float64:
		return v.Float() == 0
	case reflect.Interface, reflect.Map, reflect.Ptr, reflect.Slice:
		return v.IsNil()
	case reflect.Struct, reflect.Array:
		return reflect.DeepEqual(data, reflect.Zero(v.Type()).Interface())
	case reflect.Invalid:
		return true
	}
	return false
}

// CommandLineOptionsGroup represents a group of user-defined command line options
type CommandLineOptionsGroup struct {
	ShortDescription string
	LongDescription  string
	Options          interface{}
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/binary"
	"crypto/rand"
	"io/ioutil"
	"math"
	"os"
	"path/filepath"
	"strings"
)

// Uses /dev/urandom to generate random numbers. We don't
// need to recreate generated numbers, so we don't save
// a RNG state.
func randUint() uint64 {
	b := make([]byte, 8)
	_, err := rand.Read(b)
	for err != nil {
		_, err = rand.Read(b)
	}
	return binary.BigEndian.Uint64(b)
}

func randFloat() float64 {
	return float64(randUint()) / float64(math.MaxUint64)
}

// The range returned is inclusive.
func randRange(low, high uint) uint {
	f := randFloat() * float64(high - low + 1)
	return uint(math.Floor(f)) + low
}

// Returns the directory listing as full path names. The passed path
// must be absolute.
func listDirs(path string) []string {
	if !filepath.IsAbs(path) {
		panic("cannot list dirs on non-absolute path")
	}

	dirs := []string{}
	files, _ := ioutil.ReadDir(path)
	for _, file := range files {
		isPrivate := strings.HasPrefix(file.Name(), ".")
		if file.IsDir() && !isPrivate {
			dirs = append(dirs, filepath.Join(path, file.Name()))
		}
	}
	return dirs
}

// Returns true if you can descend from this path, descending is going
// down a direction, as opposed to up (`cd ..` is up). The passed path
// must be absolute
func canDescend(path string) bool {
	dirs := listDirs(path)
	return len(dirs) > 0
}

// Returns a random path to desend. The passed path must be absolute.
func randDescension(path string) string {
	dirs := listDirs(path)
	if len(dirs) == 0 {
		panic("Tried to descend when unable")
	}
	return dirs[randRange(0, uint(len(dirs) - 1))]
}

// Returns true if you can ascend from this path. No ascending
// below the home directory. The passed path must be absolute.
func canDescend(path string) bool {
	home := os.Getenv("HOME")
	return strings.HasPrefix(filepath.Dir(path), home)
}

// No need to be random. You can only ascend in one direction.
func ascend(path string) string {
	return filepath.Dir(path)
}
<commit_msg>Changed function name to correct name.<commit_after>package main

import (
	"encoding/binary"
	"crypto/rand"
	"io/ioutil"
	"math"
	"os"
	"path/filepath"
	"strings"
)

// Uses /dev/urandom to generate random numbers. We don't
// need to recreate generated numbers, so we don't save
// a RNG state.
func randUint() uint64 {
	b := make([]byte, 8)
	_, err := rand.Read(b)
	for err != nil {
		_, err = rand.Read(b)
	}
	return binary.BigEndian.Uint64(b)
}

func randFloat() float64 {
	return float64(randUint()) / float64(math.MaxUint64)
}

// The range returned is inclusive.
func randRange(low, high uint) uint {
	f := randFloat() * float64(high - low + 1)
	return uint(math.Floor(f)) + low
}

// Returns the directory listing as full path names. The passed path
// must be absolute.
func listDirs(path string) []string {
	if !filepath.IsAbs(path) {
		panic("cannot list dirs on non-absolute path")
	}

	dirs := []string{}
	files, _ := ioutil.ReadDir(path)
	for _, file := range files {
		isPrivate := strings.HasPrefix(file.Name(), ".")
		if file.IsDir() && !isPrivate {
			dirs = append(dirs, filepath.Join(path, file.Name()))
		}
	}
	return dirs
}

// Returns true if you can descend from this path, descending is going
// down a direction, as opposed to up (`cd ..` is up). The passed path
// must be absolute
func canDescend(path string) bool {
	dirs := listDirs(path)
	return len(dirs) > 0
}

// Returns a random path to desend. The passed path must be absolute.
func randDescension(path string) string {
	dirs := listDirs(path)
	if len(dirs) == 0 {
		panic("Tried to descend when unable")
	}
	return dirs[randRange(0, uint(len(dirs) - 1))]
}

// Returns true if you can ascend from this path. No ascending
// below the home directory. The passed path must be absolute.
func canAscend(path string) bool {
	home := os.Getenv("HOME")
	return strings.HasPrefix(filepath.Dir(path), home)
}

// No need to be random. You can only ascend in one direction.
func ascend(path string) string {
	return filepath.Dir(path)
}
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"io"
	"strings"
	"unicode"
)

// TrimAPIPrefix removes the API-specific prefix from a spec name.
// e.g., glTest becomes Test; GLX_TEST becomes TEST; egl0Test stays egl0Test
func TrimAPIPrefix(name string) string {
	prefixes := []string{"glX", "wgl", "egl", "gl", "GLX_", "WGL_", "EGL_", "GL_"}

	trimmed := name
	prefix := ""
	for _, p := range prefixes {
		if strings.HasPrefix(name, p) {
			trimmed = strings.TrimPrefix(name, p)
			prefix = p
			break
		}
	}

	if strings.IndexAny(trimmed, "0123456789") == 0 {
		return prefix + trimmed
	}
	return trimmed
}

// BlankLineStrippingWriter removes whitespace- or comment-only lines delimited
// by \n. A necessary evil to work around how text/template handles whitespace.
type BlankLineStrippingWriter struct {
	output io.Writer
	buf    *bytes.Buffer
}

// NewBlankLineStrippingWriter creates a new BlankLineStrippingWriter.
func NewBlankLineStrippingWriter(wrapped io.Writer) *BlankLineStrippingWriter {
	return &BlankLineStrippingWriter{wrapped, new(bytes.Buffer)}
}

func isBlank(line string) bool {
	blank := true
	for _, ch := range line {
		if !unicode.IsSpace(ch) && ch != '/' {
			blank = false
			break
		}
	}
	return blank
}

func (w BlankLineStrippingWriter) Write(p []byte) (n int, err error) {
	// Buffer the current write
	nn, err := w.buf.Write(p)
	if nn != len(p) || err != nil {
		return 0, err
	}
	// Write non-empty lines from the buffer
	for {
		line, err := w.buf.ReadString('\n')
		switch err {
		case nil:
			if !isBlank(line) {
				nn, e := w.output.Write([]byte(line))
				if nn != len(line) || e != nil {
					return n, err
				}
			}
			n += len(line)
		case io.EOF:
			// Did not have a whole line to read, rebuffer the unconsumed data
			w.buf.Write([]byte(line))
			return 0, nil
		default:
			return 0, err
		}
	}
	return n, err
}
<commit_msg>BlankLineStrippingWriter: clean up the code.<commit_after>package main

import (
	"bytes"
	"io"
	"strings"
	"unicode"
)

// TrimAPIPrefix removes the API-specific prefix from a spec name.
// e.g., glTest becomes Test; GLX_TEST becomes TEST; egl0Test stays egl0Test
func TrimAPIPrefix(name string) string {
	prefixes := []string{"glX", "wgl", "egl", "gl", "GLX_", "WGL_", "EGL_", "GL_"}

	trimmed := name
	prefix := ""
	for _, p := range prefixes {
		if strings.HasPrefix(name, p) {
			trimmed = strings.TrimPrefix(name, p)
			prefix = p
			break
		}
	}

	if strings.IndexAny(trimmed, "0123456789") == 0 {
		return prefix + trimmed
	}
	return trimmed
}

// BlankLineStrippingWriter removes whitespace- or comment-only lines delimited
// by \n. A necessary evil to work around how text/template handles whitespace.
type BlankLineStrippingWriter struct {
	output io.Writer
	buf    *bytes.Buffer
}

// NewBlankLineStrippingWriter creates a new BlankLineStrippingWriter.
func NewBlankLineStrippingWriter(wrapped io.Writer) *BlankLineStrippingWriter {
	return &BlankLineStrippingWriter{wrapped, new(bytes.Buffer)}
}

func isBlank(line string) bool {
	blank := true
	for _, ch := range line {
		if !unicode.IsSpace(ch) && ch != '/' {
			blank = false
			break
		}
	}
	return blank
}

func (w BlankLineStrippingWriter) Write(p []byte) (int, error) {
	// Buffer the current write
	// Error is always nil.
	w.buf.Write(p)
	n := 0

	// Write non-empty lines from the buffer
	for {
		line, err := w.buf.ReadString('\n')
		if err != nil {
			// Did not have a whole line to read, rebuffer the unconsumed data
			// Error is always nil.
			w.buf.Write([]byte(line))
			return 0, nil
		}
		if !isBlank(line) {
			// Error is always nil.
			w.output.Write([]byte(line))
		}
		n += len(line)
	}
}
<|endoftext|>


<commit_before>// Package uuid implements a fast UUID representation and integrates with JSON and SQL drivers
package uuid

import (
	"crypto/rand"
	"errors"
	"fmt"
)

// UUID represents a Universally-Unique-Identifier
type UUID [16]byte

var (
	ErrInvalid = errors.New("invalid UUID")
	zero       = [16]byte{}
)

type scanError struct {
	scanned int
	bytes   int
	length  int
}

type ErrTooShort scanError

func (e *ErrTooShort) Error() string {
	return fmt.Sprintf("invalid UUID: too few bytes (scanned: %d, length: %d, bytes: %d)", e.scanned, e.length, e.bytes)
}

type ErrTooLong scanError

func (e *ErrTooLong) Error() string {
	return fmt.Sprintf("invalid UUID: too many bytes (scanned: %d, length: %d, bytes: %d)", e.scanned, e.length, e.bytes)
}

// hexchar2byte contains the integer byte-value represented by a hexadecimal character,
// 255 if it is an invalid character
var hexchar2byte = []byte{
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
}

// hex2byte reads the first two bytes of the input string and returns the byte matched
// by their hexadecimal value
func hex2byte(x string) (byte, bool) {
	a := hexchar2byte[x[0]]
	b := hexchar2byte[x[1]]

	return (a << 4) | b, a != 255 && b != 255
}

// V4 creates a new random UUID with data from crypto/rand.Read
func V4() (UUID, error) {
	u := UUID{}

	_, err := rand.Read(u[:])
	if err != nil {
		return u, err
	}

	u[8] = (u[8] | 0x80) & 0xBF
	u[6] = (u[6] | 0x40) & 0x4F

	return u, nil
}

// FromString reads a UUID into a new UUID instance
func FromString(str string) (UUID, error) {
	u := UUID{}

	err := u.SetString(str)

	return u, err
}

// SetString reads the supplied string-representation of the UUID into the instance.
// On invalid UUID an error is returned and the UUID state will be undetermined.
// This function will ignore all non-hexadecimal digits.
func (u *UUID) SetString(str string) error {
	i := 0
	x := 0
	c := len(str)

	for x < c {
		if x+1 >= c || i >= 16 {
			return &ErrTooShort{x, i, c}
		}

		if v, ok := hex2byte(str[x:]); ok {
			u[i] = v

			x += 2
			i++
		} else {
			x++
		}
	}

	if i != 16 {
		return &ErrTooLong{x, i, c}
	}

	return nil
}

// IsZero returns true if the UUID is zero
func (u UUID) IsZero() bool {
	return u == zero
}

// String returns the string representation of the UUID
func (u UUID) String() string {
	return fmt.Sprintf("%8.x-%4.x-%4.x-%4.x-%12.x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:16])
}
<commit_msg>SetString: Made it possible to have trailing non-hex characters, improved error handling, also detects malformed hexadecimal bytes<commit_after>// Package uuid implements a fast UUID representation and integrates with JSON and SQL drivers
package uuid

import (
	"crypto/rand"
	"fmt"
)

// UUID represents a Universally-Unique-Identifier
type UUID [16]byte

var zero = [16]byte{}

type scanError struct {
	scanned int
	bytes   int
	length  int
}

type ErrTooShort scanError

func (e *ErrTooShort) Error() string {
	return fmt.Sprintf("invalid UUID: too few bytes (scanned: %d, length: %d, bytes: %d)", e.scanned, e.length, e.bytes)
}

type ErrTooLong scanError

func (e *ErrTooLong) Error() string {
	return fmt.Sprintf("invalid UUID: too many bytes (scanned: %d, length: %d, bytes: %d)", e.scanned, e.length, e.bytes)
}

type ErrUneven scanError

func (e *ErrUneven) Error() string {
	return fmt.Sprintf("invalid UUID: uneven hexadecimal bytes (scanned: %d, length: %d, bytes: %d)", e.scanned, e.length, e.bytes)
}

// hexchar2byte contains the integer byte-value represented by a hexadecimal character,
// 255 if it is an invalid character
var hexchar2byte = []byte{
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255,
	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
	255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
}

// hex2byte reads the first two bytes of the input string and returns the byte matched
// by their hexadecimal value
func hex2byte(x string) (byte, bool) {
	a := hexchar2byte[x[0]]
	b := hexchar2byte[x[1]]

	return (a << 4) | b, a != 255 && b != 255
}

// V4 creates a new random UUID with data from crypto/rand.Read
func V4() (UUID, error) {
	u := UUID{}

	_, err := rand.Read(u[:])
	if err != nil {
		return u, err
	}

	u[8] = (u[8] | 0x80) & 0xBF
	u[6] = (u[6] | 0x40) & 0x4F

	return u, nil
}

// FromString reads a UUID into a new UUID instance
func FromString(str string) (UUID, error) {
	u := UUID{}

	err := u.SetString(str)

	return u, err
}

// SetString reads the supplied string-representation of the UUID into the instance.
// On invalid UUID an error is returned and the UUID state will be undetermined.
// This function will ignore all non-hexadecimal digits.
func (u *UUID) SetString(str string) error {
	i := 0
	x := 0
	c := len(str)

	for x < c {
		a := hexchar2byte[str[x]]
		if a == 255 {
			// Invalid char, skip
			x++

			continue
		}

		// We need to perform this check after the attempted hex-read in case
		// we have trailing "}" characters
		if i >= 16 {
			return &ErrTooLong{x, i, c}
		}
		if x+1 >= c {
			// Not enough to scan
			return &ErrTooShort{x, i, c}
		}

		b := hexchar2byte[str[x+1]]
		if b == 255 {
			// Uneven hexadecimal byte
			return &ErrUneven{x, i, c}
		}

		u[i] = (a << 4) | b

		x += 2
		i++
	}

	if i != 16 {
		// Can only be too short here
		return &ErrTooShort{x, i, c}
	}

	return nil
}

// IsZero returns true if the UUID is zero
func (u UUID) IsZero() bool {
	return u == zero
}

// String returns the string representation of the UUID
func (u UUID) String() string {
	return fmt.Sprintf("%8.x-%4.x-%4.x-%4.x-%12.x", u[0:4], u[4:6], u[6:8], u[8:10], u[10:16])
}
<|endoftext|>


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

package buildkite

import "time"

// BuildKiteDateFormat is the format of the dates used throughout the
// api, note this odd string is used to parse/format dates in go
const BuildKiteDateFormat = time.RFC3339Nano

// Timestamp custom timestamp to support buildkite api timestamps
type Timestamp struct {
	time.Time
}

// NewTimestamp make a new timestamp using the time suplied.
func NewTimestamp(t time.Time) *Timestamp {
	return &Timestamp{t}
}

func (ts Timestamp) String() string {
	return ts.Time.String()
}

// MarshalJSON implements the json.Marshaler interface.
func (ts Timestamp) MarshalJSON() ([]byte, error) {
	return []byte(ts.Format(`"` + BuildKiteDateFormat + `"`)), nil
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (ts *Timestamp) UnmarshalJSON(data []byte) (err error) {
	(*ts).Time, err = time.Parse(`"`+BuildKiteDateFormat+`"`, string(data))
	return
}

// Equal reports whether t and u are equal based on time.Equal
func (ts Timestamp) Equal(u Timestamp) bool {
	return ts.Time.Equal(u.Time)
}
<commit_msg>Parse the timestamp format webhooks use<commit_after>// Copyright 2014 Mark Wolfe. All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package buildkite

import "time"

// BuildKiteDateFormat is the format of the dates used throughout the
// api, note this odd string is used to parse/format dates in go
const BuildKiteDateFormat = time.RFC3339Nano

// BuildKiteEventDateFormat is the format of the dates used in webhook events.
const BuildKiteEventDateFormat = "2006-01-02 15:04:05 MST"

// Timestamp custom timestamp to support buildkite api timestamps
type Timestamp struct {
	time.Time
}

// NewTimestamp make a new timestamp using the time suplied.
func NewTimestamp(t time.Time) *Timestamp {
	return &Timestamp{t}
}

func (ts Timestamp) String() string {
	return ts.Time.String()
}

// MarshalJSON implements the json.Marshaler interface.
func (ts Timestamp) MarshalJSON() ([]byte, error) {
	return []byte(ts.Format(`"` + BuildKiteDateFormat + `"`)), nil
}

// UnmarshalJSON implements the json.Unmarshaler interface.
func (ts *Timestamp) UnmarshalJSON(data []byte) (err error) {
	(*ts).Time, err = time.Parse(`"`+BuildKiteDateFormat+`"`, string(data))
	if err != nil {
		// try the webhook format too; avoid clobbering the error if both fail
		t, err2 := time.Parse(`"`+BuildKiteEventDateFormat+`"`, string(data))
		if err2 == nil {
			(*ts).Time = t
			err = err2
		}
	}
	return
}

// Equal reports whether t and u are equal based on time.Equal
func (ts Timestamp) Equal(u Timestamp) bool {
	return ts.Time.Equal(u.Time)
}
<|endoftext|>


<commit_before>package handlers

import (
	"bytes"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	log "github.com/Sirupsen/logrus"
	"io/ioutil"
	"net/http"

	"github.com/stellar/gateway/protocols"
	"github.com/stellar/gateway/protocols/compliance"
	"github.com/stellar/gateway/protocols/memo"
	"github.com/stellar/gateway/server"
	"github.com/stellar/gateway/submitter"
	b "github.com/stellar/go-stellar-base/build"
	"github.com/stellar/go-stellar-base/xdr"
	"github.com/zenazn/goji/web"
)

// HandlerSend implements /send endpoint
func (rh *RequestHandler) HandlerSend(c web.C, w http.ResponseWriter, r *http.Request) {
	request := &compliance.SendRequest{}
	request.FromRequest(r)

	err := request.Validate()
	if err != nil {
		errorResponse := err.(*protocols.ErrorResponse)
		log.WithFields(errorResponse.LogData).Error(errorResponse.Error())
		server.Write(w, errorResponse)
		return
	}

	destinationObject, stellarToml, err := rh.FederationResolver.Resolve(request.Destination)
	if err != nil {
		log.WithFields(log.Fields{
			"destination": request.Destination,
			"err":         err,
		}).Print("Cannot resolve address")
		server.Write(w, compliance.CannotResolveDestination)
		return
	}

	if stellarToml.AuthServer == "" {
		log.Print("No AUTH_SERVER in stellar.toml")
		server.Write(w, compliance.AuthServerNotDefined)
		return
	}

	var payWithMutator *b.PayWithPath

	if request.SendMax != "" {
		// Path payment
		var sendAsset b.Asset
		if request.SendAssetCode != "" && request.SendAssetIssuer != "" {
			sendAsset = b.CreditAsset(request.SendAssetCode, request.SendAssetIssuer)
		} else if request.SendAssetCode == "" && request.SendAssetIssuer == "" {
			sendAsset = b.NativeAsset()
		} else {
			log.Print("Missing send asset param.")
			server.Write(w, protocols.MissingParameterError)
			return
		}

		payWith := b.PayWith(sendAsset, request.SendMax)

		for _, asset := range request.Path {
			if asset.Code == "" && asset.Issuer == "" {
				payWith = payWith.Through(b.NativeAsset())
			} else {
				payWith = payWith.Through(b.CreditAsset(asset.Code, asset.Issuer))
			}
		}

		payWithMutator = &payWith
	}

	mutators := []interface{}{
		b.Destination{destinationObject.AccountID},
		b.CreditAmount{
			request.AssetCode,
			request.AssetIssuer,
			request.Amount,
		},
	}

	if payWithMutator != nil {
		mutators = append(mutators, *payWithMutator)
	}

	operationMutator := b.Payment(mutators...)
	if operationMutator.Err != nil {
		log.WithFields(log.Fields{
			"err": operationMutator.Err,
		}).Error("Error creating operation")
		server.Write(w, protocols.InternalServerError)
		return
	}

	// Fetch Sender Info
	fetchInfoRequest := compliance.FetchInfoRequest{Address: request.Sender}
	resp, err := rh.Client.PostForm(
		rh.Config.Callbacks.FetchInfo,
		fetchInfoRequest.ToValues(),
	)
	if err != nil {
		log.WithFields(log.Fields{
			"fetch_info": rh.Config.Callbacks.FetchInfo,
			"err":        err,
		}).Error("Error sending request to fetch_info server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.WithFields(log.Fields{
			"fetch_info": rh.Config.Callbacks.FetchInfo,
			"err":        err,
		}).Error("Error reading fetch_info server response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	if resp.StatusCode != http.StatusOK {
		log.WithFields(log.Fields{
			"fetch_info": rh.Config.Callbacks.FetchInfo,
			"status":     resp.StatusCode,
			"body":       string(body),
		}).Error("Error response from fetch_info server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	memoPreimage := &memo.Memo{
		Transaction: memo.Transaction{
			SenderInfo: string(body),
			Route:      request.Destination,
			Extra:      request.ExtraMemo,
		},
	}

	memoJSON := memoPreimage.Marshal()
	memoHashBytes := sha256.Sum256(memoJSON)
	memoMutator := &b.MemoHash{xdr.Hash(memoHashBytes)}

	transaction, err := submitter.BuildTransaction(
		request.Source,
		rh.Config.NetworkPassphrase,
		operationMutator,
		memoMutator,
	)

	var txBytes bytes.Buffer
	_, err = xdr.Marshal(&txBytes, transaction)
	if err != nil {
		log.Error("Error mashaling transaction")
		server.Write(w, protocols.InternalServerError)
		return
	}

	txBase64 := base64.StdEncoding.EncodeToString(txBytes.Bytes())

	authData := compliance.AuthData{
		Sender:   request.Sender,
		NeedInfo: rh.Config.NeedsAuth,
		Tx:       txBase64,
		Memo:     string(memoJSON),
	}

	data, err := json.Marshal(authData)
	if err != nil {
		log.Error("Error mashaling authData")
		server.Write(w, protocols.InternalServerError)
		return
	}

	sig, err := rh.SignatureSignerVerifier.Sign(rh.Config.Keys.SigningSeed, data)
	if err != nil {
		log.Error("Error signing authData")
		server.Write(w, protocols.InternalServerError)
		return
	}

	authRequest := compliance.AuthRequest{
		Data:      string(data),
		Signature: sig,
	}
	resp, err = rh.Client.PostForm(
		stellarToml.AuthServer,
		authRequest.ToValues(),
	)
	if err != nil {
		log.WithFields(log.Fields{
			"auth_server": stellarToml.AuthServer,
			"err":         err,
		}).Error("Error sending request to auth server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	defer resp.Body.Close()
	body, err = ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Error("Error reading auth server response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	if resp.StatusCode != 200 {
		log.WithFields(log.Fields{
			"status": resp.StatusCode,
			"body":   string(body),
		}).Error("Error response from auth server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	var authResponse compliance.AuthResponse
	err = json.Unmarshal(body, &authResponse)
	if err != nil {
		log.WithFields(log.Fields{
			"status": resp.StatusCode,
			"body":   string(body),
		}).Error("Error unmarshalling auth response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	response := compliance.SendResponse{
		AuthResponse:   authResponse,
		TransactionXdr: txBase64,
	}
	server.Write(w, &response)
}
<commit_msg>Do not send FetchInfo request in /send when not set<commit_after>package handlers

import (
	"bytes"
	"crypto/sha256"
	"encoding/base64"
	"encoding/json"
	log "github.com/Sirupsen/logrus"
	"io/ioutil"
	"net/http"

	"github.com/stellar/gateway/protocols"
	"github.com/stellar/gateway/protocols/compliance"
	"github.com/stellar/gateway/protocols/memo"
	"github.com/stellar/gateway/server"
	"github.com/stellar/gateway/submitter"
	b "github.com/stellar/go-stellar-base/build"
	"github.com/stellar/go-stellar-base/xdr"
	"github.com/zenazn/goji/web"
)

// HandlerSend implements /send endpoint
func (rh *RequestHandler) HandlerSend(c web.C, w http.ResponseWriter, r *http.Request) {
	request := &compliance.SendRequest{}
	request.FromRequest(r)

	err := request.Validate()
	if err != nil {
		errorResponse := err.(*protocols.ErrorResponse)
		log.WithFields(errorResponse.LogData).Error(errorResponse.Error())
		server.Write(w, errorResponse)
		return
	}

	destinationObject, stellarToml, err := rh.FederationResolver.Resolve(request.Destination)
	if err != nil {
		log.WithFields(log.Fields{
			"destination": request.Destination,
			"err":         err,
		}).Print("Cannot resolve address")
		server.Write(w, compliance.CannotResolveDestination)
		return
	}

	if stellarToml.AuthServer == "" {
		log.Print("No AUTH_SERVER in stellar.toml")
		server.Write(w, compliance.AuthServerNotDefined)
		return
	}

	var payWithMutator *b.PayWithPath

	if request.SendMax != "" {
		// Path payment
		var sendAsset b.Asset
		if request.SendAssetCode != "" && request.SendAssetIssuer != "" {
			sendAsset = b.CreditAsset(request.SendAssetCode, request.SendAssetIssuer)
		} else if request.SendAssetCode == "" && request.SendAssetIssuer == "" {
			sendAsset = b.NativeAsset()
		} else {
			log.Print("Missing send asset param.")
			server.Write(w, protocols.MissingParameterError)
			return
		}

		payWith := b.PayWith(sendAsset, request.SendMax)

		for _, asset := range request.Path {
			if asset.Code == "" && asset.Issuer == "" {
				payWith = payWith.Through(b.NativeAsset())
			} else {
				payWith = payWith.Through(b.CreditAsset(asset.Code, asset.Issuer))
			}
		}

		payWithMutator = &payWith
	}

	mutators := []interface{}{
		b.Destination{destinationObject.AccountID},
		b.CreditAmount{
			request.AssetCode,
			request.AssetIssuer,
			request.Amount,
		},
	}

	if payWithMutator != nil {
		mutators = append(mutators, *payWithMutator)
	}

	operationMutator := b.Payment(mutators...)
	if operationMutator.Err != nil {
		log.WithFields(log.Fields{
			"err": operationMutator.Err,
		}).Error("Error creating operation")
		server.Write(w, protocols.InternalServerError)
		return
	}

	// Fetch Sender Info
	senderInfo := ""

	if rh.Config.Callbacks.FetchInfo != "" {
		fetchInfoRequest := compliance.FetchInfoRequest{Address: request.Sender}
		resp, err := rh.Client.PostForm(
			rh.Config.Callbacks.FetchInfo,
			fetchInfoRequest.ToValues(),
		)
		if err != nil {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"err":        err,
			}).Error("Error sending request to fetch_info server")
			server.Write(w, protocols.InternalServerError)
			return
		}

		defer resp.Body.Close()
		body, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"err":        err,
			}).Error("Error reading fetch_info server response")
			server.Write(w, protocols.InternalServerError)
			return
		}

		if resp.StatusCode != http.StatusOK {
			log.WithFields(log.Fields{
				"fetch_info": rh.Config.Callbacks.FetchInfo,
				"status":     resp.StatusCode,
				"body":       string(body),
			}).Error("Error response from fetch_info server")
			server.Write(w, protocols.InternalServerError)
			return
		}

		senderInfo = string(body)
	}

	memoPreimage := &memo.Memo{
		Transaction: memo.Transaction{
			SenderInfo: senderInfo,
			Route:      request.Destination,
			Extra:      request.ExtraMemo,
		},
	}

	memoJSON := memoPreimage.Marshal()
	memoHashBytes := sha256.Sum256(memoJSON)
	memoMutator := &b.MemoHash{xdr.Hash(memoHashBytes)}

	transaction, err := submitter.BuildTransaction(
		request.Source,
		rh.Config.NetworkPassphrase,
		operationMutator,
		memoMutator,
	)

	var txBytes bytes.Buffer
	_, err = xdr.Marshal(&txBytes, transaction)
	if err != nil {
		log.Error("Error mashaling transaction")
		server.Write(w, protocols.InternalServerError)
		return
	}

	txBase64 := base64.StdEncoding.EncodeToString(txBytes.Bytes())

	authData := compliance.AuthData{
		Sender:   request.Sender,
		NeedInfo: rh.Config.NeedsAuth,
		Tx:       txBase64,
		Memo:     string(memoJSON),
	}

	data, err := json.Marshal(authData)
	if err != nil {
		log.Error("Error mashaling authData")
		server.Write(w, protocols.InternalServerError)
		return
	}

	sig, err := rh.SignatureSignerVerifier.Sign(rh.Config.Keys.SigningSeed, data)
	if err != nil {
		log.Error("Error signing authData")
		server.Write(w, protocols.InternalServerError)
		return
	}

	authRequest := compliance.AuthRequest{
		Data:      string(data),
		Signature: sig,
	}
	resp, err := rh.Client.PostForm(
		stellarToml.AuthServer,
		authRequest.ToValues(),
	)
	if err != nil {
		log.WithFields(log.Fields{
			"auth_server": stellarToml.AuthServer,
			"err":         err,
		}).Error("Error sending request to auth server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		log.Error("Error reading auth server response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	if resp.StatusCode != 200 {
		log.WithFields(log.Fields{
			"status": resp.StatusCode,
			"body":   string(body),
		}).Error("Error response from auth server")
		server.Write(w, protocols.InternalServerError)
		return
	}

	var authResponse compliance.AuthResponse
	err = json.Unmarshal(body, &authResponse)
	if err != nil {
		log.WithFields(log.Fields{
			"status": resp.StatusCode,
			"body":   string(body),
		}).Error("Error unmarshalling auth response")
		server.Write(w, protocols.InternalServerError)
		return
	}

	response := compliance.SendResponse{
		AuthResponse:   authResponse,
		TransactionXdr: txBase64,
	}
	server.Write(w, &response)
}
<|endoftext|>


<commit_before>package caddyfile

import (
	"errors"
	"fmt"
	"io"
	"strings"
)

// Dispenser is a type that dispenses tokens, similarly to a lexer,
// except that it can do so with some notion of structure and has
// some really convenient methods.
type Dispenser struct {
	filename string
	tokens   []Token
	cursor   int
	nesting  int
}

// NewDispenser returns a Dispenser, ready to use for parsing the given input.
func NewDispenser(filename string, input io.Reader) Dispenser {
	tokens, _ := allTokens(input) // ignoring error because nothing to do with it
	return Dispenser{
		filename: filename,
		tokens:   tokens,
		cursor:   -1,
	}
}

// NewDispenserTokens returns a Dispenser filled with the given tokens.
func NewDispenserTokens(filename string, tokens []Token) Dispenser {
	return Dispenser{
		filename: filename,
		tokens:   tokens,
		cursor:   -1,
	}
}

// Next loads the next token. Returns true if a token
// was loaded; false otherwise. If false, all tokens
// have been consumed.
func (d *Dispenser) Next() bool {
	if d.cursor < len(d.tokens)-1 {
		d.cursor++
		return true
	}
	return false
}

// NextArg loads the next token if it is on the same
// line. Returns true if a token was loaded; false
// otherwise. If false, all tokens on the line have
// been consumed. It handles imported tokens correctly.
func (d *Dispenser) NextArg() bool {
	if d.cursor < 0 {
		d.cursor++
		return true
	}
	if d.cursor >= len(d.tokens) {
		return false
	}
	if d.cursor < len(d.tokens)-1 &&
		d.tokens[d.cursor].File == d.tokens[d.cursor+1].File &&
		d.tokens[d.cursor].Line+d.numLineBreaks(d.cursor) == d.tokens[d.cursor+1].Line {
		d.cursor++
		return true
	}
	return false
}

// NextLine loads the next token only if it is not on the same
// line as the current token, and returns true if a token was
// loaded; false otherwise. If false, there is not another token
// or it is on the same line. It handles imported tokens correctly.
func (d *Dispenser) NextLine() bool {
	if d.cursor < 0 {
		d.cursor++
		return true
	}
	if d.cursor >= len(d.tokens) {
		return false
	}
	if d.cursor < len(d.tokens)-1 &&
		(d.tokens[d.cursor].File != d.tokens[d.cursor+1].File ||
			d.tokens[d.cursor].Line+d.numLineBreaks(d.cursor) < d.tokens[d.cursor+1].Line) {
		d.cursor++
		return true
	}
	return false
}

// NextBlock can be used as the condition of a for loop
// to load the next token as long as it opens a block or
// is already in a block. It returns true if a token was
// loaded, or false when the block's closing curly brace
// was loaded and thus the block ended. Nested blocks are
// not supported.
func (d *Dispenser) NextBlock() bool {
	if d.nesting > 0 {
		d.Next()
		if d.Val() == "}" {
			d.nesting--
			return false
		}
		return true
	}
	if !d.NextArg() { // block must open on same line
		return false
	}
	if d.Val() != "{" {
		d.cursor-- // roll back if not opening brace
		return false
	}
	d.Next()
	if d.Val() == "}" {
		// Open and then closed right away
		return false
	}
	d.nesting++
	return true
}

// Val gets the text of the current token. If there is no token
// loaded, it returns empty string.
func (d *Dispenser) Val() string {
	if d.cursor < 0 || d.cursor >= len(d.tokens) {
		return ""
	}
	return d.tokens[d.cursor].Text
}

// Line gets the line number of the current token. If there is no token
// loaded, it returns 0.
func (d *Dispenser) Line() int {
	if d.cursor < 0 || d.cursor >= len(d.tokens) {
		return 0
	}
	return d.tokens[d.cursor].Line
}

// File gets the filename of the current token. If there is no token loaded,
// it returns the filename originally given when parsing started.
func (d *Dispenser) File() string {
	if d.cursor < 0 || d.cursor >= len(d.tokens) {
		return d.filename
	}
	if tokenFilename := d.tokens[d.cursor].File; tokenFilename != "" {
		return tokenFilename
	}
	return d.filename
}

// Args is a convenience function that loads the next arguments
// (tokens on the same line) into an arbitrary number of strings
// pointed to in targets. If there are fewer tokens available
// than string pointers, the remaining strings will not be changed
// and false will be returned. If there were enough tokens available
// to fill the arguments, then true will be returned.
func (d *Dispenser) Args(targets ...*string) bool {
	enough := true
	for i := 0; i < len(targets); i++ {
		if !d.NextArg() {
			enough = false
			break
		}
		*targets[i] = d.Val()
	}
	return enough
}

// RemainingArgs loads any more arguments (tokens on the same line)
// into a slice and returns them. Open curly brace tokens also indicate
// the end of arguments, and the curly brace is not included in
// the return value nor is it loaded.
func (d *Dispenser) RemainingArgs() []string {
	var args []string

	for d.NextArg() {
		if d.Val() == "{" {
			d.cursor--
			break
		}
		args = append(args, d.Val())
	}

	return args
}

// ArgErr returns an argument error, meaning that another
// argument was expected but not found. In other words,
// a line break or open curly brace was encountered instead of
// an argument.
func (d *Dispenser) ArgErr() error {
	if d.Val() == "{" {
		return d.Err("Unexpected token '{', expecting argument")
	}
	return d.Errf("Wrong argument count or unexpected line ending after '%s'", d.Val())
}

// SyntaxErr creates a generic syntax error which explains what was
// found and what was expected.
func (d *Dispenser) SyntaxErr(expected string) error {
	msg := fmt.Sprintf("%s:%d - Syntax error: Unexpected token '%s', expecting '%s'", d.File(), d.Line(), d.Val(), expected)
	return errors.New(msg)
}

// EOFErr returns an error indicating that the dispenser reached
// the end of the input when searching for the next token.
func (d *Dispenser) EOFErr() error {
	return d.Errf("Unexpected EOF")
}

// Err generates a custom parse error with a message of msg.
func (d *Dispenser) Err(msg string) error {
	msg = fmt.Sprintf("%s:%d - Parse error: %s", d.File(), d.Line(), msg)
	return errors.New(msg)
}

// Errf is like Err, but for formatted error messages
func (d *Dispenser) Errf(format string, args ...interface{}) error {
	return d.Err(fmt.Sprintf(format, args...))
}

// numLineBreaks counts how many line breaks are in the token
// value given by the token index tknIdx. It returns 0 if the
// token does not exist or there are no line breaks.
func (d *Dispenser) numLineBreaks(tknIdx int) int {
	if tknIdx < 0 || tknIdx >= len(d.tokens) {
		return 0
	}
	return strings.Count(d.tokens[tknIdx].Text, "\n")
}

// isNewLine determines whether the current token is on a different
// line (higher line number) than the previous token. It handles imported
// tokens correctly. If there isn't a previous token, it returns true.
func (d *Dispenser) isNewLine() bool {
	if d.cursor < 1 {
		return true
	}
	if d.cursor > len(d.tokens)-1 {
		return false
	}
	return d.tokens[d.cursor-1].File != d.tokens[d.cursor].File ||
		d.tokens[d.cursor-1].Line+d.numLineBreaks(d.cursor-1) < d.tokens[d.cursor].Line
}
<commit_msg>Revert removed method<commit_after>package caddyfile

import (
	"errors"
	"fmt"
	"io"
	"strings"
)

// Dispenser is a type that dispenses tokens, similarly to a lexer,
// except that it can do so with some notion of structure and has
// some really convenient methods.
type Dispenser struct {
	filename string
	tokens   []Token
	cursor   int
	nesting  int
}

// NewDispenser returns a Dispenser, ready to use for parsing the given input.
func NewDispenser(filename string, input io.Reader) Dispenser {
	tokens, _ := allTokens(input) // ignoring error because nothing to do with it
	return Dispenser{
		filename: filename,
		tokens:   tokens,
		cursor:   -1,
	}
}

// NewDispenserTokens returns a Dispenser filled with the given tokens.
func NewDispenserTokens(filename string, tokens []Token) Dispenser {
	return Dispenser{
		filename: filename,
		tokens:   tokens,
		cursor:   -1,
	}
}

// Next loads the next token. Returns true if a token
// was loaded; false otherwise. If false, all tokens
// have been consumed.
func (d *Dispenser) Next() bool {
	if d.cursor < len(d.tokens)-1 {
		d.cursor++
		return true
	}
	return false
}

// NextArg loads the next token if it is on the same
// line. Returns true if a token was loaded; false
// otherwise. If false, all tokens on the line have
// been consumed. It handles imported tokens correctly.
func (d *Dispenser) NextArg() bool {
	if d.cursor < 0 {
		d.cursor++
		return true
	}
	if d.cursor >= len(d.tokens) {
		return false
	}
	if d.cursor < len(d.tokens)-1 &&
		d.tokens[d.cursor].File == d.tokens[d.cursor+1].File &&
		d.tokens[d.cursor].Line+d.numLineBreaks(d.cursor) == d.tokens[d.cursor+1].Line {
		d.cursor++
		return true
	}
	return false
}

// NextLine loads the next token only if it is not on the same
// line as the current token, and returns true if a token was
// loaded; false otherwise. If false, there is not another token
// or it is on the same line. It handles imported tokens correctly.
func (d *Dispenser) NextLine() bool {
	if d.cursor < 0 {
		d.cursor++
		return true
	}
	if d.cursor >= len(d.tokens) {
		return false
	}
	if d.cursor < len(d.tokens)-1 &&
		(d.tokens[d.cursor].File != d.tokens[d.cursor+1].File ||
			d.tokens[d.cursor].Line+d.numLineBreaks(d.cursor) < d.tokens[d.cursor+1].Line) {
		d.cursor++
		return true
	}
	return false
}

// NextBlock can be used as the condition of a for loop
// to load the next token as long as it opens a block or
// is already in a block. It returns true if a token was
// loaded, or false when the block's closing curly brace
// was loaded and thus the block ended. Nested blocks are
// not supported.
func (d *Dispenser) NextBlock() bool {
	if d.nesting > 0 {
		d.Next()
		if d.Val() == "}" {
			d.nesting--
			return false
		}
		return true
	}
	if !d.NextArg() { // block must open on same line
		return false
	}
	if d.Val() != "{" {
		d.cursor-- // roll back if not opening brace
		return false
	}
	d.Next()
	if d.Val() == "}" {
		// Open and then closed right away
		return false
	}
	d.nesting++
	return true
}

// IncrNest adds a level of nesting to the dispenser.
func (d *Dispenser) IncrNest() {
	d.nesting++
	return
}

// Val gets the text of the current token. If there is no token
// loaded, it returns empty string.
func (d *Dispenser) Val() string {
	if d.cursor < 0 || d.cursor >= len(d.tokens) {
		return ""
	}
	return d.tokens[d.cursor].Text
}

// Line gets the line number of the current token. If there is no token
// loaded, it returns 0.
func (d *Dispenser) Line() int {
	if d.cursor < 0 || d.cursor >= len(d.tokens) {
		return 0
	}
	return d.tokens[d.cursor].Line
}

// File gets the filename of the current token. If there is no token loaded,
// it returns the filename originally given when parsing started.
func (d *Dispenser) File() string {
	if d.cursor < 0 || d.cursor >= len(d.tokens) {
		return d.filename
	}
	if tokenFilename := d.tokens[d.cursor].File; tokenFilename != "" {
		return tokenFilename
	}
	return d.filename
}

// Args is a convenience function that loads the next arguments
// (tokens on the same line) into an arbitrary number of strings
// pointed to in targets. If there are fewer tokens available
// than string pointers, the remaining strings will not be changed
// and false will be returned. If there were enough tokens available
// to fill the arguments, then true will be returned.
func (d *Dispenser) Args(targets ...*string) bool {
	enough := true
	for i := 0; i < len(targets); i++ {
		if !d.NextArg() {
			enough = false
			break
		}
		*targets[i] = d.Val()
	}
	return enough
}

// RemainingArgs loads any more arguments (tokens on the same line)
// into a slice and returns them. Open curly brace tokens also indicate
// the end of arguments, and the curly brace is not included in
// the return value nor is it loaded.
func (d *Dispenser) RemainingArgs() []string {
	var args []string

	for d.NextArg() {
		if d.Val() == "{" {
			d.cursor--
			break
		}
		args = append(args, d.Val())
	}

	return args
}

// ArgErr returns an argument error, meaning that another
// argument was expected but not found. In other words,
// a line break or open curly brace was encountered instead of
// an argument.
func (d *Dispenser) ArgErr() error {
	if d.Val() == "{" {
		return d.Err("Unexpected token '{', expecting argument")
	}
	return d.Errf("Wrong argument count or unexpected line ending after '%s'", d.Val())
}

// SyntaxErr creates a generic syntax error which explains what was
// found and what was expected.
func (d *Dispenser) SyntaxErr(expected string) error {
	msg := fmt.Sprintf("%s:%d - Syntax error: Unexpected token '%s', expecting '%s'", d.File(), d.Line(), d.Val(), expected)
	return errors.New(msg)
}

// EOFErr returns an error indicating that the dispenser reached
// the end of the input when searching for the next token.
func (d *Dispenser) EOFErr() error {
	return d.Errf("Unexpected EOF")
}

// Err generates a custom parse error with a message of msg.
func (d *Dispenser) Err(msg string) error {
	msg = fmt.Sprintf("%s:%d - Parse error: %s", d.File(), d.Line(), msg)
	return errors.New(msg)
}

// Errf is like Err, but for formatted error messages
func (d *Dispenser) Errf(format string, args ...interface{}) error {
	return d.Err(fmt.Sprintf(format, args...))
}

// numLineBreaks counts how many line breaks are in the token
// value given by the token index tknIdx. It returns 0 if the
// token does not exist or there are no line breaks.
func (d *Dispenser) numLineBreaks(tknIdx int) int {
	if tknIdx < 0 || tknIdx >= len(d.tokens) {
		return 0
	}
	return strings.Count(d.tokens[tknIdx].Text, "\n")
}

// isNewLine determines whether the current token is on a different
// line (higher line number) than the previous token. It handles imported
// tokens correctly. If there isn't a previous token, it returns true.
func (d *Dispenser) isNewLine() bool {
	if d.cursor < 1 {
		return true
	}
	if d.cursor > len(d.tokens)-1 {
		return false
	}
	return d.tokens[d.cursor-1].File != d.tokens[d.cursor].File ||
		d.tokens[d.cursor-1].Line+d.numLineBreaks(d.cursor-1) < d.tokens[d.cursor].Line
}
<|endoftext|>


<commit_before>package integrationtests_test

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"syscall"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("containerising processes", func() {
	var (
		vmDir string
	)

	runCommandInVM := func(shellCmd string) (int, string, error) {
		containerCmd := exec.Command("vagrant", "ssh", "-c", shellCmd)
		containerCmd.Dir = vmDir
		var stdout bytes.Buffer
		containerCmd.Stdout = io.MultiWriter(&stdout, GinkgoWriter)
		containerCmd.Stderr = GinkgoWriter
		if err := containerCmd.Run(); err != nil {
			if exitErr, ok := err.(*exec.ExitError); ok {
				return exitErr.Sys().(syscall.WaitStatus).ExitStatus(), stdout.String(), nil
			}

			return 0, "", err
		}

		return 0, stdout.String(), nil
	}

	runCommandInContainer := func(containerCmd ...string) (int, string, error) {
		shellCmd := "sudo /go/bin/linux_amd64/container-run -rootFS /root/rootfs/jessie"
		for _, term := range containerCmd {
			shellCmd = fmt.Sprintf("%s '%s'", shellCmd, term)
		}
		return runCommandInVM(shellCmd)
	}

	BeforeEach(func() {
		vmDir = os.Getenv("VM_DIR")
		Expect(vmDir).NotTo(BeEmpty())
	})

	It("runs the process in a UTS namespace", func() {
		exitStatus, stdout, err := runCommandInContainer("bash", "-c", "hostname new-hostname && hostname")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(Equal("new-hostname\n"))
		exitStatus, stdout, err = runCommandInVM("hostname")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(Equal("ubuntu-xenial\n"))
	})

	It("runs the process in a PID namespace", func() {
		exitStatus, stdout, err := runCommandInContainer("ps", "-lfp", "1")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(ContainSubstring("/proc/self/exe /root/rootfs/jessie ps -lfp 1"))
	})

	It("runs the process with a Debian rootFS", func() {
		exitStatus, stdout, err := runCommandInContainer("cat", "/etc/os-release")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(ContainSubstring("Debian GNU/Linux 8 (jessie)"))
	})
})
<commit_msg>test that process is run in a mount namespace<commit_after>package integrationtests_test

import (
	"bytes"
	"fmt"
	"io"
	"os"
	"os/exec"
	"syscall"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("containerising processes", func() {
	var (
		vmDir string
	)

	runCommandInVM := func(shellCmd string) (int, string, error) {
		containerCmd := exec.Command("vagrant", "ssh", "-c", shellCmd)
		containerCmd.Dir = vmDir
		var stdout bytes.Buffer
		containerCmd.Stdout = io.MultiWriter(&stdout, GinkgoWriter)
		containerCmd.Stderr = GinkgoWriter
		if err := containerCmd.Run(); err != nil {
			if exitErr, ok := err.(*exec.ExitError); ok {
				return exitErr.Sys().(syscall.WaitStatus).ExitStatus(), stdout.String(), nil
			}

			return 0, "", err
		}

		return 0, stdout.String(), nil
	}

	runCommandInContainer := func(containerCmd ...string) (int, string, error) {
		shellCmd := "sudo /go/bin/linux_amd64/container-run -rootFS /root/rootfs/jessie"
		for _, term := range containerCmd {
			shellCmd = fmt.Sprintf("%s '%s'", shellCmd, term)
		}
		return runCommandInVM(shellCmd)
	}

	BeforeEach(func() {
		vmDir = os.Getenv("VM_DIR")
		Expect(vmDir).NotTo(BeEmpty())
	})

	It("runs the process in a UTS namespace", func() {
		exitStatus, stdout, err := runCommandInContainer("bash", "-c", "hostname new-hostname && hostname")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(Equal("new-hostname\n"))
		exitStatus, stdout, err = runCommandInVM("hostname")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(Equal("ubuntu-xenial\n"))
	})

	It("runs the process in a PID namespace", func() {
		exitStatus, stdout, err := runCommandInContainer("ps", "-lfp", "1")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(ContainSubstring("/proc/self/exe /root/rootfs/jessie ps -lfp 1"))
	})

	It("runs the process in a mount namespace", func() {
		exitStatus, stdout, err := runCommandInContainer("bash", "-c", "mount -t tmpfs tmpfs /tmp && cat /proc/self/mounts")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(ContainSubstring("tmpfs /tmp"))
		exitStatus, stdout, err = runCommandInVM("cat /proc/self/mounts")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).NotTo(ContainSubstring("tmpfs /tmp"))
	})

	It("runs the process with a Debian rootFS", func() {
		exitStatus, stdout, err := runCommandInContainer("cat", "/etc/os-release")
		Expect(err).NotTo(HaveOccurred())
		Expect(exitStatus).To(Equal(0))
		Expect(stdout).To(ContainSubstring("Debian GNU/Linux 8 (jessie)"))
	})
})
<|endoftext|>


<commit_before>package channel

import (
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/api/modules/helpers"

	"github.com/jinzhu/gorm"
)

func validateChannelRequest(c *models.Channel) error {
	if c.GroupName == "" {
		return errors.New("Group name is not set")
	}

	if c.Name == "" {
		return errors.New("Channel name is not set")
	}

	if c.CreatorId == 0 {
		return errors.New("Creator id is not set")
	}

	return nil
}

func Create(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	if err := validateChannelRequest(req); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	if err := req.Create(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(req)
}

func List(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	c := models.NewChannel()
	list, err := c.List(helpers.GetQuery(u))
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(list)
}

func Delete(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	id, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	req.Id = id

	if err := req.Delete(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}
	// yes it is deleted but not removed completely from our system
	return helpers.NewDeletedResponse()
}

func Update(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	id, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}
	req.Id = id

	if req.Id == 0 {
		return helpers.NewBadRequestResponse(err)
	}

	existingOne := models.NewChannel()
	existingOne.Id = id
	if err := existingOne.Fetch(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	if existingOne.CreatorId != req.CreatorId {
		return helpers.NewBadRequestResponse(errors.New("CreatorId doesnt match"))
	}

	// only allow purpose and name to be updated
	if req.Purpose != "" {
		existingOne.Purpose = req.Purpose
	}

	if req.Name != "" {
		existingOne.Name = req.Name
	}

	if err := req.Update(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(req)
}

func Get(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	id, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	req.Id = id
	if err := req.Fetch(); err != nil {
		if err == gorm.RecordNotFound {
			return helpers.NewNotFoundResponse()
		}
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(req)
}

func PostMessage(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	// id, err := helpers.GetURIInt64(u, "id")
	// if err != nil {
	// 	return helpers.NewBadRequestResponse(err)
	// }

	// req.Id = id
	// // TODO - check if the user is member of the channel

	// if err := req.Fetch(); err != nil {
	// 	if err == gorm.RecordNotFound {
	// 		return helpers.NewNotFoundResponse()
	// 	}
	// 	return helpers.NewBadRequestResponse(err)
	// }

	return helpers.NewOKResponse(req)
}
<commit_msg>Social: do not allow deleting group channel;<commit_after>package channel

import (
	"errors"
	"net/http"
	"net/url"
	"socialapi/models"
	"socialapi/workers/api/modules/helpers"

	"github.com/jinzhu/gorm"
)

func validateChannelRequest(c *models.Channel) error {
	if c.GroupName == "" {
		return errors.New("Group name is not set")
	}

	if c.Name == "" {
		return errors.New("Channel name is not set")
	}

	if c.CreatorId == 0 {
		return errors.New("Creator id is not set")
	}

	return nil
}

func Create(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	if err := validateChannelRequest(req); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	if err := req.Create(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(req)
}

func List(u *url.URL, h http.Header, _ interface{}) (int, http.Header, interface{}, error) {
	c := models.NewChannel()
	list, err := c.List(helpers.GetQuery(u))
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(list)
}

func Delete(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {

	id, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	req.Id = id
	if err := req.Fetch(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	if req.TypeConstant == models.Channel_TYPE_GROUP {
		return helpers.NewBadRequestResponse(errors.New("You can not delete group channel"))
	}
	if err := req.Delete(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}
	// yes it is deleted but not removed completely from our system
	return helpers.NewDeletedResponse()
}

func Update(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	id, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}
	req.Id = id

	if req.Id == 0 {
		return helpers.NewBadRequestResponse(err)
	}

	existingOne := models.NewChannel()
	existingOne.Id = id
	if err := existingOne.Fetch(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	if existingOne.CreatorId != req.CreatorId {
		return helpers.NewBadRequestResponse(errors.New("CreatorId doesnt match"))
	}

	// only allow purpose and name to be updated
	if req.Purpose != "" {
		existingOne.Purpose = req.Purpose
	}

	if req.Name != "" {
		existingOne.Name = req.Name
	}

	if err := req.Update(); err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(req)
}

func Get(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	id, err := helpers.GetURIInt64(u, "id")
	if err != nil {
		return helpers.NewBadRequestResponse(err)
	}

	req.Id = id
	if err := req.Fetch(); err != nil {
		if err == gorm.RecordNotFound {
			return helpers.NewNotFoundResponse()
		}
		return helpers.NewBadRequestResponse(err)
	}

	return helpers.NewOKResponse(req)
}

func PostMessage(u *url.URL, h http.Header, req *models.Channel) (int, http.Header, interface{}, error) {
	// id, err := helpers.GetURIInt64(u, "id")
	// if err != nil {
	// 	return helpers.NewBadRequestResponse(err)
	// }

	// req.Id = id
	// // TODO - check if the user is member of the channel

	// if err := req.Fetch(); err != nil {
	// 	if err == gorm.RecordNotFound {
	// 		return helpers.NewNotFoundResponse()
	// 	}
	// 	return helpers.NewBadRequestResponse(err)
	// }

	return helpers.NewOKResponse(req)
}
<|endoftext|>


<commit_before>package lib

import (
	"github.com/jmoiron/sqlx"
	"lib/model"

	_ "github.com/mattn/go-sqlite3"
)

var (
	DB *sqlx.DB
)

func GetDB() *sqlx.DB {
	if DB == nil {
		DB = sqlx.MustConnect("sqlite3", "/tmp/3do.sqlite3")
		return DB
	}

	return DB
}

func CreateDBSchema(db *sqlx.DB) {
	db.MustExec(`
		CREATE TABLE IF NOT EXISTS "todo_items" (
			"id" integer,
			"title" varchar(255),
			"description" varchar(255),
			"done" bool,
			"done_at" datetime,
			"created_at" datetime,
			"updated_at" datetime,
			"group_id" integer ,

			 PRIMARY KEY ("id")
		 );
	`)
	db.MustExec(`
		CREATE INDEX IF NOT EXISTS idx_todo_items_group_id ON "todo_items"("group_id");
	`)

	db.MustExec(`
		CREATE TABLE IF NOT EXISTS "todo_groups" (
			"id" integer,
			"title" varchar(255),
			"created_at" datetime,
			"updated_at" datetime,
			"list_id" integer ,

			 PRIMARY KEY ("id")
		 );
	`)
	db.MustExec(`
		CREATE INDEX IF NOT EXISTS idx_todo_groups_list_id ON "todo_groups"("list_id");
	`)

	db.MustExec(`
		CREATE TABLE IF NOT EXISTS "todo_lists" (
			"id" integer,
			"title" varchar(255),
			"description" varchar(255),
			"created_at" datetime,
			"updated_at" datetime ,

			 PRIMARY KEY ("id")
		 );
	`)
}

func SeedDB(db *sqlx.DB) error {
	l1 := &model.TodoList{
		Title:       "Hello",
		Description: "Foo",
	}
	l2 := &model.TodoList{
		Title:       "Bye",
		Description: "Bar",
	}

	i1 := &model.TodoItem{
		Title:       "Item 1",
		Description: "# Foo",
		Done:        false,
	}
	i2 := &model.TodoItem{
		Title:       "Item 2",
		Description: "Bar",
		Done:        false,
	}

	g1 := &model.TodoGroup{
		Title: "Group 1",
	}

	if err := model.InsertTodoList(db, l1); err != nil {
		return err
	}
	if err := model.InsertTodoList(db, l2); err != nil {
		return err
	}

	if err := model.InsertTodoGroup(db, g1); err != nil {
		return err
	}

	i1.Group = g1.ID.Int64
	i2.Group = g1.ID.Int64
	if err := model.InsertTodoItem(db, i1); err != nil {
		return err
	}
	if err := model.InsertTodoItem(db, i2); err != nil {
		return err
	}

	return nil
}
<commit_msg>Fix missing relation in DB seed<commit_after>package lib

import (
	"github.com/jmoiron/sqlx"
	"lib/model"

	_ "github.com/mattn/go-sqlite3"
)

var (
	DB *sqlx.DB
)

func GetDB() *sqlx.DB {
	if DB == nil {
		DB = sqlx.MustConnect("sqlite3", "/tmp/3do.sqlite3")
		return DB
	}

	return DB
}

func CreateDBSchema(db *sqlx.DB) {
	db.MustExec(`
		CREATE TABLE IF NOT EXISTS "todo_items" (
			"id" integer,
			"title" varchar(255),
			"description" varchar(255),
			"done" bool,
			"done_at" datetime,
			"created_at" datetime,
			"updated_at" datetime,
			"group_id" integer ,

			 PRIMARY KEY ("id")
		 );
	`)
	db.MustExec(`
		CREATE INDEX IF NOT EXISTS idx_todo_items_group_id ON "todo_items"("group_id");
	`)

	db.MustExec(`
		CREATE TABLE IF NOT EXISTS "todo_groups" (
			"id" integer,
			"title" varchar(255),
			"created_at" datetime,
			"updated_at" datetime,
			"list_id" integer ,

			 PRIMARY KEY ("id")
		 );
	`)
	db.MustExec(`
		CREATE INDEX IF NOT EXISTS idx_todo_groups_list_id ON "todo_groups"("list_id");
	`)

	db.MustExec(`
		CREATE TABLE IF NOT EXISTS "todo_lists" (
			"id" integer,
			"title" varchar(255),
			"description" varchar(255),
			"created_at" datetime,
			"updated_at" datetime ,

			 PRIMARY KEY ("id")
		 );
	`)
}

func SeedDB(db *sqlx.DB) error {
	l1 := &model.TodoList{
		Title:       "Hello",
		Description: "Foo",
	}
	l2 := &model.TodoList{
		Title:       "Bye",
		Description: "Bar",
	}

	g1 := &model.TodoGroup{
		Title: "Group 1",
	}

	i1 := &model.TodoItem{
		Title:       "Item 1",
		Description: "# Foo",
		Done:        false,
	}
	i2 := &model.TodoItem{
		Title:       "Item 2",
		Description: "Bar",
		Done:        false,
	}

	if err := model.InsertTodoList(db, l1); err != nil {
		return err
	}
	if err := model.InsertTodoList(db, l2); err != nil {
		return err
	}

	g1.List = l1.ID.Int64
	if err := model.InsertTodoGroup(db, g1); err != nil {
		return err
	}

	i1.Group = g1.ID.Int64
	i2.Group = g1.ID.Int64
	if err := model.InsertTodoItem(db, i1); err != nil {
		return err
	}
	if err := model.InsertTodoItem(db, i2); err != nil {
		return err
	}

	return nil
}
<|endoftext|>


<commit_before>// Copyright 2010 The GoGo Authors. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import "./libgogo/_obj/libgogo"

var InSymTable uint64 = 0;

func GetLine() string {
    var line string;
    var singleChar byte;
    for singleChar = GetCharWrapped(); (singleChar != 0) && (singleChar != 10); singleChar = GetCharWrapped() {
        libgogo.CharAppend(&line, singleChar);
    }
    if singleChar == 0 {
        tok.id = TOKEN_EOS;
    }
    return line;
}

func GetNextSymToken(lineRest string, offset *uint64) string {
    var symtoken string;
    var i uint64;
    var len uint64;
    len = libgogo.StringLength(lineRest);
    for i = *offset; (i < len) && (lineRest[i] != ','); i=i+1 {
        if (lineRest[i] != '/') && (lineRest[i] != ' ') {
            libgogo.CharAppend(&symtoken, lineRest[i]);
        }
    }
    *offset = i+1;
    return symtoken;
}

func ParseLine(line string) {
    // Something like
    // Type, Ndx, Name, Ret, Params [,...]
    // FUNC ,UND    ,test·test      ,           ,uint64
    var offset uint64 = 0;
    var symtoken string;
    symtoken = GetNextSymToken(line,&offset);
    libgogo.PrintString("Type: ");
    libgogo.PrintString(symtoken);
    libgogo.PrintString("\n");

    symtoken = GetNextSymToken(line,&offset);
    libgogo.PrintString("Defined: ");
    libgogo.PrintString(symtoken);
    libgogo.PrintString("\n");

    symtoken = GetNextSymToken(line,&offset);
    libgogo.PrintString("Packagename+Var-/Functionname: ");
    libgogo.PrintString(symtoken);
    libgogo.PrintString("\n");

    symtoken = GetNextSymToken(line,&offset);
    libgogo.PrintString("Return, vartype: ");
    libgogo.PrintString(symtoken);
    libgogo.PrintString("\n");

}

func Link() {
    var line string;
    var strCmp uint64;

    tok.id = 0;
    tok.nextChar = 0;
    tok.nextToken = 0;
    tok.llCnt = 0;

    for line = GetLine(); tok.id != TOKEN_EOS ;line = GetLine() {
        strCmp = libgogo.StringCompare("// ##START_SYM_TABLE", line)
        if (strCmp == 0) {
            libgogo.PrintString("Symboltable start\n");
            InSymTable = 1;
            line = GetLine();
        }
        strCmp = libgogo.StringCompare("// ##END_SYM_TABLE", line)
        if (strCmp == 0) {
            libgogo.PrintString("Symboltable end\n");
            InSymTable = 0;
        }
        if InSymTable != 0 {
            ParseLine(line);
            libgogo.PrintString("\n");
        }
    }
}
<commit_msg>linker.go: Syntax fixes (despite the one that cannot be fixed as direct dereferring of pointers is not supported)<commit_after>// Copyright 2010 The GoGo Authors. All rights reserved.
// Use of this source code is governed by the MIT
// license that can be found in the LICENSE file.

package main

import "./libgogo/_obj/libgogo"

var InSymTable uint64 = 0;

func GetLine() string {
    var line string;
    var singleChar byte;
    for singleChar = GetCharWrapped(); (singleChar != 0) && (singleChar != 10); singleChar = GetCharWrapped() {
        libgogo.CharAppend(&line, singleChar);
    }
    if singleChar == 0 {
        tok.id = TOKEN_EOS;
    }
    return line;
}

func GetNextSymToken(lineRest string, offset *uint64) string {
    var symtoken string;
    var i uint64;
    var len uint64;
    len = libgogo.StringLength(lineRest);
    for i = *offset; (i < len) && (lineRest[i] != ','); i=i+1 {
        if (lineRest[i] != '/') && (lineRest[i] != ' ') {
            libgogo.CharAppend(&symtoken, lineRest[i]);
        }
    }
    *offset = i+1;
    return symtoken;
}

func ParseLine(line string) {
    // Something like
    // Type, Ndx, Name, Ret, Params [,...]
    // FUNC ,UND    ,test·test      ,           ,uint64
    var offset uint64 = 0;
    var symtoken string;
    symtoken = GetNextSymToken(line,&offset);
    libgogo.PrintString("Type: ");
    libgogo.PrintString(symtoken);
    libgogo.PrintString("\n");

    symtoken = GetNextSymToken(line,&offset);
    libgogo.PrintString("Defined: ");
    libgogo.PrintString(symtoken);
    libgogo.PrintString("\n");

    symtoken = GetNextSymToken(line,&offset);
    libgogo.PrintString("Packagename+Var-/Functionname: ");
    libgogo.PrintString(symtoken);
    libgogo.PrintString("\n");

    symtoken = GetNextSymToken(line,&offset);
    libgogo.PrintString("Return, vartype: ");
    libgogo.PrintString(symtoken);
    libgogo.PrintString("\n");

}

func Link() {
    var line string;
    var strCmp uint64;

    tok.id = 0;
    tok.nextChar = 0;
    tok.nextToken = 0;
    tok.llCnt = 0;

    for line = GetLine(); tok.id != TOKEN_EOS ;line = GetLine() {
        strCmp = libgogo.StringCompare("// ##START_SYM_TABLE", line);
        if (strCmp == 0) {
            libgogo.PrintString("Symboltable start\n");
            InSymTable = 1;
            line = GetLine();
        }
        strCmp = libgogo.StringCompare("// ##END_SYM_TABLE", line);
        if (strCmp == 0) {
            libgogo.PrintString("Symboltable end\n");
            InSymTable = 0;
        }
        if InSymTable != 0 {
            ParseLine(line);
            libgogo.PrintString("\n");
        }
    }
}
<|endoftext|>


<commit_before>package tcp

import (
	"encoding/binary"
	"io"
	"net"
	"runtime"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/eliothedeman/bangarang/event"
	"github.com/eliothedeman/bangarang/provider"
)

const START_HANDSHAKE = "BANGARANG: TCP_PROVIDER"

func init() {
	provider.LoadEventProviderFactory("tcp", NewTCPProvider)
}

// provides events from tcp connections
type TCPProvider struct {
	encoding string
	pool     *event.EncodingPool
	laddr    *net.TCPAddr
	listener *net.TCPListener
}

func NewTCPProvider() provider.EventProvider {
	return &TCPProvider{}
}

// the config struct for the tcp provider
type TCPConfig struct {
	Encoding    string `json:"encoding"`
	Listen      string `json:"listen"`
	MaxDecoders int    `json:"max_decoders"`
}

func (t *TCPProvider) Init(i interface{}) error {
	c := i.(*TCPConfig)

	// make sure we have a valid address
	addr, err := net.ResolveTCPAddr("tcp4", c.Listen)
	if err != nil {
		return err
	}

	t.laddr = addr

	// build an encoding pool
	t.pool = event.NewEncodingPool(event.EncoderFactories[c.Encoding], event.DecoderFactories[c.Encoding], c.MaxDecoders)
	return nil
}

func (t *TCPProvider) ConfigStruct() interface{} {
	return &TCPConfig{
		Encoding:    event.ENCODING_TYPE_JSON,
		MaxDecoders: runtime.NumCPU(),
	}
}

// start accepting connections and consume each of them as they come in
func (t *TCPProvider) Start(p event.Passer) {

	logrus.Infof("TCP Provider listening on %s", t.laddr.String())
	// start listening on that addr
	err := t.listen()
	if err != nil {
		logrus.Error(err)
		return
	}

	go func() {
		// listen for ever
		for {
			c, err := t.listener.AcceptTCP()
			if err != nil {
				logrus.Errorf("Cannot accept new tcp connection %s", err.Error())
			} else {
				// consume the connection
				logrus.Infof("Accpeted new tcp connection from %s", c.RemoteAddr().String())
				go t.consume(c, p)
			}
		}
	}()
}

func readFull(conn *net.TCPConn, buff []byte) error {
	off := 0
	slp := time.Millisecond
	for off < len(buff) {
		n, err := conn.Read(buff[off:])
		if err != nil {
			return err
		}

		// exponentially back off if we don't have anything
		if n == 0 {
			slp = slp * 2
			time.Sleep(slp)
		} else {

			// reset the sleep timer
			slp = time.Millisecond
		}
		off += n
	}
	return nil
}

func (t *TCPProvider) consume(conn *net.TCPConn, p event.Passer) {
	buff := make([]byte, 1024*200)
	var size_buff = make([]byte, 8)
	var nextEventSize uint64
	var err error

	// write the start of the handshake so the client can verify this is a bangarang client
	conn.Write([]byte(START_HANDSHAKE))
	for {

		// read the size of the next event
		err = readFull(conn, size_buff)
		if err != nil {

			if err == io.EOF {
				time.Sleep(50 * time.Millisecond)
			} else {
				logrus.Error(err)
				return
			}
		} else {

			nextEventSize = binary.LittleEndian.Uint64(size_buff)

			// read the next event
			err = readFull(conn, buff[:nextEventSize])
			if err != nil {
				logrus.Error(err)
				conn.Close()
				return
			}
			e := &event.Event{}

			err = t.pool.Decode(buff[:nextEventSize], e)

			if err != nil {
				logrus.Error(err, string(buff[:nextEventSize]))
			} else {
				p.Pass(e)
			}
		}
	}
}

func (t *TCPProvider) listen() error {
	l, err := net.ListenTCP("tcp", t.laddr)
	if err != nil {
		logrus.Error(err)
		return err
	}

	t.listener = l
	return nil
}
<commit_msg>handle bad tcp connections more gracefully<commit_after>package tcp

import (
	"encoding/binary"
	"io"
	"net"
	"runtime"
	"time"

	"github.com/Sirupsen/logrus"
	"github.com/eliothedeman/bangarang/event"
	"github.com/eliothedeman/bangarang/provider"
)

const START_HANDSHAKE = "BANGARANG: TCP_PROVIDER"

func init() {
	provider.LoadEventProviderFactory("tcp", NewTCPProvider)
}

// provides events from tcp connections
type TCPProvider struct {
	encoding string
	pool     *event.EncodingPool
	laddr    *net.TCPAddr
	listener *net.TCPListener
}

func NewTCPProvider() provider.EventProvider {
	return &TCPProvider{}
}

// the config struct for the tcp provider
type TCPConfig struct {
	Encoding    string `json:"encoding"`
	Listen      string `json:"listen"`
	MaxDecoders int    `json:"max_decoders"`
}

func (t *TCPProvider) Init(i interface{}) error {
	c := i.(*TCPConfig)

	// make sure we have a valid address
	addr, err := net.ResolveTCPAddr("tcp4", c.Listen)
	if err != nil {
		return err
	}

	t.laddr = addr

	// build an encoding pool
	t.pool = event.NewEncodingPool(event.EncoderFactories[c.Encoding], event.DecoderFactories[c.Encoding], c.MaxDecoders)
	return nil
}

func (t *TCPProvider) ConfigStruct() interface{} {
	return &TCPConfig{
		Encoding:    event.ENCODING_TYPE_JSON,
		MaxDecoders: runtime.NumCPU(),
	}
}

// start accepting connections and consume each of them as they come in
func (t *TCPProvider) Start(p event.Passer) {

	logrus.Infof("TCP Provider listening on %s", t.laddr.String())
	// start listening on that addr
	err := t.listen()
	if err != nil {
		logrus.Error(err)
		return
	}

	go func() {
		// listen for ever
		for {
			c, err := t.listener.AcceptTCP()
			if err != nil {
				logrus.Errorf("Cannot accept new tcp connection %s", err.Error())
			} else {
				// consume the connection
				logrus.Infof("Accpeted new tcp connection from %s", c.RemoteAddr().String())
				go t.consume(c, p)
			}
		}
	}()
}

func readFull(conn *net.TCPConn, buff []byte) error {
	off := 0
	slp := time.Millisecond
	for off < len(buff) {
		n, err := conn.Read(buff[off:])
		if err != nil {
			return err
		}

		// exponentially back off if we don't have anything
		if n == 0 {
			slp = slp * 2
			time.Sleep(slp)
		} else {

			// reset the sleep timer
			slp = time.Millisecond
		}
		off += n
	}
	return nil
}

// consume a tcp connection's events and pass them on to the next step in the pipeline
func (t *TCPProvider) consume(conn *net.TCPConn, p event.Passer) {
	buff := make([]byte, 1024*200)
	var size_buff = make([]byte, 8)
	var nextEventSize uint64
	var err error
	logContext := func() {
		// log out context
		logrus.Errorf("Panic Context... size_buff: %x nextEventSize: %d buff: %x", size_buff, nextEventSize, buff)

	}

	// recover from a panaic while dealing with the tcp connection
	defer func() {
		if r := recover(); r != nil {
			err := conn.Close()
			if err != nil {
				logrus.Error(err)
			}

			logrus.Error("Recoverd from panic while reading tcp connection: ", r)
			logContext()

		}

	}()

	// write the start of the handshake so the client can verify this is a bangarang client
	conn.Write([]byte(START_HANDSHAKE))
	for {

		// read the size of the next event
		err = readFull(conn, size_buff)
		if err != nil {

			if err == io.EOF {
				time.Sleep(50 * time.Millisecond)
			} else {
				logrus.Error(err)
				return
			}
		} else {

			nextEventSize = binary.LittleEndian.Uint64(size_buff)

			// make sure the nextEventSize is not larger than the buffer we are going to read into
			if int(nextEventSize) > len(buff) {
				logrus.Errorf("Incorrect size parsed for next event %d", nextEventSize)
				logContext()
				conn.Close()
				return
			}

			// read the next event
			err = readFull(conn, buff[:nextEventSize])
			if err != nil {
				logrus.Error(err)
				conn.Close()
				return
			}
			e := &event.Event{}

			err = t.pool.Decode(buff[:nextEventSize], e)
			if err != nil {
				logrus.Errorf("Unable to parse event %s", err.Error())
				conn.Close()
			} else {
				p.Pass(e)
			}
		}
	}
}

func (t *TCPProvider) listen() error {
	l, err := net.ListenTCP("tcp", t.laddr)
	if err != nil {
		logrus.Error(err)
		return err
	}

	t.listener = l
	return nil
}
<|endoftext|>