OSDN Git Service

Hulk did something
[bytom/vapor.git] / vendor / github.com / stretchr / testify / vendor / github.com / davecgh / go-spew / spew / format.go
diff --git a/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/format.go b/vendor/github.com/stretchr/testify/vendor/github.com/davecgh/go-spew/spew/format.go
new file mode 100644 (file)
index 0000000..ecf3b80
--- /dev/null
@@ -0,0 +1,419 @@
+/*
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+package spew
+
+import (
+       "bytes"
+       "fmt"
+       "reflect"
+       "strconv"
+       "strings"
+)
+
+// supportedFlags is a list of all the character flags supported by fmt package.
+const supportedFlags = "0-+# "
+
+// formatState implements the fmt.Formatter interface and contains information
+// about the state of a formatting operation.  The NewFormatter function can
+// be used to get a new Formatter which can be used directly as arguments
+// in standard fmt package printing calls.
+type formatState struct {
+       value          interface{}
+       fs             fmt.State
+       depth          int
+       pointers       map[uintptr]int
+       ignoreNextType bool
+       cs             *ConfigState
+}
+
+// buildDefaultFormat recreates the original format string without precision
+// and width information to pass in to fmt.Sprintf in the case of an
+// unrecognized type.  Unless new types are added to the language, this
+// function won't ever be called.
+func (f *formatState) buildDefaultFormat() (format string) {
+       buf := bytes.NewBuffer(percentBytes)
+
+       for _, flag := range supportedFlags {
+               if f.fs.Flag(int(flag)) {
+                       buf.WriteRune(flag)
+               }
+       }
+
+       buf.WriteRune('v')
+
+       format = buf.String()
+       return format
+}
+
+// constructOrigFormat recreates the original format string including precision
+// and width information to pass along to the standard fmt package.  This allows
+// automatic deferral of all format strings this package doesn't support.
+func (f *formatState) constructOrigFormat(verb rune) (format string) {
+       buf := bytes.NewBuffer(percentBytes)
+
+       for _, flag := range supportedFlags {
+               if f.fs.Flag(int(flag)) {
+                       buf.WriteRune(flag)
+               }
+       }
+
+       if width, ok := f.fs.Width(); ok {
+               buf.WriteString(strconv.Itoa(width))
+       }
+
+       if precision, ok := f.fs.Precision(); ok {
+               buf.Write(precisionBytes)
+               buf.WriteString(strconv.Itoa(precision))
+       }
+
+       buf.WriteRune(verb)
+
+       format = buf.String()
+       return format
+}
+
+// unpackValue returns values inside of non-nil interfaces when possible and
+// ensures that types for values which have been unpacked from an interface
+// are displayed when the show types flag is also set.
+// This is useful for data types like structs, arrays, slices, and maps which
+// can contain varying types packed inside an interface.
+func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
+       if v.Kind() == reflect.Interface {
+               f.ignoreNextType = false
+               if !v.IsNil() {
+                       v = v.Elem()
+               }
+       }
+       return v
+}
+
+// formatPtr handles formatting of pointers by indirecting them as necessary.
+func (f *formatState) formatPtr(v reflect.Value) {
+       // Display nil if top level pointer is nil.
+       showTypes := f.fs.Flag('#')
+       if v.IsNil() && (!showTypes || f.ignoreNextType) {
+               f.fs.Write(nilAngleBytes)
+               return
+       }
+
+       // Remove pointers at or below the current depth from map used to detect
+       // circular refs.
+       for k, depth := range f.pointers {
+               if depth >= f.depth {
+                       delete(f.pointers, k)
+               }
+       }
+
+       // Keep list of all dereferenced pointers to possibly show later.
+       pointerChain := make([]uintptr, 0)
+
+       // Figure out how many levels of indirection there are by derferencing
+       // pointers and unpacking interfaces down the chain while detecting circular
+       // references.
+       nilFound := false
+       cycleFound := false
+       indirects := 0
+       ve := v
+       for ve.Kind() == reflect.Ptr {
+               if ve.IsNil() {
+                       nilFound = true
+                       break
+               }
+               indirects++
+               addr := ve.Pointer()
+               pointerChain = append(pointerChain, addr)
+               if pd, ok := f.pointers[addr]; ok && pd < f.depth {
+                       cycleFound = true
+                       indirects--
+                       break
+               }
+               f.pointers[addr] = f.depth
+
+               ve = ve.Elem()
+               if ve.Kind() == reflect.Interface {
+                       if ve.IsNil() {
+                               nilFound = true
+                               break
+                       }
+                       ve = ve.Elem()
+               }
+       }
+
+       // Display type or indirection level depending on flags.
+       if showTypes && !f.ignoreNextType {
+               f.fs.Write(openParenBytes)
+               f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
+               f.fs.Write([]byte(ve.Type().String()))
+               f.fs.Write(closeParenBytes)
+       } else {
+               if nilFound || cycleFound {
+                       indirects += strings.Count(ve.Type().String(), "*")
+               }
+               f.fs.Write(openAngleBytes)
+               f.fs.Write([]byte(strings.Repeat("*", indirects)))
+               f.fs.Write(closeAngleBytes)
+       }
+
+       // Display pointer information depending on flags.
+       if f.fs.Flag('+') && (len(pointerChain) > 0) {
+               f.fs.Write(openParenBytes)
+               for i, addr := range pointerChain {
+                       if i > 0 {
+                               f.fs.Write(pointerChainBytes)
+                       }
+                       printHexPtr(f.fs, addr)
+               }
+               f.fs.Write(closeParenBytes)
+       }
+
+       // Display dereferenced value.
+       switch {
+       case nilFound == true:
+               f.fs.Write(nilAngleBytes)
+
+       case cycleFound == true:
+               f.fs.Write(circularShortBytes)
+
+       default:
+               f.ignoreNextType = true
+               f.format(ve)
+       }
+}
+
+// format is the main workhorse for providing the Formatter interface.  It
+// uses the passed reflect value to figure out what kind of object we are
+// dealing with and formats it appropriately.  It is a recursive function,
+// however circular data structures are detected and handled properly.
+func (f *formatState) format(v reflect.Value) {
+       // Handle invalid reflect values immediately.
+       kind := v.Kind()
+       if kind == reflect.Invalid {
+               f.fs.Write(invalidAngleBytes)
+               return
+       }
+
+       // Handle pointers specially.
+       if kind == reflect.Ptr {
+               f.formatPtr(v)
+               return
+       }
+
+       // Print type information unless already handled elsewhere.
+       if !f.ignoreNextType && f.fs.Flag('#') {
+               f.fs.Write(openParenBytes)
+               f.fs.Write([]byte(v.Type().String()))
+               f.fs.Write(closeParenBytes)
+       }
+       f.ignoreNextType = false
+
+       // Call Stringer/error interfaces if they exist and the handle methods
+       // flag is enabled.
+       if !f.cs.DisableMethods {
+               if (kind != reflect.Invalid) && (kind != reflect.Interface) {
+                       if handled := handleMethods(f.cs, f.fs, v); handled {
+                               return
+                       }
+               }
+       }
+
+       switch kind {
+       case reflect.Invalid:
+               // Do nothing.  We should never get here since invalid has already
+               // been handled above.
+
+       case reflect.Bool:
+               printBool(f.fs, v.Bool())
+
+       case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
+               printInt(f.fs, v.Int(), 10)
+
+       case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
+               printUint(f.fs, v.Uint(), 10)
+
+       case reflect.Float32:
+               printFloat(f.fs, v.Float(), 32)
+
+       case reflect.Float64:
+               printFloat(f.fs, v.Float(), 64)
+
+       case reflect.Complex64:
+               printComplex(f.fs, v.Complex(), 32)
+
+       case reflect.Complex128:
+               printComplex(f.fs, v.Complex(), 64)
+
+       case reflect.Slice:
+               if v.IsNil() {
+                       f.fs.Write(nilAngleBytes)
+                       break
+               }
+               fallthrough
+
+       case reflect.Array:
+               f.fs.Write(openBracketBytes)
+               f.depth++
+               if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
+                       f.fs.Write(maxShortBytes)
+               } else {
+                       numEntries := v.Len()
+                       for i := 0; i < numEntries; i++ {
+                               if i > 0 {
+                                       f.fs.Write(spaceBytes)
+                               }
+                               f.ignoreNextType = true
+                               f.format(f.unpackValue(v.Index(i)))
+                       }
+               }
+               f.depth--
+               f.fs.Write(closeBracketBytes)
+
+       case reflect.String:
+               f.fs.Write([]byte(v.String()))
+
+       case reflect.Interface:
+               // The only time we should get here is for nil interfaces due to
+               // unpackValue calls.
+               if v.IsNil() {
+                       f.fs.Write(nilAngleBytes)
+               }
+
+       case reflect.Ptr:
+               // Do nothing.  We should never get here since pointers have already
+               // been handled above.
+
+       case reflect.Map:
+               // 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)
+}