<commit_before>// Copyright 2020 Google LLC
//
// 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
//
// 	https://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 safehttp

import (
	"net/http"
	"testing"

	"github.com/google/go-cmp/cmp"
)

func TestSet(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	if got, want := h.Get("Foo-Key"), "Bar-Value"; got != want {
		t.Errorf(`h.Get("Foo-Key") got: %q want %q`, got, want)
	}
}

func TestSetCanonicalization(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("fOo-KeY", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("fOo-KeY", "Bar-Value") got err: %v want: nil`, err)
	}
	if got, want := h.Get("FoO-kEy"), "Bar-Value"; got != want {
		t.Errorf(`h.Get("FoO-kEy") got: %q want %q`, got, want)
	}
}

func TestSetSetCookie(t *testing.T) {
	h := newHeader(http.Header{})
	err := h.Set("Set-Cookie", "x=y")
	if got, want := err.Error(), "can't write to Set-Cookie header"; got != want {
		t.Errorf(`h.Set("Set-Cookie", "x=y") got: %v want: %v`, got, want)
	}
	if diff := cmp.Diff([]string{}, h.Values("Set-Cookie")); diff != "" {
		t.Errorf(`h.Values("Set-Cookie") mismatch (-want +got):\n%s`, diff)
	}
}

func TestSetImmutable(t *testing.T) {
	h := newHeader(http.Header{})
	h.MarkImmutable("Foo-Key")
	err := h.Set("Foo-Key", "Bar-Value")
	if got, want := err.Error(), "immutable header"; got != want {
		t.Errorf(`h.Set("Foo-Key", "Bar-Value") got: %v want: %v`, got, want)
	}
	if diff := cmp.Diff([]string{}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestAdd(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Add("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Add("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	if err := h.Add("Foo-Key", "Bar-Value-2"); err != nil {
		t.Fatalf(`h.Add("Foo-Key", "Bar-Value-2") got err: %v want: nil`, err)
	}
	if diff := cmp.Diff([]string{"Bar-Value", "Bar-Value-2"}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestAddCanonicalization(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Add("fOo-KeY", "Bar-Value"); err != nil {
		t.Fatalf(`h.Add("fOo-KeY", "Bar-Value") got err: %v want: nil`, err)
	}
	if err := h.Add("FoO-kEy", "Bar-Value-2"); err != nil {
		t.Fatalf(`h.Add("FoO-kEy", "Bar-Value-2") got err: %v want: nil`, err)
	}
	if diff := cmp.Diff([]string{"Bar-Value", "Bar-Value-2"}, h.Values("fOO-KEY")); diff != "" {
		t.Errorf(`h.Values("fOO-KEY")) mismatch (-want +got):\n%s`, diff)
	}
}

func TestAddSetCookie(t *testing.T) {
	h := newHeader(http.Header{})
	err := h.Add("Set-Cookie", "x=y")
	if got, want := err.Error(), "can't write to Set-Cookie header"; got != want {
		t.Errorf(`h.Add("Set-Cookie", "x=y") got: %v want: %v`, got, want)
	}
	if diff := cmp.Diff([]string{}, h.Values("Set-Cookie")); diff != "" {
		t.Errorf(`h.Values("Set-Cookie") mismatch (-want +got):\n%s`, diff)
	}
}

func TestAddImmutable(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Add("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Add("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	h.MarkImmutable("Foo-Key")
	err := h.Add("Foo-Key", "Bar-Value-2")
	if got, want := err.Error(), "immutable header"; got != want {
		t.Errorf(`h.Add("Set-Cookie", "Bar-Value") got: %v want: %v`, got, want)
	}
	if diff := cmp.Diff([]string{"Bar-Value"}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestDel(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	if err := h.Del("Foo-Key"); err != nil {
		t.Fatalf(`h.Del("Foo-Key") got err: %v want: nil`, err)
	}
	if diff := cmp.Diff([]string{}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestDelCanonicalization(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("fOo-KeY", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("fOo-KeY", "Bar-Value") got err: %v want: nil`, err)
	}
	if err := h.Del("FoO-kEy"); err != nil {
		t.Fatalf(`h.Del("FoO-kEy") got err: %v want: nil`, err)
	}
	if diff := cmp.Diff([]string{}, h.Values("FOO-kEY")); diff != "" {
		t.Errorf(`h.Values("FOO-kEY") mismatch (-want +got):\n%s`, diff)
	}
}

func TestDelSetCookie(t *testing.T) {
	h := newHeader(http.Header{})
	err := h.Del("Set-Cookie")
	if got, want := err.Error(), "can't write to Set-Cookie header"; got != want {
		t.Errorf(`h.Del("Set-Cookie") got: %v want: %v`, got, want)
	}
}

func TestDelImmutable(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	h.MarkImmutable("Foo-Key")
	err := h.Del("Foo-Key")
	if got, want := err.Error(), "immutable header"; got != want {
		t.Errorf(`h.Add("Set-Cookie", "Bar-Value") got: %v want: %v`, got, want)
	}
	if diff := cmp.Diff([]string{"Bar-Value"}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestSetCookie(t *testing.T) {
	h := newHeader(http.Header{})
	c := &http.Cookie{Name: "x", Value: "y"}
	h.SetCookie(c)
	if got, want := h.Get("Set-Cookie"), "x=y"; got != want {
		t.Errorf(`h.Get("Set-Cookie") got: %q want: %q`, got, want)
	}
}

func TestSetCookieInvalidName(t *testing.T) {
	h := newHeader(http.Header{})
	c := &http.Cookie{Name: "x=", Value: "y"}
	h.SetCookie(c)
	if got, want := h.Get("Set-Cookie"), ""; got != want {
		t.Errorf(`h.Get("Set-Cookie") got: %q want: %q`, got, want)
	}
}

func TestValuesModifyImmutable(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	h.MarkImmutable("Foo-Key")
	v := h.Values("Foo-Key")
	if diff := cmp.Diff([]string{"Bar-Value"}, v); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
	v[0] = "Evil-Value"
	if got, want := h.Get("Foo-Key"), "Bar-Value"; got != want {
		t.Errorf(`h.Get("Foo-Key") got: %v want: %v`, got, want)
	}
}
<commit_msg>Removed checking for specific errors<commit_after>// Copyright 2020 Google LLC
//
// 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
//
// 	https://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 safehttp

import (
	"net/http"
	"testing"

	"github.com/google/go-cmp/cmp"
)

func TestSet(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	if got, want := h.Get("Foo-Key"), "Bar-Value"; got != want {
		t.Errorf(`h.Get("Foo-Key") got: %q want %q`, got, want)
	}
}

func TestSetCanonicalization(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("fOo-KeY", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("fOo-KeY", "Bar-Value") got err: %v want: nil`, err)
	}
	if got, want := h.Get("FoO-kEy"), "Bar-Value"; got != want {
		t.Errorf(`h.Get("FoO-kEy") got: %q want %q`, got, want)
	}
}

func TestSetSetCookie(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Set-Cookie", "x=y"); err == nil {
		t.Error(`h.Set("Set-Cookie", "x=y") got: nil want: error`)
	}
	if diff := cmp.Diff([]string{}, h.Values("Set-Cookie")); diff != "" {
		t.Errorf(`h.Values("Set-Cookie") mismatch (-want +got):\n%s`, diff)
	}
}

func TestSetImmutable(t *testing.T) {
	h := newHeader(http.Header{})
	h.MarkImmutable("Foo-Key")
	if err := h.Set("Foo-Key", "Bar-Value"); err == nil {
		t.Error(`h.Set("Foo-Key", "Bar-Value") got: nil want: error`)
	}
	if diff := cmp.Diff([]string{}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestAdd(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Add("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Add("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	if err := h.Add("Foo-Key", "Bar-Value-2"); err != nil {
		t.Fatalf(`h.Add("Foo-Key", "Bar-Value-2") got err: %v want: nil`, err)
	}
	if diff := cmp.Diff([]string{"Bar-Value", "Bar-Value-2"}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestAddCanonicalization(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Add("fOo-KeY", "Bar-Value"); err != nil {
		t.Fatalf(`h.Add("fOo-KeY", "Bar-Value") got err: %v want: nil`, err)
	}
	if err := h.Add("FoO-kEy", "Bar-Value-2"); err != nil {
		t.Fatalf(`h.Add("FoO-kEy", "Bar-Value-2") got err: %v want: nil`, err)
	}
	if diff := cmp.Diff([]string{"Bar-Value", "Bar-Value-2"}, h.Values("fOO-KEY")); diff != "" {
		t.Errorf(`h.Values("fOO-KEY")) mismatch (-want +got):\n%s`, diff)
	}
}

func TestAddSetCookie(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Add("Set-Cookie", "x=y"); err == nil {
		t.Error(`h.Add("Set-Cookie", "x=y") got: nil want: error`)
	}
	if diff := cmp.Diff([]string{}, h.Values("Set-Cookie")); diff != "" {
		t.Errorf(`h.Values("Set-Cookie") mismatch (-want +got):\n%s`, diff)
	}
}

func TestAddImmutable(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Add("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Add("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	h.MarkImmutable("Foo-Key")
	if err := h.Add("Foo-Key", "Bar-Value-2"); err == nil {
		t.Error(`h.Add("Set-Cookie", "Bar-Value") got: nil want: error`)
	}
	if diff := cmp.Diff([]string{"Bar-Value"}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestDel(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	if err := h.Del("Foo-Key"); err != nil {
		t.Fatalf(`h.Del("Foo-Key") got err: %v want: nil`, err)
	}
	if diff := cmp.Diff([]string{}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestDelCanonicalization(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("fOo-KeY", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("fOo-KeY", "Bar-Value") got err: %v want: nil`, err)
	}
	if err := h.Del("FoO-kEy"); err != nil {
		t.Fatalf(`h.Del("FoO-kEy") got err: %v want: nil`, err)
	}
	if diff := cmp.Diff([]string{}, h.Values("FOO-kEY")); diff != "" {
		t.Errorf(`h.Values("FOO-kEY") mismatch (-want +got):\n%s`, diff)
	}
}

func TestDelSetCookie(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Del("Set-Cookie"); err == nil {
		t.Error(`h.Del("Set-Cookie") got: nil want: error`)
	}
}

func TestDelImmutable(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	h.MarkImmutable("Foo-Key")
	if err := h.Del("Foo-Key"); err == nil {
		t.Error(`h.Add("Set-Cookie", "Bar-Value") got: nil want: error`)
	}
	if diff := cmp.Diff([]string{"Bar-Value"}, h.Values("Foo-Key")); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
}

func TestSetCookie(t *testing.T) {
	h := newHeader(http.Header{})
	c := &http.Cookie{Name: "x", Value: "y"}
	h.SetCookie(c)
	if got, want := h.Get("Set-Cookie"), "x=y"; got != want {
		t.Errorf(`h.Get("Set-Cookie") got: %q want: %q`, got, want)
	}
}

func TestSetCookieInvalidName(t *testing.T) {
	h := newHeader(http.Header{})
	c := &http.Cookie{Name: "x=", Value: "y"}
	h.SetCookie(c)
	if got, want := h.Get("Set-Cookie"), ""; got != want {
		t.Errorf(`h.Get("Set-Cookie") got: %q want: %q`, got, want)
	}
}

func TestValuesModifyImmutable(t *testing.T) {
	h := newHeader(http.Header{})
	if err := h.Set("Foo-Key", "Bar-Value"); err != nil {
		t.Fatalf(`h.Set("Foo-Key", "Bar-Value") got err: %v want: nil`, err)
	}
	h.MarkImmutable("Foo-Key")
	v := h.Values("Foo-Key")
	if diff := cmp.Diff([]string{"Bar-Value"}, v); diff != "" {
		t.Errorf(`h.Values("Foo-Key") mismatch (-want +got):\n%s`, diff)
	}
	v[0] = "Evil-Value"
	if got, want := h.Get("Foo-Key"), "Bar-Value"; got != want {
		t.Errorf(`h.Get("Foo-Key") got: %v want: %v`, got, want)
	}
}
<|endoftext|>


<commit_before>package cruncy

// VERSION of the application
const VERSION = "0.11.3"
<commit_msg>0.11.4<commit_after>package cruncy

// VERSION of the application
const VERSION = "0.11.4"
<|endoftext|>


<commit_before>package main

import (
	"bytes"
	"io"
	"log"
	"os"
	"strings"

	_ "crypto/ecdsa"
	_ "crypto/sha1"
	_ "crypto/sha256"
	_ "crypto/sha512"

	"code.google.com/p/go.crypto/openpgp"
	"code.google.com/p/go.crypto/openpgp/armor"
)

const pgpkeymask = uint64(0xffffffff)

var encryptKeys openpgp.EntityList

func encrypt(s string) string {
	buf := &bytes.Buffer{}

	wa, err := armor.Encode(buf, "PGP MESSAGE", nil)
	if err != nil {
		log.Fatalf("Can't make armor: %v", err)
	}

	w, err := openpgp.Encrypt(wa, encryptKeys, nil, nil, nil)
	if err != nil {
		log.Fatalf("Error encrypting: %v", err)
	}
	_, err = io.Copy(w, strings.NewReader(s))
	if err != nil {
		log.Fatalf("Error encrypting: %v", err)
	}
	w.Close()
	wa.Close()

	return buf.String()
}

