mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-03-27 23:02:54 +00:00
refreshed godep since some PRs are still coming into master branch
This commit is contained in:
parent
9fcec0025d
commit
2523c82d33
394 changed files with 36704 additions and 31828 deletions
154
Godeps/Godeps.json
generated
154
Godeps/Godeps.json
generated
|
@ -1,56 +1,52 @@
|
|||
{
|
||||
"ImportPath": "github.com/drone/drone",
|
||||
"GoVersion": "go1.2.1",
|
||||
"GoVersion": "go1.3.1",
|
||||
"Packages": [
|
||||
"./..."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "bitbucket.org/kardianos/osext",
|
||||
"Comment": "null-9",
|
||||
"Rev": "364fb577de68fb646c4cb39cc0e09c887ee16376"
|
||||
"Comment": "null-13",
|
||||
"Rev": "5d3ddcf53a508cc2f7404eaebf546ef2cb5cdb6e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.crypto/bcrypt",
|
||||
"Comment": "null-192",
|
||||
"Rev": "2990fc550b9ff92bc33c848f92c87a305ae62934"
|
||||
"Comment": "null-191",
|
||||
"Rev": "7aa593ce8ceaf0199504fff27455bbb60eedabc7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.crypto/blowfish",
|
||||
"Comment": "null-192",
|
||||
"Rev": "2990fc550b9ff92bc33c848f92c87a305ae62934"
|
||||
"Comment": "null-191",
|
||||
"Rev": "7aa593ce8ceaf0199504fff27455bbb60eedabc7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.crypto/ssh",
|
||||
"Comment": "null-192",
|
||||
"Rev": "2990fc550b9ff92bc33c848f92c87a305ae62934"
|
||||
"Comment": "null-191",
|
||||
"Rev": "7aa593ce8ceaf0199504fff27455bbb60eedabc7"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.net/websocket",
|
||||
"Comment": "null-117",
|
||||
"Rev": "c17ad62118ea511e1051721b429779fa40bddc74"
|
||||
"Comment": "null-144",
|
||||
"Rev": "ad01a6fcc8a19d3a4478c836895ffe883bd2ceab"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.text/transform",
|
||||
"Comment": "null-82",
|
||||
"Rev": "3a670b007ac92a10a5d9bcfc90307995a2d83d35"
|
||||
"Comment": "null-78",
|
||||
"Rev": "b381881d02615d8d58bba23bda3cb4ee20300630"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/go.text/unicode/norm",
|
||||
"Comment": "null-82",
|
||||
"Rev": "3a670b007ac92a10a5d9bcfc90307995a2d83d35"
|
||||
"Comment": "null-78",
|
||||
"Rev": "b381881d02615d8d58bba23bda3cb4ee20300630"
|
||||
},
|
||||
{
|
||||
"ImportPath": "code.google.com/p/gomock/gomock",
|
||||
"Rev": "f465e13c1a71273ab234f1e40a327556b6518a27"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/GeertJohan/go.incremental",
|
||||
"Rev": "92fd0ce4a694213e8b3dfd2d39b16e51d26d0fbf"
|
||||
"Rev": "e033c7513ca3d743bbb64df299bdec29e93fed03"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/GeertJohan/go.rice",
|
||||
"Rev": "387fd3d63f391b3155205bdc6cc089b0741273df"
|
||||
"Rev": "a4d0b5624c673fef4b517f350272136ced6bb5b1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/andybons/hipchat",
|
||||
|
@ -64,10 +60,6 @@
|
|||
"ImportPath": "github.com/daaku/go.zipexe",
|
||||
"Rev": "44882fc939f4c58d87a60de34796c6cfb9623269"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/davecgh/go-spew/spew",
|
||||
"Rev": "9ed19f9b0c9116d712e32dee78f1704cb9fc5b02"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dchest/authcookie",
|
||||
"Comment": "weekly.2012-02-07-1-gfbdef6e",
|
||||
|
@ -81,51 +73,96 @@
|
|||
"ImportPath": "github.com/dchest/uniuri",
|
||||
"Rev": "bc4af7603a3e0ce9d58009f82fca481555182e1c"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/dockerversion",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/ioutils",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/log",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/pools",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/system",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/term",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/timeutils",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/pkg/units",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/utils",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/docker/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dotcloud/docker/archive",
|
||||
"Comment": "v0.9.0-553-g36af293",
|
||||
"Rev": "36af2936af2e55216456dbe62e7fcbeff9b630d5"
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dotcloud/docker/dockerversion",
|
||||
"Comment": "v0.9.0-553-g36af293",
|
||||
"Rev": "36af2936af2e55216456dbe62e7fcbeff9b630d5"
|
||||
"ImportPath": "github.com/dotcloud/docker/pkg/parsers",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dotcloud/docker/pkg/system",
|
||||
"Comment": "v0.9.0-553-g36af293",
|
||||
"Rev": "36af2936af2e55216456dbe62e7fcbeff9b630d5"
|
||||
"ImportPath": "github.com/dotcloud/docker/pkg/stdcopy",
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dotcloud/docker/pkg/term",
|
||||
"Comment": "v0.9.0-553-g36af293",
|
||||
"Rev": "36af2936af2e55216456dbe62e7fcbeff9b630d5"
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dotcloud/docker/utils",
|
||||
"Comment": "v0.9.0-553-g36af293",
|
||||
"Rev": "36af2936af2e55216456dbe62e7fcbeff9b630d5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/dotcloud/docker/vendor/src/code.google.com/p/go/src/pkg/archive/tar",
|
||||
"Comment": "v0.9.0-553-g36af293",
|
||||
"Rev": "36af2936af2e55216456dbe62e7fcbeff9b630d5"
|
||||
"Comment": "v1.2.0-576-gf68f5fd",
|
||||
"Rev": "f68f5fd521270ad9775fb0adfe7516f9e4855ba5"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/drone/go-bitbucket/bitbucket",
|
||||
"Rev": "0c0cf4ece975efdfcf6daa78b03d4e84dd257da7"
|
||||
"Rev": "2174d45d99216e5eed9669c4f9939a199bc212d1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/drone/go-bitbucket/oauth1",
|
||||
"Rev": "0c0cf4ece975efdfcf6daa78b03d4e84dd257da7"
|
||||
"Rev": "2174d45d99216e5eed9669c4f9939a199bc212d1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/drone/go-github/github",
|
||||
"Rev": "1d31b1373d615a3cdef6eaa87d94e1601e6ee798"
|
||||
"Rev": "ebc1b301cb7009a1e8fd265b491dd89980a0d12b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/drone/go-github/oauth2",
|
||||
"Rev": "1d31b1373d615a3cdef6eaa87d94e1601e6ee798"
|
||||
"Rev": "ebc1b301cb7009a1e8fd265b491dd89980a0d12b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/fluffle/goevent/event",
|
||||
|
@ -148,22 +185,13 @@
|
|||
"Comment": "go1",
|
||||
"Rev": "9a7aa3606b82e2081a13a008ada88dfdb96c20fd"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jacobsa/oglematchers",
|
||||
"Rev": "4fc24f97b5b74022c2a3f4ca7eed57ca29083d3e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/jessevdk/go-flags",
|
||||
"Comment": "v1-154-gcee4db9",
|
||||
"Rev": "cee4db96aec1f7382a0b09d8249c09a8bb8d160b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/mattn/go-sqlite3",
|
||||
"Rev": "58c62dc30cda06e4a74e18f6489bb6c112fc6e5d"
|
||||
"Rev": "fb0ae124843f77b46af49646f8316c71106ab758"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/plouc/go-gitlab-client",
|
||||
"Rev": "b0e1b9f3f7585d066d05341bbfdf6d0dd6930cae"
|
||||
"Rev": "80398caaef592ef875851e74876d5b2d52dbcb43"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/russross/meddler",
|
||||
|
@ -171,17 +199,21 @@
|
|||
},
|
||||
{
|
||||
"ImportPath": "github.com/smartystreets/goconvey/convey",
|
||||
"Comment": "1.5.0-168-g2abea07",
|
||||
"Rev": "2abea075ec076abf0572d29bdb28ae7da64cfb7a"
|
||||
"Comment": "1.5.0-264-ge4cef38",
|
||||
"Rev": "e4cef38b8924b3cff6d84a524e8fe938ad0bcbf2"
|
||||
},
|
||||
{
|
||||
"ImportPath": "github.com/stvp/flowdock",
|
||||
"Rev": "50362abeabebf40b0f56a326d62f17e61a59302b"
|
||||
},
|
||||
{
|
||||
"ImportPath": "gopkg.in/v1/yaml",
|
||||
"Rev": "cbe5fa8cb0a9cd6fdc7efe2581c8f91b6f20f949"
|
||||
},
|
||||
{
|
||||
"ImportPath": "launchpad.net/goyaml",
|
||||
"Comment": "51",
|
||||
"Rev": "gustavo@niemeyer.net-20140305200416-7gh64vkcckre5mob"
|
||||
"Comment": "50",
|
||||
"Rev": "gustavo@niemeyer.net-20131114120802-abe042syx64z2m7s"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
18
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_plan9.go
generated
vendored
18
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_plan9.go
generated
vendored
|
@ -4,13 +4,17 @@
|
|||
|
||||
package osext
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"syscall"
|
||||
"os"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
func executable() (string, error) {
|
||||
f, err := Open("/proc/" + itoa(Getpid()) + "/text")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
return syscall.Fd2path(int(f.Fd()))
|
||||
f, err := os.Open("/proc/" + strconv.Itoa(os.Getpid()) + "/text")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer f.Close()
|
||||
return syscall.Fd2path(int(f.Fd()))
|
||||
}
|
||||
|
|
63
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_sysctl.go
generated
vendored
63
Godeps/_workspace/src/bitbucket.org/kardianos/osext/osext_sysctl.go
generated
vendored
|
@ -14,7 +14,7 @@ import (
|
|||
"unsafe"
|
||||
)
|
||||
|
||||
var startUpcwd, getwdError = os.Getwd()
|
||||
var initCwd, initCwdErr = os.Getwd()
|
||||
|
||||
func executable() (string, error) {
|
||||
var mib [4]int32
|
||||
|
@ -26,20 +26,20 @@ func executable() (string, error) {
|
|||
}
|
||||
|
||||
n := uintptr(0)
|
||||
// get length
|
||||
_, _, err := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
|
||||
if err != 0 {
|
||||
return "", err
|
||||
// Get length.
|
||||
_, _, errNum := syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, 0, uintptr(unsafe.Pointer(&n)), 0, 0)
|
||||
if errNum != 0 {
|
||||
return "", errNum
|
||||
}
|
||||
if n == 0 { // shouldn't happen
|
||||
if n == 0 { // This shouldn't happen.
|
||||
return "", nil
|
||||
}
|
||||
buf := make([]byte, n)
|
||||
_, _, err = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0)
|
||||
if err != 0 {
|
||||
return "", err
|
||||
_, _, errNum = syscall.Syscall6(syscall.SYS___SYSCTL, uintptr(unsafe.Pointer(&mib[0])), 4, uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&n)), 0, 0)
|
||||
if errNum != 0 {
|
||||
return "", errNum
|
||||
}
|
||||
if n == 0 { // shouldn't happen
|
||||
if n == 0 { // This shouldn't happen.
|
||||
return "", nil
|
||||
}
|
||||
for i, v := range buf {
|
||||
|
@ -48,35 +48,32 @@ func executable() (string, error) {
|
|||
break
|
||||
}
|
||||
}
|
||||
var strpath string
|
||||
if buf[0] != '/' {
|
||||
var e error
|
||||
if strpath, e = getAbs(buf); e != nil {
|
||||
return strpath, e
|
||||
var err error
|
||||
execPath := string(buf)
|
||||
// execPath will not be empty due to above checks.
|
||||
// Try to get the absolute path if the execPath is not rooted.
|
||||
if execPath[0] != '/' {
|
||||
execPath, err = getAbs(execPath)
|
||||
if err != nil {
|
||||
return execPath, err
|
||||
}
|
||||
} else {
|
||||
strpath = string(buf)
|
||||
}
|
||||
// darwin KERN_PROCARGS may return the path to a symlink rather than the
|
||||
// actual executable
|
||||
// For darwin KERN_PROCARGS may return the path to a symlink rather than the
|
||||
// actual executable.
|
||||
if runtime.GOOS == "darwin" {
|
||||
if strpath, err := filepath.EvalSymlinks(strpath); err != nil {
|
||||
return strpath, err
|
||||
if execPath, err = filepath.EvalSymlinks(execPath); err != nil {
|
||||
return execPath, err
|
||||
}
|
||||
}
|
||||
return strpath, nil
|
||||
return execPath, nil
|
||||
}
|
||||
|
||||
func getAbs(buf []byte) (string, error) {
|
||||
if getwdError != nil {
|
||||
return string(buf), getwdError
|
||||
} else {
|
||||
if buf[0] == '.' {
|
||||
buf = buf[1:]
|
||||
}
|
||||
if startUpcwd[len(startUpcwd)-1] != '/' && buf[0] != '/' {
|
||||
return startUpcwd + "/" + string(buf), nil
|
||||
}
|
||||
return startUpcwd + string(buf), nil
|
||||
func getAbs(execPath string) (string, error) {
|
||||
if initCwdErr != nil {
|
||||
return execPath, initCwdErr
|
||||
}
|
||||
// The execPath may begin with a "../" or a "./" so clean it first.
|
||||
// Join the two paths, trailing and starting slashes undetermined, so use
|
||||
// the generic Join function.
|
||||
return filepath.Join(initCwd, filepath.Clean(execPath)), nil
|
||||
}
|
||||
|
|
9
Godeps/_workspace/src/code.google.com/p/go.crypto/bcrypt/bcrypt_test.go
generated
vendored
9
Godeps/_workspace/src/code.google.com/p/go.crypto/bcrypt/bcrypt_test.go
generated
vendored
|
@ -53,15 +53,6 @@ func TestBcryptingIsCorrect(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestVeryShortPasswords(t *testing.T) {
|
||||
key := []byte("k")
|
||||
salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
_, err := bcrypt(key, 10, salt)
|
||||
if err != nil {
|
||||
t.Errorf("One byte key resulted in error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTooLongPasswordsWork(t *testing.T) {
|
||||
salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
// One byte over the usual 56 byte limit that blowfish has
|
||||
|
|
14
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/blowfish_test.go
generated
vendored
14
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/blowfish_test.go
generated
vendored
|
@ -192,13 +192,19 @@ func TestCipherDecrypt(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestSaltedCipherKeyLength(t *testing.T) {
|
||||
if _, err := NewSaltedCipher(nil, []byte{'a'}); err != KeySizeError(0) {
|
||||
t.Errorf("NewSaltedCipher with short key, gave error %#v, expected %#v", err, KeySizeError(0))
|
||||
var key []byte
|
||||
for i := 0; i < 4; i++ {
|
||||
_, err := NewSaltedCipher(key, []byte{'a'})
|
||||
if err != KeySizeError(i) {
|
||||
t.Errorf("NewSaltedCipher with short key, gave error %#v, expected %#v", err, KeySizeError(i))
|
||||
}
|
||||
key = append(key, 'a')
|
||||
}
|
||||
|
||||
// A 57-byte key. One over the typical blowfish restriction.
|
||||
key := []byte("012345678901234567890123456789012345678901234567890123456")
|
||||
if _, err := NewSaltedCipher(key, []byte{'a'}); err != nil {
|
||||
key = []byte("012345678901234567890123456789012345678901234567890123456")
|
||||
_, err := NewSaltedCipher(key, []byte{'a'})
|
||||
if err != nil {
|
||||
t.Errorf("NewSaltedCipher with long key, gave error %#v", err)
|
||||
}
|
||||
}
|
||||
|
|
8
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/cipher.go
generated
vendored
8
Godeps/_workspace/src/code.google.com/p/go.crypto/blowfish/cipher.go
generated
vendored
|
@ -26,10 +26,11 @@ func (k KeySizeError) Error() string {
|
|||
}
|
||||
|
||||
// NewCipher creates and returns a Cipher.
|
||||
// The key argument should be the Blowfish key, from 1 to 56 bytes.
|
||||
// The key argument should be the Blowfish key, 4 to 56 bytes.
|
||||
func NewCipher(key []byte) (*Cipher, error) {
|
||||
var result Cipher
|
||||
if k := len(key); k < 1 || k > 56 {
|
||||
k := len(key)
|
||||
if k < 4 || k > 56 {
|
||||
return nil, KeySizeError(k)
|
||||
}
|
||||
initCipher(key, &result)
|
||||
|
@ -43,7 +44,8 @@ func NewCipher(key []byte) (*Cipher, error) {
|
|||
// bytes. Only the first 16 bytes of salt are used.
|
||||
func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
|
||||
var result Cipher
|
||||
if k := len(key); k < 1 {
|
||||
k := len(key)
|
||||
if k < 4 {
|
||||
return nil, KeySizeError(k)
|
||||
}
|
||||
initCipher(key, &result)
|
||||
|
|
2
Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go
generated
vendored
2
Godeps/_workspace/src/code.google.com/p/go.net/websocket/websocket.go
generated
vendored
|
@ -129,7 +129,7 @@ type frameReaderFactory interface {
|
|||
|
||||
// frameWriter is an interface to write a WebSocket frame.
|
||||
type frameWriter interface {
|
||||
// Writer is to write playload of the frame.
|
||||
// Writer is to write payload of the frame.
|
||||
io.WriteCloser
|
||||
}
|
||||
|
||||
|
|
6
Godeps/_workspace/src/code.google.com/p/gomock/gomock/callset.go
generated
vendored
6
Godeps/_workspace/src/code.google.com/p/gomock/gomock/callset.go
generated
vendored
|
@ -61,6 +61,12 @@ func (cs callSet) FindMatch(receiver interface{}, method string, args []interfac
|
|||
// Search through the unordered set of calls expected on a method on a
|
||||
// receiver.
|
||||
for _, call := range calls {
|
||||
// A call should not normally still be here if exhausted,
|
||||
// but it can happen if, for instance, .Times(0) was used.
|
||||
// Pretend the call doesn't match.
|
||||
if call.exhausted() {
|
||||
continue
|
||||
}
|
||||
if call.matches(args) {
|
||||
return call
|
||||
}
|
||||
|
|
4
Godeps/_workspace/src/code.google.com/p/gomock/gomock/controller.go
generated
vendored
4
Godeps/_workspace/src/code.google.com/p/gomock/gomock/controller.go
generated
vendored
|
@ -86,6 +86,10 @@ func (ctrl *Controller) RecordCall(receiver interface{}, method string, args ...
|
|||
for i, arg := range args {
|
||||
if m, ok := arg.(Matcher); ok {
|
||||
margs[i] = m
|
||||
} else if arg == nil {
|
||||
// Handle nil specially so that passing a nil interface value
|
||||
// will match the typed nils of concrete args.
|
||||
margs[i] = Nil()
|
||||
} else {
|
||||
margs[i] = Eq(arg)
|
||||
}
|
||||
|
|
11
Godeps/_workspace/src/code.google.com/p/gomock/gomock/controller_test.go
generated
vendored
11
Godeps/_workspace/src/code.google.com/p/gomock/gomock/controller_test.go
generated
vendored
|
@ -382,3 +382,14 @@ func TestSetArgWithBadType(t *testing.T) {
|
|||
})
|
||||
ctrl.Call(s, "FooMethod", "1")
|
||||
}
|
||||
|
||||
func TestTimes0(t *testing.T) {
|
||||
rep, ctrl := createFixtures(t)
|
||||
defer ctrl.Finish()
|
||||
|
||||
s := new(Subject)
|
||||
ctrl.RecordCall(s, "FooMethod", "arg").Times(0)
|
||||
rep.assertFatal(func() {
|
||||
ctrl.Call(s, "FooMethod", "arg")
|
||||
})
|
||||
}
|
||||
|
|
2
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/.gitignore
generated
vendored
2
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/.gitignore
generated
vendored
|
@ -1,2 +0,0 @@
|
|||
/gen/gen
|
||||
/example/example
|
53
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/README.md
generated
vendored
53
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/README.md
generated
vendored
|
@ -1,53 +0,0 @@
|
|||
## go.incremental
|
||||
[](https://drone.io/github.com/GeertJohan/go.incremental/latest)
|
||||
Go package incremental provides typed incremental counters that are type-safe.
|
||||
|
||||
### Install
|
||||
`go get github.com/GeertJohan/go.incremental`
|
||||
|
||||
### Usage example
|
||||
This example is also located in the example subdirectory
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/GeertJohan/go.incremental"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// use max cpu's
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
// create new incremental.Int
|
||||
i := &incremental.Int{}
|
||||
|
||||
// print some numbers
|
||||
fmt.Println(i.Next()) // print 1
|
||||
fmt.Println(i.Next()) // print 2
|
||||
fmt.Println(i.Next()) // print 3
|
||||
|
||||
// create chan to check if goroutines are done
|
||||
done := make(chan int)
|
||||
|
||||
// spawn 4 goroutines
|
||||
for a := 0; a < 4; a++ {
|
||||
// call goroutine with it's number (0-3)
|
||||
go func(aa int) {
|
||||
// print 10 incremental numbers
|
||||
for b := 0; b < 10; b++ {
|
||||
fmt.Printf("routine %d: %d\n", aa, i.Next())
|
||||
}
|
||||
// signal done
|
||||
done <- aa
|
||||
}(a)
|
||||
}
|
||||
|
||||
// wait until all goroutines are done
|
||||
for a := 0; a < 4; a++ {
|
||||
fmt.Printf("goroutine %d done\n", <-done)
|
||||
}
|
||||
fmt.Println("all done")
|
||||
}
|
||||
```
|
5
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/doc.go
generated
vendored
5
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/doc.go
generated
vendored
|
@ -1,5 +0,0 @@
|
|||
|
||||
// package incremental provides concurency-safe incremental numbers.
|
||||
//
|
||||
// This package was created by a simple piece of code located in the gen subdirectory. Please modify that command if you want to modify this package.
|
||||
package incremental
|
42
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/example/example.go
generated
vendored
42
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/example/example.go
generated
vendored
|
@ -1,42 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/GeertJohan/go.incremental"
|
||||
"runtime"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// use max cpu's
|
||||
runtime.GOMAXPROCS(runtime.NumCPU())
|
||||
|
||||
// create new incremental.Int
|
||||
i := &incremental.Int{}
|
||||
|
||||
// print some numbers
|
||||
fmt.Println(i.Next()) // print 1
|
||||
fmt.Println(i.Next()) // print 2
|
||||
fmt.Println(i.Next()) // print 3
|
||||
|
||||
// create chan to check if goroutines are done
|
||||
done := make(chan int)
|
||||
|
||||
// spawn 4 goroutines
|
||||
for a := 0; a < 4; a++ {
|
||||
// call goroutine with it's number (0-3)
|
||||
go func(aa int) {
|
||||
// print 10 incremental numbers
|
||||
for b := 0; b < 10; b++ {
|
||||
fmt.Printf("routine %d: %d\n", aa, i.Next())
|
||||
}
|
||||
// signal done
|
||||
done <- aa
|
||||
}(a)
|
||||
}
|
||||
|
||||
// wait until all goroutines are done
|
||||
for a := 0; a < 4; a++ {
|
||||
fmt.Printf("goroutine %d done\n", <-done)
|
||||
}
|
||||
fmt.Println("all done")
|
||||
}
|
187
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/gen/generator.go
generated
vendored
187
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/gen/generator.go
generated
vendored
|
@ -1,187 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"strings"
|
||||
"text/template"
|
||||
)
|
||||
|
||||
var (
|
||||
tmpl *template.Template
|
||||
tmplTest *template.Template
|
||||
)
|
||||
|
||||
var types = []string{
|
||||
"int", "int8", "int16", "int32", "int64",
|
||||
"uint", "uint8", "uint16", "uint32", "uint64",
|
||||
}
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
tmpl, err = template.New("tmpl").Parse(`package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type {{.Upper}} struct {
|
||||
increment {{.Lower}}
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this {{.Upper}}
|
||||
func (i *{{.Upper}}) Next() {{.Lower}} {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number ({{.Lower}}) that was returned by the most recent call to this instance's Next()
|
||||
func (i *{{.Upper}}) Last() {{.Lower}} {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *{{.Upper}}) Set(value {{.Lower}}) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
||||
`)
|
||||
|
||||
tmplTest, err = template.New("tmplTest").Parse(`package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type some{{.Upper}}Struct struct {
|
||||
i {{.Upper}}
|
||||
}
|
||||
|
||||
func Test{{.Upper}}Ptr(t *testing.T) {
|
||||
i := &{{.Upper}}{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func Test{{.Upper}}AsField(t *testing.T) {
|
||||
s := some{{.Upper}}Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSome{{.Upper}}Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSome{{.Upper}}Struct(s *some{{.Upper}}Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
||||
`)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
type data struct {
|
||||
Upper string
|
||||
Lower string
|
||||
}
|
||||
|
||||
func main() {
|
||||
// loop over integer types
|
||||
for _, t := range types {
|
||||
// create data with upper and lower names for the type
|
||||
d := &data{
|
||||
Upper: strings.ToUpper(t[0:1]) + t[1:],
|
||||
Lower: t,
|
||||
}
|
||||
|
||||
// create file for type
|
||||
file, err := os.Create(t + ".go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// execute template, write directly to file
|
||||
err = tmpl.Execute(file, d)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// create file for test
|
||||
file, err = os.Create(t + "_test.go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// execute template, write directly to file
|
||||
err = tmplTest.Execute(file, d)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
// create doc.go
|
||||
file, err := os.Create("doc.go")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer file.Close()
|
||||
file.WriteString(`
|
||||
// package incremental provides concurency-safe incremental numbers.
|
||||
//
|
||||
// This package was created by a simple piece of code located in the gen subdirectory. Please modify that command if you want to modify this package.
|
||||
package incremental`)
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Int struct {
|
||||
increment int
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Int
|
||||
func (i *Int) Next() int {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (int) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Int) Last() int {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Int) Set(value int) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int16.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int16.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Int16 struct {
|
||||
increment int16
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Int16
|
||||
func (i *Int16) Next() int16 {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (int16) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Int16) Last() int16 {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Int16) Set(value int16) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int16_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int16_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someInt16Struct struct {
|
||||
i Int16
|
||||
}
|
||||
|
||||
func TestInt16Ptr(t *testing.T) {
|
||||
i := &Int16{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt16AsField(t *testing.T) {
|
||||
s := someInt16Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeInt16Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeInt16Struct(s *someInt16Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int32.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int32.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Int32 struct {
|
||||
increment int32
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Int32
|
||||
func (i *Int32) Next() int32 {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (int32) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Int32) Last() int32 {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Int32) Set(value int32) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int32_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int32_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someInt32Struct struct {
|
||||
i Int32
|
||||
}
|
||||
|
||||
func TestInt32Ptr(t *testing.T) {
|
||||
i := &Int32{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt32AsField(t *testing.T) {
|
||||
s := someInt32Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeInt32Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeInt32Struct(s *someInt32Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int64.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int64.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Int64 struct {
|
||||
increment int64
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Int64
|
||||
func (i *Int64) Next() int64 {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (int64) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Int64) Last() int64 {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Int64) Set(value int64) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int64_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int64_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someInt64Struct struct {
|
||||
i Int64
|
||||
}
|
||||
|
||||
func TestInt64Ptr(t *testing.T) {
|
||||
i := &Int64{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt64AsField(t *testing.T) {
|
||||
s := someInt64Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeInt64Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeInt64Struct(s *someInt64Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int8.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int8.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Int8 struct {
|
||||
increment int8
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Int8
|
||||
func (i *Int8) Next() int8 {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (int8) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Int8) Last() int8 {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Int8) Set(value int8) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int8_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int8_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someInt8Struct struct {
|
||||
i Int8
|
||||
}
|
||||
|
||||
func TestInt8Ptr(t *testing.T) {
|
||||
i := &Int8{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestInt8AsField(t *testing.T) {
|
||||
s := someInt8Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeInt8Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeInt8Struct(s *someInt8Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/int_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someIntStruct struct {
|
||||
i Int
|
||||
}
|
||||
|
||||
func TestIntPtr(t *testing.T) {
|
||||
i := &Int{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestIntAsField(t *testing.T) {
|
||||
s := someIntStruct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeIntStruct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeIntStruct(s *someIntStruct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Uint struct {
|
||||
increment uint
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Uint
|
||||
func (i *Uint) Next() uint {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (uint) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Uint) Last() uint {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Uint) Set(value uint) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint16.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint16.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Uint16 struct {
|
||||
increment uint16
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Uint16
|
||||
func (i *Uint16) Next() uint16 {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (uint16) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Uint16) Last() uint16 {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Uint16) Set(value uint16) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint16_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint16_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someUint16Struct struct {
|
||||
i Uint16
|
||||
}
|
||||
|
||||
func TestUint16Ptr(t *testing.T) {
|
||||
i := &Uint16{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUint16AsField(t *testing.T) {
|
||||
s := someUint16Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeUint16Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeUint16Struct(s *someUint16Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint32.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint32.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Uint32 struct {
|
||||
increment uint32
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Uint32
|
||||
func (i *Uint32) Next() uint32 {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (uint32) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Uint32) Last() uint32 {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Uint32) Set(value uint32) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint32_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint32_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someUint32Struct struct {
|
||||
i Uint32
|
||||
}
|
||||
|
||||
func TestUint32Ptr(t *testing.T) {
|
||||
i := &Uint32{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUint32AsField(t *testing.T) {
|
||||
s := someUint32Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeUint32Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeUint32Struct(s *someUint32Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint64.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint64.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Uint64 struct {
|
||||
increment uint64
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Uint64
|
||||
func (i *Uint64) Next() uint64 {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (uint64) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Uint64) Last() uint64 {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Uint64) Set(value uint64) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint64_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint64_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someUint64Struct struct {
|
||||
i Uint64
|
||||
}
|
||||
|
||||
func TestUint64Ptr(t *testing.T) {
|
||||
i := &Uint64{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUint64AsField(t *testing.T) {
|
||||
s := someUint64Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeUint64Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeUint64Struct(s *someUint64Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint8.go
generated
vendored
30
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint8.go
generated
vendored
|
@ -1,30 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
type Uint8 struct {
|
||||
increment uint8
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
// Next returns with an integer that is exactly one higher as the previous call to Next() for this Uint8
|
||||
func (i *Uint8) Next() uint8 {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment++
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Last returns the number (uint8) that was returned by the most recent call to this instance's Next()
|
||||
func (i *Uint8) Last() uint8 {
|
||||
return i.increment
|
||||
}
|
||||
|
||||
// Set changes the increment to given value, the succeeding call to Next() will return the given value+1
|
||||
func (i *Uint8) Set(value uint8) {
|
||||
i.lock.Lock()
|
||||
defer i.lock.Unlock()
|
||||
i.increment = value
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint8_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint8_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someUint8Struct struct {
|
||||
i Uint8
|
||||
}
|
||||
|
||||
func TestUint8Ptr(t *testing.T) {
|
||||
i := &Uint8{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUint8AsField(t *testing.T) {
|
||||
s := someUint8Struct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeUint8Struct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeUint8Struct(s *someUint8Struct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint_test.go
generated
vendored
75
Godeps/_workspace/src/github.com/GeertJohan/go.incremental/uint_test.go
generated
vendored
|
@ -1,75 +0,0 @@
|
|||
package incremental
|
||||
|
||||
import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
type someUintStruct struct {
|
||||
i Uint
|
||||
}
|
||||
|
||||
func TestUintPtr(t *testing.T) {
|
||||
i := &Uint{}
|
||||
num := i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
i.Set(42)
|
||||
num = i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUintAsField(t *testing.T) {
|
||||
s := someUintStruct{}
|
||||
num := s.i.Next()
|
||||
if num != 1 {
|
||||
t.Fatal("expected 1, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 2 {
|
||||
t.Fatal("expected 2, got %d", num)
|
||||
}
|
||||
num = s.i.Last()
|
||||
if num != 2 {
|
||||
t.Fatal("expected last to be 2, got %d", num)
|
||||
}
|
||||
|
||||
useSomeUintStruct(&s, t)
|
||||
|
||||
num = s.i.Last()
|
||||
if num != 3 {
|
||||
t.Fatal("expected last to be 3, got %d", num)
|
||||
}
|
||||
|
||||
s.i.Set(42)
|
||||
num = s.i.Last()
|
||||
if num != 42 {
|
||||
t.Fatal("expected last to be 42, got %d", num)
|
||||
}
|
||||
num = s.i.Next()
|
||||
if num != 43 {
|
||||
t.Fatal("expected 43, got %d", num)
|
||||
}
|
||||
}
|
||||
|
||||
func useSomeUintStruct(s *someUintStruct, t *testing.T) {
|
||||
num := s.i.Next()
|
||||
if num != 3 {
|
||||
t.Fatal("expected 3, got %d", num)
|
||||
}
|
||||
}
|
2
Godeps/_workspace/src/github.com/GeertJohan/go.rice/.gitignore
generated
vendored
2
Godeps/_workspace/src/github.com/GeertJohan/go.rice/.gitignore
generated
vendored
|
@ -4,4 +4,4 @@
|
|||
/rice/rice.exe
|
||||
|
||||
*.rice-box.go
|
||||
*.rice-single.go
|
||||
*.rice-box.syso
|
||||
|
|
56
Godeps/_workspace/src/github.com/GeertJohan/go.rice/README.md
generated
vendored
56
Godeps/_workspace/src/github.com/GeertJohan/go.rice/README.md
generated
vendored
|
@ -1,11 +1,11 @@
|
|||
## go.rice
|
||||
|
||||
go.rice is a [Go](http://golang.org) package that makes working with resources such as html,js,css,images and templates very easy. During development `go.rice` will load required files directly from disk. Upon deployment it is easy to add all resource files to a executable using the `rice` tool, without changing the source code for your package.
|
||||
go.rice is a [Go](http://golang.org) package that makes working with resources such as html,js,css,images and templates very easy. During development `go.rice` will load required files directly from disk. Upon deployment it is easy to add all resource files to a executable using the `rice` tool, without changing the source code for your package. go.rice provides several methods to add resources to a binary.
|
||||
|
||||
### What does it do?
|
||||
The first thing go.rice does is finding the correct absolute path for your resource files. Say you are executing go binary in your home directory, but your html files are located in `$GOPATH/src/webApplication/html-files`. `go.rice` will lookup the aboslute path for that directory. The only thing you have to do is include the resources using `rice.FindBox("html-files")`.
|
||||
The first thing go.rice does is finding the correct absolute path for your resource files. Say you are executing go binary in your home directory, but your `html-files` are located in `$GOPATH/src/yourApplication/html-files`. `go.rice` will lookup the correct path for that directory (relative to the location of yourApplication). The only thing you have to do is include the resources using `rice.FindBox("html-files")`.
|
||||
|
||||
This only works when the source is available to the machine executing the binary. This is always the case when the binary was installed with `go get` or `go install`. It might happen that you wish to simply provide a binary, without source. The `rice` tool analyses source code and finds call's to `rice.FindBox(..)` and adds the required directories to the executable binary. There are several ways to add these resources. You can 'embed' by generating go source code, or append the resource to the executable.
|
||||
This only works when the source is available to the machine executing the binary. Which is always the case when the binary was installed with `go get` or `go install`. It might occur that you wish to simply provide a binary, without source. The `rice` tool analyses source code and finds call's to `rice.FindBox(..)` and adds the required directories to the executable binary. There are several methods to add these resources. You can 'embed' by generating go source code, or append the resource to the executable as zip file. In both cases `go.rice` will detect the embedded or appended resources and load those, instead of looking up files from disk.
|
||||
|
||||
### Installation
|
||||
|
||||
|
@ -27,7 +27,7 @@ http.ListenAndServe(":8080", nil)
|
|||
|
||||
**Loading a template**
|
||||
```go
|
||||
// find/create a rice.Box
|
||||
// find a rice.Box
|
||||
templateBox, err := rice.FindBox("example-templates")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -46,22 +46,45 @@ tmplMessage.Execute(os.Stdout, map[string]string{"Message": "Hello, world!"})
|
|||
|
||||
```
|
||||
|
||||
Never call `FindBox()` or `MustFindBox()` from an `init()` function, as the boxes might have not been loaded at that time.
|
||||
|
||||
### Tool usage
|
||||
The `rice` tool lets you add the resources to a binary executable so the files are not loaded from the filesystem anymore. This creates a 'standalone' executable. There's several ways to add the resources to a binary, each has pro's and con's but all will work without changing your source code. `go.rice` will figure it all out for you.
|
||||
The `rice` tool lets you add the resources to a binary executable so the files are not loaded from the filesystem anymore. This creates a 'standalone' executable. There are several ways to add the resources to a binary, each has pro's and con's but all will work without requiring changes to the way you load the resources.
|
||||
|
||||
**Embed resources in Go source**
|
||||
#### embed-go
|
||||
**Embed resources by generating Go source code**
|
||||
|
||||
This option is pre-build, it generates Go source files that are compiled into the binary.
|
||||
This method must be executed before building. It generates Go source files that are compiled by the go compiler into the binary.
|
||||
|
||||
Run `rice embed` to generate Go source that contains all required resources. Afterwards run `go build` to create a standalone executable.
|
||||
The downside with this option is that the generated go source files can become very large, which will slow down compilation and require lots of memory to compile.
|
||||
|
||||
**Append resources to executable**
|
||||
Execute the following commands:
|
||||
```
|
||||
rice embed-go
|
||||
go build
|
||||
```
|
||||
|
||||
#### embed-syso
|
||||
**Embed resources by generating a coff .syso file and some .go source code**
|
||||
|
||||
** This method is experimental and should not be used for production systems just yet **
|
||||
|
||||
This method must be executed before building. It generates a COFF .syso file and Go source file that are compiled by the go compiler into the binary.
|
||||
|
||||
Execute the following commands:
|
||||
```
|
||||
rice embed-syso
|
||||
go build
|
||||
```
|
||||
|
||||
#### append
|
||||
**Append resources to executable as zip file**
|
||||
|
||||
_Does not work on windows (yet)_
|
||||
|
||||
This options is post-build, it appends the resources to the binary. It makes compilation a lot faster and can be used with large resource files.
|
||||
This method changes an allready built executable. It appends the resources as zip file to the binary. It makes compilation a lot faster and can be used with large resource files.
|
||||
|
||||
Appending requires `zip` to be installed.
|
||||
Downsides for appending are that it requires `zip` to be installed and does not provide a working Seek method.
|
||||
|
||||
Run the following commands to create a standalone executable.
|
||||
```
|
||||
|
@ -71,13 +94,13 @@ rice append --exec example
|
|||
|
||||
#### Help information
|
||||
Run `rice -h` for information about all options.
|
||||
|
||||
You can run the -h option for each sub-command, e.g. `rice append -h`.
|
||||
|
||||
### Order of preference
|
||||
When opening a new box, the rice pkg tries to locate it using the following order:
|
||||
### Order of precedence
|
||||
When opening a new box, the rice package tries to locate the resources in the following order:
|
||||
|
||||
- embedded in generated go source
|
||||
- embedded with .a object files (not available yet)
|
||||
- appended as zip
|
||||
- 'live' from filesystem
|
||||
|
||||
|
@ -85,21 +108,16 @@ When opening a new box, the rice pkg tries to locate it using the following orde
|
|||
### Licence
|
||||
This project is licensed under a Simplified BSD license. Please read the [LICENSE file][license].
|
||||
|
||||
|
||||
### TODO & Development
|
||||
This package is not completed yet. Though it already provides working embedding, some important featuers are still missing.
|
||||
- implement Readdir() correctly on virtualDir
|
||||
- implement Seek() for zipFile
|
||||
- implement embedding with .a object files
|
||||
- automated testing with TravisCI or Drone **important**
|
||||
- in-code TODO's
|
||||
- find boxes in imported packages
|
||||
|
||||
Less important stuff:
|
||||
- rice.FindSingle(..) that loads and embeds a single file as oposed to a complete directory. It should have methods .String(), .Bytes() and .File()
|
||||
- The rice tool uses a simple regexp to find calls to `rice.FindBox(..)`, this should be changed to `go/ast` or maybe `go.tools/oracle`?
|
||||
- idea, os/arch dependent embeds. rice checks if embedding file has _os_arch or build flags. If box is not requested by file without buildflags, then the buildflags are applied to the embed file.
|
||||
- store meta information for appended (zip) files (mod time, etc)
|
||||
|
||||
### Package documentation
|
||||
|
||||
|
|
6
Godeps/_workspace/src/github.com/GeertJohan/go.rice/appended.go
generated
vendored
6
Godeps/_workspace/src/github.com/GeertJohan/go.rice/appended.go
generated
vendored
|
@ -75,8 +75,10 @@ func init() {
|
|||
if dirName == "." {
|
||||
dirName = ""
|
||||
}
|
||||
if dir := box.Files[dirName]; dir != nil {
|
||||
dir.children = append(dir.children, af)
|
||||
if fileName != "" { // don't make box root dir a child of itself
|
||||
if dir := box.Files[dirName]; dir != nil {
|
||||
dir.children = append(dir.children, af)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
7
Godeps/_workspace/src/github.com/GeertJohan/go.rice/box.go
generated
vendored
7
Godeps/_workspace/src/github.com/GeertJohan/go.rice/box.go
generated
vendored
|
@ -29,7 +29,7 @@ func findBox(name string) (*Box, error) {
|
|||
// no support for absolute paths since gopath can be different on different machines.
|
||||
// therefore, required box must be located relative to package requiring it.
|
||||
if filepath.IsAbs(name) {
|
||||
return nil, errors.New("given name/path is aboslute")
|
||||
return nil, errors.New("given name/path is absolute")
|
||||
}
|
||||
|
||||
// find if box is embedded
|
||||
|
@ -123,11 +123,6 @@ func (b *Box) Open(name string) (*File, error) {
|
|||
fmt.Printf("Open(%s)\n", name)
|
||||
}
|
||||
|
||||
// if b.IsAppended() {
|
||||
// do stuff
|
||||
// return ....
|
||||
// }
|
||||
|
||||
if b.IsEmbedded() {
|
||||
if Debug {
|
||||
fmt.Println("Box is embedded")
|
||||
|
|
3
Godeps/_workspace/src/github.com/GeertJohan/go.rice/embedded-a.go
generated
vendored
3
Godeps/_workspace/src/github.com/GeertJohan/go.rice/embedded-a.go
generated
vendored
|
@ -1,3 +0,0 @@
|
|||
package rice
|
||||
|
||||
//++ object embedding
|
51
Godeps/_workspace/src/github.com/GeertJohan/go.rice/embedded/embedded.go
generated
vendored
51
Godeps/_workspace/src/github.com/GeertJohan/go.rice/embedded/embedded.go
generated
vendored
|
@ -1,25 +1,56 @@
|
|||
// Package embedded defines embedded data types that are shared between the go.rice package and generated code.
|
||||
// This package is seperated from go.rice to make go.rice's documentation cleaner.
|
||||
package embedded
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
EmbedTypeGo = 0
|
||||
EmbedTypeSyso = 1
|
||||
)
|
||||
|
||||
// EmbeddedBox defines an embedded box
|
||||
type EmbeddedBox struct {
|
||||
Name string // box name
|
||||
Time time.Time // embed time
|
||||
Files map[string]*EmbeddedFile // ALL embedded files by full path
|
||||
Dirs map[string]*EmbeddedDir // ALL embedded dirs by full path
|
||||
Name string // box name
|
||||
Time time.Time // embed time
|
||||
EmbedType int // kind of embedding
|
||||
Files map[string]*EmbeddedFile // ALL embedded files by full path
|
||||
Dirs map[string]*EmbeddedDir // ALL embedded dirs by full path
|
||||
}
|
||||
|
||||
// EmbeddedSingle defines an embedded single
|
||||
type EmbeddedSingle struct {
|
||||
Name string // single name
|
||||
Time time.Time // embed time
|
||||
File *EmbeddedFile // embedded file
|
||||
// Link creates the ChildDirs and ChildFiles links in all EmbeddedDir's
|
||||
func (e *EmbeddedBox) Link() {
|
||||
for path, ed := range e.Dirs {
|
||||
fmt.Println(path)
|
||||
ed.ChildDirs = make([]*EmbeddedDir, 0)
|
||||
ed.ChildFiles = make([]*EmbeddedFile, 0)
|
||||
}
|
||||
for path, ed := range e.Dirs {
|
||||
parentDirpath, _ := filepath.Split(path)
|
||||
if strings.HasSuffix(parentDirpath, "/") {
|
||||
parentDirpath = parentDirpath[:len(parentDirpath)-1]
|
||||
}
|
||||
parentDir := e.Dirs[parentDirpath]
|
||||
if parentDir == nil {
|
||||
panic("parentDir `" + parentDirpath + "` is missing in embedded box")
|
||||
}
|
||||
parentDir.ChildDirs = append(parentDir.ChildDirs, ed)
|
||||
}
|
||||
for path, ef := range e.Files {
|
||||
dirpath, _ := filepath.Split(path)
|
||||
if strings.HasSuffix(dirpath, "/") {
|
||||
dirpath = dirpath[:len(dirpath)-1]
|
||||
}
|
||||
dir := e.Dirs[dirpath]
|
||||
if dir == nil {
|
||||
panic("dir `" + dirpath + "` is missing in embedded box")
|
||||
}
|
||||
dir.ChildFiles = append(dir.ChildFiles, ef)
|
||||
}
|
||||
}
|
||||
|
||||
// EmbeddedDir is instanced in the code generated by the rice tool and contains all necicary information about an embedded file
|
||||
|
|
12
Godeps/_workspace/src/github.com/GeertJohan/go.rice/example/example.go
generated
vendored
12
Godeps/_workspace/src/github.com/GeertJohan/go.rice/example/example.go
generated
vendored
|
@ -16,7 +16,7 @@ func main() {
|
|||
if err != nil {
|
||||
log.Fatalf("error opening rice.Box: %s\n", err)
|
||||
}
|
||||
spew.Dump(box)
|
||||
// spew.Dump(box)
|
||||
|
||||
contentString, err := box.String("file.txt")
|
||||
if err != nil {
|
||||
|
@ -35,6 +35,16 @@ func main() {
|
|||
log.Fatalf("could not open file: %s\n", err)
|
||||
}
|
||||
spew.Dump(file)
|
||||
// debianFile, err := box.Open("debian-7.3.0-amd64-i386-netinst.iso")
|
||||
// if err != nil {
|
||||
// log.Fatalf("error opening file debian-7.3.0-amd64-i386-netinst.iso: %v", err)
|
||||
// }
|
||||
// info, err := debianFile.Stat()
|
||||
// if err != nil {
|
||||
// log.Fatalf("error doing stat for debian file: %v", err)
|
||||
// }
|
||||
// log.Printf("debian file was last modified at %v\n", info.ModTime())
|
||||
// log.Printf("debian file is %d bytes large\n", info.Size())
|
||||
|
||||
// find/create a rice.Box
|
||||
templateBox, err := rice.FindBox("example-templates")
|
||||
|
|
4
Godeps/_workspace/src/github.com/GeertJohan/go.rice/file.go
generated
vendored
4
Godeps/_workspace/src/github.com/GeertJohan/go.rice/file.go
generated
vendored
|
@ -59,10 +59,10 @@ func (f *File) Stat() (os.FileInfo, error) {
|
|||
func (f *File) Readdir(count int) ([]os.FileInfo, error) {
|
||||
if f.appendedF != nil {
|
||||
if f.appendedF.dir {
|
||||
fi := make([]os.FileInfo, len(f.appendedF.children))
|
||||
fi := make([]os.FileInfo, 0, len(f.appendedF.children))
|
||||
for _, childAppendedFile := range f.appendedF.children {
|
||||
if childAppendedFile.dir {
|
||||
fi = append(fi, f.appendedF.dirInfo)
|
||||
fi = append(fi, childAppendedFile.dirInfo)
|
||||
} else {
|
||||
fi = append(fi, childAppendedFile.zipFile.FileInfo())
|
||||
}
|
||||
|
|
8
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/append.go
generated
vendored
8
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/append.go
generated
vendored
|
@ -95,7 +95,13 @@ func operationAppend(pkg *build.Package) {
|
|||
}
|
||||
|
||||
// create zipFileWriter
|
||||
zipFileWriter, err := zipWriter.Create(zipFileName)
|
||||
zipFileHeader, err := zip.FileInfoHeader(info)
|
||||
if err != nil {
|
||||
fmt.Printf("Error creating zip FileHeader: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
zipFileHeader.Name = zipFileName
|
||||
zipFileWriter, err := zipWriter.CreateHeader(zipFileHeader)
|
||||
if err != nil {
|
||||
fmt.Printf("Error creating file in tmp zip: %s\n", err)
|
||||
os.Exit(1)
|
||||
|
|
17
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/clean.go
generated
vendored
17
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/clean.go
generated
vendored
|
@ -9,15 +9,24 @@ import (
|
|||
)
|
||||
|
||||
func operationClean(pkg *build.Package) {
|
||||
for _, filename := range pkg.GoFiles {
|
||||
filepath.Walk(pkg.Dir, func(filename string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
fmt.Printf("error walking pkg dir to clean files: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
if info.IsDir() {
|
||||
return nil
|
||||
}
|
||||
verbosef("checking file '%s'\n", filename)
|
||||
if strings.HasSuffix(filename, ".rice-box.go") || strings.HasSuffix(filename, ".rice-single.go") {
|
||||
err := os.Remove(filepath.Join(pkg.Dir, filename))
|
||||
if strings.HasSuffix(filename, ".rice-box.go") ||
|
||||
strings.HasSuffix(filename, ".rice-box.syso") {
|
||||
err := os.Remove(filename)
|
||||
if err != nil {
|
||||
fmt.Printf("error removing file (%s): %s\n", filename, err)
|
||||
os.Exit(-1)
|
||||
}
|
||||
verbosef("removed file '%s'\n", filename)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ import (
|
|||
"time"
|
||||
)
|
||||
|
||||
func operationEmbed(pkg *build.Package) {
|
||||
func operationEmbedGo(pkg *build.Package) {
|
||||
|
||||
boxMap := findBoxes(pkg)
|
||||
|
197
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/embed-syso.go
generated
vendored
Normal file
197
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/embed-syso.go
generated
vendored
Normal file
|
@ -0,0 +1,197 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"fmt"
|
||||
"github.com/GeertJohan/go.rice/embedded"
|
||||
"github.com/akavel/rsrc/coff"
|
||||
"go/build"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"text/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
type sizedReader struct {
|
||||
*bytes.Reader
|
||||
}
|
||||
|
||||
func (s sizedReader) Size() int64 {
|
||||
return int64(s.Len())
|
||||
}
|
||||
|
||||
var tmplEmbeddedSysoHelper *template.Template
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
tmplEmbeddedSysoHelper, err = template.New("embeddedSysoHelper").Parse(`package {{.Package}}
|
||||
// ############# GENERATED CODE #####################
|
||||
// ## This file was generated by the rice tool.
|
||||
// ## Do not edit unless you know what you're doing.
|
||||
// ##################################################
|
||||
|
||||
// extern char _bricebox_{{.Symname}}[], _ericebox_{{.Symname}};
|
||||
// int get_{{.Symname}}_length() {
|
||||
// return &_ericebox_{{.Symname}} - _bricebox_{{.Symname}};
|
||||
// }
|
||||
import "C"
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/gob"
|
||||
"github.com/GeertJohan/go.rice/embedded"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func init() {
|
||||
ptr := unsafe.Pointer(&C._bricebox_{{.Symname}})
|
||||
bts := C.GoBytes(ptr, C.get_{{.Symname}}_length())
|
||||
embeddedBox := &embedded.EmbeddedBox{}
|
||||
err := gob.NewDecoder(bytes.NewReader(bts)).Decode(embeddedBox)
|
||||
if err != nil {
|
||||
panic("error decoding embedded box: "+err.Error())
|
||||
}
|
||||
embeddedBox.Link()
|
||||
embedded.RegisterEmbeddedBox(embeddedBox.Name, embeddedBox)
|
||||
}`)
|
||||
if err != nil {
|
||||
panic("could not parse template embeddedSysoHelper: " + err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
type embeddedSysoHelperData struct {
|
||||
Package string
|
||||
Symname string
|
||||
}
|
||||
|
||||
func operationEmbedSyso(pkg *build.Package) {
|
||||
|
||||
regexpSynameReplacer := regexp.MustCompile(`[^a-z0-9_]`)
|
||||
|
||||
boxMap := findBoxes(pkg)
|
||||
|
||||
// notify user when no calls to rice.FindBox are made (is this an error and therefore os.Exit(1) ?
|
||||
if len(boxMap) == 0 {
|
||||
fmt.Println("no calls to rice.FindBox() found")
|
||||
return
|
||||
}
|
||||
|
||||
verbosef("\n")
|
||||
|
||||
for boxname := range boxMap {
|
||||
// find path and filename for this box
|
||||
boxPath := filepath.Join(pkg.Dir, boxname)
|
||||
boxFilename := strings.Replace(boxname, "/", "-", -1)
|
||||
boxFilename = strings.Replace(boxFilename, "..", "back", -1)
|
||||
boxFilename = strings.Replace(boxFilename, ".", "-", -1)
|
||||
|
||||
// verbose info
|
||||
verbosef("embedding box '%s'\n", boxname)
|
||||
verbosef("\tto file %s\n", boxFilename)
|
||||
|
||||
// create box datastructure (used by template)
|
||||
box := &embedded.EmbeddedBox{
|
||||
Name: boxname,
|
||||
Time: time.Now(),
|
||||
EmbedType: embedded.EmbedTypeSyso,
|
||||
Files: make(map[string]*embedded.EmbeddedFile),
|
||||
Dirs: make(map[string]*embedded.EmbeddedDir),
|
||||
}
|
||||
|
||||
// fill box datastructure with file data
|
||||
filepath.Walk(boxPath, func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
fmt.Printf("error walking box: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
filename := strings.TrimPrefix(path, boxPath)
|
||||
filename = strings.Replace(filename, "\\", "/", -1)
|
||||
filename = strings.TrimPrefix(filename, "/")
|
||||
if info.IsDir() {
|
||||
embeddedDir := &embedded.EmbeddedDir{
|
||||
Filename: filename,
|
||||
DirModTime: info.ModTime(),
|
||||
}
|
||||
verbosef("\tincludes dir: '%s'\n", embeddedDir.Filename)
|
||||
box.Dirs[embeddedDir.Filename] = embeddedDir
|
||||
|
||||
// add tree entry (skip for root, it'll create a recursion)
|
||||
if embeddedDir.Filename != "" {
|
||||
pathParts := strings.Split(embeddedDir.Filename, "/")
|
||||
parentDir := box.Dirs[strings.Join(pathParts[:len(pathParts)-1], "/")]
|
||||
parentDir.ChildDirs = append(parentDir.ChildDirs, embeddedDir)
|
||||
}
|
||||
} else {
|
||||
embeddedFile := &embedded.EmbeddedFile{
|
||||
Filename: filename,
|
||||
FileModTime: info.ModTime(),
|
||||
Content: "",
|
||||
}
|
||||
verbosef("\tincludes file: '%s'\n", embeddedFile.Filename)
|
||||
contentBytes, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading file content while walking box: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
embeddedFile.Content = string(contentBytes)
|
||||
box.Files[embeddedFile.Filename] = embeddedFile
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
// encode embedded box to gob file
|
||||
boxGobBuf := &bytes.Buffer{}
|
||||
err := gob.NewEncoder(boxGobBuf).Encode(box)
|
||||
if err != nil {
|
||||
fmt.Printf("error encoding box to gob: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
verbosef("gob-encoded embeddedBox is %d bytes large\n", boxGobBuf.Len())
|
||||
|
||||
// write coff
|
||||
symname := regexpSynameReplacer.ReplaceAllString(boxname, "_")
|
||||
createCoffSyso(boxname, symname, "386", boxGobBuf.Bytes())
|
||||
createCoffSyso(boxname, symname, "amd64", boxGobBuf.Bytes())
|
||||
|
||||
// write go
|
||||
sysoHelperData := embeddedSysoHelperData{
|
||||
Package: pkg.Name,
|
||||
Symname: symname,
|
||||
}
|
||||
fileSysoHelper, err := os.Create(boxFilename + ".rice-box.go")
|
||||
if err != nil {
|
||||
fmt.Printf("error creating syso helper: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
err = tmplEmbeddedSysoHelper.Execute(fileSysoHelper, sysoHelperData)
|
||||
if err != nil {
|
||||
fmt.Printf("error executing tmplEmbeddedSysoHelper: %v\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func createCoffSyso(boxFilename string, symname string, arch string, data []byte) {
|
||||
boxCoff := coff.NewRDATA()
|
||||
switch arch {
|
||||
case "386":
|
||||
case "amd64":
|
||||
boxCoff.FileHeader.Machine = 0x8664
|
||||
default:
|
||||
panic("invalid arch")
|
||||
}
|
||||
boxCoff.AddData("_bricebox_"+symname, sizedReader{bytes.NewReader(data)})
|
||||
boxCoff.AddData("_ericebox_"+symname, io.NewSectionReader(strings.NewReader("\000\000"), 0, 2)) // TODO: why? copied from rsrc, which copied it from as-generated
|
||||
boxCoff.Freeze()
|
||||
err := writeCoff(boxCoff, boxFilename+"_"+arch+".rice-box.syso")
|
||||
if err != nil {
|
||||
fmt.Printf("error writing %s coff/.syso: %v\n", arch, err)
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
96
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/find.go
generated
vendored
96
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/find.go
generated
vendored
|
@ -2,11 +2,13 @@ package main
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"go/ast"
|
||||
"go/build"
|
||||
"io/ioutil"
|
||||
"go/parser"
|
||||
"go/token"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func findBoxes(pkg *build.Package) map[string]bool {
|
||||
|
@ -15,13 +17,6 @@ func findBoxes(pkg *build.Package) map[string]bool {
|
|||
filenames = append(filenames, pkg.GoFiles...)
|
||||
filenames = append(filenames, pkg.CgoFiles...)
|
||||
|
||||
// prepare regex to find calls to rice.FindBox(..)
|
||||
regexpBox, err := regexp.Compile(`rice\.(?:Must)?FindBox\(["` + "`" + `]{1}([a-zA-Z0-9\\/\.\-_]+)["` + "`" + `]{1}\)`)
|
||||
if err != nil {
|
||||
fmt.Printf("error compiling rice.FindBox regexp: %s\n", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// create map of boxes to embed
|
||||
var boxMap = make(map[string]bool)
|
||||
|
||||
|
@ -29,29 +24,80 @@ func findBoxes(pkg *build.Package) map[string]bool {
|
|||
for _, filename := range filenames {
|
||||
// find full filepath
|
||||
fullpath := filepath.Join(pkg.Dir, filename)
|
||||
verbosef("scanning file %s\n", fullpath)
|
||||
|
||||
// open source file
|
||||
file, err := os.Open(fullpath)
|
||||
if err != nil {
|
||||
fmt.Printf("error opening file '%s': %s\n", filename, err)
|
||||
os.Exit(1)
|
||||
if strings.HasSuffix(filename, "rice-box.go") {
|
||||
// Ignore *.rice-box.go files
|
||||
verbosef("skipping file %q\n", fullpath)
|
||||
continue
|
||||
}
|
||||
defer file.Close()
|
||||
verbosef("scanning file %q\n", fullpath)
|
||||
|
||||
// slurp source code
|
||||
fileData, err := ioutil.ReadAll(file)
|
||||
fset := token.NewFileSet()
|
||||
f, err := parser.ParseFile(fset, fullpath, nil, 0)
|
||||
if err != nil {
|
||||
fmt.Printf("error reading file '%s': %s\n", filename, err)
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
// find rice.FindBox(..) calls
|
||||
matches := regexpBox.FindAllStringSubmatch(string(fileData), -1)
|
||||
for _, match := range matches {
|
||||
boxMap[match[1]] = true
|
||||
verbosef("\tfound box '%s'\n", match[1])
|
||||
var riceIsImported bool
|
||||
ricePkgName := "rice"
|
||||
for _, imp := range f.Imports {
|
||||
if strings.HasSuffix(imp.Path.Value, "go.rice\"") {
|
||||
if imp.Name != nil {
|
||||
ricePkgName = imp.Name.Name
|
||||
}
|
||||
riceIsImported = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !riceIsImported {
|
||||
// Rice wasn't imported, so we won't find a box.
|
||||
continue
|
||||
}
|
||||
if ricePkgName == "_" {
|
||||
// Rice pkg is unnamed, so we won't find a box.
|
||||
continue
|
||||
}
|
||||
|
||||
// Inspect AST, looking for calls to (Must)?FindBox.
|
||||
// First parameter of the func must be a basic literal.
|
||||
// Identifiers won't be resolved.
|
||||
var nextIdentIsBoxFunc bool
|
||||
var nextBasicLitParamIsBoxName bool
|
||||
ast.Inspect(f, func(node ast.Node) bool {
|
||||
if node == nil {
|
||||
return false
|
||||
}
|
||||
switch x := node.(type) {
|
||||
case *ast.Ident:
|
||||
if nextIdentIsBoxFunc || ricePkgName == "." {
|
||||
nextIdentIsBoxFunc = false
|
||||
if x.Name == "FindBox" || x.Name == "MustFindBox" {
|
||||
nextBasicLitParamIsBoxName = true
|
||||
}
|
||||
} else {
|
||||
if x.Name == ricePkgName {
|
||||
nextIdentIsBoxFunc = true
|
||||
}
|
||||
}
|
||||
case *ast.BasicLit:
|
||||
if nextBasicLitParamIsBoxName && x.Kind == token.STRING {
|
||||
nextBasicLitParamIsBoxName = false
|
||||
// trim "" or ``
|
||||
name := x.Value[1 : len(x.Value)-1]
|
||||
boxMap[name] = true
|
||||
verbosef("\tfound box %q\n", name)
|
||||
}
|
||||
|
||||
default:
|
||||
if nextIdentIsBoxFunc {
|
||||
nextIdentIsBoxFunc = false
|
||||
}
|
||||
if nextBasicLitParamIsBoxName {
|
||||
nextBasicLitParamIsBoxName = false
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
}
|
||||
|
||||
return boxMap
|
||||
|
|
265
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/find_test.go
generated
vendored
Normal file
265
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/find_test.go
generated
vendored
Normal file
|
@ -0,0 +1,265 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"go/build"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type sourceFile struct {
|
||||
Name string
|
||||
Contents []byte
|
||||
}
|
||||
|
||||
func expectBoxes(expected []string, actual map[string]bool) error {
|
||||
if len(expected) != len(actual) {
|
||||
return fmt.Errorf("expected %v, got %v", expected, actual)
|
||||
}
|
||||
for _, box := range expected {
|
||||
if _, ok := actual[box]; !ok {
|
||||
return fmt.Errorf("expected %v, got %v", expected, actual)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func setUpTestPkg(pkgName string, files []sourceFile) (*build.Package, func(), error) {
|
||||
temp, err := ioutil.TempDir("", "go.rice-test")
|
||||
if err != nil {
|
||||
return nil, func() {}, err
|
||||
}
|
||||
cleanup := func() {
|
||||
os.RemoveAll(temp)
|
||||
}
|
||||
dir := filepath.Join(temp, pkgName)
|
||||
if err := os.Mkdir(dir, 0770); err != nil {
|
||||
return nil, cleanup, err
|
||||
}
|
||||
for _, f := range files {
|
||||
if err := ioutil.WriteFile(filepath.Join(dir, f.Name), f.Contents, 0660); err != nil {
|
||||
return nil, cleanup, err
|
||||
}
|
||||
}
|
||||
pkg, err := build.ImportDir(dir, 0)
|
||||
return pkg, cleanup, err
|
||||
}
|
||||
|
||||
func TestFindOneBox(t *testing.T) {
|
||||
pkg, cleanup, err := setUpTestPkg("foobar", []sourceFile{
|
||||
{
|
||||
"boxes.go",
|
||||
[]byte(`package main
|
||||
|
||||
import (
|
||||
"github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rice.MustFindBox("foo")
|
||||
}
|
||||
`),
|
||||
},
|
||||
})
|
||||
defer cleanup()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
expectedBoxes := []string{"foo"}
|
||||
boxMap := findBoxes(pkg)
|
||||
if err := expectBoxes(expectedBoxes, boxMap); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFindMultipleBoxes(t *testing.T) {
|
||||
pkg, cleanup, err := setUpTestPkg("foobar", []sourceFile{
|
||||
{
|
||||
"boxes.go",
|
||||
[]byte(`package main
|
||||
|
||||
import (
|
||||
"github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
func main() {
|
||||
rice.MustFindBox("foo")
|
||||
rice.MustFindBox("bar")
|
||||
}
|
||||
`),
|
||||
},
|
||||
})
|
||||
defer cleanup()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
expectedBoxes := []string{"foo", "bar"}
|
||||
boxMap := findBoxes(pkg)
|
||||
if err := expectBoxes(expectedBoxes, boxMap); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNoBoxFoundIfRiceNotImported(t *testing.T) {
|
||||
pkg, cleanup, err := setUpTestPkg("foobar", []sourceFile{
|
||||
{
|
||||
"boxes.go",
|
||||
[]byte(`package main
|
||||
type fakerice struct {}
|
||||
|
||||
func (fr fakerice) FindBox(s string) {
|
||||
}
|
||||
|
||||
func main() {
|
||||
rice := fakerice{}
|
||||
rice.FindBox("foo")
|
||||
}
|
||||
`),
|
||||
},
|
||||
})
|
||||
defer cleanup()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
boxMap := findBoxes(pkg)
|
||||
if _, ok := boxMap["foo"]; ok {
|
||||
t.Errorf("Unexpected box %q was found", "foo")
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnrelatedBoxesAreNotFound(t *testing.T) {
|
||||
pkg, cleanup, err := setUpTestPkg("foobar", []sourceFile{
|
||||
{
|
||||
"boxes.go",
|
||||
[]byte(`package foobar
|
||||
|
||||
import (
|
||||
_ "github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
type fakerice struct {}
|
||||
|
||||
func (fr fakerice) FindBox(s string) {
|
||||
}
|
||||
|
||||
func FindBox(s string) {
|
||||
|
||||
}
|
||||
|
||||
func LoadBoxes() {
|
||||
rice := fakerice{}
|
||||
rice.FindBox("foo")
|
||||
|
||||
FindBox("bar")
|
||||
}
|
||||
`),
|
||||
},
|
||||
})
|
||||
defer cleanup()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
boxMap := findBoxes(pkg)
|
||||
for _, box := range []string{"foo", "bar"} {
|
||||
if _, ok := boxMap[box]; ok {
|
||||
t.Errorf("Unexpected box %q was found", box)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestMixGoodAndBadBoxes(t *testing.T) {
|
||||
pkg, cleanup, err := setUpTestPkg("foobar", []sourceFile{
|
||||
{
|
||||
"boxes1.go",
|
||||
[]byte(`package foobar
|
||||
|
||||
import (
|
||||
_ "github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
type fakerice struct {}
|
||||
|
||||
func (fr fakerice) FindBox(s string) {
|
||||
}
|
||||
|
||||
func FindBox(s string) {
|
||||
|
||||
}
|
||||
|
||||
func LoadBoxes1() {
|
||||
rice := fakerice{}
|
||||
rice.FindBox("foo")
|
||||
|
||||
FindBox("bar")
|
||||
}
|
||||
`),
|
||||
},
|
||||
{
|
||||
"boxes2.go",
|
||||
[]byte(`package foobar
|
||||
|
||||
import (
|
||||
noodles "github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
func LoadBoxes2() {
|
||||
FindBox("baz")
|
||||
noodles.FindBox("veggies")
|
||||
}
|
||||
`),
|
||||
},
|
||||
{
|
||||
"boxes3.go",
|
||||
[]byte(`package foobar
|
||||
|
||||
import (
|
||||
"github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
func LoadBoxes3() {
|
||||
rice.FindBox("fish")
|
||||
}
|
||||
`),
|
||||
},
|
||||
{
|
||||
"boxes4.go",
|
||||
[]byte(`package foobar
|
||||
|
||||
import (
|
||||
. "github.com/GeertJohan/go.rice"
|
||||
)
|
||||
|
||||
func LoadBoxes3() {
|
||||
MustFindBox("chicken")
|
||||
}
|
||||
`),
|
||||
},
|
||||
})
|
||||
defer cleanup()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
boxMap := findBoxes(pkg)
|
||||
for _, box := range []string{"foo", "bar", "baz"} {
|
||||
if _, ok := boxMap[box]; ok {
|
||||
t.Errorf("Unexpected box %q was found", box)
|
||||
}
|
||||
}
|
||||
for _, box := range []string{"veggies", "fish", "chicken"} {
|
||||
if _, ok := boxMap[box]; !ok {
|
||||
t.Errorf("Expected box %q not found", box)
|
||||
}
|
||||
}
|
||||
}
|
5
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/flags.go
generated
vendored
5
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/flags.go
generated
vendored
|
@ -16,8 +16,9 @@ var flags struct {
|
|||
Executable string `long:"exec" description:"Executable to append" required:"true"`
|
||||
} `command:"append"`
|
||||
|
||||
Embed struct{} `command:"embed"`
|
||||
Clean struct{} `command:"clean"`
|
||||
EmbedGo struct{} `command:"embed-go" alias:"embed"`
|
||||
EmbedSyso struct{} `command:"embed-syso"`
|
||||
Clean struct{} `command:"clean"`
|
||||
}
|
||||
|
||||
// flags parser
|
||||
|
|
7
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/main.go
generated
vendored
7
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/main.go
generated
vendored
|
@ -16,8 +16,11 @@ func main() {
|
|||
|
||||
// switch on the operation to perform
|
||||
switch flagsParser.Active.Name {
|
||||
case "embed":
|
||||
operationEmbed(pkg)
|
||||
case "embed", "embed-go":
|
||||
operationEmbedGo(pkg)
|
||||
case "embed-syso":
|
||||
log.Println("WARNING: embedding .syso is expirimental..")
|
||||
operationEmbedSyso(pkg)
|
||||
case "append":
|
||||
operationAppend(pkg)
|
||||
case "clean":
|
||||
|
|
7
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/templates.go
generated
vendored
7
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/templates.go
generated
vendored
|
@ -75,13 +75,6 @@ type boxDataType struct {
|
|||
Dirs map[string]*dirDataType
|
||||
}
|
||||
|
||||
type singleDataType struct {
|
||||
Package string
|
||||
SingleName string
|
||||
UnixNow int64
|
||||
File *fileDataType
|
||||
}
|
||||
|
||||
type fileDataType struct {
|
||||
Identifier string
|
||||
FileName string
|
||||
|
|
41
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/writecoff.go
generated
vendored
Normal file
41
Godeps/_workspace/src/github.com/GeertJohan/go.rice/rice/writecoff.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/akavel/rsrc/binutil"
|
||||
"github.com/akavel/rsrc/coff"
|
||||
"os"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// copied from github.com/akavel/rsrc
|
||||
// LICENSE: MIT
|
||||
// Copyright 2013-2014 The rsrc Authors. (https://github.com/akavel/rsrc/blob/master/AUTHORS)
|
||||
func writeCoff(coff *coff.Coff, fnameout string) error {
|
||||
out, err := os.Create(fnameout)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
w := binutil.Writer{W: out}
|
||||
|
||||
// write the resulting file to disk
|
||||
binutil.Walk(coff, func(v reflect.Value, path string) error {
|
||||
if binutil.Plain(v.Kind()) {
|
||||
w.WriteLE(v.Interface())
|
||||
return nil
|
||||
}
|
||||
vv, ok := v.Interface().(binutil.SizedReader)
|
||||
if ok {
|
||||
w.WriteFromSized(vv)
|
||||
return binutil.WALK_SKIP
|
||||
}
|
||||
return nil
|
||||
})
|
||||
|
||||
if w.Err != nil {
|
||||
return fmt.Errorf("Error writing output file: %s", w.Err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
2
Godeps/_workspace/src/github.com/GeertJohan/go.rice/virtual.go
generated
vendored
2
Godeps/_workspace/src/github.com/GeertJohan/go.rice/virtual.go
generated
vendored
|
@ -65,7 +65,7 @@ func (vf *virtualFile) readdir(count int) ([]os.FileInfo, error) {
|
|||
Err: errors.New("bad file descriptor"),
|
||||
}
|
||||
}
|
||||
//++ wont work for a file
|
||||
//TODO: return proper error for a readdir() call on a file
|
||||
return nil, ErrNotImplemented
|
||||
}
|
||||
|
||||
|
|
344
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/common.go
generated
vendored
344
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/common.go
generated
vendored
|
@ -1,344 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"reflect"
|
||||
"sort"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// offsetPtr, offsetScalar, and offsetFlag are the offsets for the internal
|
||||
// reflect.Value fields.
|
||||
var offsetPtr, offsetScalar, offsetFlag uintptr
|
||||
|
||||
// reflectValueOld mirrors the struct layout of the reflect package Value type
|
||||
// before golang commit ecccf07e7f9d.
|
||||
var reflectValueOld struct {
|
||||
typ unsafe.Pointer
|
||||
val unsafe.Pointer
|
||||
flag uintptr
|
||||
}
|
||||
|
||||
// reflectValueNew mirrors the struct layout of the reflect package Value type
|
||||
// after golang commit ecccf07e7f9d.
|
||||
var reflectValueNew struct {
|
||||
typ unsafe.Pointer
|
||||
ptr unsafe.Pointer
|
||||
scalar uintptr
|
||||
flag uintptr
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Older versions of reflect.Value stored small integers directly in the
|
||||
// ptr field (which is named val in the older versions). Newer versions
|
||||
// added a new field named scalar for this purpose which unfortuantely
|
||||
// comes before the flag field. Further the new field is before the
|
||||
// flag field, so the offset of the flag field is different as well.
|
||||
// This code constructs a new reflect.Value from a known small integer
|
||||
// and checks if the val field within it matches. When it matches, the
|
||||
// old style reflect.Value is being used. Otherwise it's the new style.
|
||||
v := 0xf00
|
||||
vv := reflect.ValueOf(v)
|
||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) +
|
||||
unsafe.Offsetof(reflectValueOld.val))
|
||||
|
||||
// Assume the old style by default.
|
||||
offsetPtr = unsafe.Offsetof(reflectValueOld.val)
|
||||
offsetScalar = 0
|
||||
offsetFlag = unsafe.Offsetof(reflectValueOld.flag)
|
||||
|
||||
// Use the new style offsets if the ptr field doesn't match the value
|
||||
// since it must be in the new scalar field.
|
||||
if int(*(*uintptr)(upv)) != v {
|
||||
offsetPtr = unsafe.Offsetof(reflectValueNew.ptr)
|
||||
offsetScalar = unsafe.Offsetof(reflectValueNew.scalar)
|
||||
offsetFlag = unsafe.Offsetof(reflectValueNew.flag)
|
||||
}
|
||||
}
|
||||
|
||||
// flagIndir indicates whether the value field of a reflect.Value is the actual
|
||||
// data or a pointer to the data.
|
||||
const flagIndir = 1 << 1
|
||||
|
||||
// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
|
||||
// the typical safety restrictions preventing access to unaddressable and
|
||||
// unexported data. It works by digging the raw pointer to the underlying
|
||||
// value out of the protected value and generating a new unprotected (unsafe)
|
||||
// reflect.Value to it.
|
||||
//
|
||||
// This allows us to check for implementations of the Stringer and error
|
||||
// interfaces to be used for pretty printing ordinarily unaddressable and
|
||||
// inaccessible values such as unexported struct fields.
|
||||
func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
|
||||
indirects := 1
|
||||
vt := v.Type()
|
||||
upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
|
||||
rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
|
||||
if rvf&flagIndir != 0 {
|
||||
vt = reflect.PtrTo(v.Type())
|
||||
indirects++
|
||||
} else if offsetScalar != 0 {
|
||||
upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetScalar)
|
||||
}
|
||||
|
||||
pv := reflect.NewAt(vt, upv)
|
||||
rv = pv
|
||||
for i := 0; i < indirects; i++ {
|
||||
rv = rv.Elem()
|
||||
}
|
||||
return rv
|
||||
}
|
||||
|
||||
// Some constants in the form of bytes to avoid string overhead. This mirrors
|
||||
// the technique used in the fmt package.
|
||||
var (
|
||||
panicBytes = []byte("(PANIC=")
|
||||
plusBytes = []byte("+")
|
||||
iBytes = []byte("i")
|
||||
trueBytes = []byte("true")
|
||||
falseBytes = []byte("false")
|
||||
interfaceBytes = []byte("(interface {})")
|
||||
commaNewlineBytes = []byte(",\n")
|
||||
newlineBytes = []byte("\n")
|
||||
openBraceBytes = []byte("{")
|
||||
openBraceNewlineBytes = []byte("{\n")
|
||||
closeBraceBytes = []byte("}")
|
||||
asteriskBytes = []byte("*")
|
||||
colonBytes = []byte(":")
|
||||
colonSpaceBytes = []byte(": ")
|
||||
openParenBytes = []byte("(")
|
||||
closeParenBytes = []byte(")")
|
||||
spaceBytes = []byte(" ")
|
||||
pointerChainBytes = []byte("->")
|
||||
nilAngleBytes = []byte("<nil>")
|
||||
maxNewlineBytes = []byte("<max depth reached>\n")
|
||||
maxShortBytes = []byte("<max>")
|
||||
circularBytes = []byte("<already shown>")
|
||||
circularShortBytes = []byte("<shown>")
|
||||
invalidAngleBytes = []byte("<invalid>")
|
||||
openBracketBytes = []byte("[")
|
||||
closeBracketBytes = []byte("]")
|
||||
percentBytes = []byte("%")
|
||||
precisionBytes = []byte(".")
|
||||
openAngleBytes = []byte("<")
|
||||
closeAngleBytes = []byte(">")
|
||||
openMapBytes = []byte("map[")
|
||||
closeMapBytes = []byte("]")
|
||||
)
|
||||
|
||||
// hexDigits is used to map a decimal value to a hex digit.
|
||||
var hexDigits = "0123456789abcdef"
|
||||
|
||||
// catchPanic handles any panics that might occur during the handleMethods
|
||||
// calls.
|
||||
func catchPanic(w io.Writer, v reflect.Value) {
|
||||
if err := recover(); err != nil {
|
||||
w.Write(panicBytes)
|
||||
fmt.Fprintf(w, "%v", err)
|
||||
w.Write(closeParenBytes)
|
||||
}
|
||||
}
|
||||
|
||||
// handleMethods attempts to call the Error and String methods on the underlying
|
||||
// type the passed reflect.Value represents and outputes the result to Writer w.
|
||||
//
|
||||
// It handles panics in any called methods by catching and displaying the error
|
||||
// as the formatted value.
|
||||
func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
|
||||
// We need an interface to check if the type implements the error or
|
||||
// Stringer interface. However, the reflect package won't give us an
|
||||
// interface on certain things like unexported struct fields in order
|
||||
// to enforce visibility rules. We use unsafe to bypass these restrictions
|
||||
// since this package does not mutate the values.
|
||||
if !v.CanInterface() {
|
||||
v = unsafeReflectValue(v)
|
||||
}
|
||||
|
||||
// Choose whether or not to do error and Stringer interface lookups against
|
||||
// the base type or a pointer to the base type depending on settings.
|
||||
// Technically calling one of these methods with a pointer receiver can
|
||||
// mutate the value, however, types which choose to satisify an error or
|
||||
// Stringer interface with a pointer receiver should not be mutating their
|
||||
// state inside these interface methods.
|
||||
var viface interface{}
|
||||
if !cs.DisablePointerMethods {
|
||||
if !v.CanAddr() {
|
||||
v = unsafeReflectValue(v)
|
||||
}
|
||||
viface = v.Addr().Interface()
|
||||
} else {
|
||||
if v.CanAddr() {
|
||||
v = v.Addr()
|
||||
}
|
||||
viface = v.Interface()
|
||||
}
|
||||
|
||||
// Is it an error or Stringer?
|
||||
switch iface := viface.(type) {
|
||||
case error:
|
||||
defer catchPanic(w, v)
|
||||
if cs.ContinueOnMethod {
|
||||
w.Write(openParenBytes)
|
||||
w.Write([]byte(iface.Error()))
|
||||
w.Write(closeParenBytes)
|
||||
w.Write(spaceBytes)
|
||||
return false
|
||||
}
|
||||
|
||||
w.Write([]byte(iface.Error()))
|
||||
return true
|
||||
|
||||
case fmt.Stringer:
|
||||
defer catchPanic(w, v)
|
||||
if cs.ContinueOnMethod {
|
||||
w.Write(openParenBytes)
|
||||
w.Write([]byte(iface.String()))
|
||||
w.Write(closeParenBytes)
|
||||
w.Write(spaceBytes)
|
||||
return false
|
||||
}
|
||||
w.Write([]byte(iface.String()))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// printBool outputs a boolean value as true or false to Writer w.
|
||||
func printBool(w io.Writer, val bool) {
|
||||
if val {
|
||||
w.Write(trueBytes)
|
||||
} else {
|
||||
w.Write(falseBytes)
|
||||
}
|
||||
}
|
||||
|
||||
// printInt outputs a signed integer value to Writer w.
|
||||
func printInt(w io.Writer, val int64, base int) {
|
||||
w.Write([]byte(strconv.FormatInt(val, base)))
|
||||
}
|
||||
|
||||
// printUint outputs an unsigned integer value to Writer w.
|
||||
func printUint(w io.Writer, val uint64, base int) {
|
||||
w.Write([]byte(strconv.FormatUint(val, base)))
|
||||
}
|
||||
|
||||
// printFloat outputs a floating point value using the specified precision,
|
||||
// which is expected to be 32 or 64bit, to Writer w.
|
||||
func printFloat(w io.Writer, val float64, precision int) {
|
||||
w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
|
||||
}
|
||||
|
||||
// printComplex outputs a complex value using the specified float precision
|
||||
// for the real and imaginary parts to Writer w.
|
||||
func printComplex(w io.Writer, c complex128, floatPrecision int) {
|
||||
r := real(c)
|
||||
w.Write(openParenBytes)
|
||||
w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
|
||||
i := imag(c)
|
||||
if i >= 0 {
|
||||
w.Write(plusBytes)
|
||||
}
|
||||
w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
|
||||
w.Write(iBytes)
|
||||
w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
|
||||
// prefix to Writer w.
|
||||
func printHexPtr(w io.Writer, p uintptr) {
|
||||
// Null pointer.
|
||||
num := uint64(p)
|
||||
if num == 0 {
|
||||
w.Write(nilAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
|
||||
buf := make([]byte, 18)
|
||||
|
||||
// It's simpler to construct the hex string right to left.
|
||||
base := uint64(16)
|
||||
i := len(buf) - 1
|
||||
for num >= base {
|
||||
buf[i] = hexDigits[num%base]
|
||||
num /= base
|
||||
i--
|
||||
}
|
||||
buf[i] = hexDigits[num]
|
||||
|
||||
// Add '0x' prefix.
|
||||
i--
|
||||
buf[i] = 'x'
|
||||
i--
|
||||
buf[i] = '0'
|
||||
|
||||
// Strip unused leading bytes.
|
||||
buf = buf[i:]
|
||||
w.Write(buf)
|
||||
}
|
||||
|
||||
// valuesSorter implements sort.Interface to allow a slice of reflect.Value
|
||||
// elements to be sorted.
|
||||
type valuesSorter struct {
|
||||
values []reflect.Value
|
||||
}
|
||||
|
||||
// Len returns the number of values in the slice. It is part of the
|
||||
// sort.Interface implementation.
|
||||
func (s *valuesSorter) Len() int {
|
||||
return len(s.values)
|
||||
}
|
||||
|
||||
// Swap swaps the values at the passed indices. It is part of the
|
||||
// sort.Interface implementation.
|
||||
func (s *valuesSorter) Swap(i, j int) {
|
||||
s.values[i], s.values[j] = s.values[j], s.values[i]
|
||||
}
|
||||
|
||||
// Less returns whether the value at index i should sort before the
|
||||
// value at index j. It is part of the sort.Interface implementation.
|
||||
func (s *valuesSorter) Less(i, j int) bool {
|
||||
switch s.values[i].Kind() {
|
||||
case reflect.Bool:
|
||||
return !s.values[i].Bool() && s.values[j].Bool()
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
return s.values[i].Int() < s.values[j].Int()
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
return s.values[i].Uint() < s.values[j].Uint()
|
||||
case reflect.Float32, reflect.Float64:
|
||||
return s.values[i].Float() < s.values[j].Float()
|
||||
case reflect.String:
|
||||
return s.values[i].String() < s.values[j].String()
|
||||
case reflect.Uintptr:
|
||||
return s.values[i].Uint() < s.values[j].Uint()
|
||||
}
|
||||
return s.values[i].String() < s.values[j].String()
|
||||
}
|
||||
|
||||
// sortValues is a generic sort function for native types: int, uint, bool,
|
||||
// string and uintptr. Other inputs are sorted according to their
|
||||
// Value.String() value to ensure display stability.
|
||||
func sortValues(values []reflect.Value) {
|
||||
if len(values) == 0 {
|
||||
return
|
||||
}
|
||||
sort.Sort(&valuesSorter{values})
|
||||
}
|
192
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/common_test.go
generated
vendored
192
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/common_test.go
generated
vendored
|
@ -1,192 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// custom type to test Stinger interface on non-pointer receiver.
|
||||
type stringer string
|
||||
|
||||
// String implements the Stringer interface for testing invocation of custom
|
||||
// stringers on types with non-pointer receivers.
|
||||
func (s stringer) String() string {
|
||||
return "stringer " + string(s)
|
||||
}
|
||||
|
||||
// custom type to test Stinger interface on pointer receiver.
|
||||
type pstringer string
|
||||
|
||||
// String implements the Stringer interface for testing invocation of custom
|
||||
// stringers on types with only pointer receivers.
|
||||
func (s *pstringer) String() string {
|
||||
return "stringer " + string(*s)
|
||||
}
|
||||
|
||||
// xref1 and xref2 are cross referencing structs for testing circular reference
|
||||
// detection.
|
||||
type xref1 struct {
|
||||
ps2 *xref2
|
||||
}
|
||||
type xref2 struct {
|
||||
ps1 *xref1
|
||||
}
|
||||
|
||||
// indirCir1, indirCir2, and indirCir3 are used to generate an indirect circular
|
||||
// reference for testing detection.
|
||||
type indirCir1 struct {
|
||||
ps2 *indirCir2
|
||||
}
|
||||
type indirCir2 struct {
|
||||
ps3 *indirCir3
|
||||
}
|
||||
type indirCir3 struct {
|
||||
ps1 *indirCir1
|
||||
}
|
||||
|
||||
// embed is used to test embedded structures.
|
||||
type embed struct {
|
||||
a string
|
||||
}
|
||||
|
||||
// embedwrap is used to test embedded structures.
|
||||
type embedwrap struct {
|
||||
*embed
|
||||
e *embed
|
||||
}
|
||||
|
||||
// panicer is used to intentionally cause a panic for testing spew properly
|
||||
// handles them
|
||||
type panicer int
|
||||
|
||||
func (p panicer) String() string {
|
||||
panic("test panic")
|
||||
}
|
||||
|
||||
// customError is used to test custom error interface invocation.
|
||||
type customError int
|
||||
|
||||
func (e customError) Error() string {
|
||||
return fmt.Sprintf("error: %d", int(e))
|
||||
}
|
||||
|
||||
// stringizeWants converts a slice of wanted test output into a format suitable
|
||||
// for a test error message.
|
||||
func stringizeWants(wants []string) string {
|
||||
s := ""
|
||||
for i, want := range wants {
|
||||
if i > 0 {
|
||||
s += fmt.Sprintf("want%d: %s", i+1, want)
|
||||
} else {
|
||||
s += "want: " + want
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// testFailed returns whether or not a test failed by checking if the result
|
||||
// of the test is in the slice of wanted strings.
|
||||
func testFailed(result string, wants []string) bool {
|
||||
for _, want := range wants {
|
||||
if result == want {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// TestSortValues ensures the sort functionality for relect.Value based sorting
|
||||
// works as intended.
|
||||
func TestSortValues(t *testing.T) {
|
||||
getInterfaces := func(values []reflect.Value) []interface{} {
|
||||
interfaces := []interface{}{}
|
||||
for _, v := range values {
|
||||
interfaces = append(interfaces, v.Interface())
|
||||
}
|
||||
return interfaces
|
||||
}
|
||||
|
||||
v := reflect.ValueOf
|
||||
|
||||
a := v("a")
|
||||
b := v("b")
|
||||
c := v("c")
|
||||
embedA := v(embed{"a"})
|
||||
embedB := v(embed{"b"})
|
||||
embedC := v(embed{"c"})
|
||||
tests := []struct {
|
||||
input []reflect.Value
|
||||
expected []reflect.Value
|
||||
}{
|
||||
// No values.
|
||||
{
|
||||
[]reflect.Value{},
|
||||
[]reflect.Value{},
|
||||
},
|
||||
// Bools.
|
||||
{
|
||||
[]reflect.Value{v(false), v(true), v(false)},
|
||||
[]reflect.Value{v(false), v(false), v(true)},
|
||||
},
|
||||
// Ints.
|
||||
{
|
||||
[]reflect.Value{v(2), v(1), v(3)},
|
||||
[]reflect.Value{v(1), v(2), v(3)},
|
||||
},
|
||||
// Uints.
|
||||
{
|
||||
[]reflect.Value{v(uint8(2)), v(uint8(1)), v(uint8(3))},
|
||||
[]reflect.Value{v(uint8(1)), v(uint8(2)), v(uint8(3))},
|
||||
},
|
||||
// Floats.
|
||||
{
|
||||
[]reflect.Value{v(2.0), v(1.0), v(3.0)},
|
||||
[]reflect.Value{v(1.0), v(2.0), v(3.0)},
|
||||
},
|
||||
// Strings.
|
||||
{
|
||||
[]reflect.Value{b, a, c},
|
||||
[]reflect.Value{a, b, c},
|
||||
},
|
||||
// Uintptrs.
|
||||
{
|
||||
[]reflect.Value{v(uintptr(2)), v(uintptr(1)), v(uintptr(3))},
|
||||
[]reflect.Value{v(uintptr(1)), v(uintptr(2)), v(uintptr(3))},
|
||||
},
|
||||
// Invalid.
|
||||
{
|
||||
[]reflect.Value{embedB, embedA, embedC},
|
||||
[]reflect.Value{embedB, embedA, embedC},
|
||||
},
|
||||
}
|
||||
for _, test := range tests {
|
||||
spew.SortValues(test.input)
|
||||
// reflect.DeepEqual cannot really make sense of reflect.Value,
|
||||
// probably because of all the pointer tricks. For instance,
|
||||
// v(2.0) != v(2.0) on a 32-bits system. Turn them into interface{}
|
||||
// instead.
|
||||
input := getInterfaces(test.input)
|
||||
expected := getInterfaces(test.expected)
|
||||
if !reflect.DeepEqual(input, expected) {
|
||||
t.Errorf("Sort mismatch:\n %v != %v", input, expected)
|
||||
}
|
||||
}
|
||||
}
|
288
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/config.go
generated
vendored
288
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/config.go
generated
vendored
|
@ -1,288 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
// ConfigState houses the configuration options used by spew to format and
|
||||
// display values. There is a global instance, Config, that is used to control
|
||||
// all top-level Formatter and Dump functionality. Each ConfigState instance
|
||||
// provides methods equivalent to the top-level functions.
|
||||
//
|
||||
// The zero value for ConfigState provides no indentation. You would typically
|
||||
// want to set it to a space or a tab.
|
||||
//
|
||||
// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
|
||||
// with default settings. See the documentation of NewDefaultConfig for default
|
||||
// values.
|
||||
type ConfigState struct {
|
||||
// Indent specifies the string to use for each indentation level. The
|
||||
// global config instance that all top-level functions use set this to a
|
||||
// single space by default. If you would like more indentation, you might
|
||||
// set this to a tab with "\t" or perhaps two spaces with " ".
|
||||
Indent string
|
||||
|
||||
// MaxDepth controls the maximum number of levels to descend into nested
|
||||
// data structures. The default, 0, means there is no limit.
|
||||
//
|
||||
// NOTE: Circular data structures are properly detected, so it is not
|
||||
// necessary to set this value unless you specifically want to limit deeply
|
||||
// nested data structures.
|
||||
MaxDepth int
|
||||
|
||||
// DisableMethods specifies whether or not error and Stringer interfaces are
|
||||
// invoked for types that implement them.
|
||||
DisableMethods bool
|
||||
|
||||
// DisablePointerMethods specifies whether or not to check for and invoke
|
||||
// error and Stringer interfaces on types which only accept a pointer
|
||||
// receiver when the current type is not a pointer.
|
||||
//
|
||||
// NOTE: This might be an unsafe action since calling one of these methods
|
||||
// with a pointer receiver could technically mutate the value, however,
|
||||
// in practice, types which choose to satisify an error or Stringer
|
||||
// interface with a pointer receiver should not be mutating their state
|
||||
// inside these interface methods.
|
||||
DisablePointerMethods bool
|
||||
|
||||
// ContinueOnMethod specifies whether or not recursion should continue once
|
||||
// a custom error or Stringer interface is invoked. The default, false,
|
||||
// means it will print the results of invoking the custom error or Stringer
|
||||
// interface and return immediately instead of continuing to recurse into
|
||||
// the internals of the data type.
|
||||
//
|
||||
// NOTE: This flag does not have any effect if method invocation is disabled
|
||||
// via the DisableMethods or DisablePointerMethods options.
|
||||
ContinueOnMethod bool
|
||||
|
||||
// SortKeys specifies map keys should be sorted before being printed. Use
|
||||
// this to have a more deterministic, diffable output. Note that only
|
||||
// native types (bool, int, uint, floats, uintptr and string) are supported
|
||||
// with other types sorted according to the reflect.Value.String() output
|
||||
// which guarantees display stability.
|
||||
SortKeys bool
|
||||
}
|
||||
|
||||
// Config is the active configuration of the top-level functions.
|
||||
// The configuration can be changed by modifying the contents of spew.Config.
|
||||
var Config = ConfigState{Indent: " "}
|
||||
|
||||
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the formatted string as a value that satisfies error. See NewFormatter
|
||||
// for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
|
||||
return fmt.Errorf(format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprint(w, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintf(w, format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
||||
// passed with a Formatter interface returned by c.NewFormatter. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintln(w, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
|
||||
return fmt.Print(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Printf(format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
|
||||
return fmt.Println(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Sprint(a ...interface{}) string {
|
||||
return fmt.Sprint(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
|
||||
// passed with a Formatter interface returned by c.NewFormatter. It returns
|
||||
// the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
|
||||
return fmt.Sprintf(format, c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
|
||||
// were passed with a Formatter interface returned by c.NewFormatter. It
|
||||
// returns the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
|
||||
func (c *ConfigState) Sprintln(a ...interface{}) string {
|
||||
return fmt.Sprintln(c.convertArgs(a)...)
|
||||
}
|
||||
|
||||
/*
|
||||
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
||||
interface. As a result, it integrates cleanly with standard fmt package
|
||||
printing functions. The formatter is useful for inline printing of smaller data
|
||||
types similar to the standard %v format specifier.
|
||||
|
||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||
addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
|
||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Typically this function shouldn't be called directly. It is much easier to make
|
||||
use of the custom formatter by calling one of the convenience functions such as
|
||||
c.Printf, c.Println, or c.Printf.
|
||||
*/
|
||||
func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
|
||||
return newFormatter(c, v)
|
||||
}
|
||||
|
||||
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
||||
// exactly the same as Dump.
|
||||
func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
|
||||
fdump(c, w, a...)
|
||||
}
|
||||
|
||||
/*
|
||||
Dump displays the passed parameters to standard out with newlines, customizable
|
||||
indentation, and additional debug information such as complete types and all
|
||||
pointer addresses used to indirect to the final value. It provides the
|
||||
following features over the built-in printing facilities provided by the fmt
|
||||
package:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output
|
||||
|
||||
The configuration options are controlled by modifying the public members
|
||||
of c. See ConfigState for options documentation.
|
||||
|
||||
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
|
||||
get the formatted result as a string.
|
||||
*/
|
||||
func (c *ConfigState) Dump(a ...interface{}) {
|
||||
fdump(c, os.Stdout, a...)
|
||||
}
|
||||
|
||||
// Sdump returns a string with the passed arguments formatted exactly the same
|
||||
// as Dump.
|
||||
func (c *ConfigState) Sdump(a ...interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
fdump(c, &buf, a...)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// convertArgs accepts a slice of arguments and returns a slice of the same
|
||||
// length with each argument converted to a spew Formatter interface using
|
||||
// the ConfigState associated with s.
|
||||
func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
|
||||
formatters = make([]interface{}, len(args))
|
||||
for index, arg := range args {
|
||||
formatters[index] = newFormatter(c, arg)
|
||||
}
|
||||
return formatters
|
||||
}
|
||||
|
||||
// NewDefaultConfig returns a ConfigState with the following default settings.
|
||||
//
|
||||
// Indent: " "
|
||||
// MaxDepth: 0
|
||||
// DisableMethods: false
|
||||
// DisablePointerMethods: false
|
||||
// ContinueOnMethod: false
|
||||
// SortKeys: false
|
||||
func NewDefaultConfig() *ConfigState {
|
||||
return &ConfigState{Indent: " "}
|
||||
}
|
196
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/doc.go
generated
vendored
196
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/doc.go
generated
vendored
|
@ -1,196 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
Package spew implements a deep pretty printer for Go data structures to aid in
|
||||
debugging.
|
||||
|
||||
A quick overview of the additional features spew provides over the built-in
|
||||
printing facilities for Go data types are as follows:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output (only when using
|
||||
Dump style)
|
||||
|
||||
There are two different approaches spew allows for dumping Go data structures:
|
||||
|
||||
* Dump style which prints with newlines, customizable indentation,
|
||||
and additional debug information such as types and all pointer addresses
|
||||
used to indirect to the final value
|
||||
* A custom Formatter interface that integrates cleanly with the standard fmt
|
||||
package and replaces %v, %+v, %#v, and %#+v to provide inline printing
|
||||
similar to the default %v while providing the additional functionality
|
||||
outlined above and passing unsupported format verbs such as %x and %q
|
||||
along to fmt
|
||||
|
||||
Quick Start
|
||||
|
||||
This section demonstrates how to quickly get started with spew. See the
|
||||
sections below for further details on formatting and configuration options.
|
||||
|
||||
To dump a variable with full newlines, indentation, type, and pointer
|
||||
information use Dump, Fdump, or Sdump:
|
||||
spew.Dump(myVar1, myVar2, ...)
|
||||
spew.Fdump(someWriter, myVar1, myVar2, ...)
|
||||
str := spew.Sdump(myVar1, myVar2, ...)
|
||||
|
||||
Alternatively, if you would prefer to use format strings with a compacted inline
|
||||
printing style, use the convenience wrappers Printf, Fprintf, etc with
|
||||
%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
|
||||
%#+v (adds types and pointer addresses):
|
||||
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
|
||||
Configuration Options
|
||||
|
||||
Configuration of spew is handled by fields in the ConfigState type. For
|
||||
convenience, all of the top-level functions use a global state available
|
||||
via the spew.Config global.
|
||||
|
||||
It is also possible to create a ConfigState instance that provides methods
|
||||
equivalent to the top-level functions. This allows concurrent configuration
|
||||
options. See the ConfigState documentation for more details.
|
||||
|
||||
The following configuration options are available:
|
||||
* Indent
|
||||
String to use for each indentation level for Dump functions.
|
||||
It is a single space by default. A popular alternative is "\t".
|
||||
|
||||
* MaxDepth
|
||||
Maximum number of levels to descend into nested data structures.
|
||||
There is no limit by default.
|
||||
|
||||
* DisableMethods
|
||||
Disables invocation of error and Stringer interface methods.
|
||||
Method invocation is enabled by default.
|
||||
|
||||
* DisablePointerMethods
|
||||
Disables invocation of error and Stringer interface methods on types
|
||||
which only accept pointer receivers from non-pointer variables.
|
||||
Pointer method invocation is enabled by default.
|
||||
|
||||
* ContinueOnMethod
|
||||
Enables recursion into types after invoking error and Stringer interface
|
||||
methods. Recursion after method invocation is disabled by default.
|
||||
|
||||
* SortKeys
|
||||
Specifies map keys should be sorted before being printed. Use
|
||||
this to have a more deterministic, diffable output. Note that
|
||||
only native types (bool, int, uint, floats, uintptr and string)
|
||||
are supported with other types sorted according to the
|
||||
reflect.Value.String() output which guarantees display stability.
|
||||
Natural map order is used by default.
|
||||
|
||||
Dump Usage
|
||||
|
||||
Simply call spew.Dump with a list of variables you want to dump:
|
||||
|
||||
spew.Dump(myVar1, myVar2, ...)
|
||||
|
||||
You may also call spew.Fdump if you would prefer to output to an arbitrary
|
||||
io.Writer. For example, to dump to standard error:
|
||||
|
||||
spew.Fdump(os.Stderr, myVar1, myVar2, ...)
|
||||
|
||||
A third option is to call spew.Sdump to get the formatted output as a string:
|
||||
|
||||
str := spew.Sdump(myVar1, myVar2, ...)
|
||||
|
||||
Sample Dump Output
|
||||
|
||||
See the Dump example for details on the setup of the types and variables being
|
||||
shown here.
|
||||
|
||||
(main.Foo) {
|
||||
unexportedField: (*main.Bar)(0xf84002e210)({
|
||||
flag: (main.Flag) flagTwo,
|
||||
data: (uintptr) <nil>
|
||||
}),
|
||||
ExportedField: (map[interface {}]interface {}) {
|
||||
(string) "one": (bool) true
|
||||
}
|
||||
}
|
||||
|
||||
Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
|
||||
command as shown.
|
||||
([]uint8) {
|
||||
00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
||||
00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
||||
00000020 31 32 |12|
|
||||
}
|
||||
|
||||
Custom Formatter
|
||||
|
||||
Spew provides a custom formatter that implements the fmt.Formatter interface
|
||||
so that it integrates cleanly with standard fmt package printing functions. The
|
||||
formatter is useful for inline printing of smaller data types similar to the
|
||||
standard %v format specifier.
|
||||
|
||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Custom Formatter Usage
|
||||
|
||||
The simplest way to make use of the spew custom formatter is to call one of the
|
||||
convenience functions such as spew.Printf, spew.Println, or spew.Printf. The
|
||||
functions have syntax you are most likely already familiar with:
|
||||
|
||||
spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
spew.Println(myVar, myVar2)
|
||||
spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
|
||||
spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
|
||||
|
||||
See the Index for the full list convenience functions.
|
||||
|
||||
Sample Formatter Output
|
||||
|
||||
Double pointer to a uint8:
|
||||
%v: <**>5
|
||||
%+v: <**>(0xf8400420d0->0xf8400420c8)5
|
||||
%#v: (**uint8)5
|
||||
%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
|
||||
|
||||
Pointer to circular struct with a uint8 field and a pointer to itself:
|
||||
%v: <*>{1 <*><shown>}
|
||||
%+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
|
||||
%#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
|
||||
%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
|
||||
|
||||
See the Printf example for details on the setup of variables being shown
|
||||
here.
|
||||
|
||||
Errors
|
||||
|
||||
Since it is possible for custom Stringer/error interfaces to panic, spew
|
||||
detects them and handles them internally by printing the panic information
|
||||
inline with the output. Since spew is intended to provide deep pretty printing
|
||||
capabilities on structures, it intentionally does not return any errors.
|
||||
*/
|
||||
package spew
|
474
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
474
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dump.go
generated
vendored
|
@ -1,474 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
// uint8Type is a reflect.Type representing a uint8. It is used to
|
||||
// convert cgo types to uint8 slices for hexdumping.
|
||||
uint8Type = reflect.TypeOf(uint8(0))
|
||||
|
||||
// cCharRE is a regular expression that matches a cgo char.
|
||||
// It is used to detect character arrays to hexdump them.
|
||||
cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
|
||||
|
||||
// cUnsignedCharRE is a regular expression that matches a cgo unsigned
|
||||
// char. It is used to detect unsigned character arrays to hexdump
|
||||
// them.
|
||||
cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
|
||||
|
||||
// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
|
||||
// It is used to detect uint8_t arrays to hexdump them.
|
||||
cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
|
||||
)
|
||||
|
||||
// dumpState contains information about the state of a dump operation.
|
||||
type dumpState struct {
|
||||
w io.Writer
|
||||
depth int
|
||||
pointers map[uintptr]int
|
||||
ignoreNextType bool
|
||||
ignoreNextIndent bool
|
||||
cs *ConfigState
|
||||
}
|
||||
|
||||
// indent performs indentation according to the depth level and cs.Indent
|
||||
// option.
|
||||
func (d *dumpState) indent() {
|
||||
if d.ignoreNextIndent {
|
||||
d.ignoreNextIndent = false
|
||||
return
|
||||
}
|
||||
d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
|
||||
}
|
||||
|
||||
// unpackValue returns values inside of non-nil interfaces when possible.
|
||||
// This is useful for data types like structs, arrays, slices, and maps which
|
||||
// can contain varying types packed inside an interface.
|
||||
func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
|
||||
if v.Kind() == reflect.Interface && !v.IsNil() {
|
||||
v = v.Elem()
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// dumpPtr handles formatting of pointers by indirecting them as necessary.
|
||||
func (d *dumpState) dumpPtr(v reflect.Value) {
|
||||
// Remove pointers at or below the current depth from map used to detect
|
||||
// circular refs.
|
||||
for k, depth := range d.pointers {
|
||||
if depth >= d.depth {
|
||||
delete(d.pointers, k)
|
||||
}
|
||||
}
|
||||
|
||||
// Keep list of all dereferenced pointers to show later.
|
||||
pointerChain := make([]uintptr, 0)
|
||||
|
||||
// Figure out how many levels of indirection there are by dereferencing
|
||||
// pointers and unpacking interfaces down the chain while detecting circular
|
||||
// references.
|
||||
nilFound := false
|
||||
cycleFound := false
|
||||
indirects := 0
|
||||
ve := v
|
||||
for ve.Kind() == reflect.Ptr {
|
||||
if ve.IsNil() {
|
||||
nilFound = true
|
||||
break
|
||||
}
|
||||
indirects++
|
||||
addr := ve.Pointer()
|
||||
pointerChain = append(pointerChain, addr)
|
||||
if pd, ok := d.pointers[addr]; ok && pd < d.depth {
|
||||
cycleFound = true
|
||||
indirects--
|
||||
break
|
||||
}
|
||||
d.pointers[addr] = d.depth
|
||||
|
||||
ve = ve.Elem()
|
||||
if ve.Kind() == reflect.Interface {
|
||||
if ve.IsNil() {
|
||||
nilFound = true
|
||||
break
|
||||
}
|
||||
ve = ve.Elem()
|
||||
}
|
||||
}
|
||||
|
||||
// Display type information.
|
||||
d.w.Write(openParenBytes)
|
||||
d.w.Write(bytes.Repeat(asteriskBytes, indirects))
|
||||
d.w.Write([]byte(ve.Type().String()))
|
||||
d.w.Write(closeParenBytes)
|
||||
|
||||
// Display pointer information.
|
||||
if len(pointerChain) > 0 {
|
||||
d.w.Write(openParenBytes)
|
||||
for i, addr := range pointerChain {
|
||||
if i > 0 {
|
||||
d.w.Write(pointerChainBytes)
|
||||
}
|
||||
printHexPtr(d.w, addr)
|
||||
}
|
||||
d.w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// Display dereferenced value.
|
||||
d.w.Write(openParenBytes)
|
||||
switch {
|
||||
case nilFound == true:
|
||||
d.w.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound == true:
|
||||
d.w.Write(circularBytes)
|
||||
|
||||
default:
|
||||
d.ignoreNextType = true
|
||||
d.dump(ve)
|
||||
}
|
||||
d.w.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// dumpSlice handles formatting of arrays and slices. Byte (uint8 under
|
||||
// reflection) arrays and slices are dumped in hexdump -C fashion.
|
||||
func (d *dumpState) dumpSlice(v reflect.Value) {
|
||||
// Determine whether this type should be hex dumped or not. Also,
|
||||
// for types which should be hexdumped, try to use the underlying data
|
||||
// first, then fall back to trying to convert them to a uint8 slice.
|
||||
var buf []uint8
|
||||
doConvert := false
|
||||
doHexDump := false
|
||||
numEntries := v.Len()
|
||||
if numEntries > 0 {
|
||||
vt := v.Index(0).Type()
|
||||
vts := vt.String()
|
||||
switch {
|
||||
// C types that need to be converted.
|
||||
case cCharRE.MatchString(vts):
|
||||
fallthrough
|
||||
case cUnsignedCharRE.MatchString(vts):
|
||||
fallthrough
|
||||
case cUint8tCharRE.MatchString(vts):
|
||||
doConvert = true
|
||||
|
||||
// Try to use existing uint8 slices and fall back to converting
|
||||
// and copying if that fails.
|
||||
case vt.Kind() == reflect.Uint8:
|
||||
// We need an addressable interface to convert the type back
|
||||
// into a byte slice. However, the reflect package won't give
|
||||
// us an interface on certain things like unexported struct
|
||||
// fields in order to enforce visibility rules. We use unsafe
|
||||
// to bypass these restrictions since this package does not
|
||||
// mutate the values.
|
||||
vs := v
|
||||
if !vs.CanInterface() || !vs.CanAddr() {
|
||||
vs = unsafeReflectValue(vs)
|
||||
}
|
||||
vs = vs.Slice(0, numEntries)
|
||||
|
||||
// Use the existing uint8 slice if it can be type
|
||||
// asserted.
|
||||
iface := vs.Interface()
|
||||
if slice, ok := iface.([]uint8); ok {
|
||||
buf = slice
|
||||
doHexDump = true
|
||||
break
|
||||
}
|
||||
|
||||
// The underlying data needs to be converted if it can't
|
||||
// be type asserted to a uint8 slice.
|
||||
doConvert = true
|
||||
}
|
||||
|
||||
// Copy and convert the underlying type if needed.
|
||||
if doConvert && vt.ConvertibleTo(uint8Type) {
|
||||
// Convert and copy each element into a uint8 byte
|
||||
// slice.
|
||||
buf = make([]uint8, numEntries)
|
||||
for i := 0; i < numEntries; i++ {
|
||||
vv := v.Index(i)
|
||||
buf[i] = uint8(vv.Convert(uint8Type).Uint())
|
||||
}
|
||||
doHexDump = true
|
||||
}
|
||||
}
|
||||
|
||||
// Hexdump the entire slice as needed.
|
||||
if doHexDump {
|
||||
indent := strings.Repeat(d.cs.Indent, d.depth)
|
||||
str := indent + hex.Dump(buf)
|
||||
str = strings.Replace(str, "\n", "\n"+indent, -1)
|
||||
str = strings.TrimRight(str, d.cs.Indent)
|
||||
d.w.Write([]byte(str))
|
||||
return
|
||||
}
|
||||
|
||||
// Recursively call dump for each item.
|
||||
for i := 0; i < numEntries; i++ {
|
||||
d.dump(d.unpackValue(v.Index(i)))
|
||||
if i < (numEntries - 1) {
|
||||
d.w.Write(commaNewlineBytes)
|
||||
} else {
|
||||
d.w.Write(newlineBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// dump is the main workhorse for dumping a value. It uses the passed reflect
|
||||
// value to figure out what kind of object we are dealing with and formats it
|
||||
// appropriately. It is a recursive function, however circular data structures
|
||||
// are detected and handled properly.
|
||||
func (d *dumpState) dump(v reflect.Value) {
|
||||
// Handle invalid reflect values immediately.
|
||||
kind := v.Kind()
|
||||
if kind == reflect.Invalid {
|
||||
d.w.Write(invalidAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle pointers specially.
|
||||
if kind == reflect.Ptr {
|
||||
d.indent()
|
||||
d.dumpPtr(v)
|
||||
return
|
||||
}
|
||||
|
||||
// Print type information unless already handled elsewhere.
|
||||
if !d.ignoreNextType {
|
||||
d.indent()
|
||||
d.w.Write(openParenBytes)
|
||||
d.w.Write([]byte(v.Type().String()))
|
||||
d.w.Write(closeParenBytes)
|
||||
d.w.Write(spaceBytes)
|
||||
}
|
||||
d.ignoreNextType = false
|
||||
|
||||
// Call Stringer/error interfaces if they exist and the handle methods flag
|
||||
// is enabled
|
||||
if !d.cs.DisableMethods {
|
||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||
if handled := handleMethods(d.cs, d.w, v); handled {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Invalid:
|
||||
// Do nothing. We should never get here since invalid has already
|
||||
// been handled above.
|
||||
|
||||
case reflect.Bool:
|
||||
printBool(d.w, v.Bool())
|
||||
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
printInt(d.w, v.Int(), 10)
|
||||
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
printUint(d.w, v.Uint(), 10)
|
||||
|
||||
case reflect.Float32:
|
||||
printFloat(d.w, v.Float(), 32)
|
||||
|
||||
case reflect.Float64:
|
||||
printFloat(d.w, v.Float(), 64)
|
||||
|
||||
case reflect.Complex64:
|
||||
printComplex(d.w, v.Complex(), 32)
|
||||
|
||||
case reflect.Complex128:
|
||||
printComplex(d.w, v.Complex(), 64)
|
||||
|
||||
case reflect.Slice:
|
||||
if v.IsNil() {
|
||||
d.w.Write(nilAngleBytes)
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case reflect.Array:
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.indent()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
d.dumpSlice(v)
|
||||
}
|
||||
d.depth--
|
||||
d.indent()
|
||||
d.w.Write(closeBraceBytes)
|
||||
|
||||
case reflect.String:
|
||||
d.w.Write([]byte(strconv.Quote(v.String())))
|
||||
|
||||
case reflect.Interface:
|
||||
// The only time we should get here is for nil interfaces due to
|
||||
// unpackValue calls.
|
||||
if v.IsNil() {
|
||||
d.w.Write(nilAngleBytes)
|
||||
}
|
||||
|
||||
case reflect.Ptr:
|
||||
// Do nothing. We should never get here since pointers have already
|
||||
// been handled above.
|
||||
|
||||
case reflect.Map:
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.indent()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
numEntries := v.Len()
|
||||
keys := v.MapKeys()
|
||||
if d.cs.SortKeys {
|
||||
sortValues(keys)
|
||||
}
|
||||
for i, key := range keys {
|
||||
d.dump(d.unpackValue(key))
|
||||
d.w.Write(colonSpaceBytes)
|
||||
d.ignoreNextIndent = true
|
||||
d.dump(d.unpackValue(v.MapIndex(key)))
|
||||
if i < (numEntries - 1) {
|
||||
d.w.Write(commaNewlineBytes)
|
||||
} else {
|
||||
d.w.Write(newlineBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
d.depth--
|
||||
d.indent()
|
||||
d.w.Write(closeBraceBytes)
|
||||
|
||||
case reflect.Struct:
|
||||
d.w.Write(openBraceNewlineBytes)
|
||||
d.depth++
|
||||
if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
|
||||
d.indent()
|
||||
d.w.Write(maxNewlineBytes)
|
||||
} else {
|
||||
vt := v.Type()
|
||||
numFields := v.NumField()
|
||||
for i := 0; i < numFields; i++ {
|
||||
d.indent()
|
||||
vtf := vt.Field(i)
|
||||
d.w.Write([]byte(vtf.Name))
|
||||
d.w.Write(colonSpaceBytes)
|
||||
d.ignoreNextIndent = true
|
||||
d.dump(d.unpackValue(v.Field(i)))
|
||||
if i < (numFields - 1) {
|
||||
d.w.Write(commaNewlineBytes)
|
||||
} else {
|
||||
d.w.Write(newlineBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
d.depth--
|
||||
d.indent()
|
||||
d.w.Write(closeBraceBytes)
|
||||
|
||||
case reflect.Uintptr:
|
||||
printHexPtr(d.w, uintptr(v.Uint()))
|
||||
|
||||
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
||||
printHexPtr(d.w, v.Pointer())
|
||||
|
||||
// There were not any other types at the time this code was written, but
|
||||
// fall back to letting the default fmt package handle it in case any new
|
||||
// types are added.
|
||||
default:
|
||||
if v.CanInterface() {
|
||||
fmt.Fprintf(d.w, "%v", v.Interface())
|
||||
} else {
|
||||
fmt.Fprintf(d.w, "%v", v.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// fdump is a helper function to consolidate the logic from the various public
|
||||
// methods which take varying writers and config states.
|
||||
func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
|
||||
for _, arg := range a {
|
||||
if arg == nil {
|
||||
w.Write(interfaceBytes)
|
||||
w.Write(spaceBytes)
|
||||
w.Write(nilAngleBytes)
|
||||
w.Write(newlineBytes)
|
||||
continue
|
||||
}
|
||||
|
||||
d := dumpState{w: w, cs: cs}
|
||||
d.pointers = make(map[uintptr]int)
|
||||
d.dump(reflect.ValueOf(arg))
|
||||
d.w.Write(newlineBytes)
|
||||
}
|
||||
}
|
||||
|
||||
// Fdump formats and displays the passed arguments to io.Writer w. It formats
|
||||
// exactly the same as Dump.
|
||||
func Fdump(w io.Writer, a ...interface{}) {
|
||||
fdump(&Config, w, a...)
|
||||
}
|
||||
|
||||
// Sdump returns a string with the passed arguments formatted exactly the same
|
||||
// as Dump.
|
||||
func Sdump(a ...interface{}) string {
|
||||
var buf bytes.Buffer
|
||||
fdump(&Config, &buf, a...)
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
/*
|
||||
Dump displays the passed parameters to standard out with newlines, customizable
|
||||
indentation, and additional debug information such as complete types and all
|
||||
pointer addresses used to indirect to the final value. It provides the
|
||||
following features over the built-in printing facilities provided by the fmt
|
||||
package:
|
||||
|
||||
* Pointers are dereferenced and followed
|
||||
* Circular data structures are detected and handled properly
|
||||
* Custom Stringer/error interfaces are optionally invoked, including
|
||||
on unexported types
|
||||
* Custom types which only implement the Stringer/error interfaces via
|
||||
a pointer receiver are optionally invoked when passing non-pointer
|
||||
variables
|
||||
* Byte arrays and slices are dumped like the hexdump -C command which
|
||||
includes offsets, byte values in hex, and ASCII output
|
||||
|
||||
The configuration options are controlled by an exported package global,
|
||||
spew.Config. See ConfigState for options documentation.
|
||||
|
||||
See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
|
||||
get the formatted result as a string.
|
||||
*/
|
||||
func Dump(a ...interface{}) {
|
||||
fdump(&Config, os.Stdout, a...)
|
||||
}
|
912
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dump_test.go
generated
vendored
912
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dump_test.go
generated
vendored
|
@ -1,912 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
Test Summary:
|
||||
NOTE: For each test, a nil pointer, a single pointer and double pointer to the
|
||||
base test element are also tested to ensure proper indirection across all types.
|
||||
|
||||
- Max int8, int16, int32, int64, int
|
||||
- Max uint8, uint16, uint32, uint64, uint
|
||||
- Boolean true and false
|
||||
- Standard complex64 and complex128
|
||||
- Array containing standard ints
|
||||
- Array containing type with custom formatter on pointer receiver only
|
||||
- Array containing interfaces
|
||||
- Array containing bytes
|
||||
- Slice containing standard float32 values
|
||||
- Slice containing type with custom formatter on pointer receiver only
|
||||
- Slice containing interfaces
|
||||
- Slice containing bytes
|
||||
- Nil slice
|
||||
- Standard string
|
||||
- Nil interface
|
||||
- Sub-interface
|
||||
- Map with string keys and int vals
|
||||
- Map with custom formatter type on pointer receiver only keys and vals
|
||||
- Map with interface keys and values
|
||||
- Map with nil interface value
|
||||
- Struct with primitives
|
||||
- Struct that contains another struct
|
||||
- Struct that contains custom type with Stringer pointer interface via both
|
||||
exported and unexported fields
|
||||
- Struct that contains embedded struct and field to same struct
|
||||
- Uintptr to 0 (null pointer)
|
||||
- Uintptr address of real variable
|
||||
- Unsafe.Pointer to 0 (null pointer)
|
||||
- Unsafe.Pointer to address of real variable
|
||||
- Nil channel
|
||||
- Standard int channel
|
||||
- Function with no params and no returns
|
||||
- Function with param and no returns
|
||||
- Function with multiple params and multiple returns
|
||||
- Struct that is circular through self referencing
|
||||
- Structs that are circular through cross referencing
|
||||
- Structs that are indirectly circular
|
||||
- Type that panics in its Stringer interface
|
||||
*/
|
||||
|
||||
package spew_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// dumpTest is used to describe a test to be perfomed against the Dump method.
|
||||
type dumpTest struct {
|
||||
in interface{}
|
||||
wants []string
|
||||
}
|
||||
|
||||
// dumpTests houses all of the tests to be performed against the Dump method.
|
||||
var dumpTests = make([]dumpTest, 0)
|
||||
|
||||
// addDumpTest is a helper method to append the passed input and desired result
|
||||
// to dumpTests
|
||||
func addDumpTest(in interface{}, wants ...string) {
|
||||
test := dumpTest{in, wants}
|
||||
dumpTests = append(dumpTests, test)
|
||||
}
|
||||
|
||||
func addIntDumpTests() {
|
||||
// Max int8.
|
||||
v := int8(127)
|
||||
nv := (*int8)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "int8"
|
||||
vs := "127"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Max int16.
|
||||
v2 := int16(32767)
|
||||
nv2 := (*int16)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "int16"
|
||||
v2s := "32767"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
|
||||
|
||||
// Max int32.
|
||||
v3 := int32(2147483647)
|
||||
nv3 := (*int32)(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3t := "int32"
|
||||
v3s := "2147483647"
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
|
||||
|
||||
// Max int64.
|
||||
v4 := int64(9223372036854775807)
|
||||
nv4 := (*int64)(nil)
|
||||
pv4 := &v4
|
||||
v4Addr := fmt.Sprintf("%p", pv4)
|
||||
pv4Addr := fmt.Sprintf("%p", &pv4)
|
||||
v4t := "int64"
|
||||
v4s := "9223372036854775807"
|
||||
addDumpTest(v4, "("+v4t+") "+v4s+"\n")
|
||||
addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
|
||||
|
||||
// Max int.
|
||||
v5 := int(2147483647)
|
||||
nv5 := (*int)(nil)
|
||||
pv5 := &v5
|
||||
v5Addr := fmt.Sprintf("%p", pv5)
|
||||
pv5Addr := fmt.Sprintf("%p", &pv5)
|
||||
v5t := "int"
|
||||
v5s := "2147483647"
|
||||
addDumpTest(v5, "("+v5t+") "+v5s+"\n")
|
||||
addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
|
||||
addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
|
||||
addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addUintDumpTests() {
|
||||
// Max uint8.
|
||||
v := uint8(255)
|
||||
nv := (*uint8)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "uint8"
|
||||
vs := "255"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Max uint16.
|
||||
v2 := uint16(65535)
|
||||
nv2 := (*uint16)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "uint16"
|
||||
v2s := "65535"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
|
||||
|
||||
// Max uint32.
|
||||
v3 := uint32(4294967295)
|
||||
nv3 := (*uint32)(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3t := "uint32"
|
||||
v3s := "4294967295"
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
|
||||
|
||||
// Max uint64.
|
||||
v4 := uint64(18446744073709551615)
|
||||
nv4 := (*uint64)(nil)
|
||||
pv4 := &v4
|
||||
v4Addr := fmt.Sprintf("%p", pv4)
|
||||
pv4Addr := fmt.Sprintf("%p", &pv4)
|
||||
v4t := "uint64"
|
||||
v4s := "18446744073709551615"
|
||||
addDumpTest(v4, "("+v4t+") "+v4s+"\n")
|
||||
addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
|
||||
|
||||
// Max uint.
|
||||
v5 := uint(4294967295)
|
||||
nv5 := (*uint)(nil)
|
||||
pv5 := &v5
|
||||
v5Addr := fmt.Sprintf("%p", pv5)
|
||||
pv5Addr := fmt.Sprintf("%p", &pv5)
|
||||
v5t := "uint"
|
||||
v5s := "4294967295"
|
||||
addDumpTest(v5, "("+v5t+") "+v5s+"\n")
|
||||
addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
|
||||
addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
|
||||
addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addBoolDumpTests() {
|
||||
// Boolean true.
|
||||
v := bool(true)
|
||||
nv := (*bool)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "bool"
|
||||
vs := "true"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Boolean false.
|
||||
v2 := bool(false)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "bool"
|
||||
v2s := "false"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
}
|
||||
|
||||
func addFloatDumpTests() {
|
||||
// Standard float32.
|
||||
v := float32(3.1415)
|
||||
nv := (*float32)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "float32"
|
||||
vs := "3.1415"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Standard float64.
|
||||
v2 := float64(3.1415926)
|
||||
nv2 := (*float64)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "float64"
|
||||
v2s := "3.1415926"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addComplexDumpTests() {
|
||||
// Standard complex64.
|
||||
v := complex(float32(6), -2)
|
||||
nv := (*complex64)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "complex64"
|
||||
vs := "(6-2i)"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Standard complex128.
|
||||
v2 := complex(float64(-6), 2)
|
||||
nv2 := (*complex128)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "complex128"
|
||||
v2s := "(-6+2i)"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addArrayDumpTests() {
|
||||
// Array containing standard ints.
|
||||
v := [3]int{1, 2, 3}
|
||||
nv := (*[3]int)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "int"
|
||||
vs := "{\n (" + vt + ") 1,\n (" + vt + ") 2,\n (" + vt + ") 3\n}"
|
||||
addDumpTest(v, "([3]"+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*[3]"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**[3]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*[3]"+vt+")(<nil>)\n")
|
||||
|
||||
// Array containing type with custom formatter on pointer receiver only.
|
||||
v2 := [3]pstringer{"1", "2", "3"}
|
||||
nv2 := (*[3]pstringer)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "spew_test.pstringer"
|
||||
v2s := "{\n (" + v2t + ") stringer 1,\n (" + v2t + ") stringer 2,\n (" +
|
||||
v2t + ") stringer 3\n}"
|
||||
addDumpTest(v2, "([3]"+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*[3]"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**[3]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*[3]"+v2t+")(<nil>)\n")
|
||||
|
||||
// Array containing interfaces.
|
||||
v3 := [3]interface{}{"one", int(2), uint(3)}
|
||||
nv3 := (*[3]interface{})(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3t := "[3]interface {}"
|
||||
v3t2 := "string"
|
||||
v3t3 := "int"
|
||||
v3t4 := "uint"
|
||||
v3s := "{\n (" + v3t2 + ") \"one\",\n (" + v3t3 + ") 2,\n (" + v3t4 +
|
||||
") 3\n}"
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
|
||||
|
||||
// Array containing bytes.
|
||||
v4 := [34]byte{
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
||||
0x31, 0x32,
|
||||
}
|
||||
nv4 := (*[34]byte)(nil)
|
||||
pv4 := &v4
|
||||
v4Addr := fmt.Sprintf("%p", pv4)
|
||||
pv4Addr := fmt.Sprintf("%p", &pv4)
|
||||
v4t := "[34]uint8"
|
||||
v4s := "{\n 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20" +
|
||||
" |............... |\n" +
|
||||
" 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30" +
|
||||
" |!\"#$%&'()*+,-./0|\n" +
|
||||
" 00000020 31 32 " +
|
||||
" |12|\n}"
|
||||
addDumpTest(v4, "("+v4t+") "+v4s+"\n")
|
||||
addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addSliceDumpTests() {
|
||||
// Slice containing standard float32 values.
|
||||
v := []float32{3.14, 6.28, 12.56}
|
||||
nv := (*[]float32)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "float32"
|
||||
vs := "{\n (" + vt + ") 3.14,\n (" + vt + ") 6.28,\n (" + vt + ") 12.56\n}"
|
||||
addDumpTest(v, "([]"+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*[]"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**[]"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*[]"+vt+")(<nil>)\n")
|
||||
|
||||
// Slice containing type with custom formatter on pointer receiver only.
|
||||
v2 := []pstringer{"1", "2", "3"}
|
||||
nv2 := (*[]pstringer)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "spew_test.pstringer"
|
||||
v2s := "{\n (" + v2t + ") stringer 1,\n (" + v2t + ") stringer 2,\n (" +
|
||||
v2t + ") stringer 3\n}"
|
||||
addDumpTest(v2, "([]"+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*[]"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**[]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*[]"+v2t+")(<nil>)\n")
|
||||
|
||||
// Slice containing interfaces.
|
||||
v3 := []interface{}{"one", int(2), uint(3), nil}
|
||||
nv3 := (*[]interface{})(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3t := "[]interface {}"
|
||||
v3t2 := "string"
|
||||
v3t3 := "int"
|
||||
v3t4 := "uint"
|
||||
v3t5 := "interface {}"
|
||||
v3s := "{\n (" + v3t2 + ") \"one\",\n (" + v3t3 + ") 2,\n (" + v3t4 +
|
||||
") 3,\n (" + v3t5 + ") <nil>\n}"
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
|
||||
|
||||
// Slice containing bytes.
|
||||
v4 := []byte{
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
||||
0x31, 0x32,
|
||||
}
|
||||
nv4 := (*[]byte)(nil)
|
||||
pv4 := &v4
|
||||
v4Addr := fmt.Sprintf("%p", pv4)
|
||||
pv4Addr := fmt.Sprintf("%p", &pv4)
|
||||
v4t := "[]uint8"
|
||||
v4s := "{\n 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20" +
|
||||
" |............... |\n" +
|
||||
" 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30" +
|
||||
" |!\"#$%&'()*+,-./0|\n" +
|
||||
" 00000020 31 32 " +
|
||||
" |12|\n}"
|
||||
addDumpTest(v4, "("+v4t+") "+v4s+"\n")
|
||||
addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
|
||||
|
||||
// Nil slice.
|
||||
v5 := []int(nil)
|
||||
nv5 := (*[]int)(nil)
|
||||
pv5 := &v5
|
||||
v5Addr := fmt.Sprintf("%p", pv5)
|
||||
pv5Addr := fmt.Sprintf("%p", &pv5)
|
||||
v5t := "[]int"
|
||||
v5s := "<nil>"
|
||||
addDumpTest(v5, "("+v5t+") "+v5s+"\n")
|
||||
addDumpTest(pv5, "(*"+v5t+")("+v5Addr+")("+v5s+")\n")
|
||||
addDumpTest(&pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")("+v5s+")\n")
|
||||
addDumpTest(nv5, "(*"+v5t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addStringDumpTests() {
|
||||
// Standard string.
|
||||
v := "test"
|
||||
nv := (*string)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "string"
|
||||
vs := "\"test\""
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addInterfaceDumpTests() {
|
||||
// Nil interface.
|
||||
var v interface{}
|
||||
nv := (*interface{})(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "interface {}"
|
||||
vs := "<nil>"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Sub-interface.
|
||||
v2 := interface{}(uint16(65535))
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "uint16"
|
||||
v2s := "65535"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
}
|
||||
|
||||
func addMapDumpTests() {
|
||||
// Map with string keys and int vals.
|
||||
v := map[string]int{"one": 1, "two": 2}
|
||||
nv := (*map[string]int)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "map[string]int"
|
||||
vt1 := "string"
|
||||
vt2 := "int"
|
||||
vs := "{\n (" + vt1 + ") \"one\": (" + vt2 + ") 1,\n (" + vt1 +
|
||||
") \"two\": (" + vt2 + ") 2\n}"
|
||||
vs2 := "{\n (" + vt1 + ") \"two\": (" + vt2 + ") 2,\n (" + vt1 +
|
||||
") \"one\": (" + vt2 + ") 1\n}"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n", "("+vt+") "+vs2+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n",
|
||||
"(*"+vt+")("+vAddr+")("+vs2+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n",
|
||||
"(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs2+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Map with custom formatter type on pointer receiver only keys and vals.
|
||||
v2 := map[pstringer]pstringer{"one": "1"}
|
||||
nv2 := (*map[pstringer]pstringer)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "map[spew_test.pstringer]spew_test.pstringer"
|
||||
v2t1 := "spew_test.pstringer"
|
||||
v2t2 := "spew_test.pstringer"
|
||||
v2s := "{\n (" + v2t1 + ") stringer one: (" + v2t2 + ") stringer 1\n}"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
|
||||
|
||||
// Map with interface keys and values.
|
||||
v3 := map[interface{}]interface{}{"one": 1}
|
||||
nv3 := (*map[interface{}]interface{})(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3t := "map[interface {}]interface {}"
|
||||
v3t1 := "string"
|
||||
v3t2 := "int"
|
||||
v3s := "{\n (" + v3t1 + ") \"one\": (" + v3t2 + ") 1\n}"
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
|
||||
|
||||
// Map with nil interface value.
|
||||
v4 := map[string]interface{}{"nil": nil}
|
||||
nv4 := (*map[string]interface{})(nil)
|
||||
pv4 := &v4
|
||||
v4Addr := fmt.Sprintf("%p", pv4)
|
||||
pv4Addr := fmt.Sprintf("%p", &pv4)
|
||||
v4t := "map[string]interface {}"
|
||||
v4t1 := "string"
|
||||
v4t2 := "interface {}"
|
||||
v4s := "{\n (" + v4t1 + ") \"nil\": (" + v4t2 + ") <nil>\n}"
|
||||
addDumpTest(v4, "("+v4t+") "+v4s+"\n")
|
||||
addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addStructDumpTests() {
|
||||
// Struct with primitives.
|
||||
type s1 struct {
|
||||
a int8
|
||||
b uint8
|
||||
}
|
||||
v := s1{127, 255}
|
||||
nv := (*s1)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "spew_test.s1"
|
||||
vt2 := "int8"
|
||||
vt3 := "uint8"
|
||||
vs := "{\n a: (" + vt2 + ") 127,\n b: (" + vt3 + ") 255\n}"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Struct that contains another struct.
|
||||
type s2 struct {
|
||||
s1 s1
|
||||
b bool
|
||||
}
|
||||
v2 := s2{s1{127, 255}, true}
|
||||
nv2 := (*s2)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "spew_test.s2"
|
||||
v2t2 := "spew_test.s1"
|
||||
v2t3 := "int8"
|
||||
v2t4 := "uint8"
|
||||
v2t5 := "bool"
|
||||
v2s := "{\n s1: (" + v2t2 + ") {\n a: (" + v2t3 + ") 127,\n b: (" +
|
||||
v2t4 + ") 255\n },\n b: (" + v2t5 + ") true\n}"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
|
||||
|
||||
// Struct that contains custom type with Stringer pointer interface via both
|
||||
// exported and unexported fields.
|
||||
type s3 struct {
|
||||
s pstringer
|
||||
S pstringer
|
||||
}
|
||||
v3 := s3{"test", "test2"}
|
||||
nv3 := (*s3)(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3t := "spew_test.s3"
|
||||
v3t2 := "spew_test.pstringer"
|
||||
v3s := "{\n s: (" + v3t2 + ") stringer test,\n S: (" + v3t2 +
|
||||
") stringer test2\n}"
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
|
||||
|
||||
// Struct that contains embedded struct and field to same struct.
|
||||
e := embed{"embedstr"}
|
||||
v4 := embedwrap{embed: &e, e: &e}
|
||||
nv4 := (*embedwrap)(nil)
|
||||
pv4 := &v4
|
||||
eAddr := fmt.Sprintf("%p", &e)
|
||||
v4Addr := fmt.Sprintf("%p", pv4)
|
||||
pv4Addr := fmt.Sprintf("%p", &pv4)
|
||||
v4t := "spew_test.embedwrap"
|
||||
v4t2 := "spew_test.embed"
|
||||
v4t3 := "string"
|
||||
v4s := "{\n embed: (*" + v4t2 + ")(" + eAddr + ")({\n a: (" + v4t3 +
|
||||
") \"embedstr\"\n }),\n e: (*" + v4t2 + ")(" + eAddr + ")({\n" +
|
||||
" a: (" + v4t3 + ") \"embedstr\"\n })\n}"
|
||||
addDumpTest(v4, "("+v4t+") "+v4s+"\n")
|
||||
addDumpTest(pv4, "(*"+v4t+")("+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(&pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")("+v4s+")\n")
|
||||
addDumpTest(nv4, "(*"+v4t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addUintptrDumpTests() {
|
||||
// Null pointer.
|
||||
v := uintptr(0)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "uintptr"
|
||||
vs := "<nil>"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
|
||||
// Address of real variable.
|
||||
i := 1
|
||||
v2 := uintptr(unsafe.Pointer(&i))
|
||||
nv2 := (*uintptr)(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "uintptr"
|
||||
v2s := fmt.Sprintf("%p", &i)
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addUnsafePointerDumpTests() {
|
||||
// Null pointer.
|
||||
v := unsafe.Pointer(uintptr(0))
|
||||
nv := (*unsafe.Pointer)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "unsafe.Pointer"
|
||||
vs := "<nil>"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Address of real variable.
|
||||
i := 1
|
||||
v2 := unsafe.Pointer(&i)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "unsafe.Pointer"
|
||||
v2s := fmt.Sprintf("%p", &i)
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addChanDumpTests() {
|
||||
// Nil channel.
|
||||
var v chan int
|
||||
pv := &v
|
||||
nv := (*chan int)(nil)
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "chan int"
|
||||
vs := "<nil>"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Real channel.
|
||||
v2 := make(chan int)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "chan int"
|
||||
v2s := fmt.Sprintf("%p", v2)
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
}
|
||||
|
||||
func addFuncDumpTests() {
|
||||
// Function with no params and no returns.
|
||||
v := addIntDumpTests
|
||||
nv := (*func())(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "func()"
|
||||
vs := fmt.Sprintf("%p", v)
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
|
||||
// Function with param and no returns.
|
||||
v2 := TestDump
|
||||
nv2 := (*func(*testing.T))(nil)
|
||||
pv2 := &v2
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "func(*testing.T)"
|
||||
v2s := fmt.Sprintf("%p", v2)
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s+")\n")
|
||||
addDumpTest(nv2, "(*"+v2t+")(<nil>)\n")
|
||||
|
||||
// Function with multiple params and multiple returns.
|
||||
var v3 = func(i int, s string) (b bool, err error) {
|
||||
return true, nil
|
||||
}
|
||||
nv3 := (*func(int, string) (bool, error))(nil)
|
||||
pv3 := &v3
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3t := "func(int, string) (bool, error)"
|
||||
v3s := fmt.Sprintf("%p", v3)
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s+")\n")
|
||||
addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addCircularDumpTests() {
|
||||
// Struct that is circular through self referencing.
|
||||
type circular struct {
|
||||
c *circular
|
||||
}
|
||||
v := circular{nil}
|
||||
v.c = &v
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "spew_test.circular"
|
||||
vs := "{\n c: (*" + vt + ")(" + vAddr + ")({\n c: (*" + vt + ")(" +
|
||||
vAddr + ")(<already shown>)\n })\n}"
|
||||
vs2 := "{\n c: (*" + vt + ")(" + vAddr + ")(<already shown>)\n}"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs2+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs2+")\n")
|
||||
|
||||
// Structs that are circular through cross referencing.
|
||||
v2 := xref1{nil}
|
||||
ts2 := xref2{&v2}
|
||||
v2.ps2 = &ts2
|
||||
pv2 := &v2
|
||||
ts2Addr := fmt.Sprintf("%p", &ts2)
|
||||
v2Addr := fmt.Sprintf("%p", pv2)
|
||||
pv2Addr := fmt.Sprintf("%p", &pv2)
|
||||
v2t := "spew_test.xref1"
|
||||
v2t2 := "spew_test.xref2"
|
||||
v2s := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
|
||||
")(" + v2Addr + ")({\n ps2: (*" + v2t2 + ")(" + ts2Addr +
|
||||
")(<already shown>)\n })\n })\n}"
|
||||
v2s2 := "{\n ps2: (*" + v2t2 + ")(" + ts2Addr + ")({\n ps1: (*" + v2t +
|
||||
")(" + v2Addr + ")(<already shown>)\n })\n}"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
addDumpTest(pv2, "(*"+v2t+")("+v2Addr+")("+v2s2+")\n")
|
||||
addDumpTest(&pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2s2+")\n")
|
||||
|
||||
// Structs that are indirectly circular.
|
||||
v3 := indirCir1{nil}
|
||||
tic2 := indirCir2{nil}
|
||||
tic3 := indirCir3{&v3}
|
||||
tic2.ps3 = &tic3
|
||||
v3.ps2 = &tic2
|
||||
pv3 := &v3
|
||||
tic2Addr := fmt.Sprintf("%p", &tic2)
|
||||
tic3Addr := fmt.Sprintf("%p", &tic3)
|
||||
v3Addr := fmt.Sprintf("%p", pv3)
|
||||
pv3Addr := fmt.Sprintf("%p", &pv3)
|
||||
v3t := "spew_test.indirCir1"
|
||||
v3t2 := "spew_test.indirCir2"
|
||||
v3t3 := "spew_test.indirCir3"
|
||||
v3s := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
|
||||
")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
|
||||
")({\n ps2: (*" + v3t2 + ")(" + tic2Addr +
|
||||
")(<already shown>)\n })\n })\n })\n}"
|
||||
v3s2 := "{\n ps2: (*" + v3t2 + ")(" + tic2Addr + ")({\n ps3: (*" + v3t3 +
|
||||
")(" + tic3Addr + ")({\n ps1: (*" + v3t + ")(" + v3Addr +
|
||||
")(<already shown>)\n })\n })\n}"
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3s2+")\n")
|
||||
addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3s2+")\n")
|
||||
}
|
||||
|
||||
func addPanicDumpTests() {
|
||||
// Type that panics in its Stringer interface.
|
||||
v := panicer(127)
|
||||
nv := (*panicer)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "spew_test.panicer"
|
||||
vs := "(PANIC=test panic)127"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
}
|
||||
|
||||
func addErrorDumpTests() {
|
||||
// Type that has a custom Error interface.
|
||||
v := customError(127)
|
||||
nv := (*customError)(nil)
|
||||
pv := &v
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "spew_test.customError"
|
||||
vs := "error: 127"
|
||||
addDumpTest(v, "("+vt+") "+vs+"\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "(*"+vt+")(<nil>)\n")
|
||||
}
|
||||
|
||||
// TestDump executes all of the tests described by dumpTests.
|
||||
func TestDump(t *testing.T) {
|
||||
// Setup tests.
|
||||
addIntDumpTests()
|
||||
addUintDumpTests()
|
||||
addBoolDumpTests()
|
||||
addFloatDumpTests()
|
||||
addComplexDumpTests()
|
||||
addArrayDumpTests()
|
||||
addSliceDumpTests()
|
||||
addStringDumpTests()
|
||||
addInterfaceDumpTests()
|
||||
addMapDumpTests()
|
||||
addStructDumpTests()
|
||||
addUintptrDumpTests()
|
||||
addUnsafePointerDumpTests()
|
||||
addChanDumpTests()
|
||||
addFuncDumpTests()
|
||||
addCircularDumpTests()
|
||||
addPanicDumpTests()
|
||||
addErrorDumpTests()
|
||||
addCgoDumpTests()
|
||||
|
||||
t.Logf("Running %d tests", len(dumpTests))
|
||||
for i, test := range dumpTests {
|
||||
buf := new(bytes.Buffer)
|
||||
spew.Fdump(buf, test.in)
|
||||
s := buf.String()
|
||||
if testFailed(s, test.wants) {
|
||||
t.Errorf("Dump #%d\n got: %s %s", i, s, stringizeWants(test.wants))
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestDumpSortedKeys(t *testing.T) {
|
||||
cfg := spew.ConfigState{SortKeys: true}
|
||||
s := cfg.Sdump(map[int]string{1: "1", 3: "3", 2: "2"})
|
||||
expected := `(map[int]string) {
|
||||
(int) 1: (string) "1",
|
||||
(int) 2: (string) "2",
|
||||
(int) 3: (string) "3"
|
||||
}
|
||||
`
|
||||
if s != expected {
|
||||
t.Errorf("Sorted keys mismatch:\n %v %v", s, expected)
|
||||
}
|
||||
}
|
82
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dumpcgo_test.go
generated
vendored
82
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dumpcgo_test.go
generated
vendored
|
@ -1,82 +0,0 @@
|
|||
// Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||
// when both cgo is supported and "-tags testcgo" is added to the go test
|
||||
// command line. This means the cgo tests are only added (and hence run) when
|
||||
// specifially requested. This configuration is used because spew itself
|
||||
// does not require cgo to run even though it does handle certain cgo types
|
||||
// specially. Rather than forcing all clients to require cgo and an external
|
||||
// C compiler just to run the tests, this scheme makes them optional.
|
||||
// +build cgo,testcgo
|
||||
|
||||
package spew_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/davecgh/go-spew/spew/testdata"
|
||||
)
|
||||
|
||||
func addCgoDumpTests() {
|
||||
// C char pointer.
|
||||
v := testdata.GetCgoCharPointer()
|
||||
nv := testdata.GetCgoNullCharPointer()
|
||||
pv := &v
|
||||
vcAddr := fmt.Sprintf("%p", v)
|
||||
vAddr := fmt.Sprintf("%p", pv)
|
||||
pvAddr := fmt.Sprintf("%p", &pv)
|
||||
vt := "*testdata._Ctype_char"
|
||||
vs := "116"
|
||||
addDumpTest(v, "("+vt+")("+vcAddr+")("+vs+")\n")
|
||||
addDumpTest(pv, "(*"+vt+")("+vAddr+"->"+vcAddr+")("+vs+")\n")
|
||||
addDumpTest(&pv, "(**"+vt+")("+pvAddr+"->"+vAddr+"->"+vcAddr+")("+vs+")\n")
|
||||
addDumpTest(nv, "("+vt+")(<nil>)\n")
|
||||
|
||||
// C char array.
|
||||
v2 := testdata.GetCgoCharArray()
|
||||
v2t := "[6]testdata._Ctype_char"
|
||||
v2s := "{\n 00000000 74 65 73 74 32 00 " +
|
||||
" |test2.|\n}"
|
||||
addDumpTest(v2, "("+v2t+") "+v2s+"\n")
|
||||
|
||||
// C unsigned char array.
|
||||
v3 := testdata.GetCgoUnsignedCharArray()
|
||||
v3t := "[6]testdata._Ctype_unsignedchar"
|
||||
v3s := "{\n 00000000 74 65 73 74 33 00 " +
|
||||
" |test3.|\n}"
|
||||
addDumpTest(v3, "("+v3t+") "+v3s+"\n")
|
||||
|
||||
// C signed char array.
|
||||
v4 := testdata.GetCgoSignedCharArray()
|
||||
v4t := "[6]testdata._Ctype_schar"
|
||||
v4t2 := "testdata._Ctype_schar"
|
||||
v4s := "{\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 101,\n (" + v4t2 +
|
||||
") 115,\n (" + v4t2 + ") 116,\n (" + v4t2 + ") 52,\n (" + v4t2 +
|
||||
") 0\n}"
|
||||
addDumpTest(v4, "("+v4t+") "+v4s+"\n")
|
||||
|
||||
// C uint8_t array.
|
||||
v5 := testdata.GetCgoUint8tArray()
|
||||
v5t := "[6]testdata._Ctype_uint8_t"
|
||||
v5s := "{\n 00000000 74 65 73 74 35 00 " +
|
||||
" |test5.|\n}"
|
||||
addDumpTest(v5, "("+v5t+") "+v5s+"\n")
|
||||
|
||||
// C typedefed unsigned char array.
|
||||
v6 := testdata.GetCgoTypdefedUnsignedCharArray()
|
||||
v6t := "[6]testdata._Ctype_custom_uchar_t"
|
||||
v6s := "{\n 00000000 74 65 73 74 36 00 " +
|
||||
" |test6.|\n}"
|
||||
addDumpTest(v6, "("+v6t+") "+v6s+"\n")
|
||||
}
|
26
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dumpnocgo_test.go
generated
vendored
26
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/dumpnocgo_test.go
generated
vendored
|
@ -1,26 +0,0 @@
|
|||
// Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||
// when either cgo is not supported or "-tags testcgo" is not added to the go
|
||||
// test command line. This file intentionally does not setup any cgo tests in
|
||||
// this scenario.
|
||||
// +build !cgo !testcgo
|
||||
|
||||
package spew_test
|
||||
|
||||
func addCgoDumpTests() {
|
||||
// Don't add any tests for cgo since this file is only compiled when
|
||||
// there should not be any cgo tests.
|
||||
}
|
230
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/example_test.go
generated
vendored
230
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/example_test.go
generated
vendored
|
@ -1,230 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew_test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
)
|
||||
|
||||
type Flag int
|
||||
|
||||
const (
|
||||
flagOne Flag = iota
|
||||
flagTwo
|
||||
)
|
||||
|
||||
var flagStrings = map[Flag]string{
|
||||
flagOne: "flagOne",
|
||||
flagTwo: "flagTwo",
|
||||
}
|
||||
|
||||
func (f Flag) String() string {
|
||||
if s, ok := flagStrings[f]; ok {
|
||||
return s
|
||||
}
|
||||
return fmt.Sprintf("Unknown flag (%d)", int(f))
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
flag Flag
|
||||
data uintptr
|
||||
}
|
||||
|
||||
type Foo struct {
|
||||
unexportedField Bar
|
||||
ExportedField map[interface{}]interface{}
|
||||
}
|
||||
|
||||
// This example demonstrates how to use Dump to dump variables to stdout.
|
||||
func ExampleDump() {
|
||||
// The following package level declarations are assumed for this example:
|
||||
/*
|
||||
type Flag int
|
||||
|
||||
const (
|
||||
flagOne Flag = iota
|
||||
flagTwo
|
||||
)
|
||||
|
||||
var flagStrings = map[Flag]string{
|
||||
flagOne: "flagOne",
|
||||
flagTwo: "flagTwo",
|
||||
}
|
||||
|
||||
func (f Flag) String() string {
|
||||
if s, ok := flagStrings[f]; ok {
|
||||
return s
|
||||
}
|
||||
return fmt.Sprintf("Unknown flag (%d)", int(f))
|
||||
}
|
||||
|
||||
type Bar struct {
|
||||
flag Flag
|
||||
data uintptr
|
||||
}
|
||||
|
||||
type Foo struct {
|
||||
unexportedField Bar
|
||||
ExportedField map[interface{}]interface{}
|
||||
}
|
||||
*/
|
||||
|
||||
// Setup some sample data structures for the example.
|
||||
bar := Bar{Flag(flagTwo), uintptr(0)}
|
||||
s1 := Foo{bar, map[interface{}]interface{}{"one": true}}
|
||||
f := Flag(5)
|
||||
b := []byte{
|
||||
0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18,
|
||||
0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20,
|
||||
0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28,
|
||||
0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30,
|
||||
0x31, 0x32,
|
||||
}
|
||||
|
||||
// Dump!
|
||||
spew.Dump(s1, f, b)
|
||||
|
||||
// Output:
|
||||
// (spew_test.Foo) {
|
||||
// unexportedField: (spew_test.Bar) {
|
||||
// flag: (spew_test.Flag) flagTwo,
|
||||
// data: (uintptr) <nil>
|
||||
// },
|
||||
// ExportedField: (map[interface {}]interface {}) {
|
||||
// (string) "one": (bool) true
|
||||
// }
|
||||
// }
|
||||
// (spew_test.Flag) Unknown flag (5)
|
||||
// ([]uint8) {
|
||||
// 00000000 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d 1e 1f 20 |............... |
|
||||
// 00000010 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d 2e 2f 30 |!"#$%&'()*+,-./0|
|
||||
// 00000020 31 32 |12|
|
||||
// }
|
||||
//
|
||||
}
|
||||
|
||||
// This example demonstrates how to use Printf to display a variable with a
|
||||
// format string and inline formatting.
|
||||
func ExamplePrintf() {
|
||||
// Create a double pointer to a uint 8.
|
||||
ui8 := uint8(5)
|
||||
pui8 := &ui8
|
||||
ppui8 := &pui8
|
||||
|
||||
// Create a circular data type.
|
||||
type circular struct {
|
||||
ui8 uint8
|
||||
c *circular
|
||||
}
|
||||
c := circular{ui8: 1}
|
||||
c.c = &c
|
||||
|
||||
// Print!
|
||||
spew.Printf("ppui8: %v\n", ppui8)
|
||||
spew.Printf("circular: %v\n", c)
|
||||
|
||||
// Output:
|
||||
// ppui8: <**>5
|
||||
// circular: {1 <*>{1 <*><shown>}}
|
||||
}
|
||||
|
||||
// This example demonstrates how to use a ConfigState.
|
||||
func ExampleConfigState() {
|
||||
// Modify the indent level of the ConfigState only. The global
|
||||
// configuration is not modified.
|
||||
scs := spew.ConfigState{Indent: "\t"}
|
||||
|
||||
// Output using the ConfigState instance.
|
||||
v := map[string]int{"one": 1}
|
||||
scs.Printf("v: %v\n", v)
|
||||
scs.Dump(v)
|
||||
|
||||
// Output:
|
||||
// v: map[one:1]
|
||||
// (map[string]int) {
|
||||
// (string) "one": (int) 1
|
||||
// }
|
||||
}
|
||||
|
||||
// This example demonstrates how to use ConfigState.Dump to dump variables to
|
||||
// stdout
|
||||
func ExampleConfigState_Dump() {
|
||||
// See the top-level Dump example for details on the types used in this
|
||||
// example.
|
||||
|
||||
// Create two ConfigState instances with different indentation.
|
||||
scs := spew.ConfigState{Indent: "\t"}
|
||||
scs2 := spew.ConfigState{Indent: " "}
|
||||
|
||||
// Setup some sample data structures for the example.
|
||||
bar := Bar{Flag(flagTwo), uintptr(0)}
|
||||
s1 := Foo{bar, map[interface{}]interface{}{"one": true}}
|
||||
|
||||
// Dump using the ConfigState instances.
|
||||
scs.Dump(s1)
|
||||
scs2.Dump(s1)
|
||||
|
||||
// Output:
|
||||
// (spew_test.Foo) {
|
||||
// unexportedField: (spew_test.Bar) {
|
||||
// flag: (spew_test.Flag) flagTwo,
|
||||
// data: (uintptr) <nil>
|
||||
// },
|
||||
// ExportedField: (map[interface {}]interface {}) {
|
||||
// (string) "one": (bool) true
|
||||
// }
|
||||
// }
|
||||
// (spew_test.Foo) {
|
||||
// unexportedField: (spew_test.Bar) {
|
||||
// flag: (spew_test.Flag) flagTwo,
|
||||
// data: (uintptr) <nil>
|
||||
// },
|
||||
// ExportedField: (map[interface {}]interface {}) {
|
||||
// (string) "one": (bool) true
|
||||
// }
|
||||
// }
|
||||
//
|
||||
}
|
||||
|
||||
// This example demonstrates how to use ConfigState.Printf to display a variable
|
||||
// with a format string and inline formatting.
|
||||
func ExampleConfigState_Printf() {
|
||||
// See the top-level Dump example for details on the types used in this
|
||||
// example.
|
||||
|
||||
// Create two ConfigState instances and modify the method handling of the
|
||||
// first ConfigState only.
|
||||
scs := spew.NewDefaultConfig()
|
||||
scs2 := spew.NewDefaultConfig()
|
||||
scs.DisableMethods = true
|
||||
|
||||
// Alternatively
|
||||
// scs := spew.ConfigState{Indent: " ", DisableMethods: true}
|
||||
// scs2 := spew.ConfigState{Indent: " "}
|
||||
|
||||
// This is of type Flag which implements a Stringer and has raw value 1.
|
||||
f := flagTwo
|
||||
|
||||
// Dump using the ConfigState instances.
|
||||
scs.Printf("f: %v\n", f)
|
||||
scs2.Printf("f: %v\n", f)
|
||||
|
||||
// Output:
|
||||
// f: 1
|
||||
// f: flagTwo
|
||||
}
|
413
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/format.go
generated
vendored
413
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/format.go
generated
vendored
|
@ -1,413 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// supportedFlags is a list of all the character flags supported by fmt package.
|
||||
const supportedFlags = "0-+# "
|
||||
|
||||
// formatState implements the fmt.Formatter interface and contains information
|
||||
// about the state of a formatting operation. The NewFormatter function can
|
||||
// be used to get a new Formatter which can be used directly as arguments
|
||||
// in standard fmt package printing calls.
|
||||
type formatState struct {
|
||||
value interface{}
|
||||
fs fmt.State
|
||||
depth int
|
||||
pointers map[uintptr]int
|
||||
ignoreNextType bool
|
||||
cs *ConfigState
|
||||
}
|
||||
|
||||
// buildDefaultFormat recreates the original format string without precision
|
||||
// and width information to pass in to fmt.Sprintf in the case of an
|
||||
// unrecognized type. Unless new types are added to the language, this
|
||||
// function won't ever be called.
|
||||
func (f *formatState) buildDefaultFormat() (format string) {
|
||||
buf := bytes.NewBuffer(percentBytes)
|
||||
|
||||
for _, flag := range supportedFlags {
|
||||
if f.fs.Flag(int(flag)) {
|
||||
buf.WriteRune(flag)
|
||||
}
|
||||
}
|
||||
|
||||
buf.WriteRune('v')
|
||||
|
||||
format = buf.String()
|
||||
return format
|
||||
}
|
||||
|
||||
// constructOrigFormat recreates the original format string including precision
|
||||
// and width information to pass along to the standard fmt package. This allows
|
||||
// automatic deferral of all format strings this package doesn't support.
|
||||
func (f *formatState) constructOrigFormat(verb rune) (format string) {
|
||||
buf := bytes.NewBuffer(percentBytes)
|
||||
|
||||
for _, flag := range supportedFlags {
|
||||
if f.fs.Flag(int(flag)) {
|
||||
buf.WriteRune(flag)
|
||||
}
|
||||
}
|
||||
|
||||
if width, ok := f.fs.Width(); ok {
|
||||
buf.WriteString(strconv.Itoa(width))
|
||||
}
|
||||
|
||||
if precision, ok := f.fs.Precision(); ok {
|
||||
buf.Write(precisionBytes)
|
||||
buf.WriteString(strconv.Itoa(precision))
|
||||
}
|
||||
|
||||
buf.WriteRune(verb)
|
||||
|
||||
format = buf.String()
|
||||
return format
|
||||
}
|
||||
|
||||
// unpackValue returns values inside of non-nil interfaces when possible and
|
||||
// ensures that types for values which have been unpacked from an interface
|
||||
// are displayed when the show types flag is also set.
|
||||
// This is useful for data types like structs, arrays, slices, and maps which
|
||||
// can contain varying types packed inside an interface.
|
||||
func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
|
||||
if v.Kind() == reflect.Interface {
|
||||
f.ignoreNextType = false
|
||||
if !v.IsNil() {
|
||||
v = v.Elem()
|
||||
}
|
||||
}
|
||||
return v
|
||||
}
|
||||
|
||||
// formatPtr handles formatting of pointers by indirecting them as necessary.
|
||||
func (f *formatState) formatPtr(v reflect.Value) {
|
||||
// Display nil if top level pointer is nil.
|
||||
showTypes := f.fs.Flag('#')
|
||||
if v.IsNil() && (!showTypes || f.ignoreNextType) {
|
||||
f.fs.Write(nilAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Remove pointers at or below the current depth from map used to detect
|
||||
// circular refs.
|
||||
for k, depth := range f.pointers {
|
||||
if depth >= f.depth {
|
||||
delete(f.pointers, k)
|
||||
}
|
||||
}
|
||||
|
||||
// Keep list of all dereferenced pointers to possibly show later.
|
||||
pointerChain := make([]uintptr, 0)
|
||||
|
||||
// Figure out how many levels of indirection there are by derferencing
|
||||
// pointers and unpacking interfaces down the chain while detecting circular
|
||||
// references.
|
||||
nilFound := false
|
||||
cycleFound := false
|
||||
indirects := 0
|
||||
ve := v
|
||||
for ve.Kind() == reflect.Ptr {
|
||||
if ve.IsNil() {
|
||||
nilFound = true
|
||||
break
|
||||
}
|
||||
indirects++
|
||||
addr := ve.Pointer()
|
||||
pointerChain = append(pointerChain, addr)
|
||||
if pd, ok := f.pointers[addr]; ok && pd < f.depth {
|
||||
cycleFound = true
|
||||
indirects--
|
||||
break
|
||||
}
|
||||
f.pointers[addr] = f.depth
|
||||
|
||||
ve = ve.Elem()
|
||||
if ve.Kind() == reflect.Interface {
|
||||
if ve.IsNil() {
|
||||
nilFound = true
|
||||
break
|
||||
}
|
||||
ve = ve.Elem()
|
||||
}
|
||||
}
|
||||
|
||||
// Display type or indirection level depending on flags.
|
||||
if showTypes && !f.ignoreNextType {
|
||||
f.fs.Write(openParenBytes)
|
||||
f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
|
||||
f.fs.Write([]byte(ve.Type().String()))
|
||||
f.fs.Write(closeParenBytes)
|
||||
} else {
|
||||
if nilFound || cycleFound {
|
||||
indirects += strings.Count(ve.Type().String(), "*")
|
||||
}
|
||||
f.fs.Write(openAngleBytes)
|
||||
f.fs.Write([]byte(strings.Repeat("*", indirects)))
|
||||
f.fs.Write(closeAngleBytes)
|
||||
}
|
||||
|
||||
// Display pointer information depending on flags.
|
||||
if f.fs.Flag('+') && (len(pointerChain) > 0) {
|
||||
f.fs.Write(openParenBytes)
|
||||
for i, addr := range pointerChain {
|
||||
if i > 0 {
|
||||
f.fs.Write(pointerChainBytes)
|
||||
}
|
||||
printHexPtr(f.fs, addr)
|
||||
}
|
||||
f.fs.Write(closeParenBytes)
|
||||
}
|
||||
|
||||
// Display dereferenced value.
|
||||
switch {
|
||||
case nilFound == true:
|
||||
f.fs.Write(nilAngleBytes)
|
||||
|
||||
case cycleFound == true:
|
||||
f.fs.Write(circularShortBytes)
|
||||
|
||||
default:
|
||||
f.ignoreNextType = true
|
||||
f.format(ve)
|
||||
}
|
||||
}
|
||||
|
||||
// format is the main workhorse for providing the Formatter interface. It
|
||||
// uses the passed reflect value to figure out what kind of object we are
|
||||
// dealing with and formats it appropriately. It is a recursive function,
|
||||
// however circular data structures are detected and handled properly.
|
||||
func (f *formatState) format(v reflect.Value) {
|
||||
// Handle invalid reflect values immediately.
|
||||
kind := v.Kind()
|
||||
if kind == reflect.Invalid {
|
||||
f.fs.Write(invalidAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
// Handle pointers specially.
|
||||
if kind == reflect.Ptr {
|
||||
f.formatPtr(v)
|
||||
return
|
||||
}
|
||||
|
||||
// Print type information unless already handled elsewhere.
|
||||
if !f.ignoreNextType && f.fs.Flag('#') {
|
||||
f.fs.Write(openParenBytes)
|
||||
f.fs.Write([]byte(v.Type().String()))
|
||||
f.fs.Write(closeParenBytes)
|
||||
}
|
||||
f.ignoreNextType = false
|
||||
|
||||
// Call Stringer/error interfaces if they exist and the handle methods
|
||||
// flag is enabled.
|
||||
if !f.cs.DisableMethods {
|
||||
if (kind != reflect.Invalid) && (kind != reflect.Interface) {
|
||||
if handled := handleMethods(f.cs, f.fs, v); handled {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
switch kind {
|
||||
case reflect.Invalid:
|
||||
// Do nothing. We should never get here since invalid has already
|
||||
// been handled above.
|
||||
|
||||
case reflect.Bool:
|
||||
printBool(f.fs, v.Bool())
|
||||
|
||||
case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
|
||||
printInt(f.fs, v.Int(), 10)
|
||||
|
||||
case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
|
||||
printUint(f.fs, v.Uint(), 10)
|
||||
|
||||
case reflect.Float32:
|
||||
printFloat(f.fs, v.Float(), 32)
|
||||
|
||||
case reflect.Float64:
|
||||
printFloat(f.fs, v.Float(), 64)
|
||||
|
||||
case reflect.Complex64:
|
||||
printComplex(f.fs, v.Complex(), 32)
|
||||
|
||||
case reflect.Complex128:
|
||||
printComplex(f.fs, v.Complex(), 64)
|
||||
|
||||
case reflect.Slice:
|
||||
if v.IsNil() {
|
||||
f.fs.Write(nilAngleBytes)
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case reflect.Array:
|
||||
f.fs.Write(openBracketBytes)
|
||||
f.depth++
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.fs.Write(maxShortBytes)
|
||||
} else {
|
||||
numEntries := v.Len()
|
||||
for i := 0; i < numEntries; i++ {
|
||||
if i > 0 {
|
||||
f.fs.Write(spaceBytes)
|
||||
}
|
||||
f.ignoreNextType = true
|
||||
f.format(f.unpackValue(v.Index(i)))
|
||||
}
|
||||
}
|
||||
f.depth--
|
||||
f.fs.Write(closeBracketBytes)
|
||||
|
||||
case reflect.String:
|
||||
f.fs.Write([]byte(v.String()))
|
||||
|
||||
case reflect.Interface:
|
||||
// The only time we should get here is for nil interfaces due to
|
||||
// unpackValue calls.
|
||||
if v.IsNil() {
|
||||
f.fs.Write(nilAngleBytes)
|
||||
}
|
||||
|
||||
case reflect.Ptr:
|
||||
// Do nothing. We should never get here since pointers have already
|
||||
// been handled above.
|
||||
|
||||
case reflect.Map:
|
||||
f.fs.Write(openMapBytes)
|
||||
f.depth++
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.fs.Write(maxShortBytes)
|
||||
} else {
|
||||
keys := v.MapKeys()
|
||||
if f.cs.SortKeys {
|
||||
sortValues(keys)
|
||||
}
|
||||
for i, key := range keys {
|
||||
if i > 0 {
|
||||
f.fs.Write(spaceBytes)
|
||||
}
|
||||
f.ignoreNextType = true
|
||||
f.format(f.unpackValue(key))
|
||||
f.fs.Write(colonBytes)
|
||||
f.ignoreNextType = true
|
||||
f.format(f.unpackValue(v.MapIndex(key)))
|
||||
}
|
||||
}
|
||||
f.depth--
|
||||
f.fs.Write(closeMapBytes)
|
||||
|
||||
case reflect.Struct:
|
||||
numFields := v.NumField()
|
||||
f.fs.Write(openBraceBytes)
|
||||
f.depth++
|
||||
if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
|
||||
f.fs.Write(maxShortBytes)
|
||||
} else {
|
||||
vt := v.Type()
|
||||
for i := 0; i < numFields; i++ {
|
||||
if i > 0 {
|
||||
f.fs.Write(spaceBytes)
|
||||
}
|
||||
vtf := vt.Field(i)
|
||||
if f.fs.Flag('+') || f.fs.Flag('#') {
|
||||
f.fs.Write([]byte(vtf.Name))
|
||||
f.fs.Write(colonBytes)
|
||||
}
|
||||
f.format(f.unpackValue(v.Field(i)))
|
||||
}
|
||||
}
|
||||
f.depth--
|
||||
f.fs.Write(closeBraceBytes)
|
||||
|
||||
case reflect.Uintptr:
|
||||
printHexPtr(f.fs, uintptr(v.Uint()))
|
||||
|
||||
case reflect.UnsafePointer, reflect.Chan, reflect.Func:
|
||||
printHexPtr(f.fs, v.Pointer())
|
||||
|
||||
// There were not any other types at the time this code was written, but
|
||||
// fall back to letting the default fmt package handle it if any get added.
|
||||
default:
|
||||
format := f.buildDefaultFormat()
|
||||
if v.CanInterface() {
|
||||
fmt.Fprintf(f.fs, format, v.Interface())
|
||||
} else {
|
||||
fmt.Fprintf(f.fs, format, v.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
|
||||
// details.
|
||||
func (f *formatState) Format(fs fmt.State, verb rune) {
|
||||
f.fs = fs
|
||||
|
||||
// Use standard formatting for verbs that are not v.
|
||||
if verb != 'v' {
|
||||
format := f.constructOrigFormat(verb)
|
||||
fmt.Fprintf(fs, format, f.value)
|
||||
return
|
||||
}
|
||||
|
||||
if f.value == nil {
|
||||
if fs.Flag('#') {
|
||||
fs.Write(interfaceBytes)
|
||||
}
|
||||
fs.Write(nilAngleBytes)
|
||||
return
|
||||
}
|
||||
|
||||
f.format(reflect.ValueOf(f.value))
|
||||
}
|
||||
|
||||
// newFormatter is a helper function to consolidate the logic from the various
|
||||
// public methods which take varying config states.
|
||||
func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
|
||||
fs := &formatState{value: v, cs: cs}
|
||||
fs.pointers = make(map[uintptr]int)
|
||||
return fs
|
||||
}
|
||||
|
||||
/*
|
||||
NewFormatter returns a custom formatter that satisfies the fmt.Formatter
|
||||
interface. As a result, it integrates cleanly with standard fmt package
|
||||
printing functions. The formatter is useful for inline printing of smaller data
|
||||
types similar to the standard %v format specifier.
|
||||
|
||||
The custom formatter only responds to the %v (most compact), %+v (adds pointer
|
||||
addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
|
||||
combinations. Any other verbs such as %x and %q will be sent to the the
|
||||
standard fmt package for formatting. In addition, the custom formatter ignores
|
||||
the width and precision arguments (however they will still work on the format
|
||||
specifiers not handled by the custom formatter).
|
||||
|
||||
Typically this function shouldn't be called directly. It is much easier to make
|
||||
use of the custom formatter by calling one of the convenience functions such as
|
||||
Printf, Println, or Fprintf.
|
||||
*/
|
||||
func NewFormatter(v interface{}) fmt.Formatter {
|
||||
return newFormatter(&Config, v)
|
||||
}
|
1483
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/format_test.go
generated
vendored
1483
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/format_test.go
generated
vendored
File diff suppressed because it is too large
Load diff
162
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/internal_test.go
generated
vendored
162
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/internal_test.go
generated
vendored
|
@ -1,162 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
This test file is part of the spew package rather than than the spew_test
|
||||
package because it needs access to internals to properly test certain cases
|
||||
which are not possible via the public interface since they should never happen.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"reflect"
|
||||
"testing"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
// dummyFmtState implements a fake fmt.State to use for testing invalid
|
||||
// reflect.Value handling. This is necessary because the fmt package catches
|
||||
// invalid values before invoking the formatter on them.
|
||||
type dummyFmtState struct {
|
||||
bytes.Buffer
|
||||
}
|
||||
|
||||
func (dfs *dummyFmtState) Flag(f int) bool {
|
||||
if f == int('+') {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (dfs *dummyFmtState) Precision() (int, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
func (dfs *dummyFmtState) Width() (int, bool) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// TestInvalidReflectValue ensures the dump and formatter code handles an
|
||||
// invalid reflect value properly. This needs access to internal state since it
|
||||
// should never happen in real code and therefore can't be tested via the public
|
||||
// API.
|
||||
func TestInvalidReflectValue(t *testing.T) {
|
||||
i := 1
|
||||
|
||||
// Dump invalid reflect value.
|
||||
v := new(reflect.Value)
|
||||
buf := new(bytes.Buffer)
|
||||
d := dumpState{w: buf, cs: &Config}
|
||||
d.dump(*v)
|
||||
s := buf.String()
|
||||
want := "<invalid>"
|
||||
if s != want {
|
||||
t.Errorf("InvalidReflectValue #%d\n got: %s want: %s", i, s, want)
|
||||
}
|
||||
i++
|
||||
|
||||
// Formatter invalid reflect value.
|
||||
buf2 := new(dummyFmtState)
|
||||
f := formatState{value: *v, cs: &Config, fs: buf2}
|
||||
f.format(*v)
|
||||
s = buf2.String()
|
||||
want = "<invalid>"
|
||||
if s != want {
|
||||
t.Errorf("InvalidReflectValue #%d got: %s want: %s", i, s, want)
|
||||
}
|
||||
}
|
||||
|
||||
// flagRO, flagKindShift and flagKindWidth indicate various bit flags that the
|
||||
// reflect package uses internally to track kind and state information.
|
||||
const flagRO = 1 << 0
|
||||
const flagKindShift = 4
|
||||
const flagKindWidth = 5
|
||||
|
||||
// changeKind uses unsafe to intentionally change the kind of a reflect.Value to
|
||||
// the maximum kind value which does not exist. This is needed to test the
|
||||
// fallback code which punts to the standard fmt library for new types that
|
||||
// might get added to the language.
|
||||
func changeKind(v *reflect.Value, readOnly bool) {
|
||||
rvf := (*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(v)) + offsetFlag))
|
||||
*rvf = *rvf | ((1<<flagKindWidth - 1) << flagKindShift)
|
||||
if readOnly {
|
||||
*rvf |= flagRO
|
||||
} else {
|
||||
*rvf &= ^uintptr(flagRO)
|
||||
}
|
||||
}
|
||||
|
||||
// TestAddedReflectValue tests functionaly of the dump and formatter code which
|
||||
// falls back to the standard fmt library for new types that might get added to
|
||||
// the language.
|
||||
func TestAddedReflectValue(t *testing.T) {
|
||||
i := 1
|
||||
|
||||
// Dump using a reflect.Value that is exported.
|
||||
v := reflect.ValueOf(int8(5))
|
||||
changeKind(&v, false)
|
||||
buf := new(bytes.Buffer)
|
||||
d := dumpState{w: buf, cs: &Config}
|
||||
d.dump(v)
|
||||
s := buf.String()
|
||||
want := "(int8) 5"
|
||||
if s != want {
|
||||
t.Errorf("TestAddedReflectValue #%d\n got: %s want: %s", i, s, want)
|
||||
}
|
||||
i++
|
||||
|
||||
// Dump using a reflect.Value that is not exported.
|
||||
changeKind(&v, true)
|
||||
buf.Reset()
|
||||
d.dump(v)
|
||||
s = buf.String()
|
||||
want = "(int8) <int8 Value>"
|
||||
if s != want {
|
||||
t.Errorf("TestAddedReflectValue #%d\n got: %s want: %s", i, s, want)
|
||||
}
|
||||
i++
|
||||
|
||||
// Formatter using a reflect.Value that is exported.
|
||||
changeKind(&v, false)
|
||||
buf2 := new(dummyFmtState)
|
||||
f := formatState{value: v, cs: &Config, fs: buf2}
|
||||
f.format(v)
|
||||
s = buf2.String()
|
||||
want = "5"
|
||||
if s != want {
|
||||
t.Errorf("TestAddedReflectValue #%d got: %s want: %s", i, s, want)
|
||||
}
|
||||
i++
|
||||
|
||||
// Formatter using a reflect.Value that is not exported.
|
||||
changeKind(&v, true)
|
||||
buf2.Reset()
|
||||
f = formatState{value: v, cs: &Config, fs: buf2}
|
||||
f.format(v)
|
||||
s = buf2.String()
|
||||
want = "<int8 Value>"
|
||||
if s != want {
|
||||
t.Errorf("TestAddedReflectValue #%d got: %s want: %s", i, s, want)
|
||||
}
|
||||
}
|
||||
|
||||
// SortValues makes the internal sortValues function available to the test
|
||||
// package.
|
||||
func SortValues(values []reflect.Value) {
|
||||
sortValues(values)
|
||||
}
|
148
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/spew.go
generated
vendored
148
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/spew.go
generated
vendored
|
@ -1,148 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the formatted string as a value that satisfies error. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Errorf(format string, a ...interface{}) (err error) {
|
||||
return fmt.Errorf(format, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprint(w, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintf(w, format, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
|
||||
// passed with a default Formatter interface returned by NewFormatter. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
|
||||
return fmt.Fprintln(w, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Print is a wrapper for fmt.Print that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Print(a ...interface{}) (n int, err error) {
|
||||
return fmt.Print(convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Printf is a wrapper for fmt.Printf that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Printf(format string, a ...interface{}) (n int, err error) {
|
||||
return fmt.Printf(format, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Println is a wrapper for fmt.Println that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the number of bytes written and any write error encountered. See
|
||||
// NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Println(a ...interface{}) (n int, err error) {
|
||||
return fmt.Println(convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Sprint(a ...interface{}) string {
|
||||
return fmt.Sprint(convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
|
||||
// passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Sprintf(format string, a ...interface{}) string {
|
||||
return fmt.Sprintf(format, convertArgs(a)...)
|
||||
}
|
||||
|
||||
// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
|
||||
// were passed with a default Formatter interface returned by NewFormatter. It
|
||||
// returns the resulting string. See NewFormatter for formatting details.
|
||||
//
|
||||
// This function is shorthand for the following syntax:
|
||||
//
|
||||
// fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
|
||||
func Sprintln(a ...interface{}) string {
|
||||
return fmt.Sprintln(convertArgs(a)...)
|
||||
}
|
||||
|
||||
// convertArgs accepts a slice of arguments and returns a slice of the same
|
||||
// length with each argument converted to a default spew Formatter interface.
|
||||
func convertArgs(args []interface{}) (formatters []interface{}) {
|
||||
formatters = make([]interface{}, len(args))
|
||||
for index, arg := range args {
|
||||
formatters[index] = NewFormatter(arg)
|
||||
}
|
||||
return formatters
|
||||
}
|
308
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/spew_test.go
generated
vendored
308
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/spew_test.go
generated
vendored
|
@ -1,308 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
package spew_test
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"github.com/davecgh/go-spew/spew"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// spewFunc is used to identify which public function of the spew package or
|
||||
// ConfigState a test applies to.
|
||||
type spewFunc int
|
||||
|
||||
const (
|
||||
fCSFdump spewFunc = iota
|
||||
fCSFprint
|
||||
fCSFprintf
|
||||
fCSFprintln
|
||||
fCSPrint
|
||||
fCSPrintln
|
||||
fCSSdump
|
||||
fCSSprint
|
||||
fCSSprintf
|
||||
fCSSprintln
|
||||
fCSErrorf
|
||||
fCSNewFormatter
|
||||
fErrorf
|
||||
fFprint
|
||||
fFprintln
|
||||
fPrint
|
||||
fPrintln
|
||||
fSdump
|
||||
fSprint
|
||||
fSprintf
|
||||
fSprintln
|
||||
)
|
||||
|
||||
// Map of spewFunc values to names for pretty printing.
|
||||
var spewFuncStrings = map[spewFunc]string{
|
||||
fCSFdump: "ConfigState.Fdump",
|
||||
fCSFprint: "ConfigState.Fprint",
|
||||
fCSFprintf: "ConfigState.Fprintf",
|
||||
fCSFprintln: "ConfigState.Fprintln",
|
||||
fCSSdump: "ConfigState.Sdump",
|
||||
fCSPrint: "ConfigState.Print",
|
||||
fCSPrintln: "ConfigState.Println",
|
||||
fCSSprint: "ConfigState.Sprint",
|
||||
fCSSprintf: "ConfigState.Sprintf",
|
||||
fCSSprintln: "ConfigState.Sprintln",
|
||||
fCSErrorf: "ConfigState.Errorf",
|
||||
fCSNewFormatter: "ConfigState.NewFormatter",
|
||||
fErrorf: "spew.Errorf",
|
||||
fFprint: "spew.Fprint",
|
||||
fFprintln: "spew.Fprintln",
|
||||
fPrint: "spew.Print",
|
||||
fPrintln: "spew.Println",
|
||||
fSdump: "spew.Sdump",
|
||||
fSprint: "spew.Sprint",
|
||||
fSprintf: "spew.Sprintf",
|
||||
fSprintln: "spew.Sprintln",
|
||||
}
|
||||
|
||||
func (f spewFunc) String() string {
|
||||
if s, ok := spewFuncStrings[f]; ok {
|
||||
return s
|
||||
}
|
||||
return fmt.Sprintf("Unknown spewFunc (%d)", int(f))
|
||||
}
|
||||
|
||||
// spewTest is used to describe a test to be performed against the public
|
||||
// functions of the spew package or ConfigState.
|
||||
type spewTest struct {
|
||||
cs *spew.ConfigState
|
||||
f spewFunc
|
||||
format string
|
||||
in interface{}
|
||||
want string
|
||||
}
|
||||
|
||||
// spewTests houses the tests to be performed against the public functions of
|
||||
// the spew package and ConfigState.
|
||||
//
|
||||
// These tests are only intended to ensure the public functions are exercised
|
||||
// and are intentionally not exhaustive of types. The exhaustive type
|
||||
// tests are handled in the dump and format tests.
|
||||
var spewTests []spewTest
|
||||
|
||||
// redirStdout is a helper function to return the standard output from f as a
|
||||
// byte slice.
|
||||
func redirStdout(f func()) ([]byte, error) {
|
||||
tempFile, err := ioutil.TempFile("", "ss-test")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
fileName := tempFile.Name()
|
||||
defer os.Remove(fileName) // Ignore error
|
||||
|
||||
origStdout := os.Stdout
|
||||
os.Stdout = tempFile
|
||||
f()
|
||||
os.Stdout = origStdout
|
||||
tempFile.Close()
|
||||
|
||||
return ioutil.ReadFile(fileName)
|
||||
}
|
||||
|
||||
func initSpewTests() {
|
||||
// Config states with various settings.
|
||||
scsDefault := spew.NewDefaultConfig()
|
||||
scsNoMethods := &spew.ConfigState{Indent: " ", DisableMethods: true}
|
||||
scsNoPmethods := &spew.ConfigState{Indent: " ", DisablePointerMethods: true}
|
||||
scsMaxDepth := &spew.ConfigState{Indent: " ", MaxDepth: 1}
|
||||
scsContinue := &spew.ConfigState{Indent: " ", ContinueOnMethod: true}
|
||||
|
||||
// Variables for tests on types which implement Stringer interface with and
|
||||
// without a pointer receiver.
|
||||
ts := stringer("test")
|
||||
tps := pstringer("test")
|
||||
|
||||
// depthTester is used to test max depth handling for structs, array, slices
|
||||
// and maps.
|
||||
type depthTester struct {
|
||||
ic indirCir1
|
||||
arr [1]string
|
||||
slice []string
|
||||
m map[string]int
|
||||
}
|
||||
dt := depthTester{indirCir1{nil}, [1]string{"arr"}, []string{"slice"},
|
||||
map[string]int{"one": 1}}
|
||||
|
||||
// Variable for tests on types which implement error interface.
|
||||
te := customError(10)
|
||||
|
||||
spewTests = []spewTest{
|
||||
{scsDefault, fCSFdump, "", int8(127), "(int8) 127\n"},
|
||||
{scsDefault, fCSFprint, "", int16(32767), "32767"},
|
||||
{scsDefault, fCSFprintf, "%v", int32(2147483647), "2147483647"},
|
||||
{scsDefault, fCSFprintln, "", int(2147483647), "2147483647\n"},
|
||||
{scsDefault, fCSPrint, "", int64(9223372036854775807), "9223372036854775807"},
|
||||
{scsDefault, fCSPrintln, "", uint8(255), "255\n"},
|
||||
{scsDefault, fCSSdump, "", uint8(64), "(uint8) 64\n"},
|
||||
{scsDefault, fCSSprint, "", complex(1, 2), "(1+2i)"},
|
||||
{scsDefault, fCSSprintf, "%v", complex(float32(3), 4), "(3+4i)"},
|
||||
{scsDefault, fCSSprintln, "", complex(float64(5), 6), "(5+6i)\n"},
|
||||
{scsDefault, fCSErrorf, "%#v", uint16(65535), "(uint16)65535"},
|
||||
{scsDefault, fCSNewFormatter, "%v", uint32(4294967295), "4294967295"},
|
||||
{scsDefault, fErrorf, "%v", uint64(18446744073709551615), "18446744073709551615"},
|
||||
{scsDefault, fFprint, "", float32(3.14), "3.14"},
|
||||
{scsDefault, fFprintln, "", float64(6.28), "6.28\n"},
|
||||
{scsDefault, fPrint, "", true, "true"},
|
||||
{scsDefault, fPrintln, "", false, "false\n"},
|
||||
{scsDefault, fSdump, "", complex(-10, -20), "(complex128) (-10-20i)\n"},
|
||||
{scsDefault, fSprint, "", complex(-1, -2), "(-1-2i)"},
|
||||
{scsDefault, fSprintf, "%v", complex(float32(-3), -4), "(-3-4i)"},
|
||||
{scsDefault, fSprintln, "", complex(float64(-5), -6), "(-5-6i)\n"},
|
||||
{scsNoMethods, fCSFprint, "", ts, "test"},
|
||||
{scsNoMethods, fCSFprint, "", &ts, "<*>test"},
|
||||
{scsNoMethods, fCSFprint, "", tps, "test"},
|
||||
{scsNoMethods, fCSFprint, "", &tps, "<*>test"},
|
||||
{scsNoPmethods, fCSFprint, "", ts, "stringer test"},
|
||||
{scsNoPmethods, fCSFprint, "", &ts, "<*>stringer test"},
|
||||
{scsNoPmethods, fCSFprint, "", tps, "test"},
|
||||
{scsNoPmethods, fCSFprint, "", &tps, "<*>stringer test"},
|
||||
{scsMaxDepth, fCSFprint, "", dt, "{{<max>} [<max>] [<max>] map[<max>]}"},
|
||||
{scsMaxDepth, fCSFdump, "", dt, "(spew_test.depthTester) {\n" +
|
||||
" ic: (spew_test.indirCir1) {\n <max depth reached>\n },\n" +
|
||||
" arr: ([1]string) {\n <max depth reached>\n },\n" +
|
||||
" slice: ([]string) {\n <max depth reached>\n },\n" +
|
||||
" m: (map[string]int) {\n <max depth reached>\n }\n}\n"},
|
||||
{scsContinue, fCSFprint, "", ts, "(stringer test) test"},
|
||||
{scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " +
|
||||
"(stringer test) \"test\"\n"},
|
||||
{scsContinue, fCSFprint, "", te, "(error: 10) 10"},
|
||||
{scsContinue, fCSFdump, "", te, "(spew_test.customError) " +
|
||||
"(error: 10) 10\n"},
|
||||
}
|
||||
}
|
||||
|
||||
// TestSpew executes all of the tests described by spewTests.
|
||||
func TestSpew(t *testing.T) {
|
||||
initSpewTests()
|
||||
|
||||
t.Logf("Running %d tests", len(spewTests))
|
||||
for i, test := range spewTests {
|
||||
buf := new(bytes.Buffer)
|
||||
switch test.f {
|
||||
case fCSFdump:
|
||||
test.cs.Fdump(buf, test.in)
|
||||
|
||||
case fCSFprint:
|
||||
test.cs.Fprint(buf, test.in)
|
||||
|
||||
case fCSFprintf:
|
||||
test.cs.Fprintf(buf, test.format, test.in)
|
||||
|
||||
case fCSFprintln:
|
||||
test.cs.Fprintln(buf, test.in)
|
||||
|
||||
case fCSPrint:
|
||||
b, err := redirStdout(func() { test.cs.Print(test.in) })
|
||||
if err != nil {
|
||||
t.Errorf("%v #%d %v", test.f, i, err)
|
||||
continue
|
||||
}
|
||||
buf.Write(b)
|
||||
|
||||
case fCSPrintln:
|
||||
b, err := redirStdout(func() { test.cs.Println(test.in) })
|
||||
if err != nil {
|
||||
t.Errorf("%v #%d %v", test.f, i, err)
|
||||
continue
|
||||
}
|
||||
buf.Write(b)
|
||||
|
||||
case fCSSdump:
|
||||
str := test.cs.Sdump(test.in)
|
||||
buf.WriteString(str)
|
||||
|
||||
case fCSSprint:
|
||||
str := test.cs.Sprint(test.in)
|
||||
buf.WriteString(str)
|
||||
|
||||
case fCSSprintf:
|
||||
str := test.cs.Sprintf(test.format, test.in)
|
||||
buf.WriteString(str)
|
||||
|
||||
case fCSSprintln:
|
||||
str := test.cs.Sprintln(test.in)
|
||||
buf.WriteString(str)
|
||||
|
||||
case fCSErrorf:
|
||||
err := test.cs.Errorf(test.format, test.in)
|
||||
buf.WriteString(err.Error())
|
||||
|
||||
case fCSNewFormatter:
|
||||
fmt.Fprintf(buf, test.format, test.cs.NewFormatter(test.in))
|
||||
|
||||
case fErrorf:
|
||||
err := spew.Errorf(test.format, test.in)
|
||||
buf.WriteString(err.Error())
|
||||
|
||||
case fFprint:
|
||||
spew.Fprint(buf, test.in)
|
||||
|
||||
case fFprintln:
|
||||
spew.Fprintln(buf, test.in)
|
||||
|
||||
case fPrint:
|
||||
b, err := redirStdout(func() { spew.Print(test.in) })
|
||||
if err != nil {
|
||||
t.Errorf("%v #%d %v", test.f, i, err)
|
||||
continue
|
||||
}
|
||||
buf.Write(b)
|
||||
|
||||
case fPrintln:
|
||||
b, err := redirStdout(func() { spew.Println(test.in) })
|
||||
if err != nil {
|
||||
t.Errorf("%v #%d %v", test.f, i, err)
|
||||
continue
|
||||
}
|
||||
buf.Write(b)
|
||||
|
||||
case fSdump:
|
||||
str := spew.Sdump(test.in)
|
||||
buf.WriteString(str)
|
||||
|
||||
case fSprint:
|
||||
str := spew.Sprint(test.in)
|
||||
buf.WriteString(str)
|
||||
|
||||
case fSprintf:
|
||||
str := spew.Sprintf(test.format, test.in)
|
||||
buf.WriteString(str)
|
||||
|
||||
case fSprintln:
|
||||
str := spew.Sprintln(test.in)
|
||||
buf.WriteString(str)
|
||||
|
||||
default:
|
||||
t.Errorf("%v #%d unrecognized function", test.f, i)
|
||||
continue
|
||||
}
|
||||
s := buf.String()
|
||||
if test.want != s {
|
||||
t.Errorf("ConfigState #%d\n got: %s want: %s", i, s, test.want)
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
81
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go
generated
vendored
81
Godeps/_workspace/src/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go
generated
vendored
|
@ -1,81 +0,0 @@
|
|||
// Copyright (c) 2013 Dave Collins <dave@davec.name>
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
// NOTE: Due to the following build constraints, this file will only be compiled
|
||||
// when both cgo is supported and "-tags testcgo" is added to the go test
|
||||
// command line. This code should really only be in the dumpcgo_test.go file,
|
||||
// but unfortunately Go will not allow cgo in test files, so this is a
|
||||
// workaround to allow cgo types to be tested. This configuration is used
|
||||
// because spew itself does not require cgo to run even though it does handle
|
||||
// certain cgo types specially. Rather than forcing all clients to require cgo
|
||||
// and an external C compiler just to run the tests, this scheme makes them
|
||||
// optional.
|
||||
// +build cgo,testcgo
|
||||
|
||||
package testdata
|
||||
|
||||
/*
|
||||
#include <stdint.h>
|
||||
typedef unsigned char custom_uchar_t;
|
||||
|
||||
char *ncp = 0;
|
||||
char *cp = "test";
|
||||
char ca[6] = {'t', 'e', 's', 't', '2', '\0'};
|
||||
unsigned char uca[6] = {'t', 'e', 's', 't', '3', '\0'};
|
||||
signed char sca[6] = {'t', 'e', 's', 't', '4', '\0'};
|
||||
uint8_t ui8ta[6] = {'t', 'e', 's', 't', '5', '\0'};
|
||||
custom_uchar_t tuca[6] = {'t', 'e', 's', 't', '6', '\0'};
|
||||
*/
|
||||
import "C"
|
||||
|
||||
// GetCgoNullCharPointer returns a null char pointer via cgo. This is only
|
||||
// used for tests.
|
||||
func GetCgoNullCharPointer() interface{} {
|
||||
return C.ncp
|
||||
}
|
||||
|
||||
// GetCgoCharPointer returns a char pointer via cgo. This is only used for
|
||||
// tests.
|
||||
func GetCgoCharPointer() interface{} {
|
||||
return C.cp
|
||||
}
|
||||
|
||||
// GetCgoCharArray returns a char array via cgo. This is only used for tests.
|
||||
func GetCgoCharArray() interface{} {
|
||||
return C.ca
|
||||
}
|
||||
|
||||
// GetCgoUnsignedCharArray returns an unsigned char array via cgo. This is only
|
||||
// used for tests.
|
||||
func GetCgoUnsignedCharArray() interface{} {
|
||||
return C.uca
|
||||
}
|
||||
|
||||
// GetCgoSignedCharArray returns a signed char array via cgo. This is only used
|
||||
// for tests.
|
||||
func GetCgoSignedCharArray() interface{} {
|
||||
return C.sca
|
||||
}
|
||||
|
||||
// GetCgoUint8tArray returns a uint8_t array via cgo. This is only used for
|
||||
// tests.
|
||||
func GetCgoUint8tArray() interface{} {
|
||||
return C.ui8ta
|
||||
}
|
||||
|
||||
// GetCgoTypdefedUnsignedCharArray returns a typedefed unsigned char array via
|
||||
// cgo. This is only used for tests.
|
||||
func GetCgoTypdefedUnsignedCharArray() interface{} {
|
||||
return C.tuca
|
||||
}
|
114
Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go
generated
vendored
Normal file
114
Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers.go
generated
vendored
Normal file
|
@ -0,0 +1,114 @@
|
|||
package ioutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type readCloserWrapper struct {
|
||||
io.Reader
|
||||
closer func() error
|
||||
}
|
||||
|
||||
func (r *readCloserWrapper) Close() error {
|
||||
return r.closer()
|
||||
}
|
||||
|
||||
func NewReadCloserWrapper(r io.Reader, closer func() error) io.ReadCloser {
|
||||
return &readCloserWrapper{
|
||||
Reader: r,
|
||||
closer: closer,
|
||||
}
|
||||
}
|
||||
|
||||
type readerErrWrapper struct {
|
||||
reader io.Reader
|
||||
closer func()
|
||||
}
|
||||
|
||||
func (r *readerErrWrapper) Read(p []byte) (int, error) {
|
||||
n, err := r.reader.Read(p)
|
||||
if err != nil {
|
||||
r.closer()
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
func NewReaderErrWrapper(r io.Reader, closer func()) io.Reader {
|
||||
return &readerErrWrapper{
|
||||
reader: r,
|
||||
closer: closer,
|
||||
}
|
||||
}
|
||||
|
||||
type bufReader struct {
|
||||
sync.Mutex
|
||||
buf *bytes.Buffer
|
||||
reader io.Reader
|
||||
err error
|
||||
wait sync.Cond
|
||||
drainBuf []byte
|
||||
}
|
||||
|
||||
func NewBufReader(r io.Reader) *bufReader {
|
||||
reader := &bufReader{
|
||||
buf: &bytes.Buffer{},
|
||||
drainBuf: make([]byte, 1024),
|
||||
reader: r,
|
||||
}
|
||||
reader.wait.L = &reader.Mutex
|
||||
go reader.drain()
|
||||
return reader
|
||||
}
|
||||
|
||||
func NewBufReaderWithDrainbufAndBuffer(r io.Reader, drainBuffer []byte, buffer *bytes.Buffer) *bufReader {
|
||||
reader := &bufReader{
|
||||
buf: buffer,
|
||||
drainBuf: drainBuffer,
|
||||
reader: r,
|
||||
}
|
||||
reader.wait.L = &reader.Mutex
|
||||
go reader.drain()
|
||||
return reader
|
||||
}
|
||||
|
||||
func (r *bufReader) drain() {
|
||||
for {
|
||||
n, err := r.reader.Read(r.drainBuf)
|
||||
r.Lock()
|
||||
if err != nil {
|
||||
r.err = err
|
||||
} else {
|
||||
r.buf.Write(r.drainBuf[0:n])
|
||||
}
|
||||
r.wait.Signal()
|
||||
r.Unlock()
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (r *bufReader) Read(p []byte) (n int, err error) {
|
||||
r.Lock()
|
||||
defer r.Unlock()
|
||||
for {
|
||||
n, err = r.buf.Read(p)
|
||||
if n > 0 {
|
||||
return n, err
|
||||
}
|
||||
if r.err != nil {
|
||||
return 0, r.err
|
||||
}
|
||||
r.wait.Wait()
|
||||
}
|
||||
}
|
||||
|
||||
func (r *bufReader) Close() error {
|
||||
closer, ok := r.reader.(io.ReadCloser)
|
||||
if !ok {
|
||||
return nil
|
||||
}
|
||||
return closer.Close()
|
||||
}
|
34
Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers_test.go
generated
vendored
Normal file
34
Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/readers_test.go
generated
vendored
Normal file
|
@ -0,0 +1,34 @@
|
|||
package ioutils
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBufReader(t *testing.T) {
|
||||
reader, writer := io.Pipe()
|
||||
bufreader := NewBufReader(reader)
|
||||
|
||||
// Write everything down to a Pipe
|
||||
// Usually, a pipe should block but because of the buffered reader,
|
||||
// the writes will go through
|
||||
done := make(chan bool)
|
||||
go func() {
|
||||
writer.Write([]byte("hello world"))
|
||||
writer.Close()
|
||||
done <- true
|
||||
}()
|
||||
|
||||
// Drain the reader *after* everything has been written, just to verify
|
||||
// it is indeed buffering
|
||||
<-done
|
||||
output, err := ioutil.ReadAll(bufreader)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if !bytes.Equal(output, []byte("hello world")) {
|
||||
t.Error(string(output))
|
||||
}
|
||||
}
|
39
Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writers.go
generated
vendored
Normal file
39
Godeps/_workspace/src/github.com/docker/docker/pkg/ioutils/writers.go
generated
vendored
Normal file
|
@ -0,0 +1,39 @@
|
|||
package ioutils
|
||||
|
||||
import "io"
|
||||
|
||||
type NopWriter struct{}
|
||||
|
||||
func (*NopWriter) Write(buf []byte) (int, error) {
|
||||
return len(buf), nil
|
||||
}
|
||||
|
||||
type nopWriteCloser struct {
|
||||
io.Writer
|
||||
}
|
||||
|
||||
func (w *nopWriteCloser) Close() error { return nil }
|
||||
|
||||
func NopWriteCloser(w io.Writer) io.WriteCloser {
|
||||
return &nopWriteCloser{w}
|
||||
}
|
||||
|
||||
type NopFlusher struct{}
|
||||
|
||||
func (f *NopFlusher) Flush() {}
|
||||
|
||||
type writeCloserWrapper struct {
|
||||
io.Writer
|
||||
closer func() error
|
||||
}
|
||||
|
||||
func (r *writeCloserWrapper) Close() error {
|
||||
return r.closer()
|
||||
}
|
||||
|
||||
func NewWriteCloserWrapper(r io.Writer, closer func() error) io.WriteCloser {
|
||||
return &writeCloserWrapper{
|
||||
Writer: r,
|
||||
closer: closer,
|
||||
}
|
||||
}
|
83
Godeps/_workspace/src/github.com/docker/docker/pkg/log/log.go
generated
vendored
Normal file
83
Godeps/_workspace/src/github.com/docker/docker/pkg/log/log.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type priority int
|
||||
|
||||
const (
|
||||
errorFormat = "[%s] %s:%d %s\n"
|
||||
logFormat = "[%s] %s\n"
|
||||
|
||||
fatal priority = iota
|
||||
error
|
||||
info
|
||||
debug
|
||||
)
|
||||
|
||||
// A common interface to access the Fatal method of
|
||||
// both testing.B and testing.T.
|
||||
type Fataler interface {
|
||||
Fatal(args ...interface{})
|
||||
}
|
||||
|
||||
func (p priority) String() string {
|
||||
switch p {
|
||||
case fatal:
|
||||
return "fatal"
|
||||
case error:
|
||||
return "error"
|
||||
case info:
|
||||
return "info"
|
||||
case debug:
|
||||
return "debug"
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
|
||||
// Debug function, if the debug flag is set, then display. Do nothing otherwise
|
||||
// If Docker is in damon mode, also send the debug info on the socket
|
||||
func Debugf(format string, a ...interface{}) {
|
||||
if os.Getenv("DEBUG") != "" {
|
||||
logf(os.Stderr, debug, format, a...)
|
||||
}
|
||||
}
|
||||
|
||||
func Infof(format string, a ...interface{}) {
|
||||
logf(os.Stdout, info, format, a...)
|
||||
}
|
||||
|
||||
func Errorf(format string, a ...interface{}) {
|
||||
logf(os.Stderr, error, format, a...)
|
||||
}
|
||||
|
||||
func Fatalf(format string, a ...interface{}) {
|
||||
logf(os.Stderr, fatal, format, a...)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func logf(stream io.Writer, level priority, format string, a ...interface{}) {
|
||||
var prefix string
|
||||
|
||||
if level <= error || level == debug {
|
||||
// Retrieve the stack infos
|
||||
_, file, line, ok := runtime.Caller(2)
|
||||
if !ok {
|
||||
file = "<unknown>"
|
||||
line = -1
|
||||
} else {
|
||||
file = file[strings.LastIndex(file, "/")+1:]
|
||||
}
|
||||
prefix = fmt.Sprintf(errorFormat, level.String(), file, line, format)
|
||||
} else {
|
||||
prefix = fmt.Sprintf(logFormat, level.String(), format)
|
||||
}
|
||||
|
||||
fmt.Fprintf(stream, prefix, a...)
|
||||
}
|
37
Godeps/_workspace/src/github.com/docker/docker/pkg/log/log_test.go
generated
vendored
Normal file
37
Godeps/_workspace/src/github.com/docker/docker/pkg/log/log_test.go
generated
vendored
Normal file
|
@ -0,0 +1,37 @@
|
|||
package log
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"regexp"
|
||||
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestLogFatalf(t *testing.T) {
|
||||
var output *bytes.Buffer
|
||||
|
||||
tests := []struct {
|
||||
Level priority
|
||||
Format string
|
||||
Values []interface{}
|
||||
ExpectedPattern string
|
||||
}{
|
||||
{fatal, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[fatal\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
||||
{error, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[error\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
||||
{info, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[info\\] 1 \\+ 1 = 2"},
|
||||
{debug, "%d + %d = %d", []interface{}{1, 1, 2}, "\\[debug\\] testing.go:\\d+ 1 \\+ 1 = 2"},
|
||||
}
|
||||
|
||||
for i, test := range tests {
|
||||
output = &bytes.Buffer{}
|
||||
logf(output, test.Level, test.Format, test.Values...)
|
||||
|
||||
expected := regexp.MustCompile(test.ExpectedPattern)
|
||||
if !expected.MatchString(output.String()) {
|
||||
t.Errorf("[%d] Log output does not match expected pattern:\n\tExpected: %s\n\tOutput: %s",
|
||||
i,
|
||||
expected.String(),
|
||||
output.String())
|
||||
}
|
||||
}
|
||||
}
|
111
Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools.go
generated
vendored
Normal file
111
Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools.go
generated
vendored
Normal file
|
@ -0,0 +1,111 @@
|
|||
// +build go1.3
|
||||
|
||||
// Package pools provides a collection of pools which provide various
|
||||
// data types with buffers. These can be used to lower the number of
|
||||
// memory allocations and reuse buffers.
|
||||
//
|
||||
// New pools should be added to this package to allow them to be
|
||||
// shared across packages.
|
||||
//
|
||||
// Utility functions which operate on pools should be added to this
|
||||
// package to allow them to be reused.
|
||||
package pools
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"sync"
|
||||
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
)
|
||||
|
||||
var (
|
||||
// Pool which returns bufio.Reader with a 32K buffer
|
||||
BufioReader32KPool *BufioReaderPool
|
||||
// Pool which returns bufio.Writer with a 32K buffer
|
||||
BufioWriter32KPool *BufioWriterPool
|
||||
)
|
||||
|
||||
const buffer32K = 32 * 1024
|
||||
|
||||
type BufioReaderPool struct {
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
func init() {
|
||||
BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K)
|
||||
BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K)
|
||||
}
|
||||
|
||||
// newBufioReaderPoolWithSize is unexported because new pools should be
|
||||
// added here to be shared where required.
|
||||
func newBufioReaderPoolWithSize(size int) *BufioReaderPool {
|
||||
pool := sync.Pool{
|
||||
New: func() interface{} { return bufio.NewReaderSize(nil, size) },
|
||||
}
|
||||
return &BufioReaderPool{pool: pool}
|
||||
}
|
||||
|
||||
// Get returns a bufio.Reader which reads from r. The buffer size is that of the pool.
|
||||
func (bufPool *BufioReaderPool) Get(r io.Reader) *bufio.Reader {
|
||||
buf := bufPool.pool.Get().(*bufio.Reader)
|
||||
buf.Reset(r)
|
||||
return buf
|
||||
}
|
||||
|
||||
// Put puts the bufio.Reader back into the pool.
|
||||
func (bufPool *BufioReaderPool) Put(b *bufio.Reader) {
|
||||
b.Reset(nil)
|
||||
bufPool.pool.Put(b)
|
||||
}
|
||||
|
||||
// NewReadCloserWrapper returns a wrapper which puts the bufio.Reader back
|
||||
// into the pool and closes the reader if it's an io.ReadCloser.
|
||||
func (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser {
|
||||
return ioutils.NewReadCloserWrapper(r, func() error {
|
||||
if readCloser, ok := r.(io.ReadCloser); ok {
|
||||
readCloser.Close()
|
||||
}
|
||||
bufPool.Put(buf)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
type BufioWriterPool struct {
|
||||
pool sync.Pool
|
||||
}
|
||||
|
||||
// newBufioWriterPoolWithSize is unexported because new pools should be
|
||||
// added here to be shared where required.
|
||||
func newBufioWriterPoolWithSize(size int) *BufioWriterPool {
|
||||
pool := sync.Pool{
|
||||
New: func() interface{} { return bufio.NewWriterSize(nil, size) },
|
||||
}
|
||||
return &BufioWriterPool{pool: pool}
|
||||
}
|
||||
|
||||
// Get returns a bufio.Writer which writes to w. The buffer size is that of the pool.
|
||||
func (bufPool *BufioWriterPool) Get(w io.Writer) *bufio.Writer {
|
||||
buf := bufPool.pool.Get().(*bufio.Writer)
|
||||
buf.Reset(w)
|
||||
return buf
|
||||
}
|
||||
|
||||
// Put puts the bufio.Writer back into the pool.
|
||||
func (bufPool *BufioWriterPool) Put(b *bufio.Writer) {
|
||||
b.Reset(nil)
|
||||
bufPool.pool.Put(b)
|
||||
}
|
||||
|
||||
// NewWriteCloserWrapper returns a wrapper which puts the bufio.Writer back
|
||||
// into the pool and closes the writer if it's an io.Writecloser.
|
||||
func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser {
|
||||
return ioutils.NewWriteCloserWrapper(w, func() error {
|
||||
buf.Flush()
|
||||
if writeCloser, ok := w.(io.WriteCloser); ok {
|
||||
writeCloser.Close()
|
||||
}
|
||||
bufPool.Put(buf)
|
||||
return nil
|
||||
})
|
||||
}
|
73
Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools_nopool.go
generated
vendored
Normal file
73
Godeps/_workspace/src/github.com/docker/docker/pkg/pools/pools_nopool.go
generated
vendored
Normal file
|
@ -0,0 +1,73 @@
|
|||
// +build !go1.3
|
||||
|
||||
package pools
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
|
||||
"github.com/docker/docker/pkg/ioutils"
|
||||
)
|
||||
|
||||
var (
|
||||
BufioReader32KPool *BufioReaderPool
|
||||
BufioWriter32KPool *BufioWriterPool
|
||||
)
|
||||
|
||||
const buffer32K = 32 * 1024
|
||||
|
||||
type BufioReaderPool struct {
|
||||
size int
|
||||
}
|
||||
|
||||
func init() {
|
||||
BufioReader32KPool = newBufioReaderPoolWithSize(buffer32K)
|
||||
BufioWriter32KPool = newBufioWriterPoolWithSize(buffer32K)
|
||||
}
|
||||
|
||||
func newBufioReaderPoolWithSize(size int) *BufioReaderPool {
|
||||
return &BufioReaderPool{size: size}
|
||||
}
|
||||
|
||||
func (bufPool *BufioReaderPool) Get(r io.Reader) *bufio.Reader {
|
||||
return bufio.NewReaderSize(r, bufPool.size)
|
||||
}
|
||||
|
||||
func (bufPool *BufioReaderPool) Put(b *bufio.Reader) {
|
||||
b.Reset(nil)
|
||||
}
|
||||
|
||||
func (bufPool *BufioReaderPool) NewReadCloserWrapper(buf *bufio.Reader, r io.Reader) io.ReadCloser {
|
||||
return ioutils.NewReadCloserWrapper(r, func() error {
|
||||
if readCloser, ok := r.(io.ReadCloser); ok {
|
||||
return readCloser.Close()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
type BufioWriterPool struct {
|
||||
size int
|
||||
}
|
||||
|
||||
func newBufioWriterPoolWithSize(size int) *BufioWriterPool {
|
||||
return &BufioWriterPool{size: size}
|
||||
}
|
||||
|
||||
func (bufPool *BufioWriterPool) Get(w io.Writer) *bufio.Writer {
|
||||
return bufio.NewWriterSize(w, bufPool.size)
|
||||
}
|
||||
|
||||
func (bufPool *BufioWriterPool) Put(b *bufio.Writer) {
|
||||
b.Reset(nil)
|
||||
}
|
||||
|
||||
func (bufPool *BufioWriterPool) NewWriteCloserWrapper(buf *bufio.Writer, w io.Writer) io.WriteCloser {
|
||||
return ioutils.NewWriteCloserWrapper(w, func() error {
|
||||
buf.Flush()
|
||||
if writeCloser, ok := w.(io.WriteCloser); ok {
|
||||
return writeCloser.Close()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
2
Godeps/_workspace/src/github.com/docker/docker/pkg/system/MAINTAINERS
generated
vendored
Normal file
2
Godeps/_workspace/src/github.com/docker/docker/pkg/system/MAINTAINERS
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
|
||||
Victor Vieux <vieux@docker.com> (@vieux)
|
11
Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_darwin.go
generated
vendored
Normal file
11
Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
package system
|
||||
|
||||
import "syscall"
|
||||
|
||||
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||
return ErrNotSupportedPlatform
|
||||
}
|
||||
|
||||
func UtimesNano(path string, ts []syscall.Timespec) error {
|
||||
return syscall.UtimesNano(path, ts)
|
||||
}
|
24
Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_freebsd.go
generated
vendored
Normal file
24
Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,24 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func LUtimesNano(path string, ts []syscall.Timespec) error {
|
||||
var _path *byte
|
||||
_path, err := syscall.BytePtrFromString(path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_LUTIMES, uintptr(unsafe.Pointer(_path)), uintptr(unsafe.Pointer(&ts[0])), 0); err != 0 && err != syscall.ENOSYS {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func UtimesNano(path string, ts []syscall.Timespec) error {
|
||||
return syscall.UtimesNano(path, ts)
|
||||
}
|
|
@ -24,8 +24,5 @@ func LUtimesNano(path string, ts []syscall.Timespec) error {
|
|||
}
|
||||
|
||||
func UtimesNano(path string, ts []syscall.Timespec) error {
|
||||
if err := syscall.UtimesNano(path, ts); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
return syscall.UtimesNano(path, ts)
|
||||
}
|
64
Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_test.go
generated
vendored
Normal file
64
Godeps/_workspace/src/github.com/docker/docker/pkg/system/utimes_test.go
generated
vendored
Normal file
|
@ -0,0 +1,64 @@
|
|||
package system
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func prepareFiles(t *testing.T) (string, string, string) {
|
||||
dir, err := ioutil.TempDir("", "docker-system-test")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
file := filepath.Join(dir, "exist")
|
||||
if err := ioutil.WriteFile(file, []byte("hello"), 0644); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
invalid := filepath.Join(dir, "doesnt-exist")
|
||||
|
||||
symlink := filepath.Join(dir, "symlink")
|
||||
if err := os.Symlink(file, symlink); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
return file, invalid, symlink
|
||||
}
|
||||
|
||||
func TestLUtimesNano(t *testing.T) {
|
||||
file, invalid, symlink := prepareFiles(t)
|
||||
|
||||
before, err := os.Stat(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ts := []syscall.Timespec{{0, 0}, {0, 0}}
|
||||
if err := LUtimesNano(symlink, ts); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
symlinkInfo, err := os.Lstat(symlink)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if before.ModTime().Unix() == symlinkInfo.ModTime().Unix() {
|
||||
t.Fatal("The modification time of the symlink should be different")
|
||||
}
|
||||
|
||||
fileInfo, err := os.Stat(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if before.ModTime().Unix() != fileInfo.ModTime().Unix() {
|
||||
t.Fatal("The modification time of the file should be same")
|
||||
}
|
||||
|
||||
if err := LUtimesNano(invalid, ts); err == nil {
|
||||
t.Fatal("Doesn't return an error on a non-existing file")
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
// +build !linux
|
||||
// +build !linux,!freebsd,!darwin
|
||||
|
||||
package system
|
||||
|
1
Godeps/_workspace/src/github.com/docker/docker/pkg/term/MAINTAINERS
generated
vendored
Normal file
1
Godeps/_workspace/src/github.com/docker/docker/pkg/term/MAINTAINERS
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Solomon Hykes <solomon@docker.com> (@shykes)
|
103
Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go
generated
vendored
Normal file
103
Godeps/_workspace/src/github.com/docker/docker/pkg/term/term.go
generated
vendored
Normal file
|
@ -0,0 +1,103 @@
|
|||
package term
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
var (
|
||||
ErrInvalidState = errors.New("Invalid terminal state")
|
||||
)
|
||||
|
||||
type State struct {
|
||||
termios Termios
|
||||
}
|
||||
|
||||
type Winsize struct {
|
||||
Height uint16
|
||||
Width uint16
|
||||
x uint16
|
||||
y uint16
|
||||
}
|
||||
|
||||
func GetWinsize(fd uintptr) (*Winsize, error) {
|
||||
ws := &Winsize{}
|
||||
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCGWINSZ), uintptr(unsafe.Pointer(ws)))
|
||||
// Skipp errno = 0
|
||||
if err == 0 {
|
||||
return ws, nil
|
||||
}
|
||||
return ws, err
|
||||
}
|
||||
|
||||
func SetWinsize(fd uintptr, ws *Winsize) error {
|
||||
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(syscall.TIOCSWINSZ), uintptr(unsafe.Pointer(ws)))
|
||||
// Skipp errno = 0
|
||||
if err == 0 {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// IsTerminal returns true if the given file descriptor is a terminal.
|
||||
func IsTerminal(fd uintptr) bool {
|
||||
var termios Termios
|
||||
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&termios)))
|
||||
return err == 0
|
||||
}
|
||||
|
||||
// Restore restores the terminal connected to the given file descriptor to a
|
||||
// previous state.
|
||||
func RestoreTerminal(fd uintptr, state *State) error {
|
||||
if state == nil {
|
||||
return ErrInvalidState
|
||||
}
|
||||
_, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&state.termios)))
|
||||
if err != 0 {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func SaveState(fd uintptr) (*State, error) {
|
||||
var oldState State
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &oldState, nil
|
||||
}
|
||||
|
||||
func DisableEcho(fd uintptr, state *State) error {
|
||||
newState := state.termios
|
||||
newState.Lflag &^= syscall.ECHO
|
||||
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||
return err
|
||||
}
|
||||
handleInterrupt(fd, state)
|
||||
return nil
|
||||
}
|
||||
|
||||
func SetRawTerminal(fd uintptr) (*State, error) {
|
||||
oldState, err := MakeRaw(fd)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
handleInterrupt(fd, oldState)
|
||||
return oldState, err
|
||||
}
|
||||
|
||||
func handleInterrupt(fd uintptr, state *State) {
|
||||
sigchan := make(chan os.Signal, 1)
|
||||
signal.Notify(sigchan, os.Interrupt)
|
||||
|
||||
go func() {
|
||||
_ = <-sigchan
|
||||
RestoreTerminal(fd, state)
|
||||
os.Exit(0)
|
||||
}()
|
||||
}
|
65
Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_darwin.go
generated
vendored
Normal file
65
Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_darwin.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
package term
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
getTermios = syscall.TIOCGETA
|
||||
setTermios = syscall.TIOCSETA
|
||||
|
||||
IGNBRK = syscall.IGNBRK
|
||||
PARMRK = syscall.PARMRK
|
||||
INLCR = syscall.INLCR
|
||||
IGNCR = syscall.IGNCR
|
||||
ECHONL = syscall.ECHONL
|
||||
CSIZE = syscall.CSIZE
|
||||
ICRNL = syscall.ICRNL
|
||||
ISTRIP = syscall.ISTRIP
|
||||
PARENB = syscall.PARENB
|
||||
ECHO = syscall.ECHO
|
||||
ICANON = syscall.ICANON
|
||||
ISIG = syscall.ISIG
|
||||
IXON = syscall.IXON
|
||||
BRKINT = syscall.BRKINT
|
||||
INPCK = syscall.INPCK
|
||||
OPOST = syscall.OPOST
|
||||
CS8 = syscall.CS8
|
||||
IEXTEN = syscall.IEXTEN
|
||||
)
|
||||
|
||||
type Termios struct {
|
||||
Iflag uint64
|
||||
Oflag uint64
|
||||
Cflag uint64
|
||||
Lflag uint64
|
||||
Cc [20]byte
|
||||
Ispeed uint64
|
||||
Ospeed uint64
|
||||
}
|
||||
|
||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
func MakeRaw(fd uintptr) (*State, error) {
|
||||
var oldState State
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newState := oldState.termios
|
||||
newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
|
||||
newState.Oflag &^= OPOST
|
||||
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
|
||||
newState.Cflag &^= (CSIZE | PARENB)
|
||||
newState.Cflag |= CS8
|
||||
newState.Cc[syscall.VMIN] = 1
|
||||
newState.Cc[syscall.VTIME] = 0
|
||||
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &oldState, nil
|
||||
}
|
65
Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_freebsd.go
generated
vendored
Normal file
65
Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_freebsd.go
generated
vendored
Normal file
|
@ -0,0 +1,65 @@
|
|||
package term
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
getTermios = syscall.TIOCGETA
|
||||
setTermios = syscall.TIOCSETA
|
||||
|
||||
IGNBRK = syscall.IGNBRK
|
||||
PARMRK = syscall.PARMRK
|
||||
INLCR = syscall.INLCR
|
||||
IGNCR = syscall.IGNCR
|
||||
ECHONL = syscall.ECHONL
|
||||
CSIZE = syscall.CSIZE
|
||||
ICRNL = syscall.ICRNL
|
||||
ISTRIP = syscall.ISTRIP
|
||||
PARENB = syscall.PARENB
|
||||
ECHO = syscall.ECHO
|
||||
ICANON = syscall.ICANON
|
||||
ISIG = syscall.ISIG
|
||||
IXON = syscall.IXON
|
||||
BRKINT = syscall.BRKINT
|
||||
INPCK = syscall.INPCK
|
||||
OPOST = syscall.OPOST
|
||||
CS8 = syscall.CS8
|
||||
IEXTEN = syscall.IEXTEN
|
||||
)
|
||||
|
||||
type Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]byte
|
||||
Ispeed uint32
|
||||
Ospeed uint32
|
||||
}
|
||||
|
||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
func MakeRaw(fd uintptr) (*State, error) {
|
||||
var oldState State
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(getTermios), uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newState := oldState.termios
|
||||
newState.Iflag &^= (IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IXON)
|
||||
newState.Oflag &^= OPOST
|
||||
newState.Lflag &^= (ECHO | ECHONL | ICANON | ISIG | IEXTEN)
|
||||
newState.Cflag &^= (CSIZE | PARENB)
|
||||
newState.Cflag |= CS8
|
||||
newState.Cc[syscall.VMIN] = 1
|
||||
newState.Cc[syscall.VTIME] = 0
|
||||
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, uintptr(setTermios), uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &oldState, nil
|
||||
}
|
44
Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_linux.go
generated
vendored
Normal file
44
Godeps/_workspace/src/github.com/docker/docker/pkg/term/termios_linux.go
generated
vendored
Normal file
|
@ -0,0 +1,44 @@
|
|||
package term
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
getTermios = syscall.TCGETS
|
||||
setTermios = syscall.TCSETS
|
||||
)
|
||||
|
||||
type Termios struct {
|
||||
Iflag uint32
|
||||
Oflag uint32
|
||||
Cflag uint32
|
||||
Lflag uint32
|
||||
Cc [20]byte
|
||||
Ispeed uint32
|
||||
Ospeed uint32
|
||||
}
|
||||
|
||||
// MakeRaw put the terminal connected to the given file descriptor into raw
|
||||
// mode and returns the previous state of the terminal so that it can be
|
||||
// restored.
|
||||
func MakeRaw(fd uintptr) (*State, error) {
|
||||
var oldState State
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, getTermios, uintptr(unsafe.Pointer(&oldState.termios))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
newState := oldState.termios
|
||||
|
||||
newState.Iflag &^= (syscall.IGNBRK | syscall.BRKINT | syscall.PARMRK | syscall.ISTRIP | syscall.INLCR | syscall.IGNCR | syscall.ICRNL | syscall.IXON)
|
||||
newState.Oflag &^= syscall.OPOST
|
||||
newState.Lflag &^= (syscall.ECHO | syscall.ECHONL | syscall.ICANON | syscall.ISIG | syscall.IEXTEN)
|
||||
newState.Cflag &^= (syscall.CSIZE | syscall.PARENB)
|
||||
newState.Cflag |= syscall.CS8
|
||||
|
||||
if _, _, err := syscall.Syscall(syscall.SYS_IOCTL, fd, setTermios, uintptr(unsafe.Pointer(&newState))); err != 0 {
|
||||
return nil, err
|
||||
}
|
||||
return &oldState, nil
|
||||
}
|
1
Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/MAINTAINERS
generated
vendored
Normal file
1
Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/MAINTAINERS
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
Cristian Staretu <cristian.staretu@gmail.com> (@unclejack)
|
23
Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/json.go
generated
vendored
Normal file
23
Godeps/_workspace/src/github.com/docker/docker/pkg/timeutils/json.go
generated
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
package timeutils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
// Define our own version of RFC339Nano because we want one
|
||||
// that pads the nano seconds part with zeros to ensure
|
||||
// the timestamps are aligned in the logs.
|
||||
RFC3339NanoFixed = "2006-01-02T15:04:05.000000000Z07:00"
|
||||
JSONFormat = `"` + time.RFC3339Nano + `"`
|
||||
)
|
||||
|
||||
func FastMarshalJSON(t time.Time) (string, error) {
|
||||
if y := t.Year(); y < 0 || y >= 10000 {
|
||||
// RFC 3339 is clear that years are 4 digits exactly.
|
||||
// See golang.org/issue/4556#c15 for more discussion.
|
||||
return "", errors.New("Time.MarshalJSON: year outside of range [0,9999]")
|
||||
}
|
||||
return t.Format(JSONFormat), nil
|
||||
}
|
2
Godeps/_workspace/src/github.com/docker/docker/pkg/units/MAINTAINERS
generated
vendored
Normal file
2
Godeps/_workspace/src/github.com/docker/docker/pkg/units/MAINTAINERS
generated
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
Michael Crosby <michael@crosbymichael.com> (@crosbymichael)
|
||||
Victor Vieux <vieux@docker.com> (@vieux)
|
31
Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration.go
generated
vendored
Normal file
31
Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration.go
generated
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
package units
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
|
||||
// HumanDuration returns a human-readable approximation of a duration
|
||||
// (eg. "About a minute", "4 hours ago", etc.)
|
||||
func HumanDuration(d time.Duration) string {
|
||||
if seconds := int(d.Seconds()); seconds < 1 {
|
||||
return "Less than a second"
|
||||
} else if seconds < 60 {
|
||||
return fmt.Sprintf("%d seconds", seconds)
|
||||
} else if minutes := int(d.Minutes()); minutes == 1 {
|
||||
return "About a minute"
|
||||
} else if minutes < 60 {
|
||||
return fmt.Sprintf("%d minutes", minutes)
|
||||
} else if hours := int(d.Hours()); hours == 1 {
|
||||
return "About an hour"
|
||||
} else if hours < 48 {
|
||||
return fmt.Sprintf("%d hours", hours)
|
||||
} else if hours < 24*7*2 {
|
||||
return fmt.Sprintf("%d days", hours/24)
|
||||
} else if hours < 24*30*3 {
|
||||
return fmt.Sprintf("%d weeks", hours/24/7)
|
||||
} else if hours < 24*365*2 {
|
||||
return fmt.Sprintf("%d months", hours/24/30)
|
||||
}
|
||||
return fmt.Sprintf("%f years", d.Hours()/24/365)
|
||||
}
|
46
Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration_test.go
generated
vendored
Normal file
46
Godeps/_workspace/src/github.com/docker/docker/pkg/units/duration_test.go
generated
vendored
Normal file
|
@ -0,0 +1,46 @@
|
|||
package units
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestHumanDuration(t *testing.T) {
|
||||
// Useful duration abstractions
|
||||
day := 24 * time.Hour
|
||||
week := 7 * day
|
||||
month := 30 * day
|
||||
year := 365 * day
|
||||
|
||||
assertEquals(t, "Less than a second", HumanDuration(450*time.Millisecond))
|
||||
assertEquals(t, "47 seconds", HumanDuration(47*time.Second))
|
||||
assertEquals(t, "About a minute", HumanDuration(1*time.Minute))
|
||||
assertEquals(t, "3 minutes", HumanDuration(3*time.Minute))
|
||||
assertEquals(t, "35 minutes", HumanDuration(35*time.Minute))
|
||||
assertEquals(t, "35 minutes", HumanDuration(35*time.Minute+40*time.Second))
|
||||
assertEquals(t, "About an hour", HumanDuration(1*time.Hour))
|
||||
assertEquals(t, "About an hour", HumanDuration(1*time.Hour+45*time.Minute))
|
||||
assertEquals(t, "3 hours", HumanDuration(3*time.Hour))
|
||||
assertEquals(t, "3 hours", HumanDuration(3*time.Hour+59*time.Minute))
|
||||
assertEquals(t, "4 hours", HumanDuration(3*time.Hour+60*time.Minute))
|
||||
assertEquals(t, "24 hours", HumanDuration(24*time.Hour))
|
||||
assertEquals(t, "36 hours", HumanDuration(1*day+12*time.Hour))
|
||||
assertEquals(t, "2 days", HumanDuration(2*day))
|
||||
assertEquals(t, "7 days", HumanDuration(7*day))
|
||||
assertEquals(t, "13 days", HumanDuration(13*day+5*time.Hour))
|
||||
assertEquals(t, "2 weeks", HumanDuration(2*week))
|
||||
assertEquals(t, "2 weeks", HumanDuration(2*week+4*day))
|
||||
assertEquals(t, "3 weeks", HumanDuration(3*week))
|
||||
assertEquals(t, "4 weeks", HumanDuration(4*week))
|
||||
assertEquals(t, "4 weeks", HumanDuration(4*week+3*day))
|
||||
assertEquals(t, "4 weeks", HumanDuration(1*month))
|
||||
assertEquals(t, "6 weeks", HumanDuration(1*month+2*week))
|
||||
assertEquals(t, "8 weeks", HumanDuration(2*month))
|
||||
assertEquals(t, "3 months", HumanDuration(3*month+1*week))
|
||||
assertEquals(t, "5 months", HumanDuration(5*month+2*week))
|
||||
assertEquals(t, "13 months", HumanDuration(13*month))
|
||||
assertEquals(t, "23 months", HumanDuration(23*month))
|
||||
assertEquals(t, "24 months", HumanDuration(24*month))
|
||||
assertEquals(t, "2.010959 years", HumanDuration(24*month+2*week))
|
||||
assertEquals(t, "3.164384 years", HumanDuration(3*year+2*month))
|
||||
}
|
81
Godeps/_workspace/src/github.com/docker/docker/pkg/units/size.go
generated
vendored
Normal file
81
Godeps/_workspace/src/github.com/docker/docker/pkg/units/size.go
generated
vendored
Normal file
|
@ -0,0 +1,81 @@
|
|||
package units
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// See: http://en.wikipedia.org/wiki/Binary_prefix
|
||||
const (
|
||||
// Decimal
|
||||
KB = 1000
|
||||
MB = 1000 * KB
|
||||
GB = 1000 * MB
|
||||
TB = 1000 * GB
|
||||
PB = 1000 * TB
|
||||
|
||||
// Binary
|
||||
KiB = 1024
|
||||
MiB = 1024 * KiB
|
||||
GiB = 1024 * MiB
|
||||
TiB = 1024 * GiB
|
||||
PiB = 1024 * TiB
|
||||
)
|
||||
|
||||
type unitMap map[string]int64
|
||||
|
||||
var (
|
||||
decimalMap = unitMap{"k": KB, "m": MB, "g": GB, "t": TB, "p": PB}
|
||||
binaryMap = unitMap{"k": KiB, "m": MiB, "g": GiB, "t": TiB, "p": PiB}
|
||||
sizeRegex = regexp.MustCompile(`^(\d+)([kKmMgGtTpP])?[bB]?$`)
|
||||
)
|
||||
|
||||
var unitAbbrs = [...]string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}
|
||||
|
||||
// HumanSize returns a human-readable approximation of a size
|
||||
// using SI standard (eg. "44kB", "17MB")
|
||||
func HumanSize(size int64) string {
|
||||
i := 0
|
||||
sizef := float64(size)
|
||||
for sizef >= 1000.0 {
|
||||
sizef = sizef / 1000.0
|
||||
i++
|
||||
}
|
||||
return fmt.Sprintf("%.4g %s", sizef, unitAbbrs[i])
|
||||
}
|
||||
|
||||
// FromHumanSize returns an integer from a human-readable specification of a
|
||||
// size using SI standard (eg. "44kB", "17MB")
|
||||
func FromHumanSize(size string) (int64, error) {
|
||||
return parseSize(size, decimalMap)
|
||||
}
|
||||
|
||||
// Parses a human-readable string representing an amount of RAM
|
||||
// in bytes, kibibytes, mebibytes, gibibytes, or tebibytes and
|
||||
// returns the number of bytes, or -1 if the string is unparseable.
|
||||
// Units are case-insensitive, and the 'b' suffix is optional.
|
||||
func RAMInBytes(size string) (int64, error) {
|
||||
return parseSize(size, binaryMap)
|
||||
}
|
||||
|
||||
// Parses the human-readable size string into the amount it represents
|
||||
func parseSize(sizeStr string, uMap unitMap) (int64, error) {
|
||||
matches := sizeRegex.FindStringSubmatch(sizeStr)
|
||||
if len(matches) != 3 {
|
||||
return -1, fmt.Errorf("Invalid size: '%s'", sizeStr)
|
||||
}
|
||||
|
||||
size, err := strconv.ParseInt(matches[1], 10, 0)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
|
||||
unitPrefix := strings.ToLower(matches[2])
|
||||
if mul, ok := uMap[unitPrefix]; ok {
|
||||
size *= mul
|
||||
}
|
||||
|
||||
return size, nil
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue