OSDN Git Service

add vendor support for make test
authorpaladz <453256728@qq.com>
Thu, 2 Nov 2017 02:54:45 +0000 (10:54 +0800)
committerpaladz <453256728@qq.com>
Thu, 2 Nov 2017 02:54:45 +0000 (10:54 +0800)
35 files changed:
node/node.go
vendor/github.com/davecgh/go-spew/.gitignore [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/.travis.yml [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/LICENSE [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/README.md [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/cov_report.sh [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/bypass.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/bypasssafe.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/common.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/common_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/config.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/doc.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/dump.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/dump_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/dumpcgo_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/dumpnocgo_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/example_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/format.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/format_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/internal_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/internalunsafe_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/spew.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/spew_test.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go [new file with mode: 0644]
vendor/github.com/davecgh/go-spew/test_coverage.txt [new file with mode: 0644]
vendor/golang.org/x/time/AUTHORS [new file with mode: 0644]
vendor/golang.org/x/time/CONTRIBUTING.md [new file with mode: 0644]
vendor/golang.org/x/time/CONTRIBUTORS [new file with mode: 0644]
vendor/golang.org/x/time/LICENSE [new file with mode: 0644]
vendor/golang.org/x/time/PATENTS [new file with mode: 0644]
vendor/golang.org/x/time/README [new file with mode: 0644]
vendor/golang.org/x/time/rate/rate.go [new file with mode: 0644]
vendor/golang.org/x/time/rate/rate_go16.go [new file with mode: 0644]
vendor/golang.org/x/time/rate/rate_go17.go [new file with mode: 0644]
vendor/golang.org/x/time/rate/rate_test.go [new file with mode: 0644]

index a40ce15..94b7baf 100644 (file)
@@ -27,12 +27,12 @@ import (
        cfg "github.com/bytom/config"
        "github.com/bytom/consensus"
        "github.com/bytom/env"
+       "github.com/bytom/errors"
        "github.com/bytom/p2p"
        "github.com/bytom/protocol"
        "github.com/bytom/protocol/bc/legacy"
        "github.com/bytom/types"
        "github.com/bytom/version"
-       "github.com/bytom/errors"
 )
 
 const (
@@ -135,7 +135,10 @@ func rpcInit(h *bc.BlockchainReactor, config *cfg.Config) {
                TLSNextProto: map[string]func(*http.Server, *tls.Conn, http.Handler){},
        }
        listenAddr := env.String("LISTEN", config.ApiAddress)
-       listener, _ := net.Listen("tcp", *listenAddr)
+       listener, err := net.Listen("tcp", *listenAddr)
+       if err != nil {
+               cmn.Exit(cmn.Fmt("Failed to register tcp port: %v", err))
+       }
 
        // The `Serve` call has to happen in its own goroutine because
        // it's blocking and we need to proceed to the rest of the core setup after
diff --git a/vendor/github.com/davecgh/go-spew/.gitignore b/vendor/github.com/davecgh/go-spew/.gitignore
new file mode 100644 (file)
index 0000000..0026861
--- /dev/null
@@ -0,0 +1,22 @@
+# Compiled Object files, Static and Dynamic libs (Shared Objects)
+*.o
+*.a
+*.so
+
+# Folders
+_obj
+_test
+
+# Architecture specific extensions/prefixes
+*.[568vq]
+[568vq].out
+
+*.cgo1.go
+*.cgo2.c
+_cgo_defun.c
+_cgo_gotypes.go
+_cgo_export.*
+
+_testmain.go
+
+*.exe
diff --git a/vendor/github.com/davecgh/go-spew/.travis.yml b/vendor/github.com/davecgh/go-spew/.travis.yml
new file mode 100644 (file)
index 0000000..1bd2340
--- /dev/null
@@ -0,0 +1,24 @@
+language: go
+go:
+    - 1.6.x
+    - 1.7.x
+    - 1.8.x
+sudo: false
+install:
+    - go get -v github.com/alecthomas/gometalinter
+    - gometalinter --install
+script:
+    - export PATH=$PATH:$HOME/gopath/bin
+    - export GORACE="halt_on_error=1"
+    - test -z "$(gometalinter --disable-all
+      --enable=gofmt
+      --enable=golint
+      --enable=vet
+      --enable=gosimple
+      --enable=unconvert
+      --deadline=4m ./spew | tee /dev/stderr)"
+    - go test -v -race -tags safe ./spew
+    - go test -v -race -tags testcgo ./spew -covermode=count -coverprofile=profile.cov
+after_success:
+    - go get -v github.com/mattn/goveralls
+    - goveralls -coverprofile=profile.cov -service=travis-ci
diff --git a/vendor/github.com/davecgh/go-spew/LICENSE b/vendor/github.com/davecgh/go-spew/LICENSE
new file mode 100644 (file)
index 0000000..bc52e96
--- /dev/null
@@ -0,0 +1,15 @@
+ISC License
+
+Copyright (c) 2012-2016 Dave Collins <dave@davec.name>
+
+Permission to use, copy, modify, and/or 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.
diff --git a/vendor/github.com/davecgh/go-spew/README.md b/vendor/github.com/davecgh/go-spew/README.md
new file mode 100644 (file)
index 0000000..f6ed02c
--- /dev/null
@@ -0,0 +1,201 @@
+go-spew
+=======
+
+[![Build Status](https://img.shields.io/travis/davecgh/go-spew.svg)](https://travis-ci.org/davecgh/go-spew)
+[![ISC License](http://img.shields.io/badge/license-ISC-blue.svg)](http://copyfree.org)
+[![Coverage Status](https://img.shields.io/coveralls/davecgh/go-spew.svg)](https://coveralls.io/r/davecgh/go-spew?branch=master)
+
+Go-spew implements a deep pretty printer for Go data structures to aid in
+debugging.  A comprehensive suite of tests with 100% test coverage is provided
+to ensure proper functionality.  See `test_coverage.txt` for the gocov coverage
+report.  Go-spew is licensed under the liberal ISC license, so it may be used in
+open source or commercial projects.
+
+If you're interested in reading about how this package came to life and some
+of the challenges involved in providing a deep pretty printer, there is a blog
+post about it
+[here](https://web.archive.org/web/20160304013555/https://blog.cyphertite.com/go-spew-a-journey-into-dumping-go-data-structures/).
+
+## Documentation
+
+[![GoDoc](https://img.shields.io/badge/godoc-reference-blue.svg)](http://godoc.org/github.com/davecgh/go-spew/spew)
+
+Full `go doc` style documentation for the project can be viewed online without
+installing this package by using the excellent GoDoc site here:
+http://godoc.org/github.com/davecgh/go-spew/spew
+
+You can also view the documentation locally once the package is installed with
+the `godoc` tool by running `godoc -http=":6060"` and pointing your browser to
+http://localhost:6060/pkg/github.com/davecgh/go-spew/spew
+
+## Installation
+
+```bash
+$ go get -u github.com/davecgh/go-spew/spew
+```
+
+## Quick Start
+
+Add this import line to the file you're working in:
+
+```Go
+import "github.com/davecgh/go-spew/spew"
+```
+
+To dump a variable with full newlines, indentation, type, and pointer
+information use Dump, Fdump, or Sdump:
+
+```Go
+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): 
+
+```Go
+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)
+```
+
+## Debugging a Web Application Example
+
+Here is an example of how you can use `spew.Sdump()` to help debug a web application. Please be sure to wrap your output using the `html.EscapeString()` function for safety reasons. You should also only use this debugging technique in a development environment, never in production.
+
+```Go
+package main
+
+import (
+    "fmt"
+    "html"
+    "net/http"
+
+    "github.com/davecgh/go-spew/spew"
+)
+
+func handler(w http.ResponseWriter, r *http.Request) {
+    w.Header().Set("Content-Type", "text/html")
+    fmt.Fprintf(w, "Hi there, %s!", r.URL.Path[1:])
+    fmt.Fprintf(w, "<!--\n" + html.EscapeString(spew.Sdump(w)) + "\n-->")
+}
+
+func main() {
+    http.HandleFunc("/", handler)
+    http.ListenAndServe(":8080", nil)
+}
+```
+
+## Sample Dump Output
+
+```
+(main.Foo) {
+ unexportedField: (*main.Bar)(0xf84002e210)({
+  flag: (main.Flag) flagTwo,
+  data: (uintptr) <nil>
+ }),
+ ExportedField: (map[interface {}]interface {}) {
+  (string) "one": (bool) true
+ }
+}
+([]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|
+}
+```
+
+## 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>}
+```
+
+## 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.
+
+```
+* 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.  This option
+       relies on access to the unsafe package, so it will not have any effect when
+       running in environments without access to the unsafe package such as Google
+       App Engine or with the "safe" build tag specified.
+       Pointer method invocation is enabled by default.
+
+* DisablePointerAddresses
+       DisablePointerAddresses specifies whether to disable the printing of
+       pointer addresses. This is useful when diffing data structures in tests.
+
+* DisableCapacities
+       DisableCapacities specifies whether to disable the printing of capacities
+       for arrays, slices, maps and channels. This is useful when diffing data
+       structures in tests.
+
+* 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)
+       and types which implement error or Stringer interfaces are supported,
+       with other types sorted according to the reflect.Value.String() output
+       which guarantees display stability.  Natural map order is used by
+       default.
+
+* SpewKeys
+       SpewKeys specifies that, as a last resort attempt, map keys should be
+       spewed to strings and sorted by those strings.  This is only considered
+       if SortKeys is true.
+
+```
+
+## Unsafe Package Dependency
+
+This package relies on the unsafe package to perform some of the more advanced
+features, however it also supports a "limited" mode which allows it to work in
+environments where the unsafe package is not available.  By default, it will
+operate in this mode on Google App Engine and when compiled with GopherJS.  The
+"safe" build tag may also be specified to force the package to build without
+using the unsafe package.
+
+## License
+
+Go-spew is licensed under the [copyfree](http://copyfree.org) ISC License.
diff --git a/vendor/github.com/davecgh/go-spew/cov_report.sh b/vendor/github.com/davecgh/go-spew/cov_report.sh
new file mode 100644 (file)
index 0000000..9579497
--- /dev/null
@@ -0,0 +1,22 @@
+#!/bin/sh
+
+# This script uses gocov to generate a test coverage report.
+# The gocov tool my be obtained with the following command:
+#   go get github.com/axw/gocov/gocov
+#
+# It will be installed to $GOPATH/bin, so ensure that location is in your $PATH.
+
+# Check for gocov.
+if ! type gocov >/dev/null 2>&1; then
+       echo >&2 "This script requires the gocov tool."
+       echo >&2 "You may obtain it with the following command:"
+       echo >&2 "go get github.com/axw/gocov/gocov"
+       exit 1
+fi
+
+# Only run the cgo tests if gcc is installed.
+if type gcc >/dev/null 2>&1; then
+       (cd spew && gocov test -tags testcgo | gocov report)
+else
+       (cd spew && gocov test | gocov report)
+fi
diff --git a/vendor/github.com/davecgh/go-spew/spew/bypass.go b/vendor/github.com/davecgh/go-spew/spew/bypass.go
new file mode 100644 (file)
index 0000000..7f166c3
--- /dev/null
@@ -0,0 +1,152 @@
+// Copyright (c) 2015-2016 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 the code is not running on Google App Engine, compiled by GopherJS, and
+// "-tags safe" is not added to the go build command line.  The "disableunsafe"
+// tag is deprecated and thus should not be used.
+// +build !js,!appengine,!safe,!disableunsafe
+
+package spew
+
+import (
+       "reflect"
+       "unsafe"
+)
+
+const (
+       // UnsafeDisabled is a build-time constant which specifies whether or
+       // not access to the unsafe package is available.
+       UnsafeDisabled = false
+
+       // ptrSize is the size of a pointer on the current arch.
+       ptrSize = unsafe.Sizeof((*byte)(nil))
+)
+
+var (
+       // offsetPtr, offsetScalar, and offsetFlag are the offsets for the
+       // internal reflect.Value fields.  These values are valid before golang
+       // commit ecccf07e7f9d which changed the format.  The are also valid
+       // after commit 82f48826c6c7 which changed the format again to mirror
+       // the original format.  Code in the init function updates these offsets
+       // as necessary.
+       offsetPtr    = ptrSize
+       offsetScalar = uintptr(0)
+       offsetFlag   = ptrSize * 2
+
+       // flagKindWidth and flagKindShift indicate various bits that the
+       // reflect package uses internally to track kind information.
+       //
+       // flagRO indicates whether or not the value field of a reflect.Value is
+       // read-only.
+       //
+       // flagIndir indicates whether the value field of a reflect.Value is
+       // the actual data or a pointer to the data.
+       //
+       // These values are valid before golang commit 90a7c3c86944 which
+       // changed their positions.  Code in the init function updates these
+       // flags as necessary.
+       flagKindWidth = uintptr(5)
+       flagKindShift = flagKindWidth - 1
+       flagRO        = uintptr(1 << 0)
+       flagIndir     = uintptr(1 << 1)
+)
+
+func init() {
+       // Older versions of reflect.Value stored small integers directly in the
+       // ptr field (which is named val in the older versions).  Versions
+       // between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
+       // scalar for this purpose which unfortunately came before the flag
+       // field, so the offset of the flag field is different for those
+       // versions.
+       //
+       // This code constructs a new reflect.Value from a known small integer
+       // and checks if the size of the reflect.Value struct indicates it has
+       // the scalar field. When it does, the offsets are updated accordingly.
+       vv := reflect.ValueOf(0xf00)
+       if unsafe.Sizeof(vv) == (ptrSize * 4) {
+               offsetScalar = ptrSize * 2
+               offsetFlag = ptrSize * 3
+       }
+
+       // Commit 90a7c3c86944 changed the flag positions such that the low
+       // order bits are the kind.  This code extracts the kind from the flags
+       // field and ensures it's the correct type.  When it's not, the flag
+       // order has been changed to the newer format, so the flags are updated
+       // accordingly.
+       upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
+       upfv := *(*uintptr)(upf)
+       flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
+       if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
+               flagKindShift = 0
+               flagRO = 1 << 5
+               flagIndir = 1 << 6
+
+               // Commit adf9b30e5594 modified the flags to separate the
+               // flagRO flag into two bits which specifies whether or not the
+               // field is embedded.  This causes flagIndir to move over a bit
+               // and means that flagRO is the combination of either of the
+               // original flagRO bit and the new bit.
+               //
+               // This code detects the change by extracting what used to be
+               // the indirect bit to ensure it's set.  When it's not, the flag
+               // order has been changed to the newer format, so the flags are
+               // updated accordingly.
+               if upfv&flagIndir == 0 {
+                       flagRO = 3 << 5
+                       flagIndir = 1 << 7
+               }
+       }
+}
+
+// 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 {
+               // The value is in the scalar field when it's not one of the
+               // reference types.
+               switch vt.Kind() {
+               case reflect.Uintptr:
+               case reflect.Chan:
+               case reflect.Func:
+               case reflect.Map:
+               case reflect.Ptr:
+               case reflect.UnsafePointer:
+               default:
+                       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
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go b/vendor/github.com/davecgh/go-spew/spew/bypasssafe.go
new file mode 100644 (file)
index 0000000..1fe3cf3
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (c) 2015-2016 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 the code is running on Google App Engine, compiled by GopherJS, or
+// "-tags safe" is added to the go build command line.  The "disableunsafe"
+// tag is deprecated and thus should not be used.
+// +build js appengine safe disableunsafe
+
+package spew
+
+import "reflect"
+
+const (
+       // UnsafeDisabled is a build-time constant which specifies whether or
+       // not access to the unsafe package is available.
+       UnsafeDisabled = true
+)
+
+// unsafeReflectValue typically converts the passed reflect.Value into a one
+// that bypasses the typical safety restrictions preventing access to
+// unaddressable and unexported data.  However, doing this relies on access to
+// the unsafe package.  This is a stub version which simply returns the passed
+// reflect.Value when the unsafe package is not available.
+func unsafeReflectValue(v reflect.Value) reflect.Value {
+       return v
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/common.go b/vendor/github.com/davecgh/go-spew/spew/common.go
new file mode 100644 (file)
index 0000000..1be8ce9
--- /dev/null
@@ -0,0 +1,341 @@
+/*
+ * Copyright (c) 2013-2016 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"
+       "reflect"
+       "sort"
+       "strconv"
+)
+
+// 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("]")
+       lenEqualsBytes        = []byte("len=")
+       capEqualsBytes        = []byte("cap=")
+)
+
+// 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, when it's available,
+       // to bypass these restrictions since this package does not mutate the
+       // values.
+       if !v.CanInterface() {
+               if UnsafeDisabled {
+                       return false
+               }
+
+               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.
+       if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
+               v = unsafeReflectValue(v)
+       }
+       if v.CanAddr() {
+               v = v.Addr()
+       }
+
+       // Is it an error or Stringer?
+       switch iface := v.Interface().(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 hexadecimal 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
+       strings []string // either nil or same len and values
+       cs      *ConfigState
+}
+
+// newValuesSorter initializes a valuesSorter instance, which holds a set of
+// surrogate keys on which the data should be sorted.  It uses flags in
+// ConfigState to decide if and how to populate those surrogate keys.
+func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
+       vs := &valuesSorter{values: values, cs: cs}
+       if canSortSimply(vs.values[0].Kind()) {
+               return vs
+       }
+       if !cs.DisableMethods {
+               vs.strings = make([]string, len(values))
+               for i := range vs.values {
+                       b := bytes.Buffer{}
+                       if !handleMethods(cs, &b, vs.values[i]) {
+                               vs.strings = nil
+                               break
+                       }
+                       vs.strings[i] = b.String()
+               }
+       }
+       if vs.strings == nil && cs.SpewKeys {
+               vs.strings = make([]string, len(values))
+               for i := range vs.values {
+                       vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
+               }
+       }
+       return vs
+}
+
+// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
+// directly, or whether it should be considered for sorting by surrogate keys
+// (if the ConfigState allows it).
+func canSortSimply(kind reflect.Kind) bool {
+       // This switch parallels valueSortLess, except for the default case.
+       switch kind {
+       case reflect.Bool:
+               return true
+       case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+               return true
+       case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+               return true
+       case reflect.Float32, reflect.Float64:
+               return true
+       case reflect.String:
+               return true
+       case reflect.Uintptr:
+               return true
+       case reflect.Array:
+               return true
+       }
+       return false
+}
+
+// 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]
+       if s.strings != nil {
+               s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
+       }
+}
+
+// valueSortLess returns whether the first value should sort before the second
+// value.  It is used by valueSorter.Less as part of the sort.Interface
+// implementation.
+func valueSortLess(a, b reflect.Value) bool {
+       switch a.Kind() {
+       case reflect.Bool:
+               return !a.Bool() && b.Bool()
+       case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+               return a.Int() < b.Int()
+       case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+               return a.Uint() < b.Uint()
+       case reflect.Float32, reflect.Float64:
+               return a.Float() < b.Float()
+       case reflect.String:
+               return a.String() < b.String()
+       case reflect.Uintptr:
+               return a.Uint() < b.Uint()
+       case reflect.Array:
+               // Compare the contents of both arrays.
+               l := a.Len()
+               for i := 0; i < l; i++ {
+                       av := a.Index(i)
+                       bv := b.Index(i)
+                       if av.Interface() == bv.Interface() {
+                               continue
+                       }
+                       return valueSortLess(av, bv)
+               }
+       }
+       return a.String() < b.String()
+}
+
+// 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 {
+       if s.strings == nil {
+               return valueSortLess(s.values[i], s.values[j])
+       }
+       return s.strings[i] < s.strings[j]
+}
+
+// sortValues is a sort function that handles both native types and any type that
+// can be converted to error or Stringer.  Other inputs are sorted according to
+// their Value.String() value to ensure display stability.
+func sortValues(values []reflect.Value, cs *ConfigState) {
+       if len(values) == 0 {
+               return
+       }
+       sort.Sort(newValuesSorter(values, cs))
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/common_test.go b/vendor/github.com/davecgh/go-spew/spew/common_test.go
new file mode 100644 (file)
index 0000000..0f5ce47
--- /dev/null
@@ -0,0 +1,298 @@
+/*
+ * Copyright (c) 2013-2016 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"
+       "reflect"
+       "testing"
+
+       "github.com/davecgh/go-spew/spew"
+)
+
+// 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
+}
+
+type sortableStruct struct {
+       x int
+}
+
+func (ss sortableStruct) String() string {
+       return fmt.Sprintf("ss.%d", ss.x)
+}
+
+type unsortableStruct struct {
+       x int
+}
+
+type sortTestCase struct {
+       input    []reflect.Value
+       expected []reflect.Value
+}
+
+func helpTestSortValues(tests []sortTestCase, cs *spew.ConfigState, t *testing.T) {
+       getInterfaces := func(values []reflect.Value) []interface{} {
+               interfaces := []interface{}{}
+               for _, v := range values {
+                       interfaces = append(interfaces, v.Interface())
+               }
+               return interfaces
+       }
+
+       for _, test := range tests {
+               spew.SortValues(test.input, cs)
+               // 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)
+               }
+       }
+}
+
+// TestSortValues ensures the sort functionality for relect.Value based sorting
+// works as intended.
+func TestSortValues(t *testing.T) {
+       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 := []sortTestCase{
+               // 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},
+               },
+               // Array
+               {
+                       []reflect.Value{v([3]int{3, 2, 1}), v([3]int{1, 3, 2}), v([3]int{1, 2, 3})},
+                       []reflect.Value{v([3]int{1, 2, 3}), v([3]int{1, 3, 2}), v([3]int{3, 2, 1})},
+               },
+               // Uintptrs.
+               {
+                       []reflect.Value{v(uintptr(2)), v(uintptr(1)), v(uintptr(3))},
+                       []reflect.Value{v(uintptr(1)), v(uintptr(2)), v(uintptr(3))},
+               },
+               // SortableStructs.
+               {
+                       // Note: not sorted - DisableMethods is set.
+                       []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
+                       []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
+               },
+               // UnsortableStructs.
+               {
+                       // Note: not sorted - SpewKeys is false.
+                       []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+                       []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+               },
+               // Invalid.
+               {
+                       []reflect.Value{embedB, embedA, embedC},
+                       []reflect.Value{embedB, embedA, embedC},
+               },
+       }
+       cs := spew.ConfigState{DisableMethods: true, SpewKeys: false}
+       helpTestSortValues(tests, &cs, t)
+}
+
+// TestSortValuesWithMethods ensures the sort functionality for relect.Value
+// based sorting works as intended when using string methods.
+func TestSortValuesWithMethods(t *testing.T) {
+       v := reflect.ValueOf
+
+       a := v("a")
+       b := v("b")
+       c := v("c")
+       tests := []sortTestCase{
+               // Ints.
+               {
+                       []reflect.Value{v(2), v(1), v(3)},
+                       []reflect.Value{v(1), v(2), v(3)},
+               },
+               // Strings.
+               {
+                       []reflect.Value{b, a, c},
+                       []reflect.Value{a, b, c},
+               },
+               // SortableStructs.
+               {
+                       []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
+                       []reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})},
+               },
+               // UnsortableStructs.
+               {
+                       // Note: not sorted - SpewKeys is false.
+                       []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+                       []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+               },
+       }
+       cs := spew.ConfigState{DisableMethods: false, SpewKeys: false}
+       helpTestSortValues(tests, &cs, t)
+}
+
+// TestSortValuesWithSpew ensures the sort functionality for relect.Value
+// based sorting works as intended when using spew to stringify keys.
+func TestSortValuesWithSpew(t *testing.T) {
+       v := reflect.ValueOf
+
+       a := v("a")
+       b := v("b")
+       c := v("c")
+       tests := []sortTestCase{
+               // Ints.
+               {
+                       []reflect.Value{v(2), v(1), v(3)},
+                       []reflect.Value{v(1), v(2), v(3)},
+               },
+               // Strings.
+               {
+                       []reflect.Value{b, a, c},
+                       []reflect.Value{a, b, c},
+               },
+               // SortableStructs.
+               {
+                       []reflect.Value{v(sortableStruct{2}), v(sortableStruct{1}), v(sortableStruct{3})},
+                       []reflect.Value{v(sortableStruct{1}), v(sortableStruct{2}), v(sortableStruct{3})},
+               },
+               // UnsortableStructs.
+               {
+                       []reflect.Value{v(unsortableStruct{2}), v(unsortableStruct{1}), v(unsortableStruct{3})},
+                       []reflect.Value{v(unsortableStruct{1}), v(unsortableStruct{2}), v(unsortableStruct{3})},
+               },
+       }
+       cs := spew.ConfigState{DisableMethods: true, SpewKeys: true}
+       helpTestSortValues(tests, &cs, t)
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/config.go b/vendor/github.com/davecgh/go-spew/spew/config.go
new file mode 100644 (file)
index 0000000..2e3d22f
--- /dev/null
@@ -0,0 +1,306 @@
+/*
+ * Copyright (c) 2013-2016 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.  As a result, this option relies on
+       // access to the unsafe package, so it will not have any effect when
+       // running in environments without access to the unsafe package such as
+       // Google App Engine or with the "safe" build tag specified.
+       DisablePointerMethods bool
+
+       // DisablePointerAddresses specifies whether to disable the printing of
+       // pointer addresses. This is useful when diffing data structures in tests.
+       DisablePointerAddresses bool
+
+       // DisableCapacities specifies whether to disable the printing of capacities
+       // for arrays, slices, maps and channels. This is useful when diffing
+       // data structures in tests.
+       DisableCapacities 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) and types
+       // that support the error or Stringer interfaces (if methods are
+       // enabled) are supported, with other types sorted according to the
+       // reflect.Value.String() output which guarantees display stability.
+       SortKeys bool
+
+       // SpewKeys specifies that, as a last resort attempt, map keys should
+       // be spewed to strings and sorted by those strings.  This is only
+       // considered if SortKeys is true.
+       SpewKeys 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: " "}
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/doc.go b/vendor/github.com/davecgh/go-spew/spew/doc.go
new file mode 100644 (file)
index 0000000..aacaac6
--- /dev/null
@@ -0,0 +1,211 @@
+/*
+ * Copyright (c) 2013-2016 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.
+
+       * DisablePointerAddresses
+               DisablePointerAddresses specifies whether to disable the printing of
+               pointer addresses. This is useful when diffing data structures in tests.
+
+       * DisableCapacities
+               DisableCapacities specifies whether to disable the printing of
+               capacities for arrays, slices, maps and channels. This is useful when
+               diffing data structures in tests.
+
+       * 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)
+               and types which implement error or Stringer interfaces are
+               supported with other types sorted according to the
+               reflect.Value.String() output which guarantees display
+               stability.  Natural map order is used by default.
+
+       * SpewKeys
+               Specifies that, as a last resort attempt, map keys should be
+               spewed to strings and sorted by those strings.  This is only
+               considered if SortKeys is true.
+
+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 {}) (len=1) {
+         (string) (len=3) "one": (bool) true
+        }
+       }
+
+Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
+command as shown.
+       ([]uint8) (len=32 cap=32) {
+        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
diff --git a/vendor/github.com/davecgh/go-spew/spew/dump.go b/vendor/github.com/davecgh/go-spew/spew/dump.go
new file mode 100644 (file)
index 0000000..f78d89f
--- /dev/null
@@ -0,0 +1,509 @@
+/*
+ * Copyright (c) 2013-2016 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 !d.cs.DisablePointerAddresses && 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:
+               d.w.Write(nilAngleBytes)
+
+       case cycleFound:
+               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
+                       // to 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, when available, to
+                       // bypass these restrictions since this package does not
+                       // mutate the values.
+                       vs := v
+                       if !vs.CanInterface() || !vs.CanAddr() {
+                               vs = unsafeReflectValue(vs)
+                       }
+                       if !UnsafeDisabled {
+                               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
+
+       // Display length and capacity if the built-in len and cap functions
+       // work with the value's kind and the len/cap itself is non-zero.
+       valueLen, valueCap := 0, 0
+       switch v.Kind() {
+       case reflect.Array, reflect.Slice, reflect.Chan:
+               valueLen, valueCap = v.Len(), v.Cap()
+       case reflect.Map, reflect.String:
+               valueLen = v.Len()
+       }
+       if valueLen != 0 || !d.cs.DisableCapacities && valueCap != 0 {
+               d.w.Write(openParenBytes)
+               if valueLen != 0 {
+                       d.w.Write(lenEqualsBytes)
+                       printInt(d.w, int64(valueLen), 10)
+               }
+               if !d.cs.DisableCapacities && valueCap != 0 {
+                       if valueLen != 0 {
+                               d.w.Write(spaceBytes)
+                       }
+                       d.w.Write(capEqualsBytes)
+                       printInt(d.w, int64(valueCap), 10)
+               }
+               d.w.Write(closeParenBytes)
+               d.w.Write(spaceBytes)
+       }
+
+       // 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:
+               // nil maps should be indicated as different than empty maps
+               if v.IsNil() {
+                       d.w.Write(nilAngleBytes)
+                       break
+               }
+
+               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, d.cs)
+                       }
+                       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...)
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/dump_test.go b/vendor/github.com/davecgh/go-spew/spew/dump_test.go
new file mode 100644 (file)
index 0000000..5aad9c7
--- /dev/null
@@ -0,0 +1,1042 @@
+/*
+ * Copyright (c) 2013-2016 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"
+       "testing"
+       "unsafe"
+
+       "github.com/davecgh/go-spew/spew"
+)
+
+// dumpTest is used to describe a test to be performed 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}
+       vLen := fmt.Sprintf("%d", len(v))
+       vCap := fmt.Sprintf("%d", cap(v))
+       nv := (*[3]int)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "int"
+       vs := "(len=" + vLen + " cap=" + vCap + ") {\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.
+       v2i0 := pstringer("1")
+       v2i1 := pstringer("2")
+       v2i2 := pstringer("3")
+       v2 := [3]pstringer{v2i0, v2i1, v2i2}
+       v2i0Len := fmt.Sprintf("%d", len(v2i0))
+       v2i1Len := fmt.Sprintf("%d", len(v2i1))
+       v2i2Len := fmt.Sprintf("%d", len(v2i2))
+       v2Len := fmt.Sprintf("%d", len(v2))
+       v2Cap := fmt.Sprintf("%d", cap(v2))
+       nv2 := (*[3]pstringer)(nil)
+       pv2 := &v2
+       v2Addr := fmt.Sprintf("%p", pv2)
+       pv2Addr := fmt.Sprintf("%p", &pv2)
+       v2t := "spew_test.pstringer"
+       v2sp := "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t +
+               ") (len=" + v2i0Len + ") stringer 1,\n (" + v2t +
+               ") (len=" + v2i1Len + ") stringer 2,\n (" + v2t +
+               ") (len=" + v2i2Len + ") " + "stringer 3\n}"
+       v2s := v2sp
+       if spew.UnsafeDisabled {
+               v2s = "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t +
+                       ") (len=" + v2i0Len + ") \"1\",\n (" + v2t + ") (len=" +
+                       v2i1Len + ") \"2\",\n (" + v2t + ") (len=" + v2i2Len +
+                       ") " + "\"3\"\n}"
+       }
+       addDumpTest(v2, "([3]"+v2t+") "+v2s+"\n")
+       addDumpTest(pv2, "(*[3]"+v2t+")("+v2Addr+")("+v2sp+")\n")
+       addDumpTest(&pv2, "(**[3]"+v2t+")("+pv2Addr+"->"+v2Addr+")("+v2sp+")\n")
+       addDumpTest(nv2, "(*[3]"+v2t+")(<nil>)\n")
+
+       // Array containing interfaces.
+       v3i0 := "one"
+       v3 := [3]interface{}{v3i0, int(2), uint(3)}
+       v3i0Len := fmt.Sprintf("%d", len(v3i0))
+       v3Len := fmt.Sprintf("%d", len(v3))
+       v3Cap := fmt.Sprintf("%d", cap(v3))
+       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 := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
+               "(len=" + v3i0Len + ") \"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,
+       }
+       v4Len := fmt.Sprintf("%d", len(v4))
+       v4Cap := fmt.Sprintf("%d", cap(v4))
+       nv4 := (*[34]byte)(nil)
+       pv4 := &v4
+       v4Addr := fmt.Sprintf("%p", pv4)
+       pv4Addr := fmt.Sprintf("%p", &pv4)
+       v4t := "[34]uint8"
+       v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
+               "{\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}
+       vLen := fmt.Sprintf("%d", len(v))
+       vCap := fmt.Sprintf("%d", cap(v))
+       nv := (*[]float32)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "float32"
+       vs := "(len=" + vLen + " cap=" + vCap + ") {\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.
+       v2i0 := pstringer("1")
+       v2i1 := pstringer("2")
+       v2i2 := pstringer("3")
+       v2 := []pstringer{v2i0, v2i1, v2i2}
+       v2i0Len := fmt.Sprintf("%d", len(v2i0))
+       v2i1Len := fmt.Sprintf("%d", len(v2i1))
+       v2i2Len := fmt.Sprintf("%d", len(v2i2))
+       v2Len := fmt.Sprintf("%d", len(v2))
+       v2Cap := fmt.Sprintf("%d", cap(v2))
+       nv2 := (*[]pstringer)(nil)
+       pv2 := &v2
+       v2Addr := fmt.Sprintf("%p", pv2)
+       pv2Addr := fmt.Sprintf("%p", &pv2)
+       v2t := "spew_test.pstringer"
+       v2s := "(len=" + v2Len + " cap=" + v2Cap + ") {\n (" + v2t + ") (len=" +
+               v2i0Len + ") stringer 1,\n (" + v2t + ") (len=" + v2i1Len +
+               ") stringer 2,\n (" + v2t + ") (len=" + v2i2Len + ") " +
+               "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.
+       v3i0 := "one"
+       v3 := []interface{}{v3i0, int(2), uint(3), nil}
+       v3i0Len := fmt.Sprintf("%d", len(v3i0))
+       v3Len := fmt.Sprintf("%d", len(v3))
+       v3Cap := fmt.Sprintf("%d", cap(v3))
+       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 := "(len=" + v3Len + " cap=" + v3Cap + ") {\n (" + v3t2 + ") " +
+               "(len=" + v3i0Len + ") \"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,
+       }
+       v4Len := fmt.Sprintf("%d", len(v4))
+       v4Cap := fmt.Sprintf("%d", cap(v4))
+       nv4 := (*[]byte)(nil)
+       pv4 := &v4
+       v4Addr := fmt.Sprintf("%p", pv4)
+       pv4Addr := fmt.Sprintf("%p", &pv4)
+       v4t := "[]uint8"
+       v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
+               "{\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"
+       vLen := fmt.Sprintf("%d", len(v))
+       nv := (*string)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "string"
+       vs := "(len=" + vLen + ") \"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.
+       k := "one"
+       kk := "two"
+       m := map[string]int{k: 1, kk: 2}
+       klen := fmt.Sprintf("%d", len(k)) // not kLen to shut golint up
+       kkLen := fmt.Sprintf("%d", len(kk))
+       mLen := fmt.Sprintf("%d", len(m))
+       nilMap := map[string]int(nil)
+       nm := (*map[string]int)(nil)
+       pm := &m
+       mAddr := fmt.Sprintf("%p", pm)
+       pmAddr := fmt.Sprintf("%p", &pm)
+       mt := "map[string]int"
+       mt1 := "string"
+       mt2 := "int"
+       ms := "(len=" + mLen + ") {\n (" + mt1 + ") (len=" + klen + ") " +
+               "\"one\": (" + mt2 + ") 1,\n (" + mt1 + ") (len=" + kkLen +
+               ") \"two\": (" + mt2 + ") 2\n}"
+       ms2 := "(len=" + mLen + ") {\n (" + mt1 + ") (len=" + kkLen + ") " +
+               "\"two\": (" + mt2 + ") 2,\n (" + mt1 + ") (len=" + klen +
+               ") \"one\": (" + mt2 + ") 1\n}"
+       addDumpTest(m, "("+mt+") "+ms+"\n", "("+mt+") "+ms2+"\n")
+       addDumpTest(pm, "(*"+mt+")("+mAddr+")("+ms+")\n",
+               "(*"+mt+")("+mAddr+")("+ms2+")\n")
+       addDumpTest(&pm, "(**"+mt+")("+pmAddr+"->"+mAddr+")("+ms+")\n",
+               "(**"+mt+")("+pmAddr+"->"+mAddr+")("+ms2+")\n")
+       addDumpTest(nm, "(*"+mt+")(<nil>)\n")
+       addDumpTest(nilMap, "("+mt+") <nil>\n")
+
+       // Map with custom formatter type on pointer receiver only keys and vals.
+       k2 := pstringer("one")
+       v2 := pstringer("1")
+       m2 := map[pstringer]pstringer{k2: v2}
+       k2Len := fmt.Sprintf("%d", len(k2))
+       v2Len := fmt.Sprintf("%d", len(v2))
+       m2Len := fmt.Sprintf("%d", len(m2))
+       nilMap2 := map[pstringer]pstringer(nil)
+       nm2 := (*map[pstringer]pstringer)(nil)
+       pm2 := &m2
+       m2Addr := fmt.Sprintf("%p", pm2)
+       pm2Addr := fmt.Sprintf("%p", &pm2)
+       m2t := "map[spew_test.pstringer]spew_test.pstringer"
+       m2t1 := "spew_test.pstringer"
+       m2t2 := "spew_test.pstringer"
+       m2s := "(len=" + m2Len + ") {\n (" + m2t1 + ") (len=" + k2Len + ") " +
+               "stringer one: (" + m2t2 + ") (len=" + v2Len + ") stringer 1\n}"
+       if spew.UnsafeDisabled {
+               m2s = "(len=" + m2Len + ") {\n (" + m2t1 + ") (len=" + k2Len +
+                       ") " + "\"one\": (" + m2t2 + ") (len=" + v2Len +
+                       ") \"1\"\n}"
+       }
+       addDumpTest(m2, "("+m2t+") "+m2s+"\n")
+       addDumpTest(pm2, "(*"+m2t+")("+m2Addr+")("+m2s+")\n")
+       addDumpTest(&pm2, "(**"+m2t+")("+pm2Addr+"->"+m2Addr+")("+m2s+")\n")
+       addDumpTest(nm2, "(*"+m2t+")(<nil>)\n")
+       addDumpTest(nilMap2, "("+m2t+") <nil>\n")
+
+       // Map with interface keys and values.
+       k3 := "one"
+       k3Len := fmt.Sprintf("%d", len(k3))
+       m3 := map[interface{}]interface{}{k3: 1}
+       m3Len := fmt.Sprintf("%d", len(m3))
+       nilMap3 := map[interface{}]interface{}(nil)
+       nm3 := (*map[interface{}]interface{})(nil)
+       pm3 := &m3
+       m3Addr := fmt.Sprintf("%p", pm3)
+       pm3Addr := fmt.Sprintf("%p", &pm3)
+       m3t := "map[interface {}]interface {}"
+       m3t1 := "string"
+       m3t2 := "int"
+       m3s := "(len=" + m3Len + ") {\n (" + m3t1 + ") (len=" + k3Len + ") " +
+               "\"one\": (" + m3t2 + ") 1\n}"
+       addDumpTest(m3, "("+m3t+") "+m3s+"\n")
+       addDumpTest(pm3, "(*"+m3t+")("+m3Addr+")("+m3s+")\n")
+       addDumpTest(&pm3, "(**"+m3t+")("+pm3Addr+"->"+m3Addr+")("+m3s+")\n")
+       addDumpTest(nm3, "(*"+m3t+")(<nil>)\n")
+       addDumpTest(nilMap3, "("+m3t+") <nil>\n")
+
+       // Map with nil interface value.
+       k4 := "nil"
+       k4Len := fmt.Sprintf("%d", len(k4))
+       m4 := map[string]interface{}{k4: nil}
+       m4Len := fmt.Sprintf("%d", len(m4))
+       nilMap4 := map[string]interface{}(nil)
+       nm4 := (*map[string]interface{})(nil)
+       pm4 := &m4
+       m4Addr := fmt.Sprintf("%p", pm4)
+       pm4Addr := fmt.Sprintf("%p", &pm4)
+       m4t := "map[string]interface {}"
+       m4t1 := "string"
+       m4t2 := "interface {}"
+       m4s := "(len=" + m4Len + ") {\n (" + m4t1 + ") (len=" + k4Len + ")" +
+               " \"nil\": (" + m4t2 + ") <nil>\n}"
+       addDumpTest(m4, "("+m4t+") "+m4s+"\n")
+       addDumpTest(pm4, "(*"+m4t+")("+m4Addr+")("+m4s+")\n")
+       addDumpTest(&pm4, "(**"+m4t+")("+pm4Addr+"->"+m4Addr+")("+m4s+")\n")
+       addDumpTest(nm4, "(*"+m4t+")(<nil>)\n")
+       addDumpTest(nilMap4, "("+m4t+") <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 + ") (len=4) stringer test,\n S: (" + v3t2 +
+               ") (len=5) stringer test2\n}"
+       v3sp := v3s
+       if spew.UnsafeDisabled {
+               v3s = "{\n s: (" + v3t2 + ") (len=4) \"test\",\n S: (" +
+                       v3t2 + ") (len=5) \"test2\"\n}"
+               v3sp = "{\n s: (" + v3t2 + ") (len=4) \"test\",\n S: (" +
+                       v3t2 + ") (len=5) stringer test2\n}"
+       }
+       addDumpTest(v3, "("+v3t+") "+v3s+"\n")
+       addDumpTest(pv3, "(*"+v3t+")("+v3Addr+")("+v3sp+")\n")
+       addDumpTest(&pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")("+v3sp+")\n")
+       addDumpTest(nv3, "(*"+v3t+")(<nil>)\n")
+
+       // Struct that contains embedded struct and field to same struct.
+       e := embed{"embedstr"}
+       eLen := fmt.Sprintf("%d", len("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 +
+               ") (len=" + eLen + ") \"embedstr\"\n }),\n e: (*" + v4t2 +
+               ")(" + eAddr + ")({\n  a: (" + v4t3 + ") (len=" + eLen + ")" +
+               " \"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) (len=3) {\n(int) 1: (string) (len=1) " +
+               "\"1\",\n(int) 2: (string) (len=1) \"2\",\n(int) 3: (string) " +
+               "(len=1) \"3\"\n" +
+               "}\n"
+       if s != expected {
+               t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
+       }
+
+       s = cfg.Sdump(map[stringer]int{"1": 1, "3": 3, "2": 2})
+       expected = "(map[spew_test.stringer]int) (len=3) {\n" +
+               "(spew_test.stringer) (len=1) stringer 1: (int) 1,\n" +
+               "(spew_test.stringer) (len=1) stringer 2: (int) 2,\n" +
+               "(spew_test.stringer) (len=1) stringer 3: (int) 3\n" +
+               "}\n"
+       if s != expected {
+               t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
+       }
+
+       s = cfg.Sdump(map[pstringer]int{pstringer("1"): 1, pstringer("3"): 3, pstringer("2"): 2})
+       expected = "(map[spew_test.pstringer]int) (len=3) {\n" +
+               "(spew_test.pstringer) (len=1) stringer 1: (int) 1,\n" +
+               "(spew_test.pstringer) (len=1) stringer 2: (int) 2,\n" +
+               "(spew_test.pstringer) (len=1) stringer 3: (int) 3\n" +
+               "}\n"
+       if spew.UnsafeDisabled {
+               expected = "(map[spew_test.pstringer]int) (len=3) {\n" +
+                       "(spew_test.pstringer) (len=1) \"1\": (int) 1,\n" +
+                       "(spew_test.pstringer) (len=1) \"2\": (int) 2,\n" +
+                       "(spew_test.pstringer) (len=1) \"3\": (int) 3\n" +
+                       "}\n"
+       }
+       if s != expected {
+               t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
+       }
+
+       s = cfg.Sdump(map[customError]int{customError(1): 1, customError(3): 3, customError(2): 2})
+       expected = "(map[spew_test.customError]int) (len=3) {\n" +
+               "(spew_test.customError) error: 1: (int) 1,\n" +
+               "(spew_test.customError) error: 2: (int) 2,\n" +
+               "(spew_test.customError) error: 3: (int) 3\n" +
+               "}\n"
+       if s != expected {
+               t.Errorf("Sorted keys mismatch:\n  %v %v", s, expected)
+       }
+
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/dumpcgo_test.go b/vendor/github.com/davecgh/go-spew/spew/dumpcgo_test.go
new file mode 100644 (file)
index 0000000..6ab1808
--- /dev/null
@@ -0,0 +1,99 @@
+// Copyright (c) 2013-2016 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, v2l, v2c := testdata.GetCgoCharArray()
+       v2Len := fmt.Sprintf("%d", v2l)
+       v2Cap := fmt.Sprintf("%d", v2c)
+       v2t := "[6]testdata._Ctype_char"
+       v2s := "(len=" + v2Len + " cap=" + v2Cap + ") " +
+               "{\n 00000000  74 65 73 74 32 00                               " +
+               "  |test2.|\n}"
+       addDumpTest(v2, "("+v2t+") "+v2s+"\n")
+
+       // C unsigned char array.
+       v3, v3l, v3c := testdata.GetCgoUnsignedCharArray()
+       v3Len := fmt.Sprintf("%d", v3l)
+       v3Cap := fmt.Sprintf("%d", v3c)
+       v3t := "[6]testdata._Ctype_unsignedchar"
+       v3t2 := "[6]testdata._Ctype_uchar"
+       v3s := "(len=" + v3Len + " cap=" + v3Cap + ") " +
+               "{\n 00000000  74 65 73 74 33 00                               " +
+               "  |test3.|\n}"
+       addDumpTest(v3, "("+v3t+") "+v3s+"\n", "("+v3t2+") "+v3s+"\n")
+
+       // C signed char array.
+       v4, v4l, v4c := testdata.GetCgoSignedCharArray()
+       v4Len := fmt.Sprintf("%d", v4l)
+       v4Cap := fmt.Sprintf("%d", v4c)
+       v4t := "[6]testdata._Ctype_schar"
+       v4t2 := "testdata._Ctype_schar"
+       v4s := "(len=" + v4Len + " cap=" + v4Cap + ") " +
+               "{\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, v5l, v5c := testdata.GetCgoUint8tArray()
+       v5Len := fmt.Sprintf("%d", v5l)
+       v5Cap := fmt.Sprintf("%d", v5c)
+       v5t := "[6]testdata._Ctype_uint8_t"
+       v5s := "(len=" + v5Len + " cap=" + v5Cap + ") " +
+               "{\n 00000000  74 65 73 74 35 00                               " +
+               "  |test5.|\n}"
+       addDumpTest(v5, "("+v5t+") "+v5s+"\n")
+
+       // C typedefed unsigned char array.
+       v6, v6l, v6c := testdata.GetCgoTypdefedUnsignedCharArray()
+       v6Len := fmt.Sprintf("%d", v6l)
+       v6Cap := fmt.Sprintf("%d", v6c)
+       v6t := "[6]testdata._Ctype_custom_uchar_t"
+       v6s := "(len=" + v6Len + " cap=" + v6Cap + ") " +
+               "{\n 00000000  74 65 73 74 36 00                               " +
+               "  |test6.|\n}"
+       addDumpTest(v6, "("+v6t+") "+v6s+"\n")
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/dumpnocgo_test.go b/vendor/github.com/davecgh/go-spew/spew/dumpnocgo_test.go
new file mode 100644 (file)
index 0000000..52a0971
--- /dev/null
@@ -0,0 +1,26 @@
+// 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.
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/example_test.go b/vendor/github.com/davecgh/go-spew/spew/example_test.go
new file mode 100644 (file)
index 0000000..c6ec8c6
--- /dev/null
@@ -0,0 +1,226 @@
+/*
+ * Copyright (c) 2013-2016 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 {
+       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 {
+                       data uintptr
+               }
+
+               type Foo struct {
+                       unexportedField Bar
+                       ExportedField   map[interface{}]interface{}
+               }
+       */
+
+       // Setup some sample data structures for the example.
+       bar := Bar{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) {
+       //   data: (uintptr) <nil>
+       //  },
+       //  ExportedField: (map[interface {}]interface {}) (len=1) {
+       //   (string) (len=3) "one": (bool) true
+       //  }
+       // }
+       // (spew_test.Flag) Unknown flag (5)
+       // ([]uint8) (len=34 cap=34) {
+       //  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) (len=1) {
+       //      (string) (len=3) "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{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) {
+       //              data: (uintptr) <nil>
+       //      },
+       //      ExportedField: (map[interface {}]interface {}) (len=1) {
+       //              (string) (len=3) "one": (bool) true
+       //      }
+       // }
+       // (spew_test.Foo) {
+       //  unexportedField: (spew_test.Bar) {
+       //   data: (uintptr) <nil>
+       //  },
+       //  ExportedField: (map[interface {}]interface {}) (len=1) {
+       //   (string) (len=3) "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
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/davecgh/go-spew/spew/format.go
new file mode 100644 (file)
index 0000000..b04edb7
--- /dev/null
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2013-2016 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:
+               f.fs.Write(nilAngleBytes)
+
+       case cycleFound:
+               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:
+               // nil maps should be indicated as different than empty maps
+               if v.IsNil() {
+                       f.fs.Write(nilAngleBytes)
+                       break
+               }
+
+               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, f.cs)
+                       }
+                       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)
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/format_test.go b/vendor/github.com/davecgh/go-spew/spew/format_test.go
new file mode 100644 (file)
index 0000000..0719eb9
--- /dev/null
@@ -0,0 +1,1558 @@
+/*
+ * Copyright (c) 2013-2016 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
+- Slice containing standard float32 values
+- Slice containing type with custom formatter on pointer receiver only
+- Slice containing interfaces
+- 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
+- Type that has a custom Error interface
+- %x passthrough with uint
+- %#x passthrough with uint
+- %f passthrough with precision
+- %f passthrough with width and precision
+- %d passthrough with width
+- %q passthrough with string
+*/
+
+package spew_test
+
+import (
+       "bytes"
+       "fmt"
+       "testing"
+       "unsafe"
+
+       "github.com/davecgh/go-spew/spew"
+)
+
+// formatterTest is used to describe a test to be performed against NewFormatter.
+type formatterTest struct {
+       format string
+       in     interface{}
+       wants  []string
+}
+
+// formatterTests houses all of the tests to be performed against NewFormatter.
+var formatterTests = make([]formatterTest, 0)
+
+// addFormatterTest is a helper method to append the passed input and desired
+// result to formatterTests.
+func addFormatterTest(format string, in interface{}, wants ...string) {
+       test := formatterTest{format, in, wants}
+       formatterTests = append(formatterTests, test)
+}
+
+func addIntFormatterTests() {
+       // Max int8.
+       v := int8(127)
+       nv := (*int8)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "int8"
+       vs := "127"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // Max int16.
+       v2 := int16(32767)
+       nv2 := (*int16)(nil)
+       pv2 := &v2
+       v2Addr := fmt.Sprintf("%p", pv2)
+       pv2Addr := fmt.Sprintf("%p", &pv2)
+       v2t := "int16"
+       v2s := "32767"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+       // Max int32.
+       v3 := int32(2147483647)
+       nv3 := (*int32)(nil)
+       pv3 := &v3
+       v3Addr := fmt.Sprintf("%p", pv3)
+       pv3Addr := fmt.Sprintf("%p", &pv3)
+       v3t := "int32"
+       v3s := "2147483647"
+       addFormatterTest("%v", v3, v3s)
+       addFormatterTest("%v", pv3, "<*>"+v3s)
+       addFormatterTest("%v", &pv3, "<**>"+v3s)
+       addFormatterTest("%v", nv3, "<nil>")
+       addFormatterTest("%+v", v3, v3s)
+       addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+       addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%#v", v3, "("+v3t+")"+v3s)
+       addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s)
+       addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+       addFormatterTest("%#+v", v3, "("+v3t+")"+v3s)
+       addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s)
+       addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+
+       // Max int64.
+       v4 := int64(9223372036854775807)
+       nv4 := (*int64)(nil)
+       pv4 := &v4
+       v4Addr := fmt.Sprintf("%p", pv4)
+       pv4Addr := fmt.Sprintf("%p", &pv4)
+       v4t := "int64"
+       v4s := "9223372036854775807"
+       addFormatterTest("%v", v4, v4s)
+       addFormatterTest("%v", pv4, "<*>"+v4s)
+       addFormatterTest("%v", &pv4, "<**>"+v4s)
+       addFormatterTest("%v", nv4, "<nil>")
+       addFormatterTest("%+v", v4, v4s)
+       addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
+       addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
+       addFormatterTest("%+v", nv4, "<nil>")
+       addFormatterTest("%#v", v4, "("+v4t+")"+v4s)
+       addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s)
+       addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s)
+       addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+       addFormatterTest("%#+v", v4, "("+v4t+")"+v4s)
+       addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s)
+       addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s)
+       addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+
+       // Max int.
+       v5 := int(2147483647)
+       nv5 := (*int)(nil)
+       pv5 := &v5
+       v5Addr := fmt.Sprintf("%p", pv5)
+       pv5Addr := fmt.Sprintf("%p", &pv5)
+       v5t := "int"
+       v5s := "2147483647"
+       addFormatterTest("%v", v5, v5s)
+       addFormatterTest("%v", pv5, "<*>"+v5s)
+       addFormatterTest("%v", &pv5, "<**>"+v5s)
+       addFormatterTest("%v", nv5, "<nil>")
+       addFormatterTest("%+v", v5, v5s)
+       addFormatterTest("%+v", pv5, "<*>("+v5Addr+")"+v5s)
+       addFormatterTest("%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s)
+       addFormatterTest("%+v", nv5, "<nil>")
+       addFormatterTest("%#v", v5, "("+v5t+")"+v5s)
+       addFormatterTest("%#v", pv5, "(*"+v5t+")"+v5s)
+       addFormatterTest("%#v", &pv5, "(**"+v5t+")"+v5s)
+       addFormatterTest("%#v", nv5, "(*"+v5t+")"+"<nil>")
+       addFormatterTest("%#+v", v5, "("+v5t+")"+v5s)
+       addFormatterTest("%#+v", pv5, "(*"+v5t+")("+v5Addr+")"+v5s)
+       addFormatterTest("%#+v", &pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")"+v5s)
+       addFormatterTest("%#+v", nv5, "(*"+v5t+")"+"<nil>")
+}
+
+func addUintFormatterTests() {
+       // Max uint8.
+       v := uint8(255)
+       nv := (*uint8)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "uint8"
+       vs := "255"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // Max uint16.
+       v2 := uint16(65535)
+       nv2 := (*uint16)(nil)
+       pv2 := &v2
+       v2Addr := fmt.Sprintf("%p", pv2)
+       pv2Addr := fmt.Sprintf("%p", &pv2)
+       v2t := "uint16"
+       v2s := "65535"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+       // Max uint32.
+       v3 := uint32(4294967295)
+       nv3 := (*uint32)(nil)
+       pv3 := &v3
+       v3Addr := fmt.Sprintf("%p", pv3)
+       pv3Addr := fmt.Sprintf("%p", &pv3)
+       v3t := "uint32"
+       v3s := "4294967295"
+       addFormatterTest("%v", v3, v3s)
+       addFormatterTest("%v", pv3, "<*>"+v3s)
+       addFormatterTest("%v", &pv3, "<**>"+v3s)
+       addFormatterTest("%v", nv3, "<nil>")
+       addFormatterTest("%+v", v3, v3s)
+       addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+       addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%#v", v3, "("+v3t+")"+v3s)
+       addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s)
+       addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+       addFormatterTest("%#+v", v3, "("+v3t+")"+v3s)
+       addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s)
+       addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+
+       // Max uint64.
+       v4 := uint64(18446744073709551615)
+       nv4 := (*uint64)(nil)
+       pv4 := &v4
+       v4Addr := fmt.Sprintf("%p", pv4)
+       pv4Addr := fmt.Sprintf("%p", &pv4)
+       v4t := "uint64"
+       v4s := "18446744073709551615"
+       addFormatterTest("%v", v4, v4s)
+       addFormatterTest("%v", pv4, "<*>"+v4s)
+       addFormatterTest("%v", &pv4, "<**>"+v4s)
+       addFormatterTest("%v", nv4, "<nil>")
+       addFormatterTest("%+v", v4, v4s)
+       addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
+       addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
+       addFormatterTest("%+v", nv4, "<nil>")
+       addFormatterTest("%#v", v4, "("+v4t+")"+v4s)
+       addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s)
+       addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s)
+       addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+       addFormatterTest("%#+v", v4, "("+v4t+")"+v4s)
+       addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s)
+       addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s)
+       addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+
+       // Max uint.
+       v5 := uint(4294967295)
+       nv5 := (*uint)(nil)
+       pv5 := &v5
+       v5Addr := fmt.Sprintf("%p", pv5)
+       pv5Addr := fmt.Sprintf("%p", &pv5)
+       v5t := "uint"
+       v5s := "4294967295"
+       addFormatterTest("%v", v5, v5s)
+       addFormatterTest("%v", pv5, "<*>"+v5s)
+       addFormatterTest("%v", &pv5, "<**>"+v5s)
+       addFormatterTest("%v", nv5, "<nil>")
+       addFormatterTest("%+v", v5, v5s)
+       addFormatterTest("%+v", pv5, "<*>("+v5Addr+")"+v5s)
+       addFormatterTest("%+v", &pv5, "<**>("+pv5Addr+"->"+v5Addr+")"+v5s)
+       addFormatterTest("%+v", nv5, "<nil>")
+       addFormatterTest("%#v", v5, "("+v5t+")"+v5s)
+       addFormatterTest("%#v", pv5, "(*"+v5t+")"+v5s)
+       addFormatterTest("%#v", &pv5, "(**"+v5t+")"+v5s)
+       addFormatterTest("%#v", nv5, "(*"+v5t+")"+"<nil>")
+       addFormatterTest("%#+v", v5, "("+v5t+")"+v5s)
+       addFormatterTest("%#+v", pv5, "(*"+v5t+")("+v5Addr+")"+v5s)
+       addFormatterTest("%#+v", &pv5, "(**"+v5t+")("+pv5Addr+"->"+v5Addr+")"+v5s)
+       addFormatterTest("%#v", nv5, "(*"+v5t+")"+"<nil>")
+}
+
+func addBoolFormatterTests() {
+       // Boolean true.
+       v := bool(true)
+       nv := (*bool)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "bool"
+       vs := "true"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // Boolean false.
+       v2 := bool(false)
+       pv2 := &v2
+       v2Addr := fmt.Sprintf("%p", pv2)
+       pv2Addr := fmt.Sprintf("%p", &pv2)
+       v2t := "bool"
+       v2s := "false"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addFloatFormatterTests() {
+       // 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"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // 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"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+}
+
+func addComplexFormatterTests() {
+       // 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)"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // 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)"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+}
+
+func addArrayFormatterTests() {
+       // 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 := "[3]int"
+       vs := "[1 2 3]"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // 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 := "[3]spew_test.pstringer"
+       v2sp := "[stringer 1 stringer 2 stringer 3]"
+       v2s := v2sp
+       if spew.UnsafeDisabled {
+               v2s = "[1 2 3]"
+       }
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2sp)
+       addFormatterTest("%v", &pv2, "<**>"+v2sp)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2sp)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2sp)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2sp)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2sp)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2sp)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2sp)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+       // 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 := "[one 2 3]"
+       v3s2 := "[(" + v3t2 + ")one (" + v3t3 + ")2 (" + v3t4 + ")3]"
+       addFormatterTest("%v", v3, v3s)
+       addFormatterTest("%v", pv3, "<*>"+v3s)
+       addFormatterTest("%v", &pv3, "<**>"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%+v", v3, v3s)
+       addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+       addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%#v", v3, "("+v3t+")"+v3s2)
+       addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2)
+       addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+       addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2)
+       addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2)
+       addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2)
+       addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+}
+
+func addSliceFormatterTests() {
+       // 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 := "[3.14 6.28 12.56]"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // 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 := "[stringer 1 stringer 2 stringer 3]"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+       // 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 := "[one 2 3 <nil>]"
+       v3s2 := "[(" + v3t2 + ")one (" + v3t3 + ")2 (" + v3t4 + ")3 (" + v3t5 +
+               ")<nil>]"
+       addFormatterTest("%v", v3, v3s)
+       addFormatterTest("%v", pv3, "<*>"+v3s)
+       addFormatterTest("%v", &pv3, "<**>"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%+v", v3, v3s)
+       addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+       addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%#v", v3, "("+v3t+")"+v3s2)
+       addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2)
+       addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+       addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2)
+       addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2)
+       addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2)
+       addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+
+       // Nil slice.
+       var v4 []int
+       nv4 := (*[]int)(nil)
+       pv4 := &v4
+       v4Addr := fmt.Sprintf("%p", pv4)
+       pv4Addr := fmt.Sprintf("%p", &pv4)
+       v4t := "[]int"
+       v4s := "<nil>"
+       addFormatterTest("%v", v4, v4s)
+       addFormatterTest("%v", pv4, "<*>"+v4s)
+       addFormatterTest("%v", &pv4, "<**>"+v4s)
+       addFormatterTest("%+v", nv4, "<nil>")
+       addFormatterTest("%+v", v4, v4s)
+       addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
+       addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
+       addFormatterTest("%+v", nv4, "<nil>")
+       addFormatterTest("%#v", v4, "("+v4t+")"+v4s)
+       addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s)
+       addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s)
+       addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+       addFormatterTest("%#+v", v4, "("+v4t+")"+v4s)
+       addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s)
+       addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s)
+       addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+}
+
+func addStringFormatterTests() {
+       // Standard string.
+       v := "test"
+       nv := (*string)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "string"
+       vs := "test"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+}
+
+func addInterfaceFormatterTests() {
+       // Nil interface.
+       var v interface{}
+       nv := (*interface{})(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "interface {}"
+       vs := "<nil>"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // Sub-interface.
+       v2 := interface{}(uint16(65535))
+       pv2 := &v2
+       v2Addr := fmt.Sprintf("%p", pv2)
+       pv2Addr := fmt.Sprintf("%p", &pv2)
+       v2t := "uint16"
+       v2s := "65535"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addMapFormatterTests() {
+       // Map with string keys and int vals.
+       v := map[string]int{"one": 1, "two": 2}
+       nilMap := map[string]int(nil)
+       nv := (*map[string]int)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "map[string]int"
+       vs := "map[one:1 two:2]"
+       vs2 := "map[two:2 one:1]"
+       addFormatterTest("%v", v, vs, vs2)
+       addFormatterTest("%v", pv, "<*>"+vs, "<*>"+vs2)
+       addFormatterTest("%v", &pv, "<**>"+vs, "<**>"+vs2)
+       addFormatterTest("%+v", nilMap, "<nil>")
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs, vs2)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs, "<*>("+vAddr+")"+vs2)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs,
+               "<**>("+pvAddr+"->"+vAddr+")"+vs2)
+       addFormatterTest("%+v", nilMap, "<nil>")
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs, "("+vt+")"+vs2)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs, "(*"+vt+")"+vs2)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs, "(**"+vt+")"+vs2)
+       addFormatterTest("%#v", nilMap, "("+vt+")"+"<nil>")
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs, "("+vt+")"+vs2)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs,
+               "(*"+vt+")("+vAddr+")"+vs2)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs,
+               "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs2)
+       addFormatterTest("%#+v", nilMap, "("+vt+")"+"<nil>")
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // 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"
+       v2s := "map[stringer one:stringer 1]"
+       if spew.UnsafeDisabled {
+               v2s = "map[one:1]"
+       }
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+       // 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 := "map[one:1]"
+       v3s2 := "map[(" + v3t1 + ")one:(" + v3t2 + ")1]"
+       addFormatterTest("%v", v3, v3s)
+       addFormatterTest("%v", pv3, "<*>"+v3s)
+       addFormatterTest("%v", &pv3, "<**>"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%+v", v3, v3s)
+       addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+       addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%#v", v3, "("+v3t+")"+v3s2)
+       addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s2)
+       addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s2)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+       addFormatterTest("%#+v", v3, "("+v3t+")"+v3s2)
+       addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s2)
+       addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s2)
+       addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+
+       // 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 := "interface {}"
+       v4s := "map[nil:<nil>]"
+       v4s2 := "map[nil:(" + v4t1 + ")<nil>]"
+       addFormatterTest("%v", v4, v4s)
+       addFormatterTest("%v", pv4, "<*>"+v4s)
+       addFormatterTest("%v", &pv4, "<**>"+v4s)
+       addFormatterTest("%+v", nv4, "<nil>")
+       addFormatterTest("%+v", v4, v4s)
+       addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s)
+       addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s)
+       addFormatterTest("%+v", nv4, "<nil>")
+       addFormatterTest("%#v", v4, "("+v4t+")"+v4s2)
+       addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s2)
+       addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s2)
+       addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+       addFormatterTest("%#+v", v4, "("+v4t+")"+v4s2)
+       addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s2)
+       addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s2)
+       addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+}
+
+func addStructFormatterTests() {
+       // 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 := "{127 255}"
+       vs2 := "{a:127 b:255}"
+       vs3 := "{a:(" + vt2 + ")127 b:(" + vt3 + ")255}"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs2)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs2)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs2)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs3)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs3)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs3)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs3)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs3)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs3)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // 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 := "{{127 255} true}"
+       v2s2 := "{s1:{a:127 b:255} b:true}"
+       v2s3 := "{s1:(" + v2t2 + "){a:(" + v2t3 + ")127 b:(" + v2t4 + ")255} b:(" +
+               v2t5 + ")true}"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s2)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s2)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s2)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s3)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s3)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s3)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s3)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s3)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s3)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+       // 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 := "{stringer test stringer test2}"
+       v3sp := v3s
+       v3s2 := "{s:stringer test S:stringer test2}"
+       v3s2p := v3s2
+       v3s3 := "{s:(" + v3t2 + ")stringer test S:(" + v3t2 + ")stringer test2}"
+       v3s3p := v3s3
+       if spew.UnsafeDisabled {
+               v3s = "{test test2}"
+               v3sp = "{test stringer test2}"
+               v3s2 = "{s:test S:test2}"
+               v3s2p = "{s:test S:stringer test2}"
+               v3s3 = "{s:(" + v3t2 + ")test S:(" + v3t2 + ")test2}"
+               v3s3p = "{s:(" + v3t2 + ")test S:(" + v3t2 + ")stringer test2}"
+       }
+       addFormatterTest("%v", v3, v3s)
+       addFormatterTest("%v", pv3, "<*>"+v3sp)
+       addFormatterTest("%v", &pv3, "<**>"+v3sp)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%+v", v3, v3s2)
+       addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s2p)
+       addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s2p)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%#v", v3, "("+v3t+")"+v3s3)
+       addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s3p)
+       addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s3p)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+       addFormatterTest("%#+v", v3, "("+v3t+")"+v3s3)
+       addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s3p)
+       addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s3p)
+       addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+
+       // 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 := "{<*>{embedstr} <*>{embedstr}}"
+       v4s2 := "{embed:<*>(" + eAddr + "){a:embedstr} e:<*>(" + eAddr +
+               "){a:embedstr}}"
+       v4s3 := "{embed:(*" + v4t2 + "){a:(" + v4t3 + ")embedstr} e:(*" + v4t2 +
+               "){a:(" + v4t3 + ")embedstr}}"
+       v4s4 := "{embed:(*" + v4t2 + ")(" + eAddr + "){a:(" + v4t3 +
+               ")embedstr} e:(*" + v4t2 + ")(" + eAddr + "){a:(" + v4t3 + ")embedstr}}"
+       addFormatterTest("%v", v4, v4s)
+       addFormatterTest("%v", pv4, "<*>"+v4s)
+       addFormatterTest("%v", &pv4, "<**>"+v4s)
+       addFormatterTest("%+v", nv4, "<nil>")
+       addFormatterTest("%+v", v4, v4s2)
+       addFormatterTest("%+v", pv4, "<*>("+v4Addr+")"+v4s2)
+       addFormatterTest("%+v", &pv4, "<**>("+pv4Addr+"->"+v4Addr+")"+v4s2)
+       addFormatterTest("%+v", nv4, "<nil>")
+       addFormatterTest("%#v", v4, "("+v4t+")"+v4s3)
+       addFormatterTest("%#v", pv4, "(*"+v4t+")"+v4s3)
+       addFormatterTest("%#v", &pv4, "(**"+v4t+")"+v4s3)
+       addFormatterTest("%#v", nv4, "(*"+v4t+")"+"<nil>")
+       addFormatterTest("%#+v", v4, "("+v4t+")"+v4s4)
+       addFormatterTest("%#+v", pv4, "(*"+v4t+")("+v4Addr+")"+v4s4)
+       addFormatterTest("%#+v", &pv4, "(**"+v4t+")("+pv4Addr+"->"+v4Addr+")"+v4s4)
+       addFormatterTest("%#+v", nv4, "(*"+v4t+")"+"<nil>")
+}
+
+func addUintptrFormatterTests() {
+       // Null pointer.
+       v := uintptr(0)
+       nv := (*uintptr)(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "uintptr"
+       vs := "<nil>"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // Address of real variable.
+       i := 1
+       v2 := uintptr(unsafe.Pointer(&i))
+       pv2 := &v2
+       v2Addr := fmt.Sprintf("%p", pv2)
+       pv2Addr := fmt.Sprintf("%p", &pv2)
+       v2t := "uintptr"
+       v2s := fmt.Sprintf("%p", &i)
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addUnsafePointerFormatterTests() {
+       // 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>"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // 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)
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addChanFormatterTests() {
+       // 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>"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // 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)
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+}
+
+func addFuncFormatterTests() {
+       // Function with no params and no returns.
+       v := addIntFormatterTests
+       nv := (*func())(nil)
+       pv := &v
+       vAddr := fmt.Sprintf("%p", pv)
+       pvAddr := fmt.Sprintf("%p", &pv)
+       vt := "func()"
+       vs := fmt.Sprintf("%p", v)
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+
+       // Function with param and no returns.
+       v2 := TestFormatter
+       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)
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s)
+       addFormatterTest("%v", &pv2, "<**>"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%+v", v2, v2s)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%+v", nv2, "<nil>")
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s)
+       addFormatterTest("%#v", nv2, "(*"+v2t+")"+"<nil>")
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s)
+       addFormatterTest("%#+v", nv2, "(*"+v2t+")"+"<nil>")
+
+       // 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)
+       addFormatterTest("%v", v3, v3s)
+       addFormatterTest("%v", pv3, "<*>"+v3s)
+       addFormatterTest("%v", &pv3, "<**>"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%+v", v3, v3s)
+       addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s)
+       addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%+v", nv3, "<nil>")
+       addFormatterTest("%#v", v3, "("+v3t+")"+v3s)
+       addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s)
+       addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s)
+       addFormatterTest("%#v", nv3, "(*"+v3t+")"+"<nil>")
+       addFormatterTest("%#+v", v3, "("+v3t+")"+v3s)
+       addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s)
+       addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s)
+       addFormatterTest("%#+v", nv3, "(*"+v3t+")"+"<nil>")
+}
+
+func addCircularFormatterTests() {
+       // 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 := "{<*>{<*><shown>}}"
+       vs2 := "{<*><shown>}"
+       vs3 := "{c:<*>(" + vAddr + "){c:<*>(" + vAddr + ")<shown>}}"
+       vs4 := "{c:<*>(" + vAddr + ")<shown>}"
+       vs5 := "{c:(*" + vt + "){c:(*" + vt + ")<shown>}}"
+       vs6 := "{c:(*" + vt + ")<shown>}"
+       vs7 := "{c:(*" + vt + ")(" + vAddr + "){c:(*" + vt + ")(" + vAddr +
+               ")<shown>}}"
+       vs8 := "{c:(*" + vt + ")(" + vAddr + ")<shown>}"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs2)
+       addFormatterTest("%v", &pv, "<**>"+vs2)
+       addFormatterTest("%+v", v, vs3)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs4)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs4)
+       addFormatterTest("%#v", v, "("+vt+")"+vs5)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs6)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs6)
+       addFormatterTest("%#+v", v, "("+vt+")"+vs7)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs8)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs8)
+
+       // 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 := "{<*>{<*>{<*><shown>}}}"
+       v2s2 := "{<*>{<*><shown>}}"
+       v2s3 := "{ps2:<*>(" + ts2Addr + "){ps1:<*>(" + v2Addr + "){ps2:<*>(" +
+               ts2Addr + ")<shown>}}}"
+       v2s4 := "{ps2:<*>(" + ts2Addr + "){ps1:<*>(" + v2Addr + ")<shown>}}"
+       v2s5 := "{ps2:(*" + v2t2 + "){ps1:(*" + v2t + "){ps2:(*" + v2t2 +
+               ")<shown>}}}"
+       v2s6 := "{ps2:(*" + v2t2 + "){ps1:(*" + v2t + ")<shown>}}"
+       v2s7 := "{ps2:(*" + v2t2 + ")(" + ts2Addr + "){ps1:(*" + v2t +
+               ")(" + v2Addr + "){ps2:(*" + v2t2 + ")(" + ts2Addr +
+               ")<shown>}}}"
+       v2s8 := "{ps2:(*" + v2t2 + ")(" + ts2Addr + "){ps1:(*" + v2t +
+               ")(" + v2Addr + ")<shown>}}"
+       addFormatterTest("%v", v2, v2s)
+       addFormatterTest("%v", pv2, "<*>"+v2s2)
+       addFormatterTest("%v", &pv2, "<**>"+v2s2)
+       addFormatterTest("%+v", v2, v2s3)
+       addFormatterTest("%+v", pv2, "<*>("+v2Addr+")"+v2s4)
+       addFormatterTest("%+v", &pv2, "<**>("+pv2Addr+"->"+v2Addr+")"+v2s4)
+       addFormatterTest("%#v", v2, "("+v2t+")"+v2s5)
+       addFormatterTest("%#v", pv2, "(*"+v2t+")"+v2s6)
+       addFormatterTest("%#v", &pv2, "(**"+v2t+")"+v2s6)
+       addFormatterTest("%#+v", v2, "("+v2t+")"+v2s7)
+       addFormatterTest("%#+v", pv2, "(*"+v2t+")("+v2Addr+")"+v2s8)
+       addFormatterTest("%#+v", &pv2, "(**"+v2t+")("+pv2Addr+"->"+v2Addr+")"+v2s8)
+
+       // 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 := "{<*>{<*>{<*>{<*><shown>}}}}"
+       v3s2 := "{<*>{<*>{<*><shown>}}}"
+       v3s3 := "{ps2:<*>(" + tic2Addr + "){ps3:<*>(" + tic3Addr + "){ps1:<*>(" +
+               v3Addr + "){ps2:<*>(" + tic2Addr + ")<shown>}}}}"
+       v3s4 := "{ps2:<*>(" + tic2Addr + "){ps3:<*>(" + tic3Addr + "){ps1:<*>(" +
+               v3Addr + ")<shown>}}}"
+       v3s5 := "{ps2:(*" + v3t2 + "){ps3:(*" + v3t3 + "){ps1:(*" + v3t +
+               "){ps2:(*" + v3t2 + ")<shown>}}}}"
+       v3s6 := "{ps2:(*" + v3t2 + "){ps3:(*" + v3t3 + "){ps1:(*" + v3t +
+               ")<shown>}}}"
+       v3s7 := "{ps2:(*" + v3t2 + ")(" + tic2Addr + "){ps3:(*" + v3t3 + ")(" +
+               tic3Addr + "){ps1:(*" + v3t + ")(" + v3Addr + "){ps2:(*" + v3t2 +
+               ")(" + tic2Addr + ")<shown>}}}}"
+       v3s8 := "{ps2:(*" + v3t2 + ")(" + tic2Addr + "){ps3:(*" + v3t3 + ")(" +
+               tic3Addr + "){ps1:(*" + v3t + ")(" + v3Addr + ")<shown>}}}"
+       addFormatterTest("%v", v3, v3s)
+       addFormatterTest("%v", pv3, "<*>"+v3s2)
+       addFormatterTest("%v", &pv3, "<**>"+v3s2)
+       addFormatterTest("%+v", v3, v3s3)
+       addFormatterTest("%+v", pv3, "<*>("+v3Addr+")"+v3s4)
+       addFormatterTest("%+v", &pv3, "<**>("+pv3Addr+"->"+v3Addr+")"+v3s4)
+       addFormatterTest("%#v", v3, "("+v3t+")"+v3s5)
+       addFormatterTest("%#v", pv3, "(*"+v3t+")"+v3s6)
+       addFormatterTest("%#v", &pv3, "(**"+v3t+")"+v3s6)
+       addFormatterTest("%#+v", v3, "("+v3t+")"+v3s7)
+       addFormatterTest("%#+v", pv3, "(*"+v3t+")("+v3Addr+")"+v3s8)
+       addFormatterTest("%#+v", &pv3, "(**"+v3t+")("+pv3Addr+"->"+v3Addr+")"+v3s8)
+}
+
+func addPanicFormatterTests() {
+       // 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"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+}
+
+func addErrorFormatterTests() {
+       // 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"
+       addFormatterTest("%v", v, vs)
+       addFormatterTest("%v", pv, "<*>"+vs)
+       addFormatterTest("%v", &pv, "<**>"+vs)
+       addFormatterTest("%v", nv, "<nil>")
+       addFormatterTest("%+v", v, vs)
+       addFormatterTest("%+v", pv, "<*>("+vAddr+")"+vs)
+       addFormatterTest("%+v", &pv, "<**>("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%+v", nv, "<nil>")
+       addFormatterTest("%#v", v, "("+vt+")"+vs)
+       addFormatterTest("%#v", pv, "(*"+vt+")"+vs)
+       addFormatterTest("%#v", &pv, "(**"+vt+")"+vs)
+       addFormatterTest("%#v", nv, "(*"+vt+")"+"<nil>")
+       addFormatterTest("%#+v", v, "("+vt+")"+vs)
+       addFormatterTest("%#+v", pv, "(*"+vt+")("+vAddr+")"+vs)
+       addFormatterTest("%#+v", &pv, "(**"+vt+")("+pvAddr+"->"+vAddr+")"+vs)
+       addFormatterTest("%#+v", nv, "(*"+vt+")"+"<nil>")
+}
+
+func addPassthroughFormatterTests() {
+       // %x passthrough with uint.
+       v := uint(4294967295)
+       pv := &v
+       vAddr := fmt.Sprintf("%x", pv)
+       pvAddr := fmt.Sprintf("%x", &pv)
+       vs := "ffffffff"
+       addFormatterTest("%x", v, vs)
+       addFormatterTest("%x", pv, vAddr)
+       addFormatterTest("%x", &pv, pvAddr)
+
+       // %#x passthrough with uint.
+       v2 := int(2147483647)
+       pv2 := &v2
+       v2Addr := fmt.Sprintf("%#x", pv2)
+       pv2Addr := fmt.Sprintf("%#x", &pv2)
+       v2s := "0x7fffffff"
+       addFormatterTest("%#x", v2, v2s)
+       addFormatterTest("%#x", pv2, v2Addr)
+       addFormatterTest("%#x", &pv2, pv2Addr)
+
+       // %f passthrough with precision.
+       addFormatterTest("%.2f", 3.1415, "3.14")
+       addFormatterTest("%.3f", 3.1415, "3.142")
+       addFormatterTest("%.4f", 3.1415, "3.1415")
+
+       // %f passthrough with width and precision.
+       addFormatterTest("%5.2f", 3.1415, " 3.14")
+       addFormatterTest("%6.3f", 3.1415, " 3.142")
+       addFormatterTest("%7.4f", 3.1415, " 3.1415")
+
+       // %d passthrough with width.
+       addFormatterTest("%3d", 127, "127")
+       addFormatterTest("%4d", 127, " 127")
+       addFormatterTest("%5d", 127, "  127")
+
+       // %q passthrough with string.
+       addFormatterTest("%q", "test", "\"test\"")
+}
+
+// TestFormatter executes all of the tests described by formatterTests.
+func TestFormatter(t *testing.T) {
+       // Setup tests.
+       addIntFormatterTests()
+       addUintFormatterTests()
+       addBoolFormatterTests()
+       addFloatFormatterTests()
+       addComplexFormatterTests()
+       addArrayFormatterTests()
+       addSliceFormatterTests()
+       addStringFormatterTests()
+       addInterfaceFormatterTests()
+       addMapFormatterTests()
+       addStructFormatterTests()
+       addUintptrFormatterTests()
+       addUnsafePointerFormatterTests()
+       addChanFormatterTests()
+       addFuncFormatterTests()
+       addCircularFormatterTests()
+       addPanicFormatterTests()
+       addErrorFormatterTests()
+       addPassthroughFormatterTests()
+
+       t.Logf("Running %d tests", len(formatterTests))
+       for i, test := range formatterTests {
+               buf := new(bytes.Buffer)
+               spew.Fprintf(buf, test.format, test.in)
+               s := buf.String()
+               if testFailed(s, test.wants) {
+                       t.Errorf("Formatter #%d format: %s got: %s %s", i, test.format, s,
+                               stringizeWants(test.wants))
+                       continue
+               }
+       }
+}
+
+type testStruct struct {
+       x int
+}
+
+func (ts testStruct) String() string {
+       return fmt.Sprintf("ts.%d", ts.x)
+}
+
+type testStructP struct {
+       x int
+}
+
+func (ts *testStructP) String() string {
+       return fmt.Sprintf("ts.%d", ts.x)
+}
+
+func TestPrintSortedKeys(t *testing.T) {
+       cfg := spew.ConfigState{SortKeys: true}
+       s := cfg.Sprint(map[int]string{1: "1", 3: "3", 2: "2"})
+       expected := "map[1:1 2:2 3:3]"
+       if s != expected {
+               t.Errorf("Sorted keys mismatch 1:\n  %v %v", s, expected)
+       }
+
+       s = cfg.Sprint(map[stringer]int{"1": 1, "3": 3, "2": 2})
+       expected = "map[stringer 1:1 stringer 2:2 stringer 3:3]"
+       if s != expected {
+               t.Errorf("Sorted keys mismatch 2:\n  %v %v", s, expected)
+       }
+
+       s = cfg.Sprint(map[pstringer]int{pstringer("1"): 1, pstringer("3"): 3, pstringer("2"): 2})
+       expected = "map[stringer 1:1 stringer 2:2 stringer 3:3]"
+       if spew.UnsafeDisabled {
+               expected = "map[1:1 2:2 3:3]"
+       }
+       if s != expected {
+               t.Errorf("Sorted keys mismatch 3:\n  %v %v", s, expected)
+       }
+
+       s = cfg.Sprint(map[testStruct]int{{1}: 1, {3}: 3, {2}: 2})
+       expected = "map[ts.1:1 ts.2:2 ts.3:3]"
+       if s != expected {
+               t.Errorf("Sorted keys mismatch 4:\n  %v %v", s, expected)
+       }
+
+       if !spew.UnsafeDisabled {
+               s = cfg.Sprint(map[testStructP]int{{1}: 1, {3}: 3, {2}: 2})
+               expected = "map[ts.1:1 ts.2:2 ts.3:3]"
+               if s != expected {
+                       t.Errorf("Sorted keys mismatch 5:\n  %v %v", s, expected)
+               }
+       }
+
+       s = cfg.Sprint(map[customError]int{customError(1): 1, customError(3): 3, customError(2): 2})
+       expected = "map[error: 1:1 error: 2:2 error: 3:3]"
+       if s != expected {
+               t.Errorf("Sorted keys mismatch 6:\n  %v %v", s, expected)
+       }
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/internal_test.go b/vendor/github.com/davecgh/go-spew/spew/internal_test.go
new file mode 100644 (file)
index 0000000..e312b4f
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) 2013-2016 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"
+)
+
+// 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 {
+       return f == int('+')
+}
+
+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)
+       }
+}
+
+// SortValues makes the internal sortValues function available to the test
+// package.
+func SortValues(values []reflect.Value, cs *ConfigState) {
+       sortValues(values, cs)
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/internalunsafe_test.go b/vendor/github.com/davecgh/go-spew/spew/internalunsafe_test.go
new file mode 100644 (file)
index 0000000..a0c612e
--- /dev/null
@@ -0,0 +1,102 @@
+// Copyright (c) 2013-2016 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 the code is not running on Google App Engine, compiled by GopherJS, and
+// "-tags safe" is not added to the go build command line.  The "disableunsafe"
+// tag is deprecated and thus should not be used.
+// +build !js,!appengine,!safe,!disableunsafe
+
+/*
+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"
+)
+
+// 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)
+       }
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/spew.go b/vendor/github.com/davecgh/go-spew/spew/spew.go
new file mode 100644 (file)
index 0000000..32c0e33
--- /dev/null
@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2013-2016 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
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/spew_test.go b/vendor/github.com/davecgh/go-spew/spew/spew_test.go
new file mode 100644 (file)
index 0000000..b70466c
--- /dev/null
@@ -0,0 +1,320 @@
+/*
+ * Copyright (c) 2013-2016 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"
+       "io/ioutil"
+       "os"
+       "testing"
+
+       "github.com/davecgh/go-spew/spew"
+)
+
+// 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}
+       scsNoPtrAddr := &spew.ConfigState{DisablePointerAddresses: true}
+       scsNoCap := &spew.ConfigState{DisableCapacities: true}
+
+       // Variables for tests on types which implement Stringer interface with and
+       // without a pointer receiver.
+       ts := stringer("test")
+       tps := pstringer("test")
+
+       type ptrTester struct {
+               s *struct{}
+       }
+       tptr := &ptrTester{s: &struct{}{}}
+
+       // 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) (len=1 cap=1) {\n  <max depth reached>\n },\n" +
+                       " slice: ([]string) (len=1 cap=1) {\n  <max depth reached>\n },\n" +
+                       " m: (map[string]int) (len=1) {\n  <max depth reached>\n }\n}\n"},
+               {scsContinue, fCSFprint, "", ts, "(stringer test) test"},
+               {scsContinue, fCSFdump, "", ts, "(spew_test.stringer) " +
+                       "(len=4) (stringer test) \"test\"\n"},
+               {scsContinue, fCSFprint, "", te, "(error: 10) 10"},
+               {scsContinue, fCSFdump, "", te, "(spew_test.customError) " +
+                       "(error: 10) 10\n"},
+               {scsNoPtrAddr, fCSFprint, "", tptr, "<*>{<*>{}}"},
+               {scsNoPtrAddr, fCSSdump, "", tptr, "(*spew_test.ptrTester)({\ns: (*struct {})({\n})\n})\n"},
+               {scsNoCap, fCSSdump, "", make([]string, 0, 10), "([]string) {\n}\n"},
+               {scsNoCap, fCSSdump, "", make([]string, 1, 10), "([]string) (len=1) {\n(string) \"\"\n}\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
+               }
+       }
+}
diff --git a/vendor/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go b/vendor/github.com/davecgh/go-spew/spew/testdata/dumpcgo.go
new file mode 100644 (file)
index 0000000..5c87dd4
--- /dev/null
@@ -0,0 +1,82 @@
+// 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 and the array's len and cap.
+// This is only used for tests.
+func GetCgoCharArray() (interface{}, int, int) {
+       return C.ca, len(C.ca), cap(C.ca)
+}
+
+// GetCgoUnsignedCharArray returns an unsigned char array via cgo and the
+// array's len and cap.  This is only used for tests.
+func GetCgoUnsignedCharArray() (interface{}, int, int) {
+       return C.uca, len(C.uca), cap(C.uca)
+}
+
+// GetCgoSignedCharArray returns a signed char array via cgo and the array's len
+// and cap.  This is only used for tests.
+func GetCgoSignedCharArray() (interface{}, int, int) {
+       return C.sca, len(C.sca), cap(C.sca)
+}
+
+// GetCgoUint8tArray returns a uint8_t array via cgo and the array's len and
+// cap.  This is only used for tests.
+func GetCgoUint8tArray() (interface{}, int, int) {
+       return C.ui8ta, len(C.ui8ta), cap(C.ui8ta)
+}
+
+// GetCgoTypdefedUnsignedCharArray returns a typedefed unsigned char array via
+// cgo and the array's len and cap.  This is only used for tests.
+func GetCgoTypdefedUnsignedCharArray() (interface{}, int, int) {
+       return C.tuca, len(C.tuca), cap(C.tuca)
+}
diff --git a/vendor/github.com/davecgh/go-spew/test_coverage.txt b/vendor/github.com/davecgh/go-spew/test_coverage.txt
new file mode 100644 (file)
index 0000000..2cd087a
--- /dev/null
@@ -0,0 +1,61 @@
+
+github.com/davecgh/go-spew/spew/dump.go                 dumpState.dump                  100.00% (88/88)
+github.com/davecgh/go-spew/spew/format.go       formatState.format              100.00% (82/82)
+github.com/davecgh/go-spew/spew/format.go       formatState.formatPtr           100.00% (52/52)
+github.com/davecgh/go-spew/spew/dump.go                 dumpState.dumpPtr               100.00% (44/44)
+github.com/davecgh/go-spew/spew/dump.go                 dumpState.dumpSlice             100.00% (39/39)
+github.com/davecgh/go-spew/spew/common.go       handleMethods                   100.00% (30/30)
+github.com/davecgh/go-spew/spew/common.go       printHexPtr                     100.00% (18/18)
+github.com/davecgh/go-spew/spew/common.go       unsafeReflectValue              100.00% (13/13)
+github.com/davecgh/go-spew/spew/format.go       formatState.constructOrigFormat 100.00% (12/12)
+github.com/davecgh/go-spew/spew/dump.go                 fdump                           100.00% (11/11)
+github.com/davecgh/go-spew/spew/format.go       formatState.Format              100.00% (11/11)
+github.com/davecgh/go-spew/spew/common.go       init                            100.00% (10/10)
+github.com/davecgh/go-spew/spew/common.go       printComplex                    100.00% (9/9)
+github.com/davecgh/go-spew/spew/common.go       valuesSorter.Less               100.00% (8/8)
+github.com/davecgh/go-spew/spew/format.go       formatState.buildDefaultFormat  100.00% (7/7)
+github.com/davecgh/go-spew/spew/format.go       formatState.unpackValue         100.00% (5/5)
+github.com/davecgh/go-spew/spew/dump.go                 dumpState.indent                100.00% (4/4)
+github.com/davecgh/go-spew/spew/common.go       catchPanic                      100.00% (4/4)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.convertArgs         100.00% (4/4)
+github.com/davecgh/go-spew/spew/spew.go                 convertArgs                     100.00% (4/4)
+github.com/davecgh/go-spew/spew/format.go       newFormatter                    100.00% (3/3)
+github.com/davecgh/go-spew/spew/dump.go                 Sdump                           100.00% (3/3)
+github.com/davecgh/go-spew/spew/common.go       printBool                       100.00% (3/3)
+github.com/davecgh/go-spew/spew/common.go       sortValues                      100.00% (3/3)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Sdump               100.00% (3/3)
+github.com/davecgh/go-spew/spew/dump.go                 dumpState.unpackValue           100.00% (3/3)
+github.com/davecgh/go-spew/spew/spew.go                 Printf                          100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Println                         100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Sprint                          100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Sprintf                         100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Sprintln                        100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go       printFloat                      100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       NewDefaultConfig                100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go       printInt                        100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go       printUint                       100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go       valuesSorter.Len                100.00% (1/1)
+github.com/davecgh/go-spew/spew/common.go       valuesSorter.Swap               100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Errorf              100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Fprint              100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Fprintf             100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Fprintln            100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Print               100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Printf              100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Println             100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Sprint              100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Sprintf             100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Sprintln            100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.NewFormatter        100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Fdump               100.00% (1/1)
+github.com/davecgh/go-spew/spew/config.go       ConfigState.Dump                100.00% (1/1)
+github.com/davecgh/go-spew/spew/dump.go                 Fdump                           100.00% (1/1)
+github.com/davecgh/go-spew/spew/dump.go                 Dump                            100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Fprintln                        100.00% (1/1)
+github.com/davecgh/go-spew/spew/format.go       NewFormatter                    100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Errorf                          100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Fprint                          100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Fprintf                         100.00% (1/1)
+github.com/davecgh/go-spew/spew/spew.go                 Print                           100.00% (1/1)
+github.com/davecgh/go-spew/spew                         ------------------------------- 100.00% (505/505)
+
diff --git a/vendor/golang.org/x/time/AUTHORS b/vendor/golang.org/x/time/AUTHORS
new file mode 100644 (file)
index 0000000..15167cd
--- /dev/null
@@ -0,0 +1,3 @@
+# This source code refers to The Go Authors for copyright purposes.
+# The master list of authors is in the main Go distribution,
+# visible at http://tip.golang.org/AUTHORS.
diff --git a/vendor/golang.org/x/time/CONTRIBUTING.md b/vendor/golang.org/x/time/CONTRIBUTING.md
new file mode 100644 (file)
index 0000000..88dff59
--- /dev/null
@@ -0,0 +1,31 @@
+# Contributing to Go
+
+Go is an open source project.
+
+It is the work of hundreds of contributors. We appreciate your help!
+
+
+## Filing issues
+
+When [filing an issue](https://golang.org/issue/new), make sure to answer these five questions:
+
+1. What version of Go are you using (`go version`)?
+2. What operating system and processor architecture are you using?
+3. What did you do?
+4. What did you expect to see?
+5. What did you see instead?
+
+General questions should go to the [golang-nuts mailing list](https://groups.google.com/group/golang-nuts) instead of the issue tracker.
+The gophers there will answer or ask you to file an issue if you've tripped over a bug.
+
+## Contributing code
+
+Please read the [Contribution Guidelines](https://golang.org/doc/contribute.html)
+before sending patches.
+
+**We do not accept GitHub pull requests**
+(we use [Gerrit](https://code.google.com/p/gerrit/) instead for code review).
+
+Unless otherwise noted, the Go source files are distributed under
+the BSD-style license found in the LICENSE file.
+
diff --git a/vendor/golang.org/x/time/CONTRIBUTORS b/vendor/golang.org/x/time/CONTRIBUTORS
new file mode 100644 (file)
index 0000000..1c4577e
--- /dev/null
@@ -0,0 +1,3 @@
+# This source code was written by the Go contributors.
+# The master list of contributors is in the main Go distribution,
+# visible at http://tip.golang.org/CONTRIBUTORS.
diff --git a/vendor/golang.org/x/time/LICENSE b/vendor/golang.org/x/time/LICENSE
new file mode 100644 (file)
index 0000000..6a66aea
--- /dev/null
@@ -0,0 +1,27 @@
+Copyright (c) 2009 The Go Authors. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+   * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+   * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+   * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/vendor/golang.org/x/time/PATENTS b/vendor/golang.org/x/time/PATENTS
new file mode 100644 (file)
index 0000000..7330990
--- /dev/null
@@ -0,0 +1,22 @@
+Additional IP Rights Grant (Patents)
+
+"This implementation" means the copyrightable works distributed by
+Google as part of the Go project.
+
+Google hereby grants to You a perpetual, worldwide, non-exclusive,
+no-charge, royalty-free, irrevocable (except as stated in this section)
+patent license to make, have made, use, offer to sell, sell, import,
+transfer and otherwise run, modify and propagate the contents of this
+implementation of Go, where such license applies only to those patent
+claims, both currently owned or controlled by Google and acquired in
+the future, licensable by Google that are necessarily infringed by this
+implementation of Go.  This grant does not include claims that would be
+infringed only as a consequence of further modification of this
+implementation.  If you or your agent or exclusive licensee institute or
+order or agree to the institution of patent litigation against any
+entity (including a cross-claim or counterclaim in a lawsuit) alleging
+that this implementation of Go or any code incorporated within this
+implementation of Go constitutes direct or contributory patent
+infringement, or inducement of patent infringement, then any patent
+rights granted to you under this License for this implementation of Go
+shall terminate as of the date such litigation is filed.
diff --git a/vendor/golang.org/x/time/README b/vendor/golang.org/x/time/README
new file mode 100644 (file)
index 0000000..144e347
--- /dev/null
@@ -0,0 +1 @@
+This repository provides supplementary Go time packages.
diff --git a/vendor/golang.org/x/time/rate/rate.go b/vendor/golang.org/x/time/rate/rate.go
new file mode 100644 (file)
index 0000000..eabcd11
--- /dev/null
@@ -0,0 +1,380 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package rate provides a rate limiter.
+package rate
+
+import (
+       "fmt"
+       "math"
+       "sync"
+       "time"
+)
+
+// Limit defines the maximum frequency of some events.
+// Limit is represented as number of events per second.
+// A zero Limit allows no events.
+type Limit float64
+
+// Inf is the infinite rate limit; it allows all events (even if burst is zero).
+const Inf = Limit(math.MaxFloat64)
+
+// Every converts a minimum time interval between events to a Limit.
+func Every(interval time.Duration) Limit {
+       if interval <= 0 {
+               return Inf
+       }
+       return 1 / Limit(interval.Seconds())
+}
+
+// A Limiter controls how frequently events are allowed to happen.
+// It implements a "token bucket" of size b, initially full and refilled
+// at rate r tokens per second.
+// Informally, in any large enough time interval, the Limiter limits the
+// rate to r tokens per second, with a maximum burst size of b events.
+// As a special case, if r == Inf (the infinite rate), b is ignored.
+// See https://en.wikipedia.org/wiki/Token_bucket for more about token buckets.
+//
+// The zero value is a valid Limiter, but it will reject all events.
+// Use NewLimiter to create non-zero Limiters.
+//
+// Limiter has three main methods, Allow, Reserve, and Wait.
+// Most callers should use Wait.
+//
+// Each of the three methods consumes a single token.
+// They differ in their behavior when no token is available.
+// If no token is available, Allow returns false.
+// If no token is available, Reserve returns a reservation for a future token
+// and the amount of time the caller must wait before using it.
+// If no token is available, Wait blocks until one can be obtained
+// or its associated context.Context is canceled.
+//
+// The methods AllowN, ReserveN, and WaitN consume n tokens.
+type Limiter struct {
+       limit Limit
+       burst int
+
+       mu     sync.Mutex
+       tokens float64
+       // last is the last time the limiter's tokens field was updated
+       last time.Time
+       // lastEvent is the latest time of a rate-limited event (past or future)
+       lastEvent time.Time
+}
+
+// Limit returns the maximum overall event rate.
+func (lim *Limiter) Limit() Limit {
+       lim.mu.Lock()
+       defer lim.mu.Unlock()
+       return lim.limit
+}
+
+// Burst returns the maximum burst size. Burst is the maximum number of tokens
+// that can be consumed in a single call to Allow, Reserve, or Wait, so higher
+// Burst values allow more events to happen at once.
+// A zero Burst allows no events, unless limit == Inf.
+func (lim *Limiter) Burst() int {
+       return lim.burst
+}
+
+// NewLimiter returns a new Limiter that allows events up to rate r and permits
+// bursts of at most b tokens.
+func NewLimiter(r Limit, b int) *Limiter {
+       return &Limiter{
+               limit: r,
+               burst: b,
+       }
+}
+
+// Allow is shorthand for AllowN(time.Now(), 1).
+func (lim *Limiter) Allow() bool {
+       return lim.AllowN(time.Now(), 1)
+}
+
+// AllowN reports whether n events may happen at time now.
+// Use this method if you intend to drop / skip events that exceed the rate limit.
+// Otherwise use Reserve or Wait.
+func (lim *Limiter) AllowN(now time.Time, n int) bool {
+       return lim.reserveN(now, n, 0).ok
+}
+
+// A Reservation holds information about events that are permitted by a Limiter to happen after a delay.
+// A Reservation may be canceled, which may enable the Limiter to permit additional events.
+type Reservation struct {
+       ok        bool
+       lim       *Limiter
+       tokens    int
+       timeToAct time.Time
+       // This is the Limit at reservation time, it can change later.
+       limit Limit
+}
+
+// OK returns whether the limiter can provide the requested number of tokens
+// within the maximum wait time.  If OK is false, Delay returns InfDuration, and
+// Cancel does nothing.
+func (r *Reservation) OK() bool {
+       return r.ok
+}
+
+// Delay is shorthand for DelayFrom(time.Now()).
+func (r *Reservation) Delay() time.Duration {
+       return r.DelayFrom(time.Now())
+}
+
+// InfDuration is the duration returned by Delay when a Reservation is not OK.
+const InfDuration = time.Duration(1<<63 - 1)
+
+// DelayFrom returns the duration for which the reservation holder must wait
+// before taking the reserved action.  Zero duration means act immediately.
+// InfDuration means the limiter cannot grant the tokens requested in this
+// Reservation within the maximum wait time.
+func (r *Reservation) DelayFrom(now time.Time) time.Duration {
+       if !r.ok {
+               return InfDuration
+       }
+       delay := r.timeToAct.Sub(now)
+       if delay < 0 {
+               return 0
+       }
+       return delay
+}
+
+// Cancel is shorthand for CancelAt(time.Now()).
+func (r *Reservation) Cancel() {
+       r.CancelAt(time.Now())
+       return
+}
+
+// CancelAt indicates that the reservation holder will not perform the reserved action
+// and reverses the effects of this Reservation on the rate limit as much as possible,
+// considering that other reservations may have already been made.
+func (r *Reservation) CancelAt(now time.Time) {
+       if !r.ok {
+               return
+       }
+
+       r.lim.mu.Lock()
+       defer r.lim.mu.Unlock()
+
+       if r.lim.limit == Inf || r.tokens == 0 || r.timeToAct.Before(now) {
+               return
+       }
+
+       // calculate tokens to restore
+       // The duration between lim.lastEvent and r.timeToAct tells us how many tokens were reserved
+       // after r was obtained. These tokens should not be restored.
+       restoreTokens := float64(r.tokens) - r.limit.tokensFromDuration(r.lim.lastEvent.Sub(r.timeToAct))
+       if restoreTokens <= 0 {
+               return
+       }
+       // advance time to now
+       now, _, tokens := r.lim.advance(now)
+       // calculate new number of tokens
+       tokens += restoreTokens
+       if burst := float64(r.lim.burst); tokens > burst {
+               tokens = burst
+       }
+       // update state
+       r.lim.last = now
+       r.lim.tokens = tokens
+       if r.timeToAct == r.lim.lastEvent {
+               prevEvent := r.timeToAct.Add(r.limit.durationFromTokens(float64(-r.tokens)))
+               if !prevEvent.Before(now) {
+                       r.lim.lastEvent = prevEvent
+               }
+       }
+
+       return
+}
+
+// Reserve is shorthand for ReserveN(time.Now(), 1).
+func (lim *Limiter) Reserve() *Reservation {
+       return lim.ReserveN(time.Now(), 1)
+}
+
+// ReserveN returns a Reservation that indicates how long the caller must wait before n events happen.
+// The Limiter takes this Reservation into account when allowing future events.
+// ReserveN returns false if n exceeds the Limiter's burst size.
+// Usage example:
+//   r := lim.ReserveN(time.Now(), 1)
+//   if !r.OK() {
+//     // Not allowed to act! Did you remember to set lim.burst to be > 0 ?
+//     return
+//   }
+//   time.Sleep(r.Delay())
+//   Act()
+// Use this method if you wish to wait and slow down in accordance with the rate limit without dropping events.
+// If you need to respect a deadline or cancel the delay, use Wait instead.
+// To drop or skip events exceeding rate limit, use Allow instead.
+func (lim *Limiter) ReserveN(now time.Time, n int) *Reservation {
+       r := lim.reserveN(now, n, InfDuration)
+       return &r
+}
+
+// contextContext is a temporary(?) copy of the context.Context type
+// to support both Go 1.6 using golang.org/x/net/context and Go 1.7+
+// with the built-in context package. If people ever stop using Go 1.6
+// we can remove this.
+type contextContext interface {
+       Deadline() (deadline time.Time, ok bool)
+       Done() <-chan struct{}
+       Err() error
+       Value(key interface{}) interface{}
+}
+
+// Wait is shorthand for WaitN(ctx, 1).
+func (lim *Limiter) wait(ctx contextContext) (err error) {
+       return lim.WaitN(ctx, 1)
+}
+
+// WaitN blocks until lim permits n events to happen.
+// It returns an error if n exceeds the Limiter's burst size, the Context is
+// canceled, or the expected wait time exceeds the Context's Deadline.
+// The burst limit is ignored if the rate limit is Inf.
+func (lim *Limiter) waitN(ctx contextContext, n int) (err error) {
+       if n > lim.burst && lim.limit != Inf {
+               return fmt.Errorf("rate: Wait(n=%d) exceeds limiter's burst %d", n, lim.burst)
+       }
+       // Check if ctx is already cancelled
+       select {
+       case <-ctx.Done():
+               return ctx.Err()
+       default:
+       }
+       // Determine wait limit
+       now := time.Now()
+       waitLimit := InfDuration
+       if deadline, ok := ctx.Deadline(); ok {
+               waitLimit = deadline.Sub(now)
+       }
+       // Reserve
+       r := lim.reserveN(now, n, waitLimit)
+       if !r.ok {
+               return fmt.Errorf("rate: Wait(n=%d) would exceed context deadline", n)
+       }
+       // Wait
+       t := time.NewTimer(r.DelayFrom(now))
+       defer t.Stop()
+       select {
+       case <-t.C:
+               // We can proceed.
+               return nil
+       case <-ctx.Done():
+               // Context was canceled before we could proceed.  Cancel the
+               // reservation, which may permit other events to proceed sooner.
+               r.Cancel()
+               return ctx.Err()
+       }
+}
+
+// SetLimit is shorthand for SetLimitAt(time.Now(), newLimit).
+func (lim *Limiter) SetLimit(newLimit Limit) {
+       lim.SetLimitAt(time.Now(), newLimit)
+}
+
+// SetLimitAt sets a new Limit for the limiter. The new Limit, and Burst, may be violated
+// or underutilized by those which reserved (using Reserve or Wait) but did not yet act
+// before SetLimitAt was called.
+func (lim *Limiter) SetLimitAt(now time.Time, newLimit Limit) {
+       lim.mu.Lock()
+       defer lim.mu.Unlock()
+
+       now, _, tokens := lim.advance(now)
+
+       lim.last = now
+       lim.tokens = tokens
+       lim.limit = newLimit
+}
+
+// reserveN is a helper method for AllowN, ReserveN, and WaitN.
+// maxFutureReserve specifies the maximum reservation wait duration allowed.
+// reserveN returns Reservation, not *Reservation, to avoid allocation in AllowN and WaitN.
+func (lim *Limiter) reserveN(now time.Time, n int, maxFutureReserve time.Duration) Reservation {
+       lim.mu.Lock()
+
+       if lim.limit == Inf {
+               lim.mu.Unlock()
+               return Reservation{
+                       ok:        true,
+                       lim:       lim,
+                       tokens:    n,
+                       timeToAct: now,
+               }
+       }
+
+       now, last, tokens := lim.advance(now)
+
+       // Calculate the remaining number of tokens resulting from the request.
+       tokens -= float64(n)
+
+       // Calculate the wait duration
+       var waitDuration time.Duration
+       if tokens < 0 {
+               waitDuration = lim.limit.durationFromTokens(-tokens)
+       }
+
+       // Decide result
+       ok := n <= lim.burst && waitDuration <= maxFutureReserve
+
+       // Prepare reservation
+       r := Reservation{
+               ok:    ok,
+               lim:   lim,
+               limit: lim.limit,
+       }
+       if ok {
+               r.tokens = n
+               r.timeToAct = now.Add(waitDuration)
+       }
+
+       // Update state
+       if ok {
+               lim.last = now
+               lim.tokens = tokens
+               lim.lastEvent = r.timeToAct
+       } else {
+               lim.last = last
+       }
+
+       lim.mu.Unlock()
+       return r
+}
+
+// advance calculates and returns an updated state for lim resulting from the passage of time.
+// lim is not changed.
+func (lim *Limiter) advance(now time.Time) (newNow time.Time, newLast time.Time, newTokens float64) {
+       last := lim.last
+       if now.Before(last) {
+               last = now
+       }
+
+       // Avoid making delta overflow below when last is very old.
+       maxElapsed := lim.limit.durationFromTokens(float64(lim.burst) - lim.tokens)
+       elapsed := now.Sub(last)
+       if elapsed > maxElapsed {
+               elapsed = maxElapsed
+       }
+
+       // Calculate the new number of tokens, due to time that passed.
+       delta := lim.limit.tokensFromDuration(elapsed)
+       tokens := lim.tokens + delta
+       if burst := float64(lim.burst); tokens > burst {
+               tokens = burst
+       }
+
+       return now, last, tokens
+}
+
+// durationFromTokens is a unit conversion function from the number of tokens to the duration
+// of time it takes to accumulate them at a rate of limit tokens per second.
+func (limit Limit) durationFromTokens(tokens float64) time.Duration {
+       seconds := tokens / float64(limit)
+       return time.Nanosecond * time.Duration(1e9*seconds)
+}
+
+// tokensFromDuration is a unit conversion function from a time duration to the number of tokens
+// which could be accumulated during that duration at a rate of limit tokens per second.
+func (limit Limit) tokensFromDuration(d time.Duration) float64 {
+       return d.Seconds() * float64(limit)
+}
diff --git a/vendor/golang.org/x/time/rate/rate_go16.go b/vendor/golang.org/x/time/rate/rate_go16.go
new file mode 100644 (file)
index 0000000..6bab185
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build !go1.7
+
+package rate
+
+import "golang.org/x/net/context"
+
+// Wait is shorthand for WaitN(ctx, 1).
+func (lim *Limiter) Wait(ctx context.Context) (err error) {
+       return lim.waitN(ctx, 1)
+}
+
+// WaitN blocks until lim permits n events to happen.
+// It returns an error if n exceeds the Limiter's burst size, the Context is
+// canceled, or the expected wait time exceeds the Context's Deadline.
+func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) {
+       return lim.waitN(ctx, n)
+}
diff --git a/vendor/golang.org/x/time/rate/rate_go17.go b/vendor/golang.org/x/time/rate/rate_go17.go
new file mode 100644 (file)
index 0000000..f90d85f
--- /dev/null
@@ -0,0 +1,21 @@
+// Copyright 2017 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package rate
+
+import "context"
+
+// Wait is shorthand for WaitN(ctx, 1).
+func (lim *Limiter) Wait(ctx context.Context) (err error) {
+       return lim.waitN(ctx, 1)
+}
+
+// WaitN blocks until lim permits n events to happen.
+// It returns an error if n exceeds the Limiter's burst size, the Context is
+// canceled, or the expected wait time exceeds the Context's Deadline.
+func (lim *Limiter) WaitN(ctx context.Context, n int) (err error) {
+       return lim.waitN(ctx, n)
+}
diff --git a/vendor/golang.org/x/time/rate/rate_test.go b/vendor/golang.org/x/time/rate/rate_test.go
new file mode 100644 (file)
index 0000000..e8add69
--- /dev/null
@@ -0,0 +1,449 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package rate
+
+import (
+       "context"
+       "math"
+       "runtime"
+       "sync"
+       "sync/atomic"
+       "testing"
+       "time"
+)
+
+func TestLimit(t *testing.T) {
+       if Limit(10) == Inf {
+               t.Errorf("Limit(10) == Inf should be false")
+       }
+}
+
+func closeEnough(a, b Limit) bool {
+       return (math.Abs(float64(a)/float64(b)) - 1.0) < 1e-9
+}
+
+func TestEvery(t *testing.T) {
+       cases := []struct {
+               interval time.Duration
+               lim      Limit
+       }{
+               {0, Inf},
+               {-1, Inf},
+               {1 * time.Nanosecond, Limit(1e9)},
+               {1 * time.Microsecond, Limit(1e6)},
+               {1 * time.Millisecond, Limit(1e3)},
+               {10 * time.Millisecond, Limit(100)},
+               {100 * time.Millisecond, Limit(10)},
+               {1 * time.Second, Limit(1)},
+               {2 * time.Second, Limit(0.5)},
+               {time.Duration(2.5 * float64(time.Second)), Limit(0.4)},
+               {4 * time.Second, Limit(0.25)},
+               {10 * time.Second, Limit(0.1)},
+               {time.Duration(math.MaxInt64), Limit(1e9 / float64(math.MaxInt64))},
+       }
+       for _, tc := range cases {
+               lim := Every(tc.interval)
+               if !closeEnough(lim, tc.lim) {
+                       t.Errorf("Every(%v) = %v want %v", tc.interval, lim, tc.lim)
+               }
+       }
+}
+
+const (
+       d = 100 * time.Millisecond
+)
+
+var (
+       t0 = time.Now()
+       t1 = t0.Add(time.Duration(1) * d)
+       t2 = t0.Add(time.Duration(2) * d)
+       t3 = t0.Add(time.Duration(3) * d)
+       t4 = t0.Add(time.Duration(4) * d)
+       t5 = t0.Add(time.Duration(5) * d)
+       t9 = t0.Add(time.Duration(9) * d)
+)
+
+type allow struct {
+       t  time.Time
+       n  int
+       ok bool
+}
+
+func run(t *testing.T, lim *Limiter, allows []allow) {
+       for i, allow := range allows {
+               ok := lim.AllowN(allow.t, allow.n)
+               if ok != allow.ok {
+                       t.Errorf("step %d: lim.AllowN(%v, %v) = %v want %v",
+                               i, allow.t, allow.n, ok, allow.ok)
+               }
+       }
+}
+
+func TestLimiterBurst1(t *testing.T) {
+       run(t, NewLimiter(10, 1), []allow{
+               {t0, 1, true},
+               {t0, 1, false},
+               {t0, 1, false},
+               {t1, 1, true},
+               {t1, 1, false},
+               {t1, 1, false},
+               {t2, 2, false}, // burst size is 1, so n=2 always fails
+               {t2, 1, true},
+               {t2, 1, false},
+       })
+}
+
+func TestLimiterBurst3(t *testing.T) {
+       run(t, NewLimiter(10, 3), []allow{
+               {t0, 2, true},
+               {t0, 2, false},
+               {t0, 1, true},
+               {t0, 1, false},
+               {t1, 4, false},
+               {t2, 1, true},
+               {t3, 1, true},
+               {t4, 1, true},
+               {t4, 1, true},
+               {t4, 1, false},
+               {t4, 1, false},
+               {t9, 3, true},
+               {t9, 0, true},
+       })
+}
+
+func TestLimiterJumpBackwards(t *testing.T) {
+       run(t, NewLimiter(10, 3), []allow{
+               {t1, 1, true}, // start at t1
+               {t0, 1, true}, // jump back to t0, two tokens remain
+               {t0, 1, true},
+               {t0, 1, false},
+               {t0, 1, false},
+               {t1, 1, true}, // got a token
+               {t1, 1, false},
+               {t1, 1, false},
+               {t2, 1, true}, // got another token
+               {t2, 1, false},
+               {t2, 1, false},
+       })
+}
+
+func TestSimultaneousRequests(t *testing.T) {
+       const (
+               limit       = 1
+               burst       = 5
+               numRequests = 15
+       )
+       var (
+               wg    sync.WaitGroup
+               numOK = uint32(0)
+       )
+
+       // Very slow replenishing bucket.
+       lim := NewLimiter(limit, burst)
+
+       // Tries to take a token, atomically updates the counter and decreases the wait
+       // group counter.
+       f := func() {
+               defer wg.Done()
+               if ok := lim.Allow(); ok {
+                       atomic.AddUint32(&numOK, 1)
+               }
+       }
+
+       wg.Add(numRequests)
+       for i := 0; i < numRequests; i++ {
+               go f()
+       }
+       wg.Wait()
+       if numOK != burst {
+               t.Errorf("numOK = %d, want %d", numOK, burst)
+       }
+}
+
+func TestLongRunningQPS(t *testing.T) {
+       if testing.Short() {
+               t.Skip("skipping in short mode")
+       }
+       if runtime.GOOS == "openbsd" {
+               t.Skip("low resolution time.Sleep invalidates test (golang.org/issue/14183)")
+               return
+       }
+
+       // The test runs for a few seconds executing many requests and then checks
+       // that overall number of requests is reasonable.
+       const (
+               limit = 100
+               burst = 100
+       )
+       var numOK = int32(0)
+
+       lim := NewLimiter(limit, burst)
+
+       var wg sync.WaitGroup
+       f := func() {
+               if ok := lim.Allow(); ok {
+                       atomic.AddInt32(&numOK, 1)
+               }
+               wg.Done()
+       }
+
+       start := time.Now()
+       end := start.Add(5 * time.Second)
+       for time.Now().Before(end) {
+               wg.Add(1)
+               go f()
+
+               // This will still offer ~500 requests per second, but won't consume
+               // outrageous amount of CPU.
+               time.Sleep(2 * time.Millisecond)
+       }
+       wg.Wait()
+       elapsed := time.Since(start)
+       ideal := burst + (limit * float64(elapsed) / float64(time.Second))
+
+       // We should never get more requests than allowed.
+       if want := int32(ideal + 1); numOK > want {
+               t.Errorf("numOK = %d, want %d (ideal %f)", numOK, want, ideal)
+       }
+       // We should get very close to the number of requests allowed.
+       if want := int32(0.999 * ideal); numOK < want {
+               t.Errorf("numOK = %d, want %d (ideal %f)", numOK, want, ideal)
+       }
+}
+
+type request struct {
+       t   time.Time
+       n   int
+       act time.Time
+       ok  bool
+}
+
+// dFromDuration converts a duration to a multiple of the global constant d
+func dFromDuration(dur time.Duration) int {
+       // Adding a millisecond to be swallowed by the integer division
+       // because we don't care about small inaccuracies
+       return int((dur + time.Millisecond) / d)
+}
+
+// dSince returns multiples of d since t0
+func dSince(t time.Time) int {
+       return dFromDuration(t.Sub(t0))
+}
+
+func runReserve(t *testing.T, lim *Limiter, req request) *Reservation {
+       return runReserveMax(t, lim, req, InfDuration)
+}
+
+func runReserveMax(t *testing.T, lim *Limiter, req request, maxReserve time.Duration) *Reservation {
+       r := lim.reserveN(req.t, req.n, maxReserve)
+       if r.ok && (dSince(r.timeToAct) != dSince(req.act)) || r.ok != req.ok {
+               t.Errorf("lim.reserveN(t%d, %v, %v) = (t%d, %v) want (t%d, %v)",
+                       dSince(req.t), req.n, maxReserve, dSince(r.timeToAct), r.ok, dSince(req.act), req.ok)
+       }
+       return &r
+}
+
+func TestSimpleReserve(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t0, 2, t0, true})
+       runReserve(t, lim, request{t0, 2, t2, true})
+       runReserve(t, lim, request{t3, 2, t4, true})
+}
+
+func TestMix(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t0, 3, t1, false}) // should return false because n > Burst
+       runReserve(t, lim, request{t0, 2, t0, true})
+       run(t, lim, []allow{{t1, 2, false}}) // not enought tokens - don't allow
+       runReserve(t, lim, request{t1, 2, t2, true})
+       run(t, lim, []allow{{t1, 1, false}}) // negative tokens - don't allow
+       run(t, lim, []allow{{t3, 1, true}})
+}
+
+func TestCancelInvalid(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t0, 2, t0, true})
+       r := runReserve(t, lim, request{t0, 3, t3, false})
+       r.CancelAt(t0)                               // should have no effect
+       runReserve(t, lim, request{t0, 2, t2, true}) // did not get extra tokens
+}
+
+func TestCancelLast(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t0, 2, t0, true})
+       r := runReserve(t, lim, request{t0, 2, t2, true})
+       r.CancelAt(t1) // got 2 tokens back
+       runReserve(t, lim, request{t1, 2, t2, true})
+}
+
+func TestCancelTooLate(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t0, 2, t0, true})
+       r := runReserve(t, lim, request{t0, 2, t2, true})
+       r.CancelAt(t3) // too late to cancel - should have no effect
+       runReserve(t, lim, request{t3, 2, t4, true})
+}
+
+func TestCancel0Tokens(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t0, 2, t0, true})
+       r := runReserve(t, lim, request{t0, 1, t1, true})
+       runReserve(t, lim, request{t0, 1, t2, true})
+       r.CancelAt(t0) // got 0 tokens back
+       runReserve(t, lim, request{t0, 1, t3, true})
+}
+
+func TestCancel1Token(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t0, 2, t0, true})
+       r := runReserve(t, lim, request{t0, 2, t2, true})
+       runReserve(t, lim, request{t0, 1, t3, true})
+       r.CancelAt(t2) // got 1 token back
+       runReserve(t, lim, request{t2, 2, t4, true})
+}
+
+func TestCancelMulti(t *testing.T) {
+       lim := NewLimiter(10, 4)
+
+       runReserve(t, lim, request{t0, 4, t0, true})
+       rA := runReserve(t, lim, request{t0, 3, t3, true})
+       runReserve(t, lim, request{t0, 1, t4, true})
+       rC := runReserve(t, lim, request{t0, 1, t5, true})
+       rC.CancelAt(t1) // get 1 token back
+       rA.CancelAt(t1) // get 2 tokens back, as if C was never reserved
+       runReserve(t, lim, request{t1, 3, t5, true})
+}
+
+func TestReserveJumpBack(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t1, 2, t1, true}) // start at t1
+       runReserve(t, lim, request{t0, 1, t1, true}) // should violate Limit,Burst
+       runReserve(t, lim, request{t2, 2, t3, true})
+}
+
+func TestReserveJumpBackCancel(t *testing.T) {
+       lim := NewLimiter(10, 2)
+
+       runReserve(t, lim, request{t1, 2, t1, true}) // start at t1
+       r := runReserve(t, lim, request{t1, 2, t3, true})
+       runReserve(t, lim, request{t1, 1, t4, true})
+       r.CancelAt(t0)                               // cancel at t0, get 1 token back
+       runReserve(t, lim, request{t1, 2, t4, true}) // should violate Limit,Burst
+}
+
+func TestReserveSetLimit(t *testing.T) {
+       lim := NewLimiter(5, 2)
+
+       runReserve(t, lim, request{t0, 2, t0, true})
+       runReserve(t, lim, request{t0, 2, t4, true})
+       lim.SetLimitAt(t2, 10)
+       runReserve(t, lim, request{t2, 1, t4, true}) // violates Limit and Burst
+}
+
+func TestReserveSetLimitCancel(t *testing.T) {
+       lim := NewLimiter(5, 2)
+
+       runReserve(t, lim, request{t0, 2, t0, true})
+       r := runReserve(t, lim, request{t0, 2, t4, true})
+       lim.SetLimitAt(t2, 10)
+       r.CancelAt(t2) // 2 tokens back
+       runReserve(t, lim, request{t2, 2, t3, true})
+}
+
+func TestReserveMax(t *testing.T) {
+       lim := NewLimiter(10, 2)
+       maxT := d
+
+       runReserveMax(t, lim, request{t0, 2, t0, true}, maxT)
+       runReserveMax(t, lim, request{t0, 1, t1, true}, maxT)  // reserve for close future
+       runReserveMax(t, lim, request{t0, 1, t2, false}, maxT) // time to act too far in the future
+}
+
+type wait struct {
+       name   string
+       ctx    context.Context
+       n      int
+       delay  int // in multiples of d
+       nilErr bool
+}
+
+func runWait(t *testing.T, lim *Limiter, w wait) {
+       start := time.Now()
+       err := lim.WaitN(w.ctx, w.n)
+       delay := time.Now().Sub(start)
+       if (w.nilErr && err != nil) || (!w.nilErr && err == nil) || w.delay != dFromDuration(delay) {
+               errString := "<nil>"
+               if !w.nilErr {
+                       errString = "<non-nil error>"
+               }
+               t.Errorf("lim.WaitN(%v, lim, %v) = %v with delay %v ; want %v with delay %v",
+                       w.name, w.n, err, delay, errString, d*time.Duration(w.delay))
+       }
+}
+
+func TestWaitSimple(t *testing.T) {
+       lim := NewLimiter(10, 3)
+
+       ctx, cancel := context.WithCancel(context.Background())
+       cancel()
+       runWait(t, lim, wait{"already-cancelled", ctx, 1, 0, false})
+
+       runWait(t, lim, wait{"exceed-burst-error", context.Background(), 4, 0, false})
+
+       runWait(t, lim, wait{"act-now", context.Background(), 2, 0, true})
+       runWait(t, lim, wait{"act-later", context.Background(), 3, 2, true})
+}
+
+func TestWaitCancel(t *testing.T) {
+       lim := NewLimiter(10, 3)
+
+       ctx, cancel := context.WithCancel(context.Background())
+       runWait(t, lim, wait{"act-now", ctx, 2, 0, true}) // after this lim.tokens = 1
+       go func() {
+               time.Sleep(d)
+               cancel()
+       }()
+       runWait(t, lim, wait{"will-cancel", ctx, 3, 1, false})
+       // should get 3 tokens back, and have lim.tokens = 2
+       t.Logf("tokens:%v last:%v lastEvent:%v", lim.tokens, lim.last, lim.lastEvent)
+       runWait(t, lim, wait{"act-now-after-cancel", context.Background(), 2, 0, true})
+}
+
+func TestWaitTimeout(t *testing.T) {
+       lim := NewLimiter(10, 3)
+
+       ctx, cancel := context.WithTimeout(context.Background(), d)
+       defer cancel()
+       runWait(t, lim, wait{"act-now", ctx, 2, 0, true})
+       runWait(t, lim, wait{"w-timeout-err", ctx, 3, 0, false})
+}
+
+func TestWaitInf(t *testing.T) {
+       lim := NewLimiter(Inf, 0)
+
+       runWait(t, lim, wait{"exceed-burst-no-error", context.Background(), 3, 0, true})
+}
+
+func BenchmarkAllowN(b *testing.B) {
+       lim := NewLimiter(Every(1*time.Second), 1)
+       now := time.Now()
+       b.ReportAllocs()
+       b.ResetTimer()
+       b.RunParallel(func(pb *testing.PB) {
+               for pb.Next() {
+                       lim.AllowN(now, 1)
+               }
+       })
+}