func initPgp(kr string, keyids []string) {
	f, err := os.Open(kr)
	if err != nil {
		log.Fatalf("Can't open keyring: %v", err)
	}
	defer f.Close()

	kl, err := openpgp.ReadKeyRing(f)
	if err != nil {
		log.Fatalf("Can't read keyring: %v", err)
	}

	for _, w := range keyids {
		for _, e := range kl {
			if e.PrimaryKey.KeyIdShortString() == w {
				encryptKeys = append(encryptKeys, e)
			}
		}
	}

	if len(encryptKeys) != len(keyids) {
		log.Fatalf("Couldn't find all keys")
	}
}
<commit_msg>Don't need the pgp key mask.<commit_after>package main

import (
	"bytes"
	"io"
	"log"
	"os"
	"strings"

	_ "crypto/ecdsa"
	_ "crypto/sha1"
	_ "crypto/sha256"
	_ "crypto/sha512"

	"code.google.com/p/go.crypto/openpgp"
	"code.google.com/p/go.crypto/openpgp/armor"
)

var encryptKeys openpgp.EntityList

func encrypt(s string) string {
	buf := &bytes.Buffer{}

	wa, err := armor.Encode(buf, "PGP MESSAGE", nil)
	if err != nil {
		log.Fatalf("Can't make armor: %v", err)
	}

	w, err := openpgp.Encrypt(wa, encryptKeys, nil, nil, nil)
	if err != nil {
		log.Fatalf("Error encrypting: %v", err)
	}
	_, err = io.Copy(w, strings.NewReader(s))
	if err != nil {
		log.Fatalf("Error encrypting: %v", err)
	}
	w.Close()
	wa.Close()

	return buf.String()
}

func initPgp(kr string, keyids []string) {
	f, err := os.Open(kr)
	if err != nil {
		log.Fatalf("Can't open keyring: %v", err)
	}
	defer f.Close()

	kl, err := openpgp.ReadKeyRing(f)
	if err != nil {
		log.Fatalf("Can't read keyring: %v", err)
	}

	for _, w := range keyids {
		for _, e := range kl {
			if e.PrimaryKey.KeyIdShortString() == w {
				encryptKeys = append(encryptKeys, e)
			}
		}
	}

	if len(encryptKeys) != len(keyids) {
		log.Fatalf("Couldn't find all keys")
	}
}
<|endoftext|>


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

// Package crypto collects common cryptographic constants.
package crypto

import (
	"hash"
	"io"
	"strconv"
)

// Hash identifies a cryptographic hash function that is implemented in another
// package.
type Hash uint

// HashFunc simply returns the value of h so that Hash implements SignerOpts.
func (h Hash) HashFunc() Hash {
	return h
}

const (
	MD4       Hash = 1 + iota // import golang.org/x/crypto/md4
	MD5                       // import crypto/md5
	SHA1                      // import crypto/sha1
	SHA224                    // import crypto/sha256
	SHA256                    // import crypto/sha256
	SHA384                    // import crypto/sha512
	SHA512                    // import crypto/sha512
	MD5SHA1                   // no implementation; MD5+SHA1 used for TLS RSA
	RIPEMD160                 // import golang.org/x/crypto/ripemd160
	SHA3_224                  // import golang.org/x/crypto/sha3
	SHA3_256                  // import golang.org/x/crypto/sha3
	SHA3_384                  // import golang.org/x/crypto/sha3
	SHA3_512                  // import golang.org/x/crypto/sha3
	maxHash
)

var digestSizes = []uint8{
	MD4:       16,
	MD5:       16,
	SHA1:      20,
	SHA224:    28,
	SHA256:    32,
	SHA384:    48,
	SHA512:    64,
	SHA3_224:  28,
	SHA3_256:  32,
	SHA3_384:  48,
	SHA3_512:  64,
	MD5SHA1:   36,
	RIPEMD160: 20,
}

// Size returns the length, in bytes, of a digest resulting from the given hash
// function. It doesn't require that the hash function in question be linked
// into the program.
func (h Hash) Size() int {
	if h > 0 && h < maxHash {
		return int(digestSizes[h])
	}
	panic("crypto: Size of unknown hash function")
}

var hashes = make([]func() hash.Hash, maxHash)

// New returns a new hash.Hash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() hash.Hash {
	if h > 0 && h < maxHash {
		f := hashes[h]
		if f != nil {
			return f()
		}
	}
	panic("crypto: requested hash function #" + strconv.Itoa(int(h)) + " is unavailable")
}

// Available reports whether the given hash function is linked into the binary.
func (h Hash) Available() bool {
	return h < maxHash && hashes[h] != nil
}

// RegisterHash registers a function that returns a new instance of the given
// hash function. This is intended to be called from the init function in
// packages that implement hash functions.
func RegisterHash(h Hash, f func() hash.Hash) {
	if h >= maxHash {
		panic("crypto: RegisterHash of unknown hash function")
	}
	hashes[h] = f
}

// PublicKey represents a public key using an unspecified algorithm.
type PublicKey interface{}

// PrivateKey represents a private key using an unspecified algorithm.
type PrivateKey interface{}

// Signer is an interface for an opaque private key that can be used for
// signing operations. For example, an RSA key kept in a hardware module.
type Signer interface {
	// Public returns the public key corresponding to the opaque,
	// private key.
	Public() PublicKey

	// Sign signs msg with the private key, possibly using entropy from
	// rand. For an RSA key, the resulting signature should be either a
	// PKCS#1 v1.5 or PSS signature (as indicated by opts). For an (EC)DSA
	// key, it should be a DER-serialised, ASN.1 signature structure.
	//
	// Hash implements the SignerOpts interface and, in most cases, one can
	// simply pass in the hash function used as opts. Sign may also attempt
	// to type assert opts to other types in order to obtain algorithm
	// specific values. See the documentation in each package for details.
	Sign(rand io.Reader, msg []byte, opts SignerOpts) (signature []byte, err error)
}

// SignerOpts contains options for signing with a Signer.
type SignerOpts interface {
	// HashFunc returns an identifier for the hash function used to produce
	// the message passed to Signer.Sign, or else zero to indicate that no
	// hashing was done.
	HashFunc() Hash
}

// Decrypter is an interface for an opaque private key that can be used for
// asymmetric decryption operations. For example, an RSA key kept in a hardware
// module.
type Decrypter interface {
	// Public returns the public key corresponding to the opaque,
	// private key.
	Public() PublicKey

	// Decrypt decrypts msg. The opts argument should be appropriate for
	// the primitive used. See the documentation in each implementation for
	// details.
	Decrypt(rand io.Reader, msg []byte, opts DecrypterOpts) (plaintext []byte, err error)
}

type DecrypterOpts interface{}
<commit_msg>Remove unnecessary bits, add ResumableHash<commit_after>// Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package crypto collects common cryptographic constants.
package crypto

import (
	"hash"
	"io"
	"strconv"
)

// Hash identifies a cryptographic hash function that is implemented in another
// package.
type Hash uint

// HashFunc simply returns the value of h so that Hash implements SignerOpts.
func (h Hash) HashFunc() Hash {
	return h
}

const (
	SHA224 Hash = 1 + iota // import crypto/sha256
	SHA256                 // import crypto/sha256
	SHA384                 // import crypto/sha512
	SHA512                 // import crypto/sha512
	maxHash
)

var digestSizes = []uint8{
	SHA224: 28,
	SHA256: 32,
	SHA384: 48,
	SHA512: 64,
}

// Size returns the length, in bytes, of a digest resulting from the given hash
// function. It doesn't require that the hash function in question be linked
// into the program.
func (h Hash) Size() int {
	if h > 0 && h < maxHash {
		return int(digestSizes[h])
	}
	panic("crypto: Size of unknown hash function")
}

// ResumableHash is the common interface implemented by all resumable hash
// functions.
type ResumableHash interface {
	// ResumableHash is a superset of hash.Hash
	hash.Hash
	// Len returns the number of bytes written to the Hash so far.
	Len() int64
	// State returns a snapshot of the state of the Hash.
	State() ([]byte, error)
	// Restore resets the Hash to the given state.
	Restore(state []byte) error
}

var hashes = make([]func() ResumableHash, maxHash)

// New returns a new ResumableHash calculating the given hash function. New panics
// if the hash function is not linked into the binary.
func (h Hash) New() ResumableHash {
	if h > 0 && h < maxHash {
		f := hashes[h]
		if f != nil {
			return f()
		}
	}
	panic("crypto: requested hash function #" + strconv.Itoa(int(h)) + " is unavailable")
}

// Available reports whether the given hash function is linked into the binary.
func (h Hash) Available() bool {
	return h < maxHash && hashes[h] != nil
}

// RegisterHash registers a function that returns a new instance of the given
// hash function. This is intended to be called from the init function in
// packages that implement hash functions.
func RegisterHash(h Hash, f func() ResumableHash) {
	if h >= maxHash {
		panic("crypto: RegisterHash of unknown hash function")
	}
	hashes[h] = f
}
<|endoftext|>


<commit_before>package main

import (
	"code.google.com/p/go.crypto/bcrypt"
)

func GenerateHash(password string) []byte {
	hex := []byte(password)
	hashedPassword, err := bcrypt.GenerateFromPassword(hex, 10)
	if err != nil {
		panic(err)
	}
	return hashedPassword
}

func CompareHash(digest []byte, password string) bool {
	hex := []byte(password)
	if err := bcrypt.CompareHashAndPassword(digest, hex); err == nil {
		return true
	}
	return false
}
<commit_msg>doc: add documentation to crypto<commit_after>package main

import (
	"code.google.com/p/go.crypto/bcrypt"
)

// Generates bcrypt hash from plaintext password
func GenerateHash(password string) []byte {
	hex := []byte(password)
	hashedPassword, err := bcrypt.GenerateFromPassword(hex, 10)
	if err != nil {
		panic(err)
	}
	return hashedPassword
}

// Compares bcrypt password with a plaintext one. Returns true if passwords match
// and false if they do not.
func CompareHash(digest []byte, password string) bool {
	hex := []byte(password)
	if err := bcrypt.CompareHashAndPassword(digest, hex); err == nil {
		return true
	}
	return false
}
<|endoftext|>


<commit_before>package main

import (
	"math"

	"github.com/bcicen/ctop/connector"
	"github.com/bcicen/ctop/container"
	ui "github.com/gizak/termui"
)

var enabledConnectors = map[string]func() connector.Connector{
	"docker": connector.NewDocker,
	"runc":   connector.NewRunc,
}

type GridCursor struct {
	selectedID  string // id of currently selected container
	filtered    container.Containers
	cSource     connector.Connector
	isScrolling bool // toggled when actively scrolling
}

func NewGridCursor(connector string) *GridCursor {
	return &GridCursor{
		cSource: enabledConnectors[connector](),
	}
}

func (gc *GridCursor) Len() int { return len(gc.filtered) }

func (gc *GridCursor) Selected() *container.Container {
	idx := gc.Idx()
	if idx < gc.Len() {
		return gc.filtered[idx]
	}
	return nil
}

// Refresh containers from source
func (gc *GridCursor) RefreshContainers() (lenChanged bool) {
	oldLen := gc.Len()

	// Containers filtered by display bool
	gc.filtered = container.Containers{}
	var cursorVisible bool
	for _, c := range gc.cSource.All() {
		if c.Display {
			if c.Id == gc.selectedID {
				cursorVisible = true
			}
			gc.filtered = append(gc.filtered, c)
		}
	}

	if oldLen != gc.Len() {
		lenChanged = true
	}

	if !cursorVisible {
		gc.Reset()
	}
	if gc.selectedID == "" {
		gc.Reset()
	}
	return lenChanged
}

// Set an initial cursor position, if possible
func (gc *GridCursor) Reset() {
	for _, c := range gc.cSource.All() {
		c.Widgets.Name.UnHighlight()
	}
	if gc.Len() > 0 {
		gc.selectedID = gc.filtered[0].Id
		gc.filtered[0].Widgets.Name.Highlight()
	}
}

// Return current cursor index
func (gc *GridCursor) Idx() int {
	for n, c := range gc.filtered {
		if c.Id == gc.selectedID {
			return n
		}
	}
	gc.Reset()
	return 0
}

func (gc *GridCursor) ScrollPage() {
	// skip scroll if no need to page
	if gc.Len() < cGrid.MaxRows() {
		cGrid.Offset = 0
		return
	}

	idx := gc.Idx()

	// page down
	if idx >= cGrid.Offset+cGrid.MaxRows() {
		cGrid.Offset++
		cGrid.Align()
	}
	// page up
	if idx < cGrid.Offset {
		cGrid.Offset--
		cGrid.Align()
	}

}

func (gc *GridCursor) Up() {
	gc.isScrolling = true
	defer func() { gc.isScrolling = false }()

	idx := gc.Idx()
	if idx <= 0 { // already at top
		return
	}
	active := gc.filtered[idx]
	next := gc.filtered[idx-1]

	active.Widgets.Name.UnHighlight()
	gc.selectedID = next.Id
	next.Widgets.Name.Highlight()

	gc.ScrollPage()
	ui.Render(cGrid)
}

func (gc *GridCursor) Down() {
	gc.isScrolling = true
	defer func() { gc.isScrolling = false }()

	idx := gc.Idx()
	if idx >= gc.Len()-1 { // already at bottom
		return
	}
	active := gc.filtered[idx]
	next := gc.filtered[idx+1]

	active.Widgets.Name.UnHighlight()
	gc.selectedID = next.Id
	next.Widgets.Name.Highlight()

	gc.ScrollPage()
	ui.Render(cGrid)
}

func (gc *GridCursor) PgUp() {
	idx := gc.Idx()
	if idx <= 0 { // already at top
		return
	}

	var nextidx int
	nextidx = int(math.Max(0.0, float64(idx-cGrid.MaxRows())))
	cGrid.Offset = int(math.Max(float64(cGrid.Offset-cGrid.MaxRows()),
		float64(0)))

	active := gc.filtered[idx]
	next := gc.filtered[nextidx]

	active.Widgets.Name.UnHighlight()
	gc.selectedID = next.Id
	next.Widgets.Name.Highlight()

	cGrid.Align()
	ui.Render(cGrid)
}

func (gc *GridCursor) PgDown() {
	idx := gc.Idx()
	if idx >= gc.Len()-1 { // already at bottom
		return
	}

	var nextidx int
	nextidx = int(math.Min(float64(gc.Len()-1),
		float64(idx+cGrid.MaxRows())))
	cGrid.Offset = int(math.Min(float64(cGrid.Offset+cGrid.MaxRows()),
		float64(gc.Len()-cGrid.MaxRows())))

	active := gc.filtered[idx]
	next := gc.filtered[nextidx]

	active.Widgets.Name.UnHighlight()
	gc.selectedID = next.Id
	next.Widgets.Name.Highlight()

	cGrid.Align()
	ui.Render(cGrid)
}
<commit_msg>update potentially conflicting variable name<commit_after>package main

import (
	"math"

	"github.com/bcicen/ctop/connector"
	"github.com/bcicen/ctop/container"
	ui "github.com/gizak/termui"
)

var enabledConnectors = map[string]func() connector.Connector{
	"docker": connector.NewDocker,
	"runc":   connector.NewRunc,
}

type GridCursor struct {
	selectedID  string // id of currently selected container
	filtered    container.Containers
	cSource     connector.Connector
	isScrolling bool // toggled when actively scrolling
}

func NewGridCursor(connectorName string) *GridCursor {
	return &GridCursor{
		cSource: enabledConnectors[connectorName](),
	}
}

func (gc *GridCursor) Len() int { return len(gc.filtered) }

func (gc *GridCursor) Selected() *container.Container {
	idx := gc.Idx()
	if idx < gc.Len() {
		return gc.filtered[idx]
	}
	return nil
}

// Refresh containers from source
func (gc *GridCursor) RefreshContainers() (lenChanged bool) {
	oldLen := gc.Len()

	// Containers filtered by display bool
	gc.filtered = container.Containers{}
	var cursorVisible bool
	for _, c := range gc.cSource.All() {
		if c.Display {
			if c.Id == gc.selectedID {
				cursorVisible = true
			}
			gc.filtered = append(gc.filtered, c)
		}
	}

	if oldLen != gc.Len() {
		lenChanged = true
	}

	if !cursorVisible {
		gc.Reset()
	}
	if gc.selectedID == "" {
		gc.Reset()
	}
	return lenChanged
}

// Set an initial cursor position, if possible
func (gc *GridCursor) Reset() {
	for _, c := range gc.cSource.All() {
		c.Widgets.Name.UnHighlight()
	}
	if gc.Len() > 0 {
		gc.selectedID = gc.filtered[0].Id
		gc.filtered[0].Widgets.Name.Highlight()
	}
}

// Return current cursor index
func (gc *GridCursor) Idx() int {
	for n, c := range gc.filtered {
		if c.Id == gc.selectedID {
			return n
		}
	}
	gc.Reset()
	return 0
}

func (gc *GridCursor) ScrollPage() {
	// skip scroll if no need to page
	if gc.Len() < cGrid.MaxRows() {
		cGrid.Offset = 0
		return
	}

	idx := gc.Idx()

	// page down
	if idx >= cGrid.Offset+cGrid.MaxRows() {
		cGrid.Offset++
		cGrid.Align()
	}
	// page up
	if idx < cGrid.Offset {
		cGrid.Offset--
		cGrid.Align()
	}

}

func (gc *GridCursor) Up() {
	gc.isScrolling = true
	defer func() { gc.isScrolling = false }()

	idx := gc.Idx()
	if idx <= 0 { // already at top
		return
	}
	active := gc.filtered[idx]
	next := gc.filtered[idx-1]

	active.Widgets.Name.UnHighlight()
	gc.selectedID = next.Id
	next.Widgets.Name.Highlight()

	gc.ScrollPage()
	ui.Render(cGrid)
}

func (gc *GridCursor) Down() {
	gc.isScrolling = true
	defer func() { gc.isScrolling = false }()

	idx := gc.Idx()
	if idx >= gc.Len()-1 { // already at bottom
		return
	}
	active := gc.filtered[idx]
	next := gc.filtered[idx+1]

	active.Widgets.Name.UnHighlight()
	gc.selectedID = next.Id
	next.Widgets.Name.Highlight()

	gc.ScrollPage()
	ui.Render(cGrid)
}

func (gc *GridCursor) PgUp() {
	idx := gc.Idx()
	if idx <= 0 { // already at top
		return
	}

	var nextidx int
	nextidx = int(math.Max(0.0, float64(idx-cGrid.MaxRows())))
	cGrid.Offset = int(math.Max(float64(cGrid.Offset-cGrid.MaxRows()),
		float64(0)))

	active := gc.filtered[idx]
	next := gc.filtered[nextidx]

	active.Widgets.Name.UnHighlight()
	gc.selectedID = next.Id
	next.Widgets.Name.Highlight()

	cGrid.Align()
	ui.Render(cGrid)
}

func (gc *GridCursor) PgDown() {
	idx := gc.Idx()
	if idx >= gc.Len()-1 { // already at bottom
		return
	}

	var nextidx int
	nextidx = int(math.Min(float64(gc.Len()-1),
		float64(idx+cGrid.MaxRows())))
	cGrid.Offset = int(math.Min(float64(cGrid.Offset+cGrid.MaxRows()),
		float64(gc.Len()-cGrid.MaxRows())))

	active := gc.filtered[idx]
	next := gc.filtered[nextidx]

	active.Widgets.Name.UnHighlight()
	gc.selectedID = next.Id
	next.Widgets.Name.Highlight()

	cGrid.Align()
	ui.Render(cGrid)
}
<|endoftext|>


<commit_before>package search

import (
	"errors"
	"math"
	"sort"

	gr "github.com/gonum/graph"
)

// Finds all shortest paths between start and goal
type AllPathFunc func(start, goal gr.Node) (path [][]gr.Node, cost float64, err error)

// Finds one path between start and goal, which it finds is arbitrary
type SinglePathFunc func(start, goal gr.Node) (path []gr.Node, cost float64, err error)

// This function returns two functions: one that will generate all shortest paths between two nodes with ids i and j, and one that will generate just one path.
//
// This algorithm requires the CrunchGraph interface which means it only works on nodes with dense ids since it uses an adjacency matrix.
//
// This algorithm isn't blazingly fast, but is relatively fast for the domain. It runs at O((number of vertices)^3), and successfully computes
// the cost between all pairs of vertices.
//
// Generating a single path should be pretty cheap after FW is done running. The AllPathFunc is likely to be considerably more expensive,
// simply because it has to effectively generate all combinations of known valid paths at each recursive step of the algorithm.
func FloydWarshall(graph gr.CrunchGraph, cost func(gr.Node, gr.Node) float64) (AllPathFunc, SinglePathFunc) {
	graph.Crunch()
	successors, _, _, isSuccessor, _, _, cost, _ := setupFuncs(graph, cost, nil)

	nodes := denseNodeSorter(graph.NodeList())
	sort.Sort(nodes)
	numNodes := len(nodes)

	dist := make([]float64, numNodes*numNodes)
	next := make([][]int, numNodes*numNodes)
	for i := 0; i < numNodes; i++ {
		for j := 0; j < numNodes; j++ {
			if j != i {
				dist[i+j*numNodes] = math.Inf(1)
			}
		}
	}

	for _, node := range nodes {
		for _, succ := range successors(node) {
			dist[node.ID()+succ.ID()*numNodes] = cost(node, succ)
		}
	}

	for k := 0; k < numNodes; k++ {
		for i := 0; i < numNodes; i++ {
			for j := 0; j < numNodes; j++ {
				if dist[i+j*numNodes] > dist[i+k*numNodes]+dist[k+j*numNodes] {
					dist[i+j*numNodes] = dist[i+k*numNodes] + dist[k+j*numNodes]

					// Avoid generating too much garbage by reusing the memory in the list if we've allocated one already
					if next[i+j*numNodes] == nil {
						next[i+j*numNodes] = []int{k}
					} else {
						next[i+j*numNodes] = next[i+j*numNodes][:1]
						next[i+j*numNodes][0] = k
					}
					// If the cost between the nodes happens to be the same cost as what we know, add the approriate
					// intermediary to the list
				} else if math.Abs(dist[i+k*numNodes]+dist[k+j*numNodes]-dist[i+j*numNodes]) < 0.00001 && i != k && i != j && j != k {
					next[i+j*numNodes] = append(next[i+j*numNodes], k)
				}
			}
		}
	}

	return genAllPathsFunc(dist, next, nodes, graph, cost, isSuccessor), genSinglePathFunc(dist, next, nodes)
}

func genAllPathsFunc(dist []float64, next [][]int, nodes []gr.Node, graph gr.Graph, cost func(gr.Node, gr.Node) float64, isSuccessor func(gr.Node, gr.Node) bool) func(start, goal gr.Node) ([][]gr.Node, float64, error) {
	numNodes := len(nodes)

	// A recursive function to reconstruct all possible paths.
	// It's not fast, but it's about as fast as can be reasonably expected
	var allPathFinder func(i, j int) ([][]gr.Node, error)
	allPathFinder = func(i, j int) ([][]gr.Node, error) {
		if dist[i+j*numNodes] == math.Inf(1) {
			return nil, errors.New("No path")
		}
		intermediates := next[i+j*numNodes]
		if intermediates == nil || len(intermediates) == 0 {
			// There is exactly one path
			return [][]gr.Node{[]gr.Node{}}, nil
		}

		toReturn := make([][]gr.Node, 0, len(intermediates))
		// Special case: if intermediates exist we need to explicitly check to see if the i and j is also an optimal path
		if isSuccessor(nodes[i], nodes[j]) && math.Abs(dist[i+j*numNodes]-cost(nodes[i], nodes[j])) < .000001 {
			toReturn = append(toReturn, []gr.Node{nodes[i], nodes[j]})
		}

		// This step is a tad convoluted: we have some list of intermediates.
		// We can think of each intermediate as a path junction
		//
		// At this junction, we can find all the shortest paths back to i,
		// and all the shortest paths down to j. Since this is a junction,
		// any predecessor path that runs through this intermediate may
		// freely choose any successor path to get to j. They'll all be
		// of equivalent length.
		//
		// Thus, for each intermediate, we run through and join each predecessor
		// path with each successor path via its junction.
		for _, intermediate := range intermediates {

			// Find predecessors
			preds, err := allPathFinder(i, intermediate)
			if err != nil {
				return nil, err
			}

			// Join each predecessor with its junction
			for a := range preds {
				preds[a] = append(preds[a], nodes[intermediate])
			}

			// Find successors
			succs, err := allPathFinder(intermediate, j)
			if err != nil {
				return nil, err
			}

			// Join each successor with its predecessor at the junction.
			// (the copying stuff is because slices are reference types)
			for a := range succs {
				for b := range preds {
					path := make([]gr.Node, len(succs[a]), len(succs[a])+len(preds[b]))
					copy(path, succs[a])
					path = append(path, preds[b]...)
					toReturn = append(toReturn, path)
				}
			}

		}

		return toReturn, nil
	}

	return func(start, goal gr.Node) ([][]gr.Node, float64, error) {
		paths, err := allPathFinder(start.ID(), goal.ID())
		if err != nil {
			return nil, math.Inf(1), nil
		}

		for i := range paths {
			// Prepend start and postpend goal, but don't repeat start/goal

			if len(paths[i]) != 0 {
				if paths[i][0].ID() != start.ID() {
					paths[i] = append(paths[i], nil)
					copy(paths[i][1:], paths[i][:len(paths[i])-1])
					paths[i][0] = start
				}

				if paths[i][len(paths[i])-1].ID() != goal.ID() {
					paths[i] = append(paths[i], goal)
				}
			} else {
				paths[i] = append(paths[i], start, goal)
			}
		}

		return paths, dist[start.ID()+goal.ID()*numNodes], nil
	}
}

func genSinglePathFunc(dist []float64, next [][]int, nodes []gr.Node) func(start, goal gr.Node) ([]gr.Node, float64, error) {
	numNodes := len(nodes)

	var singlePathFinder func(i, j int) ([]gr.Node, error)
	singlePathFinder = func(i, j int) ([]gr.Node, error) {
		if dist[i+j*numNodes] == math.Inf(1) {
			return nil, errors.New("No path")
		}

		intermediates := next[i+j*numNodes]
		if intermediates == nil || len(intermediates) == 0 {
			return []gr.Node{}, nil
		}

		intermediate := intermediates[0]
		path, err := singlePathFinder(i, intermediate)
		if err != nil {
			return nil, err
		}

		path = append(path, nodes[intermediate])
		p, err := singlePathFinder(intermediate, j)
		if err != nil {
			return nil, err
		}
		path = append(path, p...)

		return path, nil
	}

	return func(start, goal gr.Node) ([]gr.Node, float64, error) {
		path, err := singlePathFinder(start.ID(), goal.ID())
		if err != nil {
			return nil, math.Inf(1), nil
		}

		path = append(path, nil)
		copy(path[1:], path[:len(path)-1])
		path[0] = start
		path = append(path, goal)

		return path, dist[start.ID()+goal.ID()*numNodes], nil
	}
}
<commit_msg>Made FW comment better<commit_after>package search

import (
	"errors"
	"math"
	"sort"

	gr "github.com/gonum/graph"
)

// Finds all shortest paths between start and goal
type AllPathFunc func(start, goal gr.Node) (path [][]gr.Node, cost float64, err error)

// Finds one path between start and goal, which it finds is arbitrary
type PathFunc func(start, goal gr.Node) (path []gr.Node, cost float64, err error)

// This function returns two functions: one that will generate all shortest paths between two nodes with ids i and j, and one that will generate just one path.
//
// This algorithm requires the CrunchGraph interface which means it only works on graphs with dense node ids since it uses an adjacency matrix.
//
// This algorithm isn't blazingly fast, but is relatively fast for the domain. It runs at O((number of vertices)^3) in best, worst, and average case,
//  and successfully computes the cost between all pairs of vertices.
//
// This function operates slightly differently from the others for convenience -- rather than generating paths and returning them to you,
// it gives you the option of calling one of two functions for each start/goal pair you need info for. One will return the path, cost,
// or an error if no path exists.
//
// The other will return the cost and an error if no path exists, but it will also return ALL possible shortest paths between start and goal.
// This is not too much more expensive than generating one path, but it does obviously increase with the number of paths.
func FloydWarshall(graph gr.CrunchGraph, cost func(gr.Node, gr.Node) float64) (AllPathFunc, PathFunc) {
	graph.Crunch()
	successors, _, _, isSuccessor, _, _, cost, _ := setupFuncs(graph, cost, nil)

	nodes := denseNodeSorter(graph.NodeList())
	sort.Sort(nodes)
	numNodes := len(nodes)

	dist := make([]float64, numNodes*numNodes)
	next := make([][]int, numNodes*numNodes)
	for i := 0; i < numNodes; i++ {
		for j := 0; j < numNodes; j++ {
			if j != i {
				dist[i+j*numNodes] = math.Inf(1)
			}
		}
	}

	for _, node := range nodes {
		for _, succ := range successors(node) {
			dist[node.ID()+succ.ID()*numNodes] = cost(node, succ)
		}
	}

	for k := 0; k < numNodes; k++ {
		for i := 0; i < numNodes; i++ {
			for j := 0; j < numNodes; j++ {
				if dist[i+j*numNodes] > dist[i+k*numNodes]+dist[k+j*numNodes] {
					dist[i+j*numNodes] = dist[i+k*numNodes] + dist[k+j*numNodes]

					// Avoid generating too much garbage by reusing the memory in the list if we've allocated one already
					if next[i+j*numNodes] == nil {
						next[i+j*numNodes] = []int{k}
					} else {
						next[i+j*numNodes] = next[i+j*numNodes][:1]
						next[i+j*numNodes][0] = k
					}
					// If the cost between the nodes happens to be the same cost as what we know, add the approriate
					// intermediary to the list
				} else if math.Abs(dist[i+k*numNodes]+dist[k+j*numNodes]-dist[i+j*numNodes]) < 0.00001 && i != k && i != j && j != k {
					next[i+j*numNodes] = append(next[i+j*numNodes], k)
				}
			}
		}
	}

	return genAllPathsFunc(dist, next, nodes, graph, cost, isSuccessor), genSinglePathFunc(dist, next, nodes)
}

func genAllPathsFunc(dist []float64, next [][]int, nodes []gr.Node, graph gr.Graph, cost func(gr.Node, gr.Node) float64, isSuccessor func(gr.Node, gr.Node) bool) func(start, goal gr.Node) ([][]gr.Node, float64, error) {
	numNodes := len(nodes)

	// A recursive function to reconstruct all possible paths.
	// It's not fast, but it's about as fast as can be reasonably expected
	var allPathFinder func(i, j int) ([][]gr.Node, error)
	allPathFinder = func(i, j int) ([][]gr.Node, error) {
		if dist[i+j*numNodes] == math.Inf(1) {
			return nil, errors.New("No path")
		}
		intermediates := next[i+j*numNodes]
		if intermediates == nil || len(intermediates) == 0 {
			// There is exactly one path
			return [][]gr.Node{[]gr.Node{}}, nil
		}

		toReturn := make([][]gr.Node, 0, len(intermediates))
		// Special case: if intermediates exist we need to explicitly check to see if the i and j is also an optimal path
		if isSuccessor(nodes[i], nodes[j]) && math.Abs(dist[i+j*numNodes]-cost(nodes[i], nodes[j])) < .000001 {
			toReturn = append(toReturn, []gr.Node{nodes[i], nodes[j]})
		}

		// This step is a tad convoluted: we have some list of intermediates.
		// We can think of each intermediate as a path junction
		//
		// At this junction, we can find all the shortest paths back to i,
		// and all the shortest paths down to j. Since this is a junction,
		// any predecessor path that runs through this intermediate may
		// freely choose any successor path to get to j. They'll all be
		// of equivalent length.
		//
		// Thus, for each intermediate, we run through and join each predecessor
		// path with each successor path via its junction.
		for _, intermediate := range intermediates {

			// Find predecessors
			preds, err := allPathFinder(i, intermediate)
			if err != nil {
				return nil, err
			}

			// Join each predecessor with its junction
			for a := range preds {
				preds[a] = append(preds[a], nodes[intermediate])
			}

			// Find successors
			succs, err := allPathFinder(intermediate, j)
			if err != nil {
				return nil, err
			}

			// Join each successor with its predecessor at the junction.
			// (the copying stuff is because slices are reference types)
			for a := range succs {
				for b := range preds {
					path := make([]gr.Node, len(succs[a]), len(succs[a])+len(preds[b]))
					copy(path, succs[a])
					path = append(path, preds[b]...)
					toReturn = append(toReturn, path)
				}
			}

		}

		return toReturn, nil
	}

	return func(start, goal gr.Node) ([][]gr.Node, float64, error) {
		paths, err := allPathFinder(start.ID(), goal.ID())
		if err != nil {
			return nil, math.Inf(1), nil
		}

		for i := range paths {
			// Prepend start and postpend goal, but don't repeat start/goal

			if len(paths[i]) != 0 {
				if paths[i][0].ID() != start.ID() {
					paths[i] = append(paths[i], nil)
					copy(paths[i][1:], paths[i][:len(paths[i])-1])
					paths[i][0] = start
				}

				if paths[i][len(paths[i])-1].ID() != goal.ID() {
					paths[i] = append(paths[i], goal)
				}
			} else {
				paths[i] = append(paths[i], start, goal)
			}
		}

		return paths, dist[start.ID()+goal.ID()*numNodes], nil
	}
}

func genSinglePathFunc(dist []float64, next [][]int, nodes []gr.Node) func(start, goal gr.Node) ([]gr.Node, float64, error) {
	numNodes := len(nodes)

	var singlePathFinder func(i, j int) ([]gr.Node, error)
	singlePathFinder = func(i, j int) ([]gr.Node, error) {
		if dist[i+j*numNodes] == math.Inf(1) {
			return nil, errors.New("No path")
		}

		intermediates := next[i+j*numNodes]
		if intermediates == nil || len(intermediates) == 0 {
			return []gr.Node{}, nil
		}

		intermediate := intermediates[0]
		path, err := singlePathFinder(i, intermediate)
		if err != nil {
			return nil, err
		}

		path = append(path, nodes[intermediate])
		p, err := singlePathFinder(intermediate, j)
		if err != nil {
			return nil, err
		}
		path = append(path, p...)

		return path, nil
	}

	return func(start, goal gr.Node) ([]gr.Node, float64, error) {
		path, err := singlePathFinder(start.ID(), goal.ID())
		if err != nil {
			return nil, math.Inf(1), nil
		}

		path = append(path, nil)
		copy(path[1:], path[:len(path)-1])
		path[0] = start
		path = append(path, goal)

		return path, dist[start.ID()+goal.ID()*numNodes], nil
	}
}
<|endoftext|>


<commit_before>package option

type Option struct {
	NoColor bool `long:"nocolor" description:"Don't print color codes in results (Disabled by default)"`
	NoGroup bool `long:"nogroup" description:"Don't print file name at header (Disabled by default)"`
}
<commit_msg>Added a option for VCS Ignore files.<commit_after>package option

type Option struct {
	NoColor   bool     `long:"nocolor" description:"Don't print color codes in results (Disabled by default)"`
	NoGroup   bool     `long:"nogroup" description:"Don't print file name at header (Disabled by default)"`
	VcsIgnore []string `long:"vsc-ignore" description:"VCS ignore files (Default: .gitignore)"`
}

func (self *Option) VcsIgnores() []string {
	if len(self.VcsIgnore) == 0 {
		self.VcsIgnore = []string{".gitignore"}
	}
	return self.VcsIgnore
}
<|endoftext|>


<commit_before>package azurerm

import (
	"fmt"
	"log"
	"regexp"

	"github.com/Azure/azure-sdk-for-go/arm/trafficmanager"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmTrafficManagerEndpoint() *schema.Resource {
	return &schema.Resource{
		Create: resourceArmTrafficManagerEndpointCreate,
		Read:   resourceArmTrafficManagerEndpointRead,
		Update: resourceArmTrafficManagerEndpointCreate,
		Delete: resourceArmTrafficManagerEndpointDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"type": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
				ValidateFunc: validation.StringInSlice([]string{
					"azureEndpoints",
					"nestedEndpoints",
					"externalEndpoints",
				}, false),
			},

			"profile_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"target": {
				Type:     schema.TypeString,
				Optional: true,
				// when targeting an Azure resource the FQDN of that resource will be set as the target
				Computed: true,
			},

			"target_resource_id": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"endpoint_status": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
			},

			"weight": {
				Type:         schema.TypeInt,
				Optional:     true,
				Computed:     true,
				ValidateFunc: validation.IntBetween(1, 1000),
			},

			"priority": {
				Type:         schema.TypeInt,
				Optional:     true,
				Computed:     true,
				ValidateFunc: validation.IntBetween(1, 1000),
			},

			// when targeting an Azure resource the location of that resource will be set on the endpoint
			"endpoint_location": {
				Type:             schema.TypeString,
				Optional:         true,
				Computed:         true,
				StateFunc:        azureRMNormalizeLocation,
				DiffSuppressFunc: azureRMSuppressLocationDiff,
			},

			"min_child_endpoints": {
				Type:     schema.TypeInt,
				Optional: true,
			},

			"resource_group_name": resourceGroupNameDiffSuppressSchema(),
		},
	}
}

func resourceArmTrafficManagerEndpointCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).trafficManagerEndpointsClient

	log.Printf("[INFO] preparing arguments for ARM TrafficManager Endpoint creation.")

	name := d.Get("name").(string)
	endpointType := d.Get("type").(string)
	fullEndpointType := fmt.Sprintf("Microsoft.Network/TrafficManagerProfiles/%s", endpointType)
	profileName := d.Get("profile_name").(string)
	resGroup := d.Get("resource_group_name").(string)

	params := trafficmanager.Endpoint{
		Name:               &name,
		Type:               &fullEndpointType,
		EndpointProperties: getArmTrafficManagerEndpointProperties(d),
	}

	_, err := client.CreateOrUpdate(resGroup, profileName, endpointType, name, params)
	if err != nil {
		return err
	}

	read, err := client.Get(resGroup, profileName, endpointType, name)
	if err != nil {
		return err
	}
	if read.ID == nil {
		return fmt.Errorf("Cannot read TrafficManager endpoint %s (resource group %s) ID", name, resGroup)
	}

	d.SetId(*read.ID)

	return resourceArmTrafficManagerEndpointRead(d, meta)
}

func resourceArmTrafficManagerEndpointRead(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).trafficManagerEndpointsClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup

	// lookup endpointType in Azure ID path
	var endpointType string
	typeRegex := regexp.MustCompile("azureEndpoints|externalEndpoints|nestedEndpoints")
	for k := range id.Path {
		if typeRegex.MatchString(k) {
			endpointType = k
		}
	}
	profileName := id.Path["trafficManagerProfiles"]

	// endpoint name is keyed by endpoint type in ARM ID
	name := id.Path[endpointType]

	resp, err := client.Get(resGroup, profileName, endpointType, name)
	if err != nil {
		if utils.ResponseWasNotFound(resp.Response) {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error making Read request on TrafficManager Endpoint %s: %+v", name, err)
	}

	endpoint := *resp.EndpointProperties

	d.Set("resource_group_name", resGroup)
	d.Set("name", resp.Name)
	d.Set("type", endpointType)
	d.Set("profile_name", profileName)
	d.Set("endpoint_status", endpoint.EndpointStatus)
	d.Set("target_resource_id", endpoint.TargetResourceID)
	d.Set("target", endpoint.Target)
	d.Set("weight", endpoint.Weight)
	d.Set("priority", endpoint.Priority)
	d.Set("endpoint_location", endpoint.EndpointLocation)
	d.Set("endpoint_monitor_status", endpoint.EndpointMonitorStatus)
	d.Set("min_child_endpoints", endpoint.MinChildEndpoints)

	return nil
}

func resourceArmTrafficManagerEndpointDelete(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).trafficManagerEndpointsClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	endpointType := d.Get("type").(string)
	profileName := id.Path["trafficManagerProfiles"]

	// endpoint name is keyed by endpoint type in ARM ID
	name := id.Path[endpointType]

	_, err = client.Delete(resGroup, profileName, endpointType, name)

	return err
}

func getArmTrafficManagerEndpointProperties(d *schema.ResourceData) *trafficmanager.EndpointProperties {
	var endpointProps trafficmanager.EndpointProperties

	if targetResID := d.Get("target_resource_id").(string); targetResID != "" {
		endpointProps.TargetResourceID = &targetResID
	}

	if target := d.Get("target").(string); target != "" {
		endpointProps.Target = &target
	}

	if status := d.Get("endpoint_status").(string); status != "" {
		endpointProps.EndpointStatus = &status
	}

	if weight := d.Get("weight").(int); weight != 0 {
		w64 := int64(weight)
		endpointProps.Weight = &w64
	}

	if priority := d.Get("priority").(int); priority != 0 {
		p64 := int64(priority)
		endpointProps.Priority = &p64
	}

	if location := d.Get("endpoint_location").(string); location != "" {
		endpointProps.EndpointLocation = &location
	}

	if minChildEndpoints := d.Get("min_child_endpoints").(int); minChildEndpoints != 0 {
		mci64 := int64(minChildEndpoints)
		endpointProps.MinChildEndpoints = &mci64
	}

	return &endpointProps
}
<commit_msg>Fixing Traffic Manager Endpoints<commit_after>package azurerm

import (
	"fmt"
	"log"
	"regexp"

	"github.com/Azure/azure-sdk-for-go/arm/trafficmanager"
	"github.com/hashicorp/terraform/helper/schema"
	"github.com/hashicorp/terraform/helper/validation"
	"github.com/terraform-providers/terraform-provider-azurerm/azurerm/utils"
)

func resourceArmTrafficManagerEndpoint() *schema.Resource {
	return &schema.Resource{
		Create: resourceArmTrafficManagerEndpointCreate,
		Read:   resourceArmTrafficManagerEndpointRead,
		Update: resourceArmTrafficManagerEndpointCreate,
		Delete: resourceArmTrafficManagerEndpointDelete,
		Importer: &schema.ResourceImporter{
			State: schema.ImportStatePassthrough,
		},

		Schema: map[string]*schema.Schema{
			"name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"type": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
				ValidateFunc: validation.StringInSlice([]string{
					"azureEndpoints",
					"nestedEndpoints",
					"externalEndpoints",
				}, false),
			},

			"profile_name": {
				Type:     schema.TypeString,
				Required: true,
				ForceNew: true,
			},

			"target": {
				Type:     schema.TypeString,
				Optional: true,
				// when targeting an Azure resource the FQDN of that resource will be set as the target
				Computed: true,
			},

			"target_resource_id": {
				Type:     schema.TypeString,
				Optional: true,
			},

			"endpoint_status": {
				Type:     schema.TypeString,
				Optional: true,
				Computed: true,
				ValidateFunc: validation.StringInSlice([]string{
					string(trafficmanager.EndpointStatusDisabled),
					string(trafficmanager.EndpointStatusEnabled),
				}, true),
				DiffSuppressFunc: ignoreCaseDiffSuppressFunc,
			},

			"weight": {
				Type:         schema.TypeInt,
				Optional:     true,
				Computed:     true,
				ValidateFunc: validation.IntBetween(1, 1000),
			},

			"priority": {
				Type:         schema.TypeInt,
				Optional:     true,
				Computed:     true,
				ValidateFunc: validation.IntBetween(1, 1000),
			},

			// when targeting an Azure resource the location of that resource will be set on the endpoint
			"endpoint_location": {
				Type:             schema.TypeString,
				Optional:         true,
				Computed:         true,
				StateFunc:        azureRMNormalizeLocation,
				DiffSuppressFunc: azureRMSuppressLocationDiff,
			},

			"min_child_endpoints": {
				Type:     schema.TypeInt,
				Optional: true,
			},

			"resource_group_name": resourceGroupNameDiffSuppressSchema(),
		},
	}
}

func resourceArmTrafficManagerEndpointCreate(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).trafficManagerEndpointsClient

	log.Printf("[INFO] preparing arguments for ARM TrafficManager Endpoint creation.")

	name := d.Get("name").(string)
	endpointType := d.Get("type").(string)
	fullEndpointType := fmt.Sprintf("Microsoft.Network/TrafficManagerProfiles/%s", endpointType)
	profileName := d.Get("profile_name").(string)
	resGroup := d.Get("resource_group_name").(string)

	params := trafficmanager.Endpoint{
		Name:               &name,
		Type:               &fullEndpointType,
		EndpointProperties: getArmTrafficManagerEndpointProperties(d),
	}

	_, err := client.CreateOrUpdate(resGroup, profileName, endpointType, name, params)
	if err != nil {
		return err
	}

	read, err := client.Get(resGroup, profileName, endpointType, name)
	if err != nil {
		return err
	}
	if read.ID == nil {
		return fmt.Errorf("Cannot read TrafficManager endpoint %s (resource group %s) ID", name, resGroup)
	}

	d.SetId(*read.ID)

	return resourceArmTrafficManagerEndpointRead(d, meta)
}

func resourceArmTrafficManagerEndpointRead(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).trafficManagerEndpointsClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup

	// lookup endpointType in Azure ID path
	var endpointType string
	typeRegex := regexp.MustCompile("azureEndpoints|externalEndpoints|nestedEndpoints")
	for k := range id.Path {
		if typeRegex.MatchString(k) {
			endpointType = k
		}
	}
	profileName := id.Path["trafficManagerProfiles"]

	// endpoint name is keyed by endpoint type in ARM ID
	name := id.Path[endpointType]

	resp, err := client.Get(resGroup, profileName, endpointType, name)
	if err != nil {
		if utils.ResponseWasNotFound(resp.Response) {
			d.SetId("")
			return nil
		}
		return fmt.Errorf("Error making Read request on TrafficManager Endpoint %s: %+v", name, err)
	}

	endpoint := *resp.EndpointProperties

	d.Set("resource_group_name", resGroup)
	d.Set("name", resp.Name)
	d.Set("type", endpointType)
	d.Set("profile_name", profileName)
	d.Set("endpoint_status", string(endpoint.EndpointStatus))
	d.Set("target_resource_id", endpoint.TargetResourceID)
	d.Set("target", endpoint.Target)
	d.Set("weight", endpoint.Weight)
	d.Set("priority", endpoint.Priority)
	d.Set("endpoint_location", endpoint.EndpointLocation)
	d.Set("endpoint_monitor_status", endpoint.EndpointMonitorStatus)
	d.Set("min_child_endpoints", endpoint.MinChildEndpoints)

	return nil
}

func resourceArmTrafficManagerEndpointDelete(d *schema.ResourceData, meta interface{}) error {
	client := meta.(*ArmClient).trafficManagerEndpointsClient

	id, err := parseAzureResourceID(d.Id())
	if err != nil {
		return err
	}
	resGroup := id.ResourceGroup
	endpointType := d.Get("type").(string)
	profileName := id.Path["trafficManagerProfiles"]

	// endpoint name is keyed by endpoint type in ARM ID
	name := id.Path[endpointType]

	_, err = client.Delete(resGroup, profileName, endpointType, name)

	return err
}

func getArmTrafficManagerEndpointProperties(d *schema.ResourceData) *trafficmanager.EndpointProperties {
	var endpointProps trafficmanager.EndpointProperties

	if targetResID := d.Get("target_resource_id").(string); targetResID != "" {
		endpointProps.TargetResourceID = &targetResID
	}

	if target := d.Get("target").(string); target != "" {
		endpointProps.Target = &target
	}

	if status := d.Get("endpoint_status").(string); status != "" {
		endpointProps.EndpointStatus = trafficmanager.EndpointStatus(status)
	}

	if weight := d.Get("weight").(int); weight != 0 {
		w64 := int64(weight)
		endpointProps.Weight = &w64
	}

	if priority := d.Get("priority").(int); priority != 0 {
		p64 := int64(priority)
		endpointProps.Priority = &p64
	}

	if location := d.Get("endpoint_location").(string); location != "" {
		endpointProps.EndpointLocation = &location
	}

	if minChildEndpoints := d.Get("min_child_endpoints").(int); minChildEndpoints != 0 {
		mci64 := int64(minChildEndpoints)
		endpointProps.MinChildEndpoints = &mci64
	}

	return &endpointProps
}
<|endoftext|>


<commit_before>// Package kut provides column cutting for CSV (RFC 4180) files.
package kut

import (
	"bufio"
	"encoding/csv"
	"io"
)

// A ColRange specifies a range of columns to include. Column numbers begin at
// 1. Both Start and End are inclusive.
type ColRange struct {
	Start int
	End   int
}

// EOL can be used as the End in a ColRange to include all remaining columns.
const EOL = int(^uint(0) >> 1)

const lf = byte('\n')
const cr = byte('\r')

// A Cutter reads from an input CSV file and writes only the specified columns
// to an output file.
type Cutter struct {
	buf    *bufio.Reader
	i      *csv.Reader
	o      *csv.Writer
	Ranges []ColRange
}

// NewCutter returns a Cutter that reads from r and writes to w.
func NewCutter(r io.Reader, w io.Writer) *Cutter {
	bufReader := bufio.NewReader(r)
	c := &Cutter{
		buf: bufReader,
		i:   csv.NewReader(bufReader),
		o:   csv.NewWriter(w),
	}
	c.i.FieldsPerRecord = -1
	c.i.LazyQuotes = true
	return c
}

func (c *Cutter) isIncluded(colNum int) bool {
	for _, r := range c.Ranges {
		if colNum >= r.Start && colNum <= r.End {
			return true
		}
	}
	return false
}

// Scan advances one record on the input, outputting only the columns specified
// in Ranges. If there is no input left to read, Scan returns io.EOF.
func (c *Cutter) Scan() error {
	err := c.scan()
	if err != nil {
		return err
	}
	return c.flush()
}

// This is like csv.Reader.Read, except it doesn't skip blank-line records,
// instead returning a nil slice in that case.
func (c *Cutter) read() ([]string, error) {
	bytes, err := c.buf.Peek(1)
	if err == nil && bytes[0] == lf {
		c.buf.Discard(1)
		return nil, nil
	}
	bytes, err = c.buf.Peek(2)
	if err == nil && bytes[0] == cr && bytes[1] == lf {
		c.buf.Discard(2)
		return nil, nil
	}
	return c.i.Read()
}

func (c *Cutter) scan() error {
	inputRecord, err := c.read()
	if err != nil {
		return err
	}
	var outputRecord []string
	for i, value := range inputRecord {
		colNum := i + 1 // column numbers begin at 1
		if c.isIncluded(colNum) {
			outputRecord = append(outputRecord, value)
		}
	}
	return c.o.Write(outputRecord)
}

func (c *Cutter) flush() error {
	c.o.Flush()
	return c.o.Error()
}

// ScanAll advances to the end of the input, outputting only the columns
// specified in Ranges. Because ScanAll deliberately reads until EOF, it does
// not report EOF as an error.
func (c *Cutter) ScanAll() error {
	for {
		err := c.scan()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
	}
	return c.flush()
}

// SetDelimiter sets the field delimiter, which defaults to a comma.
func (c *Cutter) SetDelimiter(d rune) {
	c.i.Comma = d
	c.o.Comma = d
}

// Delimiter returns the field delimiter.
func (c *Cutter) Delimiter() rune {
	return c.i.Comma
}
<commit_msg>Fix documentation<commit_after>// Package kut provides column cutting for CSV (RFC 4180) files.
package kut

import (
	"bufio"
	"encoding/csv"
	"io"
)

// A ColRange specifies a range of columns to include. Column numbers begin at
// 1. Both Start and End are inclusive.
type ColRange struct {
	Start int
	End   int
}

// EOL can be used as the End in a ColRange to include all remaining columns.
const EOL = int(^uint(0) >> 1)

const lf = byte('\n')
const cr = byte('\r')

// A Cutter reads from an input CSV and writes only the specified columns to an
// output CSV.
type Cutter struct {
	buf    *bufio.Reader
	i      *csv.Reader
	o      *csv.Writer
	Ranges []ColRange
}

// NewCutter returns a Cutter that reads from r and writes to w.
func NewCutter(r io.Reader, w io.Writer) *Cutter {
	bufReader := bufio.NewReader(r)
	c := &Cutter{
		buf: bufReader,
		i:   csv.NewReader(bufReader),
		o:   csv.NewWriter(w),
	}
	c.i.FieldsPerRecord = -1
	c.i.LazyQuotes = true
	return c
}

func (c *Cutter) isIncluded(colNum int) bool {
	for _, r := range c.Ranges {
		if colNum >= r.Start && colNum <= r.End {
			return true
		}
	}
	return false
}

// Scan advances one record on the input, outputting only the columns specified
// in Ranges. If there is no input left to read, Scan returns io.EOF.
func (c *Cutter) Scan() error {
	err := c.scan()
	if err != nil {
		return err
	}
	return c.flush()
}

// This is like csv.Reader.Read, except it doesn't skip blank-line records,
// instead returning a nil slice in that case.
func (c *Cutter) read() ([]string, error) {
	bytes, err := c.buf.Peek(1)
	if err == nil && bytes[0] == lf {
		c.buf.Discard(1)
		return nil, nil
	}
	bytes, err = c.buf.Peek(2)
	if err == nil && bytes[0] == cr && bytes[1] == lf {
		c.buf.Discard(2)
		return nil, nil
	}
	return c.i.Read()
}

func (c *Cutter) scan() error {
	inputRecord, err := c.read()
	if err != nil {
		return err
	}
	var outputRecord []string
	for i, value := range inputRecord {
		colNum := i + 1 // column numbers begin at 1
		if c.isIncluded(colNum) {
			outputRecord = append(outputRecord, value)
		}
	}
	return c.o.Write(outputRecord)
}

func (c *Cutter) flush() error {
	c.o.Flush()
	return c.o.Error()
}

// ScanAll advances to the end of the input, outputting only the columns
// specified in Ranges. Because ScanAll deliberately reads until EOF, it does
// not report EOF as an error.
func (c *Cutter) ScanAll() error {
	for {
		err := c.scan()
		if err == io.EOF {
			break
		}
		if err != nil {
			return err
		}
	}
	return c.flush()
}

// SetDelimiter sets the field delimiter, which defaults to a comma.
func (c *Cutter) SetDelimiter(d rune) {
	c.i.Comma = d
	c.o.Comma = d
}

// Delimiter returns the field delimiter.
func (c *Cutter) Delimiter() rune {
	return c.i.Comma
}
<|endoftext|>


<commit_before>/*
CompileDaemon is a very simple compile daemon for Go.

CompileDaemon watches your .go files in a directory and invokes `go build`
if a file changes.

Examples

In its simplest form, the defaults will do. With the current working directory set
to the source directory you can simply…

    $ CompileDaemon

… and it will recompile your code whenever you save a source file.

If you want it to also run your program each time it builds you might add…

    $ CompileDaemon -command="./MyProgram -my-options"

… and it will also keep a copy of your program running. Killing the old one and
starting a new one each time you build. For advanced usage you can also supply
the changed file to the command by doing…

	$ CompileDaemon -command="./MyProgram -my-options %[1]s"

…but note that this will not be set on the first start.

You may find that you need to exclude some directories and files from
monitoring, such as a .git repository or emacs temporary files…

    $ CompileDaemon -exclude-dir=.git -exclude=".#*"

If you want to monitor files other than .go and .c files you might…

    $ CompileDaemon -include=Makefile -include="*.less" -include="*.tmpl"

Options

There are command line options.

	FILE SELECTION
	-directory=XXX    – Which directory to monitor for changes
	-recursive=XXX    – Look into subdirectories
	-exclude-dir=XXX  – Exclude directories matching glob pattern XXX
	-exlude=XXX       – Exclude files whose basename matches glob pattern XXX
	-include=XXX      – Include files whose basename matches glob pattern XXX
	-pattern=XXX      – Include files whose path matches regexp XXX

	MISC
	-color            - Enable colorized output
	-log-prefix       - Enable/disable stdout/stderr labelling for the child process
	-graceful-kill    - On supported platforms, send the child process a SIGTERM to
	                    allow it to exit gracefully if possible.
	-graceful-timeout - Duration (in seconds) to wait for graceful kill to complete
	-verbose          - Print information about watched directories.

	ACTIONS
	-build=CCC        – Execute CCC to rebuild when a file changes
	-command=CCC      – Run command CCC after a successful build, stops previous command first

*/
package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"path/filepath"
	"regexp"
	"strings"
	"syscall"
	"time"

	"github.com/fatih/color"
	"github.com/fsnotify/fsnotify"
)

// Milliseconds to wait for the next job to begin after a file change
const WorkDelay = 900

// Default pattern to match files which trigger a build
const FilePattern = `(.+\.go|.+\.c)$`

type globList []string

func (g *globList) String() string {
	return fmt.Sprint(*g)
}
func (g *globList) Set(value string) error {
	*g = append(*g, filepath.Clean(value))
	return nil
}
func (g *globList) Matches(value string) bool {
	for _, v := range *g {
		if match, err := filepath.Match(v, value); err != nil {
			log.Fatalf("Bad pattern \"%s\": %s", v, err.Error())
		} else if match {
			return true
		}
	}
	return false
}

var (
	flagDirectory       = flag.String("directory", ".", "Directory to watch for changes")
	flagPattern         = flag.String("pattern", FilePattern, "Pattern of watched files")
	flagCommand         = flag.String("command", "", "Command to run and restart after build")
	flagCommandStop     = flag.Bool("command-stop", false, "Stop command before building")
	flagRecursive       = flag.Bool("recursive", true, "Watch all dirs. recursively")
	flagBuild           = flag.String("build", "go build", "Command to rebuild after changes")
	flagBuildDir        = flag.String("build-dir", "", "Directory to run build command in.  Defaults to directory")
	flagRunDir          = flag.String("run-dir", "", "Directory to run command in.  Defaults to directory")
	flagColor           = flag.Bool("color", false, "Colorize output for CompileDaemon status messages")
	flagLogPrefix       = flag.Bool("log-prefix", true, "Print log timestamps and subprocess stderr/stdout output")
	flagGracefulKill    = flag.Bool("graceful-kill", false, "Gracefully attempt to kill the child process by sending a SIGTERM first")
	flagGracefulTimeout = flag.Uint("graceful-timeout", 3, "Duration (in seconds) to wait for graceful kill to complete")
	flagVerbose         = flag.Bool("verbose", false, "Be verbose about which directories are watched.")

	// initialized in main() due to custom type.
	flagExcludedDirs  globList
	flagExcludedFiles globList
	flagIncludedFiles globList
)

func okColor(format string, args ...interface{}) string {
	if *flagColor {
		return color.GreenString(format, args...)
	} else {
		return fmt.Sprintf(format, args...)
	}
}

func failColor(format string, args ...interface{}) string {
	if *flagColor {
		return color.RedString(format, args...)
	} else {
		return fmt.Sprintf(format, args...)
	}
}

// Run `go build` and print the output if something's gone wrong.
func build() bool {
	log.Println(okColor("Running build command!"))

	args := strings.Split(*flagBuild, " ")
	if len(args) == 0 {
		// If the user has specified and empty then we are done.
		return true
	}

	cmd := exec.Command(args[0], args[1:]...)

	if *flagBuildDir != "" {
		cmd.Dir = *flagBuildDir
	} else {
		cmd.Dir = *flagDirectory
	}

	output, err := cmd.CombinedOutput()

	if err == nil {
		log.Println(okColor("Build ok."))
	} else {
		log.Println(failColor("Error while building:\n"), failColor(string(output)))
	}

	return err == nil
}

func matchesPattern(pattern *regexp.Regexp, file string) bool {
	return pattern.MatchString(file)
}

// Accept build jobs and start building when there are no jobs rushing in.
// The inrush protection is WorkDelay milliseconds long, in this period
// every incoming job will reset the timer.
func builder(jobs <-chan string, buildStarted chan<- string, buildDone chan<- bool) {
	createThreshold := func() <-chan time.Time {
		return time.After(time.Duration(WorkDelay * time.Millisecond))
	}

	threshold := createThreshold()
	eventPath := ""

	for {
		select {
		case eventPath = <-jobs:
			threshold = createThreshold()
		case <-threshold:
			buildStarted <- eventPath
			buildDone <- build()
		}
	}
}

func logger(pipeChan <-chan io.ReadCloser) {
	dumper := func(pipe io.ReadCloser, prefix string) {
		reader := bufio.NewReader(pipe)

	readloop:
		for {
			line, err := reader.ReadString('\n')

			if err != nil {
				break readloop
			}

			if *flagLogPrefix {
				log.Print(prefix, " ", line)
			} else {
				log.Print(line)
			}
		}
	}

	for {
		pipe := <-pipeChan
		go dumper(pipe, "stdout:")

		pipe = <-pipeChan
		go dumper(pipe, "stderr:")
	}
}

// Start the supplied command and return stdout and stderr pipes for logging.
func startCommand(command string) (cmd *exec.Cmd, stdout io.ReadCloser, stderr io.ReadCloser, err error) {
	args := strings.Split(command, " ")
	cmd = exec.Command(args[0], args[1:]...)

	if *flagRunDir != "" {
		cmd.Dir = *flagRunDir
	}

	if stdout, err = cmd.StdoutPipe(); err != nil {
		err = fmt.Errorf("can't get stdout pipe for command: %s", err)
		return
	}

	if stderr, err = cmd.StderrPipe(); err != nil {
		err = fmt.Errorf("can't get stderr pipe for command: %s", err)
		return
	}

	if err = cmd.Start(); err != nil {
		err = fmt.Errorf("can't start command: %s", err)
		return
	}

	return
}

// Run the command in the given string and restart it after
// a message was received on the buildDone channel.
func runner(commandTemplate string, buildStarted <-chan string, buildSuccess <-chan bool) {
	var currentProcess *os.Process
	pipeChan := make(chan io.ReadCloser)

	go logger(pipeChan)

	go func() {
		sigChan := make(chan os.Signal, 1)
		signal.Notify(sigChan, fatalSignals...)
		<-sigChan
		log.Println(okColor("Received signal, terminating cleanly."))
		if currentProcess != nil {
			killProcess(currentProcess)
		}
		os.Exit(0)
	}()

	for {
		eventPath := <-buildStarted

		// append %0.s to use format specifier even if not supplied by user
		// to suppress warning in returned string.
		command := fmt.Sprintf("%0.s"+commandTemplate, eventPath)

		if !*flagCommandStop {
			if !<-buildSuccess {
				continue
			}
		}

		if currentProcess != nil {
			killProcess(currentProcess)
		}
		if *flagCommandStop {
			log.Println(okColor("Command stopped. Waiting for build to complete."))
			if !<-buildSuccess {
				continue
			}
		}

		log.Println(okColor("Restarting the given command."))
		cmd, stdoutPipe, stderrPipe, err := startCommand(command)

		if err != nil {
			log.Fatal(failColor("Could not start command: %s", err))
		}

		pipeChan <- stdoutPipe
		pipeChan <- stderrPipe

		currentProcess = cmd.Process
	}
}

func killProcess(process *os.Process) {
	if *flagGracefulKill {
		killProcessGracefully(process)
	} else {
		killProcessHard(process)
	}
}

func killProcessHard(process *os.Process) {
	log.Println(okColor("Hard stopping the current process.."))

	if err := process.Kill(); err != nil {
		log.Println(failColor("Warning: could not kill child process.  It may have already exited."))
	}

	if _, err := process.Wait(); err != nil {
		log.Fatal(failColor("Could not wait for child process. Aborting due to danger of infinite forks."))
	}
}

func killProcessGracefully(process *os.Process) {
	done := make(chan error, 1)
	go func() {
		log.Println(okColor("Gracefully stopping the current process.."))
		if err := terminateGracefully(process); err != nil {
			done <- err
			return
		}
		_, err := process.Wait()
		done <- err
	}()

	select {
	case <-time.After(time.Duration(*flagGracefulTimeout) * time.Second):
		log.Println(failColor("Could not gracefully stop the current process, proceeding to hard stop."))
		killProcessHard(process)
		<-done
	case err := <-done:
		if err != nil {
			log.Fatal(failColor("Could not kill child process. Aborting due to danger of infinite forks."))
		}
	}
}

func flusher(buildStarted <-chan string, buildSuccess <-chan bool) {
	for {
		<-buildStarted
		<-buildSuccess
	}
}

func main() {
	flag.Var(&flagExcludedDirs, "exclude-dir", " Don't watch directories matching this name")
	flag.Var(&flagExcludedFiles, "exclude", " Don't watch files matching this name")
	flag.Var(&flagIncludedFiles, "include", " Watch files matching this name")

	flag.Parse()

	if !*flagLogPrefix {
		log.SetFlags(0)
	}

	if *flagDirectory == "" {
		fmt.Fprintf(os.Stderr, "-directory=... is required.\n")
		os.Exit(1)
	}

	if *flagGracefulKill && !gracefulTerminationPossible() {
		log.Fatal("Graceful termination is not supported on your platform.")
	}

	watcher, err := fsnotify.NewWatcher()

	if err != nil {
		log.Fatal(err)
	}

	defer watcher.Close()

	if *flagRecursive == true {
		err = filepath.Walk(*flagDirectory, func(path string, info os.FileInfo, err error) error {
			if err == nil && info.IsDir() {
				if flagExcludedDirs.Matches(path) {
					return filepath.SkipDir
				} else {
					if *flagVerbose {
						log.Printf("Watching directory '%s' for changes.\n", path)
					}
					return watcher.Add(path)
				}
			}
			return err
		})

		if err != nil {
			log.Fatal("filepath.Walk():", err)
		}

		if err := watcher.Add(*flagDirectory); err != nil {
			log.Fatal("watcher.Add():", err)
		}

	} else {
		if err := watcher.Add(*flagDirectory); err != nil {
			log.Fatal("watcher.Add():", err)
		}
	}

	pattern := regexp.MustCompile(*flagPattern)
	jobs := make(chan string)
	buildSuccess := make(chan bool)
	buildStarted := make(chan string)

	go builder(jobs, buildStarted, buildSuccess)

	if *flagCommand != "" {
		go runner(*flagCommand, buildStarted, buildSuccess)
	} else {
		go flusher(buildStarted, buildSuccess)
	}

	for {
		select {
		case ev := <-watcher.Events:
			if ev.Op&fsnotify.Remove == fsnotify.Remove || ev.Op&fsnotify.Write == fsnotify.Write || ev.Op&fsnotify.Create == fsnotify.Create {
				base := filepath.Base(ev.Name)

				// Assume it is a directory and track it.
				if *flagRecursive == true && !flagExcludedDirs.Matches(ev.Name) {
					watcher.Add(ev.Name)
				}

				if flagIncludedFiles.Matches(base) || matchesPattern(pattern, ev.Name) {
					if !flagExcludedFiles.Matches(base) {
						jobs <- ev.Name
					}
				}
			}

		case err := <-watcher.Errors:
			if v, ok := err.(*os.SyscallError); ok {
				if v.Err == syscall.EINTR {
					continue
				}
				log.Fatal("watcher.Error: SyscallError:", v)
			}
			log.Fatal("watcher.Error:", err)
		}
	}
}
<commit_msg>Clarify some code<commit_after>/*
CompileDaemon is a very simple compile daemon for Go.

CompileDaemon watches your .go files in a directory and invokes `go build`
if a file changes.

Examples

In its simplest form, the defaults will do. With the current working directory set
to the source directory you can simply…

    $ CompileDaemon

… and it will recompile your code whenever you save a source file.

If you want it to also run your program each time it builds you might add…

    $ CompileDaemon -command="./MyProgram -my-options"

… and it will also keep a copy of your program running. Killing the old one and
starting a new one each time you build. For advanced usage you can also supply
the changed file to the command by doing…

	$ CompileDaemon -command="./MyProgram -my-options %[1]s"

…but note that this will not be set on the first start.

You may find that you need to exclude some directories and files from
monitoring, such as a .git repository or emacs temporary files…

    $ CompileDaemon -exclude-dir=.git -exclude=".#*"

If you want to monitor files other than .go and .c files you might…

    $ CompileDaemon -include=Makefile -include="*.less" -include="*.tmpl"

Options

There are command line options.

	FILE SELECTION
	-directory=XXX    – Which directory to monitor for changes
	-recursive=XXX    – Look into subdirectories
	-exclude-dir=XXX  – Exclude directories matching glob pattern XXX
	-exlude=XXX       – Exclude files whose basename matches glob pattern XXX
	-include=XXX      – Include files whose basename matches glob pattern XXX
	-pattern=XXX      – Include files whose path matches regexp XXX

	MISC
	-color            - Enable colorized output
	-log-prefix       - Enable/disable stdout/stderr labelling for the child process
	-graceful-kill    - On supported platforms, send the child process a SIGTERM to
	                    allow it to exit gracefully if possible.
	-graceful-timeout - Duration (in seconds) to wait for graceful kill to complete
	-verbose          - Print information about watched directories.

	ACTIONS
	-build=CCC        – Execute CCC to rebuild when a file changes
	-command=CCC      – Run command CCC after a successful build, stops previous command first

*/
package main

import (
	"bufio"
	"flag"
	"fmt"
	"io"
	"log"
	"os"
	"os/exec"
	"os/signal"
	"path/filepath"
	"regexp"
	"strings"
	"syscall"
	"time"

	"github.com/fatih/color"
	"github.com/fsnotify/fsnotify"
)

// Milliseconds to wait for the next job to begin after a file change
const WorkDelay = 900

// Default pattern to match files which trigger a build
const FilePattern = `(.+\.go|.+\.c)$`

type globList []string

func (g *globList) String() string {
	return fmt.Sprint(*g)
}
func (g *globList) Set(value string) error {
	*g = append(*g, filepath.Clean(value))
	return nil
}
func (g *globList) Matches(value string) bool {
	for _, v := range *g {
		if match, err := filepath.Match(v, value); err != nil {
			log.Fatalf("Bad pattern \"%s\": %s", v, err.Error())
		} else if match {
			return true
		}
	}
	return false
}

var (
	flagDirectory       = flag.String("directory", ".", "Directory to watch for changes")
	flagPattern         = flag.String("pattern", FilePattern, "Pattern of watched files")
	flagCommand         = flag.String("command", "", "Command to run and restart after build")
	flagCommandStop     = flag.Bool("command-stop", false, "Stop command before building")
	flagRecursive       = flag.Bool("recursive", true, "Watch all dirs. recursively")
	flagBuild           = flag.String("build", "go build", "Command to rebuild after changes")
	flagBuildDir        = flag.String("build-dir", "", "Directory to run build command in.  Defaults to directory")
	flagRunDir          = flag.String("run-dir", "", "Directory to run command in.  Defaults to directory")
	flagColor           = flag.Bool("color", false, "Colorize output for CompileDaemon status messages")
	flagLogPrefix       = flag.Bool("log-prefix", true, "Print log timestamps and subprocess stderr/stdout output")
	flagGracefulKill    = flag.Bool("graceful-kill", false, "Gracefully attempt to kill the child process by sending a SIGTERM first")
	flagGracefulTimeout = flag.Uint("graceful-timeout", 3, "Duration (in seconds) to wait for graceful kill to complete")
	flagVerbose         = flag.Bool("verbose", false, "Be verbose about which directories are watched.")

	// initialized in main() due to custom type.
	flagExcludedDirs  globList
	flagExcludedFiles globList
	flagIncludedFiles globList
)

func okColor(format string, args ...interface{}) string {
	if *flagColor {
		return color.GreenString(format, args...)
	} else {
		return fmt.Sprintf(format, args...)
	}
}

func failColor(format string, args ...interface{}) string {
	if *flagColor {
		return color.RedString(format, args...)
	} else {
		return fmt.Sprintf(format, args...)
	}
}

// Run `go build` and print the output if something's gone wrong.
func build() bool {
	log.Println(okColor("Running build command!"))

	args := strings.Split(*flagBuild, " ")
	if len(args) == 0 {
		// If the user has specified and empty then we are done.
		return true
	}

	cmd := exec.Command(args[0], args[1:]...)

	if *flagBuildDir != "" {
		cmd.Dir = *flagBuildDir
	} else {
		cmd.Dir = *flagDirectory
	}

	output, err := cmd.CombinedOutput()

	if err == nil {
		log.Println(okColor("Build ok."))
	} else {
		log.Println(failColor("Error while building:\n"), failColor(string(output)))
	}

	return err == nil
}

func matchesPattern(pattern *regexp.Regexp, file string) bool {
	return pattern.MatchString(file)
}

// Accept build jobs and start building when there are no jobs rushing in.
// The inrush protection is WorkDelay milliseconds long, in this period
// every incoming job will reset the timer.
func builder(jobs <-chan string, buildStarted chan<- string, buildDone chan<- bool) {
	createThreshold := func() <-chan time.Time {
		return time.After(time.Duration(WorkDelay * time.Millisecond))
	}

	threshold := createThreshold()
	eventPath := ""

	for {
		select {
		case eventPath = <-jobs:
			threshold = createThreshold()
		case <-threshold:
			buildStarted <- eventPath
			buildDone <- build()
		}
	}
}

func logger(pipeChan <-chan io.ReadCloser) {
	dumper := func(pipe io.ReadCloser, prefix string) {
		reader := bufio.NewReader(pipe)

	readloop:
		for {
			line, err := reader.ReadString('\n')

			if err != nil {
				break readloop
			}

			if *flagLogPrefix {
				log.Print(prefix, " ", line)
			} else {
				log.Print(line)
			}
		}
	}

	for {
		pipe := <-pipeChan
		go dumper(pipe, "stdout:")

		pipe = <-pipeChan
		go dumper(pipe, "stderr:")
	}
}

// Start the supplied command and return stdout and stderr pipes for logging.
func startCommand(command string) (cmd *exec.Cmd, stdout io.ReadCloser, stderr io.ReadCloser, err error) {
	args := strings.Split(command, " ")
	cmd = exec.Command(args[0], args[1:]...)

	if *flagRunDir != "" {
		cmd.Dir = *flagRunDir
	}

	if stdout, err = cmd.StdoutPipe(); err != nil {
		err = fmt.Errorf("can't get stdout pipe for command: %s", err)
		return
	}

	if stderr, err = cmd.StderrPipe(); err != nil {
		err = fmt.Errorf("can't get stderr pipe for command: %s", err)
		return
	}

	if err = cmd.Start(); err != nil {
		err = fmt.Errorf("can't start command: %s", err)
		return
	}

	return
}

// Run the command in the given string and restart it after
// a message was received on the buildDone channel.
func runner(commandTemplate string, buildStarted <-chan string, buildSuccess <-chan bool) {
	var currentProcess *os.Process
	pipeChan := make(chan io.ReadCloser)

	go logger(pipeChan)

	// Launch concurrent process watching for signals from outside that
	// indicate termination to kill the running process alongside
	// CompileDaemon to prevent orphan processes.
	go func() {
		processSignalChannel := make(chan os.Signal, 1)
		signal.Notify(processSignalChannel, fatalSignals...)
		<-processSignalChannel

		log.Println(okColor("Received signal, terminating cleanly."))
		if currentProcess != nil {
			killProcess(currentProcess)
		}
		os.Exit(0)
	}()

	for {
		eventPath := <-buildStarted

		// prepend %0.s (which adds nothing) to prevent warning about missing
		// format specifier if the user did not supply one.
		command := fmt.Sprintf("%0.s"+commandTemplate, eventPath)

		if !*flagCommandStop {
			if !<-buildSuccess {
				continue
			}
		}

		if currentProcess != nil {
			killProcess(currentProcess)
		}

		if *flagCommandStop {
			log.Println(okColor("Command stopped. Waiting for build to complete."))
			if !<-buildSuccess {
				continue
			}
		}

		log.Println(okColor("Restarting the given command."))
		cmd, stdoutPipe, stderrPipe, err := startCommand(command)

		if err != nil {
			log.Fatal(failColor("Could not start command: %s", err))
		}

		pipeChan <- stdoutPipe
		pipeChan <- stderrPipe

		currentProcess = cmd.Process
	}
}

func killProcess(process *os.Process) {
	if *flagGracefulKill {
		killProcessGracefully(process)
	} else {
		killProcessHard(process)
	}
}

func killProcessHard(process *os.Process) {
	log.Println(okColor("Hard stopping the current process.."))

	if err := process.Kill(); err != nil {
		log.Println(failColor("Warning: could not kill child process.  It may have already exited."))
	}

	if _, err := process.Wait(); err != nil {
		log.Fatal(failColor("Could not wait for child process. Aborting due to danger of infinite forks."))
	}
}

func killProcessGracefully(process *os.Process) {
	done := make(chan error, 1)
	go func() {
		log.Println(okColor("Gracefully stopping the current process.."))
		if err := terminateGracefully(process); err != nil {
			done <- err
			return
		}
		_, err := process.Wait()
		done <- err
	}()

	select {
	case <-time.After(time.Duration(*flagGracefulTimeout) * time.Second):
		log.Println(failColor("Could not gracefully stop the current process, proceeding to hard stop."))
		killProcessHard(process)
		<-done
	case err := <-done:
		if err != nil {
			log.Fatal(failColor("Could not kill child process. Aborting due to danger of infinite forks."))
		}
	}
}

func flusher(buildStarted <-chan string, buildSuccess <-chan bool) {
	for {
		<-buildStarted
		<-buildSuccess
	}
}

func main() {
	flag.Var(&flagExcludedDirs, "exclude-dir", " Don't watch directories matching this name")
	flag.Var(&flagExcludedFiles, "exclude", " Don't watch files matching this name")
	flag.Var(&flagIncludedFiles, "include", " Watch files matching this name")

	flag.Parse()

	if !*flagLogPrefix {
		log.SetFlags(0)
	}

	if *flagDirectory == "" {
		fmt.Fprintf(os.Stderr, "-directory=... is required.\n")
		os.Exit(1)
	}

	if *flagGracefulKill && !gracefulTerminationPossible() {
		log.Fatal("Graceful termination is not supported on your platform.")
	}

	watcher, err := fsnotify.NewWatcher()

	if err != nil {
		log.Fatal(err)
	}

	defer watcher.Close()

	if *flagRecursive == true {
		err = filepath.Walk(*flagDirectory, func(path string, info os.FileInfo, err error) error {
			if err == nil && info.IsDir() {
				if flagExcludedDirs.Matches(path) {
					return filepath.SkipDir
				} else {
					if *flagVerbose {
						log.Printf("Watching directory '%s' for changes.\n", path)
					}
					return watcher.Add(path)
				}
			}
			return err
		})

		if err != nil {
			log.Fatal("filepath.Walk():", err)
		}

		if err := watcher.Add(*flagDirectory); err != nil {
			log.Fatal("watcher.Add():", err)
		}

	} else {
		if err := watcher.Add(*flagDirectory); err != nil {
			log.Fatal("watcher.Add():", err)
		}
	}

	pattern := regexp.MustCompile(*flagPattern)
	jobs := make(chan string)
	buildSuccess := make(chan bool)
	buildStarted := make(chan string)

	go builder(jobs, buildStarted, buildSuccess)

	if *flagCommand != "" {
		go runner(*flagCommand, buildStarted, buildSuccess)
	} else {
		go flusher(buildStarted, buildSuccess)
	}

	for {
		select {
		case ev := <-watcher.Events:
			if ev.Op&fsnotify.Remove == fsnotify.Remove || ev.Op&fsnotify.Write == fsnotify.Write || ev.Op&fsnotify.Create == fsnotify.Create {
				base := filepath.Base(ev.Name)

				// Assume it is a directory and track it.
				if *flagRecursive == true && !flagExcludedDirs.Matches(ev.Name) {
					watcher.Add(ev.Name)
				}

				if flagIncludedFiles.Matches(base) || matchesPattern(pattern, ev.Name) {
					if !flagExcludedFiles.Matches(base) {
						jobs <- ev.Name
					}
				}
			}

		case err := <-watcher.Errors:
			if v, ok := err.(*os.SyscallError); ok {
				if v.Err == syscall.EINTR {
					continue
				}
				log.Fatal("watcher.Error: SyscallError:", v)
			}
			log.Fatal("watcher.Error:", err)
		}
	}
}
<|endoftext|>


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

package scanner

import (
	"reflect"
	"testing"
)

func T(ty TokenType, v string) Token {
	return Token{ty, v, 0, 0}
}

func TestSuccessfulScan(t *testing.T) {
	for _, test := range []struct {
		input  string
		tokens []Token
	}{
		{"bar(", []Token{T(TokenFunction, "bar(")}},
		{"abcd", []Token{T(TokenIdent, "abcd")}},
		{`"abcd"`, []Token{T(TokenString, `"abcd"`)}},
		{"'abcd'", []Token{T(TokenString, "'abcd'")}},
		{"#name", []Token{T(TokenHash, "#name")}},
		{"4.2", []Token{T(TokenNumber, "4.2")}},
		{".42", []Token{T(TokenNumber, ".42")}},
		{"42%", []Token{T(TokenPercentage, "42%")}},
		{"4.2%", []Token{T(TokenPercentage, "4.2%")}},
		{".42%", []Token{T(TokenPercentage, ".42%")}},
		{"42px", []Token{T(TokenDimension, "42px")}},
		{"url('http://www.google.com/')", []Token{T(TokenURI, "url('http://www.google.com/')")}},
		{"U+0042", []Token{T(TokenUnicodeRange, "U+0042")}},
		{"<!--", []Token{T(TokenCDO, "<!--")}},
		{"-->", []Token{T(TokenCDC, "-->")}},
		{"   \n   \t   \n", []Token{T(TokenS, "   \n   \t   \n")}},
		{"/* foo */", []Token{T(TokenComment, "/* foo */")}},
		{"bar(", []Token{T(TokenFunction, "bar(")}},
		{"~=", []Token{T(TokenIncludes, "~=")}},
		{"|=", []Token{T(TokenDashMatch, "|=")}},
		{"^=", []Token{T(TokenPrefixMatch, "^=")}},
		{"$=", []Token{T(TokenSuffixMatch, "$=")}},
		{"*=", []Token{T(TokenSubstringMatch, "*=")}},
		{"{", []Token{T(TokenChar, "{")}},
		{"\uFEFF", []Token{T(TokenBOM, "\uFEFF")}},

		{"42''", []Token{
			T(TokenNumber, "42"),
			T(TokenString, "''"),
		}},
		{`╯︵┻━┻"stuff"`, []Token{
			T(TokenIdent, "╯︵┻━┻"),
			T(TokenString, `"stuff"`),
		}},
		{"color:red", []Token{
			T(TokenIdent, "color"),
			T(TokenChar, ":"),
			T(TokenIdent, "red"),
		}},
		{"color:red;background:blue", []Token{
			T(TokenIdent, "color"),
			T(TokenChar, ":"),
			T(TokenIdent, "red"),
			T(TokenChar, ";"),
			T(TokenIdent, "background"),
			T(TokenChar, ":"),
			T(TokenIdent, "blue"),
		}},
		{"color:rgb(0,1,2)", []Token{
			T(TokenIdent, "color"),
			T(TokenChar, ":"),
			T(TokenFunction, "rgb("),
			T(TokenNumber, "0"),
			T(TokenChar, ","),
			T(TokenNumber, "1"),
			T(TokenChar, ","),
			T(TokenNumber, "2"),
			T(TokenChar, ")"),
		}},
		{"color:#fff", []Token{
			T(TokenIdent, "color"),
			T(TokenChar, ":"),
			T(TokenHash, "#fff"),
		}},

		// Check note in CSS2 4.3.4:
		// Note that COMMENT tokens cannot occur within other tokens: thus, "url(/*x*/pic.png)" denotes the URI "/*x*/pic.png", not "pic.png".
		{"url(/*x*/pic.png)", []Token{
			T(TokenURI, "url(/*x*/pic.png)"),
		}},

		// More URI testing, since it's important
		{"url(/pic.png)", []Token{
			T(TokenURI, "url(/pic.png)"),
		}},
		{"uRl(/pic.png)", []Token{
			T(TokenURI, "uRl(/pic.png)"),
		}},
		{"url(\"/pic.png\")", []Token{
			T(TokenURI, "url(\"/pic.png\")"),
		}},
		{"url('/pic.png')", []Token{
			T(TokenURI, "url('/pic.png')"),
		}},
		{"url('/pic.png?badchars=\\(\\'\\\"\\)\\ ')", []Token{
			T(TokenURI, "url('/pic.png?badchars=\\(\\'\\\"\\)\\ ')"),
		}},
	} {
		tokens := []Token{}
		s := New(test.input)
		for {
			tok := s.Next()
			if tok.Type == TokenError {
				t.Fatalf("Error token with: %q", test.input)
			}
			if tok.Type == TokenEOF {
				break
			}
			tok.Line = 0
			tok.Column = 0
			tokens = append(tokens, *tok)
		}
		if !reflect.DeepEqual(tokens, test.tokens) {
			t.Fatalf("For input string %q, bad tokens. Expected:\n%#v\n\nGot:\n%#v", test.input, test.tokens, tokens)
		}
	}
}
<commit_msg>Add more tests from the CSS standard.<commit_after>// Copyright 2012 The Gorilla Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package scanner

import (
	"reflect"
	"testing"
)

func T(ty TokenType, v string) Token {
	return Token{ty, v, 0, 0}
}

func TestSuccessfulScan(t *testing.T) {
	for _, test := range []struct {
		input  string
		tokens []Token
	}{
		{"bar(", []Token{T(TokenFunction, "bar(")}},
		{"abcd", []Token{T(TokenIdent, "abcd")}},
		{`"abcd"`, []Token{T(TokenString, `"abcd"`)}},
		{"'abcd'", []Token{T(TokenString, "'abcd'")}},
		{"#name", []Token{T(TokenHash, "#name")}},
		{"4.2", []Token{T(TokenNumber, "4.2")}},
		{".42", []Token{T(TokenNumber, ".42")}},
		{"42%", []Token{T(TokenPercentage, "42%")}},
		{"4.2%", []Token{T(TokenPercentage, "4.2%")}},
		{".42%", []Token{T(TokenPercentage, ".42%")}},
		{"42px", []Token{T(TokenDimension, "42px")}},
		{"url('http://www.google.com/')", []Token{T(TokenURI, "url('http://www.google.com/')")}},
		{"U+0042", []Token{T(TokenUnicodeRange, "U+0042")}},
		{"<!--", []Token{T(TokenCDO, "<!--")}},
		{"-->", []Token{T(TokenCDC, "-->")}},
		{"   \n   \t   \n", []Token{T(TokenS, "   \n   \t   \n")}},
		{"/* foo */", []Token{T(TokenComment, "/* foo */")}},
		{"bar(", []Token{T(TokenFunction, "bar(")}},
		{"~=", []Token{T(TokenIncludes, "~=")}},
		{"|=", []Token{T(TokenDashMatch, "|=")}},
		{"^=", []Token{T(TokenPrefixMatch, "^=")}},
		{"$=", []Token{T(TokenSuffixMatch, "$=")}},
		{"*=", []Token{T(TokenSubstringMatch, "*=")}},
		{"{", []Token{T(TokenChar, "{")}},
		{"\uFEFF", []Token{T(TokenBOM, "\uFEFF")}},

		{"42''", []Token{
			T(TokenNumber, "42"),
			T(TokenString, "''"),
		}},
		{`╯︵┻━┻"stuff"`, []Token{
			T(TokenIdent, "╯︵┻━┻"),
			T(TokenString, `"stuff"`),
		}},
		{"color:red", []Token{
			T(TokenIdent, "color"),
			T(TokenChar, ":"),
			T(TokenIdent, "red"),
		}},
		{"color:red;background:blue", []Token{
			T(TokenIdent, "color"),
			T(TokenChar, ":"),
			T(TokenIdent, "red"),
			T(TokenChar, ";"),
			T(TokenIdent, "background"),
			T(TokenChar, ":"),
			T(TokenIdent, "blue"),
		}},
		{"color:rgb(0,1,2)", []Token{
			T(TokenIdent, "color"),
			T(TokenChar, ":"),
			T(TokenFunction, "rgb("),
			T(TokenNumber, "0"),
			T(TokenChar, ","),
			T(TokenNumber, "1"),
			T(TokenChar, ","),
			T(TokenNumber, "2"),
			T(TokenChar, ")"),
		}},
		{"color:#fff", []Token{
			T(TokenIdent, "color"),
			T(TokenChar, ":"),
			T(TokenHash, "#fff"),
		}},

		// Check note in CSS2 4.3.4:
		// Note that COMMENT tokens cannot occur within other tokens: thus, "url(/*x*/pic.png)" denotes the URI "/*x*/pic.png", not "pic.png".
		{"url(/*x*/pic.png)", []Token{
			T(TokenURI, "url(/*x*/pic.png)"),
		}},

		// More URI testing, since it's important
		{"url(/pic.png)", []Token{
			T(TokenURI, "url(/pic.png)"),
		}},
		{"url( /pic.png )", []Token{
			T(TokenURI, "url( /pic.png )"),
		}},
		{"uRl(/pic.png)", []Token{
			T(TokenURI, "uRl(/pic.png)"),
		}},
		{"url(\"/pic.png\")", []Token{
			T(TokenURI, "url(\"/pic.png\")"),
		}},
		{"url('/pic.png')", []Token{
			T(TokenURI, "url('/pic.png')"),
		}},
		{"url('/pic.png?badchars=\\(\\'\\\"\\)\\ ')", []Token{
			T(TokenURI, "url('/pic.png?badchars=\\(\\'\\\"\\)\\ ')"),
		}},

		// CSS2 section 4.1.1: "red-->" is IDENT "red--" followed by DELIM ">",
		{"red-->", []Token{
			T(TokenIdent, "red--"),
			T(TokenChar, ">"),
		}},
	} {
		tokens := []Token{}
		s := New(test.input)
		for {
			tok := s.Next()
			if tok.Type == TokenError {
				t.Fatalf("Error token with: %q", test.input)
			}
			if tok.Type == TokenEOF {
				break
			}
			tok.Line = 0
			tok.Column = 0
			tokens = append(tokens, *tok)
		}
		if !reflect.DeepEqual(tokens, test.tokens) {
			t.Fatalf("For input string %q, bad tokens. Expected:\n%#v\n\nGot:\n%#v", test.input, test.tokens, tokens)
		}
	}
}
<|endoftext|>