Browse code

Vendor davecgh/gospew @ 6d212880

Signed-off-by: John Howard <jhoward@microsoft.com>

John Howard authored on 2016/10/13 07:30:47
Showing 10 changed files
... ...
@@ -51,6 +51,7 @@ clone git github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62
51 51
 clone git github.com/Microsoft/hcsshim v0.5.2
52 52
 clone git github.com/Microsoft/go-winio v0.3.5
53 53
 clone git github.com/Sirupsen/logrus f76d643702a30fbffecdfe50831e11881c96ceb3 https://github.com/aaronlehmann/logrus
54
+clone git github.com/davecgh/go-spew 6d212800a42e8ab5c146b8ace3490ee17e5225f9
54 55
 clone git github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a
55 56
 clone git github.com/go-check/check 4ed411733c5785b40214c70bce814c3a3a689609 https://github.com/cpuguy83/check.git
56 57
 clone git github.com/gorilla/context v1.1
57 58
new file mode 100644
... ...
@@ -0,0 +1,15 @@
0
+ISC License
1
+
2
+Copyright (c) 2012-2013 Dave Collins <dave@davec.name>
3
+
4
+Permission to use, copy, modify, and distribute this software for any
5
+purpose with or without fee is hereby granted, provided that the above
6
+copyright notice and this permission notice appear in all copies.
7
+
8
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
0 15
new file mode 100644
... ...
@@ -0,0 +1,152 @@
0
+// Copyright (c) 2015 Dave Collins <dave@davec.name>
1
+//
2
+// Permission to use, copy, modify, and distribute this software for any
3
+// purpose with or without fee is hereby granted, provided that the above
4
+// copyright notice and this permission notice appear in all copies.
5
+//
6
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
7
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
8
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
9
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
10
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
13
+
14
+// NOTE: Due to the following build constraints, this file will only be compiled
15
+// when the code is not running on Google App Engine, compiled by GopherJS, and
16
+// "-tags safe" is not added to the go build command line.  The "disableunsafe"
17
+// tag is deprecated and thus should not be used.
18
+// +build !js,!appengine,!safe,!disableunsafe
19
+
20
+package spew
21
+
22
+import (
23
+	"reflect"
24
+	"unsafe"
25
+)
26
+
27
+const (
28
+	// UnsafeDisabled is a build-time constant which specifies whether or
29
+	// not access to the unsafe package is available.
30
+	UnsafeDisabled = false
31
+
32
+	// ptrSize is the size of a pointer on the current arch.
33
+	ptrSize = unsafe.Sizeof((*byte)(nil))
34
+)
35
+
36
+var (
37
+	// offsetPtr, offsetScalar, and offsetFlag are the offsets for the
38
+	// internal reflect.Value fields.  These values are valid before golang
39
+	// commit ecccf07e7f9d which changed the format.  The are also valid
40
+	// after commit 82f48826c6c7 which changed the format again to mirror
41
+	// the original format.  Code in the init function updates these offsets
42
+	// as necessary.
43
+	offsetPtr    = uintptr(ptrSize)
44
+	offsetScalar = uintptr(0)
45
+	offsetFlag   = uintptr(ptrSize * 2)
46
+
47
+	// flagKindWidth and flagKindShift indicate various bits that the
48
+	// reflect package uses internally to track kind information.
49
+	//
50
+	// flagRO indicates whether or not the value field of a reflect.Value is
51
+	// read-only.
52
+	//
53
+	// flagIndir indicates whether the value field of a reflect.Value is
54
+	// the actual data or a pointer to the data.
55
+	//
56
+	// These values are valid before golang commit 90a7c3c86944 which
57
+	// changed their positions.  Code in the init function updates these
58
+	// flags as necessary.
59
+	flagKindWidth = uintptr(5)
60
+	flagKindShift = uintptr(flagKindWidth - 1)
61
+	flagRO        = uintptr(1 << 0)
62
+	flagIndir     = uintptr(1 << 1)
63
+)
64
+
65
+func init() {
66
+	// Older versions of reflect.Value stored small integers directly in the
67
+	// ptr field (which is named val in the older versions).  Versions
68
+	// between commits ecccf07e7f9d and 82f48826c6c7 added a new field named
69
+	// scalar for this purpose which unfortunately came before the flag
70
+	// field, so the offset of the flag field is different for those
71
+	// versions.
72
+	//
73
+	// This code constructs a new reflect.Value from a known small integer
74
+	// and checks if the size of the reflect.Value struct indicates it has
75
+	// the scalar field. When it does, the offsets are updated accordingly.
76
+	vv := reflect.ValueOf(0xf00)
77
+	if unsafe.Sizeof(vv) == (ptrSize * 4) {
78
+		offsetScalar = ptrSize * 2
79
+		offsetFlag = ptrSize * 3
80
+	}
81
+
82
+	// Commit 90a7c3c86944 changed the flag positions such that the low
83
+	// order bits are the kind.  This code extracts the kind from the flags
84
+	// field and ensures it's the correct type.  When it's not, the flag
85
+	// order has been changed to the newer format, so the flags are updated
86
+	// accordingly.
87
+	upf := unsafe.Pointer(uintptr(unsafe.Pointer(&vv)) + offsetFlag)
88
+	upfv := *(*uintptr)(upf)
89
+	flagKindMask := uintptr((1<<flagKindWidth - 1) << flagKindShift)
90
+	if (upfv&flagKindMask)>>flagKindShift != uintptr(reflect.Int) {
91
+		flagKindShift = 0
92
+		flagRO = 1 << 5
93
+		flagIndir = 1 << 6
94
+
95
+		// Commit adf9b30e5594 modified the flags to separate the
96
+		// flagRO flag into two bits which specifies whether or not the
97
+		// field is embedded.  This causes flagIndir to move over a bit
98
+		// and means that flagRO is the combination of either of the
99
+		// original flagRO bit and the new bit.
100
+		//
101
+		// This code detects the change by extracting what used to be
102
+		// the indirect bit to ensure it's set.  When it's not, the flag
103
+		// order has been changed to the newer format, so the flags are
104
+		// updated accordingly.
105
+		if upfv&flagIndir == 0 {
106
+			flagRO = 3 << 5
107
+			flagIndir = 1 << 7
108
+		}
109
+	}
110
+}
111
+
112
+// unsafeReflectValue converts the passed reflect.Value into a one that bypasses
113
+// the typical safety restrictions preventing access to unaddressable and
114
+// unexported data.  It works by digging the raw pointer to the underlying
115
+// value out of the protected value and generating a new unprotected (unsafe)
116
+// reflect.Value to it.
117
+//
118
+// This allows us to check for implementations of the Stringer and error
119
+// interfaces to be used for pretty printing ordinarily unaddressable and
120
+// inaccessible values such as unexported struct fields.
121
+func unsafeReflectValue(v reflect.Value) (rv reflect.Value) {
122
+	indirects := 1
123
+	vt := v.Type()
124
+	upv := unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetPtr)
125
+	rvf := *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&v)) + offsetFlag))
126
+	if rvf&flagIndir != 0 {
127
+		vt = reflect.PtrTo(v.Type())
128
+		indirects++
129
+	} else if offsetScalar != 0 {
130
+		// The value is in the scalar field when it's not one of the
131
+		// reference types.
132
+		switch vt.Kind() {
133
+		case reflect.Uintptr:
134
+		case reflect.Chan:
135
+		case reflect.Func:
136
+		case reflect.Map:
137
+		case reflect.Ptr:
138
+		case reflect.UnsafePointer:
139
+		default:
140
+			upv = unsafe.Pointer(uintptr(unsafe.Pointer(&v)) +
141
+				offsetScalar)
142
+		}
143
+	}
144
+
145
+	pv := reflect.NewAt(vt, upv)
146
+	rv = pv
147
+	for i := 0; i < indirects; i++ {
148
+		rv = rv.Elem()
149
+	}
150
+	return rv
151
+}
0 152
new file mode 100644
... ...
@@ -0,0 +1,38 @@
0
+// Copyright (c) 2015 Dave Collins <dave@davec.name>
1
+//
2
+// Permission to use, copy, modify, and distribute this software for any
3
+// purpose with or without fee is hereby granted, provided that the above
4
+// copyright notice and this permission notice appear in all copies.
5
+//
6
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
7
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
8
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
9
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
10
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
11
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
12
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
13
+
14
+// NOTE: Due to the following build constraints, this file will only be compiled
15
+// when the code is running on Google App Engine, compiled by GopherJS, or
16
+// "-tags safe" is added to the go build command line.  The "disableunsafe"
17
+// tag is deprecated and thus should not be used.
18
+// +build js appengine safe disableunsafe
19
+
20
+package spew
21
+
22
+import "reflect"
23
+
24
+const (
25
+	// UnsafeDisabled is a build-time constant which specifies whether or
26
+	// not access to the unsafe package is available.
27
+	UnsafeDisabled = true
28
+)
29
+
30
+// unsafeReflectValue typically converts the passed reflect.Value into a one
31
+// that bypasses the typical safety restrictions preventing access to
32
+// unaddressable and unexported data.  However, doing this relies on access to
33
+// the unsafe package.  This is a stub version which simply returns the passed
34
+// reflect.Value when the unsafe package is not available.
35
+func unsafeReflectValue(v reflect.Value) reflect.Value {
36
+	return v
37
+}
0 38
new file mode 100644
... ...
@@ -0,0 +1,341 @@
0
+/*
1
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
2
+ *
3
+ * Permission to use, copy, modify, and distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ */
15
+
16
+package spew
17
+
18
+import (
19
+	"bytes"
20
+	"fmt"
21
+	"io"
22
+	"reflect"
23
+	"sort"
24
+	"strconv"
25
+)
26
+
27
+// Some constants in the form of bytes to avoid string overhead.  This mirrors
28
+// the technique used in the fmt package.
29
+var (
30
+	panicBytes            = []byte("(PANIC=")
31
+	plusBytes             = []byte("+")
32
+	iBytes                = []byte("i")
33
+	trueBytes             = []byte("true")
34
+	falseBytes            = []byte("false")
35
+	interfaceBytes        = []byte("(interface {})")
36
+	commaNewlineBytes     = []byte(",\n")
37
+	newlineBytes          = []byte("\n")
38
+	openBraceBytes        = []byte("{")
39
+	openBraceNewlineBytes = []byte("{\n")
40
+	closeBraceBytes       = []byte("}")
41
+	asteriskBytes         = []byte("*")
42
+	colonBytes            = []byte(":")
43
+	colonSpaceBytes       = []byte(": ")
44
+	openParenBytes        = []byte("(")
45
+	closeParenBytes       = []byte(")")
46
+	spaceBytes            = []byte(" ")
47
+	pointerChainBytes     = []byte("->")
48
+	nilAngleBytes         = []byte("<nil>")
49
+	maxNewlineBytes       = []byte("<max depth reached>\n")
50
+	maxShortBytes         = []byte("<max>")
51
+	circularBytes         = []byte("<already shown>")
52
+	circularShortBytes    = []byte("<shown>")
53
+	invalidAngleBytes     = []byte("<invalid>")
54
+	openBracketBytes      = []byte("[")
55
+	closeBracketBytes     = []byte("]")
56
+	percentBytes          = []byte("%")
57
+	precisionBytes        = []byte(".")
58
+	openAngleBytes        = []byte("<")
59
+	closeAngleBytes       = []byte(">")
60
+	openMapBytes          = []byte("map[")
61
+	closeMapBytes         = []byte("]")
62
+	lenEqualsBytes        = []byte("len=")
63
+	capEqualsBytes        = []byte("cap=")
64
+)
65
+
66
+// hexDigits is used to map a decimal value to a hex digit.
67
+var hexDigits = "0123456789abcdef"
68
+
69
+// catchPanic handles any panics that might occur during the handleMethods
70
+// calls.
71
+func catchPanic(w io.Writer, v reflect.Value) {
72
+	if err := recover(); err != nil {
73
+		w.Write(panicBytes)
74
+		fmt.Fprintf(w, "%v", err)
75
+		w.Write(closeParenBytes)
76
+	}
77
+}
78
+
79
+// handleMethods attempts to call the Error and String methods on the underlying
80
+// type the passed reflect.Value represents and outputes the result to Writer w.
81
+//
82
+// It handles panics in any called methods by catching and displaying the error
83
+// as the formatted value.
84
+func handleMethods(cs *ConfigState, w io.Writer, v reflect.Value) (handled bool) {
85
+	// We need an interface to check if the type implements the error or
86
+	// Stringer interface.  However, the reflect package won't give us an
87
+	// interface on certain things like unexported struct fields in order
88
+	// to enforce visibility rules.  We use unsafe, when it's available,
89
+	// to bypass these restrictions since this package does not mutate the
90
+	// values.
91
+	if !v.CanInterface() {
92
+		if UnsafeDisabled {
93
+			return false
94
+		}
95
+
96
+		v = unsafeReflectValue(v)
97
+	}
98
+
99
+	// Choose whether or not to do error and Stringer interface lookups against
100
+	// the base type or a pointer to the base type depending on settings.
101
+	// Technically calling one of these methods with a pointer receiver can
102
+	// mutate the value, however, types which choose to satisify an error or
103
+	// Stringer interface with a pointer receiver should not be mutating their
104
+	// state inside these interface methods.
105
+	if !cs.DisablePointerMethods && !UnsafeDisabled && !v.CanAddr() {
106
+		v = unsafeReflectValue(v)
107
+	}
108
+	if v.CanAddr() {
109
+		v = v.Addr()
110
+	}
111
+
112
+	// Is it an error or Stringer?
113
+	switch iface := v.Interface().(type) {
114
+	case error:
115
+		defer catchPanic(w, v)
116
+		if cs.ContinueOnMethod {
117
+			w.Write(openParenBytes)
118
+			w.Write([]byte(iface.Error()))
119
+			w.Write(closeParenBytes)
120
+			w.Write(spaceBytes)
121
+			return false
122
+		}
123
+
124
+		w.Write([]byte(iface.Error()))
125
+		return true
126
+
127
+	case fmt.Stringer:
128
+		defer catchPanic(w, v)
129
+		if cs.ContinueOnMethod {
130
+			w.Write(openParenBytes)
131
+			w.Write([]byte(iface.String()))
132
+			w.Write(closeParenBytes)
133
+			w.Write(spaceBytes)
134
+			return false
135
+		}
136
+		w.Write([]byte(iface.String()))
137
+		return true
138
+	}
139
+	return false
140
+}
141
+
142
+// printBool outputs a boolean value as true or false to Writer w.
143
+func printBool(w io.Writer, val bool) {
144
+	if val {
145
+		w.Write(trueBytes)
146
+	} else {
147
+		w.Write(falseBytes)
148
+	}
149
+}
150
+
151
+// printInt outputs a signed integer value to Writer w.
152
+func printInt(w io.Writer, val int64, base int) {
153
+	w.Write([]byte(strconv.FormatInt(val, base)))
154
+}
155
+
156
+// printUint outputs an unsigned integer value to Writer w.
157
+func printUint(w io.Writer, val uint64, base int) {
158
+	w.Write([]byte(strconv.FormatUint(val, base)))
159
+}
160
+
161
+// printFloat outputs a floating point value using the specified precision,
162
+// which is expected to be 32 or 64bit, to Writer w.
163
+func printFloat(w io.Writer, val float64, precision int) {
164
+	w.Write([]byte(strconv.FormatFloat(val, 'g', -1, precision)))
165
+}
166
+
167
+// printComplex outputs a complex value using the specified float precision
168
+// for the real and imaginary parts to Writer w.
169
+func printComplex(w io.Writer, c complex128, floatPrecision int) {
170
+	r := real(c)
171
+	w.Write(openParenBytes)
172
+	w.Write([]byte(strconv.FormatFloat(r, 'g', -1, floatPrecision)))
173
+	i := imag(c)
174
+	if i >= 0 {
175
+		w.Write(plusBytes)
176
+	}
177
+	w.Write([]byte(strconv.FormatFloat(i, 'g', -1, floatPrecision)))
178
+	w.Write(iBytes)
179
+	w.Write(closeParenBytes)
180
+}
181
+
182
+// printHexPtr outputs a uintptr formatted as hexidecimal with a leading '0x'
183
+// prefix to Writer w.
184
+func printHexPtr(w io.Writer, p uintptr) {
185
+	// Null pointer.
186
+	num := uint64(p)
187
+	if num == 0 {
188
+		w.Write(nilAngleBytes)
189
+		return
190
+	}
191
+
192
+	// Max uint64 is 16 bytes in hex + 2 bytes for '0x' prefix
193
+	buf := make([]byte, 18)
194
+
195
+	// It's simpler to construct the hex string right to left.
196
+	base := uint64(16)
197
+	i := len(buf) - 1
198
+	for num >= base {
199
+		buf[i] = hexDigits[num%base]
200
+		num /= base
201
+		i--
202
+	}
203
+	buf[i] = hexDigits[num]
204
+
205
+	// Add '0x' prefix.
206
+	i--
207
+	buf[i] = 'x'
208
+	i--
209
+	buf[i] = '0'
210
+
211
+	// Strip unused leading bytes.
212
+	buf = buf[i:]
213
+	w.Write(buf)
214
+}
215
+
216
+// valuesSorter implements sort.Interface to allow a slice of reflect.Value
217
+// elements to be sorted.
218
+type valuesSorter struct {
219
+	values  []reflect.Value
220
+	strings []string // either nil or same len and values
221
+	cs      *ConfigState
222
+}
223
+
224
+// newValuesSorter initializes a valuesSorter instance, which holds a set of
225
+// surrogate keys on which the data should be sorted.  It uses flags in
226
+// ConfigState to decide if and how to populate those surrogate keys.
227
+func newValuesSorter(values []reflect.Value, cs *ConfigState) sort.Interface {
228
+	vs := &valuesSorter{values: values, cs: cs}
229
+	if canSortSimply(vs.values[0].Kind()) {
230
+		return vs
231
+	}
232
+	if !cs.DisableMethods {
233
+		vs.strings = make([]string, len(values))
234
+		for i := range vs.values {
235
+			b := bytes.Buffer{}
236
+			if !handleMethods(cs, &b, vs.values[i]) {
237
+				vs.strings = nil
238
+				break
239
+			}
240
+			vs.strings[i] = b.String()
241
+		}
242
+	}
243
+	if vs.strings == nil && cs.SpewKeys {
244
+		vs.strings = make([]string, len(values))
245
+		for i := range vs.values {
246
+			vs.strings[i] = Sprintf("%#v", vs.values[i].Interface())
247
+		}
248
+	}
249
+	return vs
250
+}
251
+
252
+// canSortSimply tests whether a reflect.Kind is a primitive that can be sorted
253
+// directly, or whether it should be considered for sorting by surrogate keys
254
+// (if the ConfigState allows it).
255
+func canSortSimply(kind reflect.Kind) bool {
256
+	// This switch parallels valueSortLess, except for the default case.
257
+	switch kind {
258
+	case reflect.Bool:
259
+		return true
260
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
261
+		return true
262
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
263
+		return true
264
+	case reflect.Float32, reflect.Float64:
265
+		return true
266
+	case reflect.String:
267
+		return true
268
+	case reflect.Uintptr:
269
+		return true
270
+	case reflect.Array:
271
+		return true
272
+	}
273
+	return false
274
+}
275
+
276
+// Len returns the number of values in the slice.  It is part of the
277
+// sort.Interface implementation.
278
+func (s *valuesSorter) Len() int {
279
+	return len(s.values)
280
+}
281
+
282
+// Swap swaps the values at the passed indices.  It is part of the
283
+// sort.Interface implementation.
284
+func (s *valuesSorter) Swap(i, j int) {
285
+	s.values[i], s.values[j] = s.values[j], s.values[i]
286
+	if s.strings != nil {
287
+		s.strings[i], s.strings[j] = s.strings[j], s.strings[i]
288
+	}
289
+}
290
+
291
+// valueSortLess returns whether the first value should sort before the second
292
+// value.  It is used by valueSorter.Less as part of the sort.Interface
293
+// implementation.
294
+func valueSortLess(a, b reflect.Value) bool {
295
+	switch a.Kind() {
296
+	case reflect.Bool:
297
+		return !a.Bool() && b.Bool()
298
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
299
+		return a.Int() < b.Int()
300
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
301
+		return a.Uint() < b.Uint()
302
+	case reflect.Float32, reflect.Float64:
303
+		return a.Float() < b.Float()
304
+	case reflect.String:
305
+		return a.String() < b.String()
306
+	case reflect.Uintptr:
307
+		return a.Uint() < b.Uint()
308
+	case reflect.Array:
309
+		// Compare the contents of both arrays.
310
+		l := a.Len()
311
+		for i := 0; i < l; i++ {
312
+			av := a.Index(i)
313
+			bv := b.Index(i)
314
+			if av.Interface() == bv.Interface() {
315
+				continue
316
+			}
317
+			return valueSortLess(av, bv)
318
+		}
319
+	}
320
+	return a.String() < b.String()
321
+}
322
+
323
+// Less returns whether the value at index i should sort before the
324
+// value at index j.  It is part of the sort.Interface implementation.
325
+func (s *valuesSorter) Less(i, j int) bool {
326
+	if s.strings == nil {
327
+		return valueSortLess(s.values[i], s.values[j])
328
+	}
329
+	return s.strings[i] < s.strings[j]
330
+}
331
+
332
+// sortValues is a sort function that handles both native types and any type that
333
+// can be converted to error or Stringer.  Other inputs are sorted according to
334
+// their Value.String() value to ensure display stability.
335
+func sortValues(values []reflect.Value, cs *ConfigState) {
336
+	if len(values) == 0 {
337
+		return
338
+	}
339
+	sort.Sort(newValuesSorter(values, cs))
340
+}
0 341
new file mode 100644
... ...
@@ -0,0 +1,297 @@
0
+/*
1
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
2
+ *
3
+ * Permission to use, copy, modify, and distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ */
15
+
16
+package spew
17
+
18
+import (
19
+	"bytes"
20
+	"fmt"
21
+	"io"
22
+	"os"
23
+)
24
+
25
+// ConfigState houses the configuration options used by spew to format and
26
+// display values.  There is a global instance, Config, that is used to control
27
+// all top-level Formatter and Dump functionality.  Each ConfigState instance
28
+// provides methods equivalent to the top-level functions.
29
+//
30
+// The zero value for ConfigState provides no indentation.  You would typically
31
+// want to set it to a space or a tab.
32
+//
33
+// Alternatively, you can use NewDefaultConfig to get a ConfigState instance
34
+// with default settings.  See the documentation of NewDefaultConfig for default
35
+// values.
36
+type ConfigState struct {
37
+	// Indent specifies the string to use for each indentation level.  The
38
+	// global config instance that all top-level functions use set this to a
39
+	// single space by default.  If you would like more indentation, you might
40
+	// set this to a tab with "\t" or perhaps two spaces with "  ".
41
+	Indent string
42
+
43
+	// MaxDepth controls the maximum number of levels to descend into nested
44
+	// data structures.  The default, 0, means there is no limit.
45
+	//
46
+	// NOTE: Circular data structures are properly detected, so it is not
47
+	// necessary to set this value unless you specifically want to limit deeply
48
+	// nested data structures.
49
+	MaxDepth int
50
+
51
+	// DisableMethods specifies whether or not error and Stringer interfaces are
52
+	// invoked for types that implement them.
53
+	DisableMethods bool
54
+
55
+	// DisablePointerMethods specifies whether or not to check for and invoke
56
+	// error and Stringer interfaces on types which only accept a pointer
57
+	// receiver when the current type is not a pointer.
58
+	//
59
+	// NOTE: This might be an unsafe action since calling one of these methods
60
+	// with a pointer receiver could technically mutate the value, however,
61
+	// in practice, types which choose to satisify an error or Stringer
62
+	// interface with a pointer receiver should not be mutating their state
63
+	// inside these interface methods.  As a result, this option relies on
64
+	// access to the unsafe package, so it will not have any effect when
65
+	// running in environments without access to the unsafe package such as
66
+	// Google App Engine or with the "safe" build tag specified.
67
+	DisablePointerMethods bool
68
+
69
+	// ContinueOnMethod specifies whether or not recursion should continue once
70
+	// a custom error or Stringer interface is invoked.  The default, false,
71
+	// means it will print the results of invoking the custom error or Stringer
72
+	// interface and return immediately instead of continuing to recurse into
73
+	// the internals of the data type.
74
+	//
75
+	// NOTE: This flag does not have any effect if method invocation is disabled
76
+	// via the DisableMethods or DisablePointerMethods options.
77
+	ContinueOnMethod bool
78
+
79
+	// SortKeys specifies map keys should be sorted before being printed. Use
80
+	// this to have a more deterministic, diffable output.  Note that only
81
+	// native types (bool, int, uint, floats, uintptr and string) and types
82
+	// that support the error or Stringer interfaces (if methods are
83
+	// enabled) are supported, with other types sorted according to the
84
+	// reflect.Value.String() output which guarantees display stability.
85
+	SortKeys bool
86
+
87
+	// SpewKeys specifies that, as a last resort attempt, map keys should
88
+	// be spewed to strings and sorted by those strings.  This is only
89
+	// considered if SortKeys is true.
90
+	SpewKeys bool
91
+}
92
+
93
+// Config is the active configuration of the top-level functions.
94
+// The configuration can be changed by modifying the contents of spew.Config.
95
+var Config = ConfigState{Indent: " "}
96
+
97
+// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
98
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
99
+// the formatted string as a value that satisfies error.  See NewFormatter
100
+// for formatting details.
101
+//
102
+// This function is shorthand for the following syntax:
103
+//
104
+//	fmt.Errorf(format, c.NewFormatter(a), c.NewFormatter(b))
105
+func (c *ConfigState) Errorf(format string, a ...interface{}) (err error) {
106
+	return fmt.Errorf(format, c.convertArgs(a)...)
107
+}
108
+
109
+// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
110
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
111
+// the number of bytes written and any write error encountered.  See
112
+// NewFormatter for formatting details.
113
+//
114
+// This function is shorthand for the following syntax:
115
+//
116
+//	fmt.Fprint(w, c.NewFormatter(a), c.NewFormatter(b))
117
+func (c *ConfigState) Fprint(w io.Writer, a ...interface{}) (n int, err error) {
118
+	return fmt.Fprint(w, c.convertArgs(a)...)
119
+}
120
+
121
+// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
122
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
123
+// the number of bytes written and any write error encountered.  See
124
+// NewFormatter for formatting details.
125
+//
126
+// This function is shorthand for the following syntax:
127
+//
128
+//	fmt.Fprintf(w, format, c.NewFormatter(a), c.NewFormatter(b))
129
+func (c *ConfigState) Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
130
+	return fmt.Fprintf(w, format, c.convertArgs(a)...)
131
+}
132
+
133
+// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
134
+// passed with a Formatter interface returned by c.NewFormatter.  See
135
+// NewFormatter for formatting details.
136
+//
137
+// This function is shorthand for the following syntax:
138
+//
139
+//	fmt.Fprintln(w, c.NewFormatter(a), c.NewFormatter(b))
140
+func (c *ConfigState) Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
141
+	return fmt.Fprintln(w, c.convertArgs(a)...)
142
+}
143
+
144
+// Print is a wrapper for fmt.Print that treats each argument as if it were
145
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
146
+// the number of bytes written and any write error encountered.  See
147
+// NewFormatter for formatting details.
148
+//
149
+// This function is shorthand for the following syntax:
150
+//
151
+//	fmt.Print(c.NewFormatter(a), c.NewFormatter(b))
152
+func (c *ConfigState) Print(a ...interface{}) (n int, err error) {
153
+	return fmt.Print(c.convertArgs(a)...)
154
+}
155
+
156
+// Printf is a wrapper for fmt.Printf that treats each argument as if it were
157
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
158
+// the number of bytes written and any write error encountered.  See
159
+// NewFormatter for formatting details.
160
+//
161
+// This function is shorthand for the following syntax:
162
+//
163
+//	fmt.Printf(format, c.NewFormatter(a), c.NewFormatter(b))
164
+func (c *ConfigState) Printf(format string, a ...interface{}) (n int, err error) {
165
+	return fmt.Printf(format, c.convertArgs(a)...)
166
+}
167
+
168
+// Println is a wrapper for fmt.Println that treats each argument as if it were
169
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
170
+// the number of bytes written and any write error encountered.  See
171
+// NewFormatter for formatting details.
172
+//
173
+// This function is shorthand for the following syntax:
174
+//
175
+//	fmt.Println(c.NewFormatter(a), c.NewFormatter(b))
176
+func (c *ConfigState) Println(a ...interface{}) (n int, err error) {
177
+	return fmt.Println(c.convertArgs(a)...)
178
+}
179
+
180
+// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
181
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
182
+// the resulting string.  See NewFormatter for formatting details.
183
+//
184
+// This function is shorthand for the following syntax:
185
+//
186
+//	fmt.Sprint(c.NewFormatter(a), c.NewFormatter(b))
187
+func (c *ConfigState) Sprint(a ...interface{}) string {
188
+	return fmt.Sprint(c.convertArgs(a)...)
189
+}
190
+
191
+// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
192
+// passed with a Formatter interface returned by c.NewFormatter.  It returns
193
+// the resulting string.  See NewFormatter for formatting details.
194
+//
195
+// This function is shorthand for the following syntax:
196
+//
197
+//	fmt.Sprintf(format, c.NewFormatter(a), c.NewFormatter(b))
198
+func (c *ConfigState) Sprintf(format string, a ...interface{}) string {
199
+	return fmt.Sprintf(format, c.convertArgs(a)...)
200
+}
201
+
202
+// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
203
+// were passed with a Formatter interface returned by c.NewFormatter.  It
204
+// returns the resulting string.  See NewFormatter for formatting details.
205
+//
206
+// This function is shorthand for the following syntax:
207
+//
208
+//	fmt.Sprintln(c.NewFormatter(a), c.NewFormatter(b))
209
+func (c *ConfigState) Sprintln(a ...interface{}) string {
210
+	return fmt.Sprintln(c.convertArgs(a)...)
211
+}
212
+
213
+/*
214
+NewFormatter returns a custom formatter that satisfies the fmt.Formatter
215
+interface.  As a result, it integrates cleanly with standard fmt package
216
+printing functions.  The formatter is useful for inline printing of smaller data
217
+types similar to the standard %v format specifier.
218
+
219
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
220
+addresses), %#v (adds types), and %#+v (adds types and pointer addresses) verb
221
+combinations.  Any other verbs such as %x and %q will be sent to the the
222
+standard fmt package for formatting.  In addition, the custom formatter ignores
223
+the width and precision arguments (however they will still work on the format
224
+specifiers not handled by the custom formatter).
225
+
226
+Typically this function shouldn't be called directly.  It is much easier to make
227
+use of the custom formatter by calling one of the convenience functions such as
228
+c.Printf, c.Println, or c.Printf.
229
+*/
230
+func (c *ConfigState) NewFormatter(v interface{}) fmt.Formatter {
231
+	return newFormatter(c, v)
232
+}
233
+
234
+// Fdump formats and displays the passed arguments to io.Writer w.  It formats
235
+// exactly the same as Dump.
236
+func (c *ConfigState) Fdump(w io.Writer, a ...interface{}) {
237
+	fdump(c, w, a...)
238
+}
239
+
240
+/*
241
+Dump displays the passed parameters to standard out with newlines, customizable
242
+indentation, and additional debug information such as complete types and all
243
+pointer addresses used to indirect to the final value.  It provides the
244
+following features over the built-in printing facilities provided by the fmt
245
+package:
246
+
247
+	* Pointers are dereferenced and followed
248
+	* Circular data structures are detected and handled properly
249
+	* Custom Stringer/error interfaces are optionally invoked, including
250
+	  on unexported types
251
+	* Custom types which only implement the Stringer/error interfaces via
252
+	  a pointer receiver are optionally invoked when passing non-pointer
253
+	  variables
254
+	* Byte arrays and slices are dumped like the hexdump -C command which
255
+	  includes offsets, byte values in hex, and ASCII output
256
+
257
+The configuration options are controlled by modifying the public members
258
+of c.  See ConfigState for options documentation.
259
+
260
+See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
261
+get the formatted result as a string.
262
+*/
263
+func (c *ConfigState) Dump(a ...interface{}) {
264
+	fdump(c, os.Stdout, a...)
265
+}
266
+
267
+// Sdump returns a string with the passed arguments formatted exactly the same
268
+// as Dump.
269
+func (c *ConfigState) Sdump(a ...interface{}) string {
270
+	var buf bytes.Buffer
271
+	fdump(c, &buf, a...)
272
+	return buf.String()
273
+}
274
+
275
+// convertArgs accepts a slice of arguments and returns a slice of the same
276
+// length with each argument converted to a spew Formatter interface using
277
+// the ConfigState associated with s.
278
+func (c *ConfigState) convertArgs(args []interface{}) (formatters []interface{}) {
279
+	formatters = make([]interface{}, len(args))
280
+	for index, arg := range args {
281
+		formatters[index] = newFormatter(c, arg)
282
+	}
283
+	return formatters
284
+}
285
+
286
+// NewDefaultConfig returns a ConfigState with the following default settings.
287
+//
288
+// 	Indent: " "
289
+// 	MaxDepth: 0
290
+// 	DisableMethods: false
291
+// 	DisablePointerMethods: false
292
+// 	ContinueOnMethod: false
293
+// 	SortKeys: false
294
+func NewDefaultConfig() *ConfigState {
295
+	return &ConfigState{Indent: " "}
296
+}
0 297
new file mode 100644
... ...
@@ -0,0 +1,202 @@
0
+/*
1
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
2
+ *
3
+ * Permission to use, copy, modify, and distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ */
15
+
16
+/*
17
+Package spew implements a deep pretty printer for Go data structures to aid in
18
+debugging.
19
+
20
+A quick overview of the additional features spew provides over the built-in
21
+printing facilities for Go data types are as follows:
22
+
23
+	* Pointers are dereferenced and followed
24
+	* Circular data structures are detected and handled properly
25
+	* Custom Stringer/error interfaces are optionally invoked, including
26
+	  on unexported types
27
+	* Custom types which only implement the Stringer/error interfaces via
28
+	  a pointer receiver are optionally invoked when passing non-pointer
29
+	  variables
30
+	* Byte arrays and slices are dumped like the hexdump -C command which
31
+	  includes offsets, byte values in hex, and ASCII output (only when using
32
+	  Dump style)
33
+
34
+There are two different approaches spew allows for dumping Go data structures:
35
+
36
+	* Dump style which prints with newlines, customizable indentation,
37
+	  and additional debug information such as types and all pointer addresses
38
+	  used to indirect to the final value
39
+	* A custom Formatter interface that integrates cleanly with the standard fmt
40
+	  package and replaces %v, %+v, %#v, and %#+v to provide inline printing
41
+	  similar to the default %v while providing the additional functionality
42
+	  outlined above and passing unsupported format verbs such as %x and %q
43
+	  along to fmt
44
+
45
+Quick Start
46
+
47
+This section demonstrates how to quickly get started with spew.  See the
48
+sections below for further details on formatting and configuration options.
49
+
50
+To dump a variable with full newlines, indentation, type, and pointer
51
+information use Dump, Fdump, or Sdump:
52
+	spew.Dump(myVar1, myVar2, ...)
53
+	spew.Fdump(someWriter, myVar1, myVar2, ...)
54
+	str := spew.Sdump(myVar1, myVar2, ...)
55
+
56
+Alternatively, if you would prefer to use format strings with a compacted inline
57
+printing style, use the convenience wrappers Printf, Fprintf, etc with
58
+%v (most compact), %+v (adds pointer addresses), %#v (adds types), or
59
+%#+v (adds types and pointer addresses):
60
+	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
61
+	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
62
+	spew.Fprintf(someWriter, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
63
+	spew.Fprintf(someWriter, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
64
+
65
+Configuration Options
66
+
67
+Configuration of spew is handled by fields in the ConfigState type.  For
68
+convenience, all of the top-level functions use a global state available
69
+via the spew.Config global.
70
+
71
+It is also possible to create a ConfigState instance that provides methods
72
+equivalent to the top-level functions.  This allows concurrent configuration
73
+options.  See the ConfigState documentation for more details.
74
+
75
+The following configuration options are available:
76
+	* Indent
77
+		String to use for each indentation level for Dump functions.
78
+		It is a single space by default.  A popular alternative is "\t".
79
+
80
+	* MaxDepth
81
+		Maximum number of levels to descend into nested data structures.
82
+		There is no limit by default.
83
+
84
+	* DisableMethods
85
+		Disables invocation of error and Stringer interface methods.
86
+		Method invocation is enabled by default.
87
+
88
+	* DisablePointerMethods
89
+		Disables invocation of error and Stringer interface methods on types
90
+		which only accept pointer receivers from non-pointer variables.
91
+		Pointer method invocation is enabled by default.
92
+
93
+	* ContinueOnMethod
94
+		Enables recursion into types after invoking error and Stringer interface
95
+		methods. Recursion after method invocation is disabled by default.
96
+
97
+	* SortKeys
98
+		Specifies map keys should be sorted before being printed. Use
99
+		this to have a more deterministic, diffable output.  Note that
100
+		only native types (bool, int, uint, floats, uintptr and string)
101
+		and types which implement error or Stringer interfaces are
102
+		supported with other types sorted according to the
103
+		reflect.Value.String() output which guarantees display
104
+		stability.  Natural map order is used by default.
105
+
106
+	* SpewKeys
107
+		Specifies that, as a last resort attempt, map keys should be
108
+		spewed to strings and sorted by those strings.  This is only
109
+		considered if SortKeys is true.
110
+
111
+Dump Usage
112
+
113
+Simply call spew.Dump with a list of variables you want to dump:
114
+
115
+	spew.Dump(myVar1, myVar2, ...)
116
+
117
+You may also call spew.Fdump if you would prefer to output to an arbitrary
118
+io.Writer.  For example, to dump to standard error:
119
+
120
+	spew.Fdump(os.Stderr, myVar1, myVar2, ...)
121
+
122
+A third option is to call spew.Sdump to get the formatted output as a string:
123
+
124
+	str := spew.Sdump(myVar1, myVar2, ...)
125
+
126
+Sample Dump Output
127
+
128
+See the Dump example for details on the setup of the types and variables being
129
+shown here.
130
+
131
+	(main.Foo) {
132
+	 unexportedField: (*main.Bar)(0xf84002e210)({
133
+	  flag: (main.Flag) flagTwo,
134
+	  data: (uintptr) <nil>
135
+	 }),
136
+	 ExportedField: (map[interface {}]interface {}) (len=1) {
137
+	  (string) (len=3) "one": (bool) true
138
+	 }
139
+	}
140
+
141
+Byte (and uint8) arrays and slices are displayed uniquely like the hexdump -C
142
+command as shown.
143
+	([]uint8) (len=32 cap=32) {
144
+	 00000000  11 12 13 14 15 16 17 18  19 1a 1b 1c 1d 1e 1f 20  |............... |
145
+	 00000010  21 22 23 24 25 26 27 28  29 2a 2b 2c 2d 2e 2f 30  |!"#$%&'()*+,-./0|
146
+	 00000020  31 32                                             |12|
147
+	}
148
+
149
+Custom Formatter
150
+
151
+Spew provides a custom formatter that implements the fmt.Formatter interface
152
+so that it integrates cleanly with standard fmt package printing functions. The
153
+formatter is useful for inline printing of smaller data types similar to the
154
+standard %v format specifier.
155
+
156
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
157
+addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
158
+combinations.  Any other verbs such as %x and %q will be sent to the the
159
+standard fmt package for formatting.  In addition, the custom formatter ignores
160
+the width and precision arguments (however they will still work on the format
161
+specifiers not handled by the custom formatter).
162
+
163
+Custom Formatter Usage
164
+
165
+The simplest way to make use of the spew custom formatter is to call one of the
166
+convenience functions such as spew.Printf, spew.Println, or spew.Printf.  The
167
+functions have syntax you are most likely already familiar with:
168
+
169
+	spew.Printf("myVar1: %v -- myVar2: %+v", myVar1, myVar2)
170
+	spew.Printf("myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
171
+	spew.Println(myVar, myVar2)
172
+	spew.Fprintf(os.Stderr, "myVar1: %v -- myVar2: %+v", myVar1, myVar2)
173
+	spew.Fprintf(os.Stderr, "myVar3: %#v -- myVar4: %#+v", myVar3, myVar4)
174
+
175
+See the Index for the full list convenience functions.
176
+
177
+Sample Formatter Output
178
+
179
+Double pointer to a uint8:
180
+	  %v: <**>5
181
+	 %+v: <**>(0xf8400420d0->0xf8400420c8)5
182
+	 %#v: (**uint8)5
183
+	%#+v: (**uint8)(0xf8400420d0->0xf8400420c8)5
184
+
185
+Pointer to circular struct with a uint8 field and a pointer to itself:
186
+	  %v: <*>{1 <*><shown>}
187
+	 %+v: <*>(0xf84003e260){ui8:1 c:<*>(0xf84003e260)<shown>}
188
+	 %#v: (*main.circular){ui8:(uint8)1 c:(*main.circular)<shown>}
189
+	%#+v: (*main.circular)(0xf84003e260){ui8:(uint8)1 c:(*main.circular)(0xf84003e260)<shown>}
190
+
191
+See the Printf example for details on the setup of variables being shown
192
+here.
193
+
194
+Errors
195
+
196
+Since it is possible for custom Stringer/error interfaces to panic, spew
197
+detects them and handles them internally by printing the panic information
198
+inline with the output.  Since spew is intended to provide deep pretty printing
199
+capabilities on structures, it intentionally does not return any errors.
200
+*/
201
+package spew
0 202
new file mode 100644
... ...
@@ -0,0 +1,509 @@
0
+/*
1
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
2
+ *
3
+ * Permission to use, copy, modify, and distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ */
15
+
16
+package spew
17
+
18
+import (
19
+	"bytes"
20
+	"encoding/hex"
21
+	"fmt"
22
+	"io"
23
+	"os"
24
+	"reflect"
25
+	"regexp"
26
+	"strconv"
27
+	"strings"
28
+)
29
+
30
+var (
31
+	// uint8Type is a reflect.Type representing a uint8.  It is used to
32
+	// convert cgo types to uint8 slices for hexdumping.
33
+	uint8Type = reflect.TypeOf(uint8(0))
34
+
35
+	// cCharRE is a regular expression that matches a cgo char.
36
+	// It is used to detect character arrays to hexdump them.
37
+	cCharRE = regexp.MustCompile("^.*\\._Ctype_char$")
38
+
39
+	// cUnsignedCharRE is a regular expression that matches a cgo unsigned
40
+	// char.  It is used to detect unsigned character arrays to hexdump
41
+	// them.
42
+	cUnsignedCharRE = regexp.MustCompile("^.*\\._Ctype_unsignedchar$")
43
+
44
+	// cUint8tCharRE is a regular expression that matches a cgo uint8_t.
45
+	// It is used to detect uint8_t arrays to hexdump them.
46
+	cUint8tCharRE = regexp.MustCompile("^.*\\._Ctype_uint8_t$")
47
+)
48
+
49
+// dumpState contains information about the state of a dump operation.
50
+type dumpState struct {
51
+	w                io.Writer
52
+	depth            int
53
+	pointers         map[uintptr]int
54
+	ignoreNextType   bool
55
+	ignoreNextIndent bool
56
+	cs               *ConfigState
57
+}
58
+
59
+// indent performs indentation according to the depth level and cs.Indent
60
+// option.
61
+func (d *dumpState) indent() {
62
+	if d.ignoreNextIndent {
63
+		d.ignoreNextIndent = false
64
+		return
65
+	}
66
+	d.w.Write(bytes.Repeat([]byte(d.cs.Indent), d.depth))
67
+}
68
+
69
+// unpackValue returns values inside of non-nil interfaces when possible.
70
+// This is useful for data types like structs, arrays, slices, and maps which
71
+// can contain varying types packed inside an interface.
72
+func (d *dumpState) unpackValue(v reflect.Value) reflect.Value {
73
+	if v.Kind() == reflect.Interface && !v.IsNil() {
74
+		v = v.Elem()
75
+	}
76
+	return v
77
+}
78
+
79
+// dumpPtr handles formatting of pointers by indirecting them as necessary.
80
+func (d *dumpState) dumpPtr(v reflect.Value) {
81
+	// Remove pointers at or below the current depth from map used to detect
82
+	// circular refs.
83
+	for k, depth := range d.pointers {
84
+		if depth >= d.depth {
85
+			delete(d.pointers, k)
86
+		}
87
+	}
88
+
89
+	// Keep list of all dereferenced pointers to show later.
90
+	pointerChain := make([]uintptr, 0)
91
+
92
+	// Figure out how many levels of indirection there are by dereferencing
93
+	// pointers and unpacking interfaces down the chain while detecting circular
94
+	// references.
95
+	nilFound := false
96
+	cycleFound := false
97
+	indirects := 0
98
+	ve := v
99
+	for ve.Kind() == reflect.Ptr {
100
+		if ve.IsNil() {
101
+			nilFound = true
102
+			break
103
+		}
104
+		indirects++
105
+		addr := ve.Pointer()
106
+		pointerChain = append(pointerChain, addr)
107
+		if pd, ok := d.pointers[addr]; ok && pd < d.depth {
108
+			cycleFound = true
109
+			indirects--
110
+			break
111
+		}
112
+		d.pointers[addr] = d.depth
113
+
114
+		ve = ve.Elem()
115
+		if ve.Kind() == reflect.Interface {
116
+			if ve.IsNil() {
117
+				nilFound = true
118
+				break
119
+			}
120
+			ve = ve.Elem()
121
+		}
122
+	}
123
+
124
+	// Display type information.
125
+	d.w.Write(openParenBytes)
126
+	d.w.Write(bytes.Repeat(asteriskBytes, indirects))
127
+	d.w.Write([]byte(ve.Type().String()))
128
+	d.w.Write(closeParenBytes)
129
+
130
+	// Display pointer information.
131
+	if len(pointerChain) > 0 {
132
+		d.w.Write(openParenBytes)
133
+		for i, addr := range pointerChain {
134
+			if i > 0 {
135
+				d.w.Write(pointerChainBytes)
136
+			}
137
+			printHexPtr(d.w, addr)
138
+		}
139
+		d.w.Write(closeParenBytes)
140
+	}
141
+
142
+	// Display dereferenced value.
143
+	d.w.Write(openParenBytes)
144
+	switch {
145
+	case nilFound == true:
146
+		d.w.Write(nilAngleBytes)
147
+
148
+	case cycleFound == true:
149
+		d.w.Write(circularBytes)
150
+
151
+	default:
152
+		d.ignoreNextType = true
153
+		d.dump(ve)
154
+	}
155
+	d.w.Write(closeParenBytes)
156
+}
157
+
158
+// dumpSlice handles formatting of arrays and slices.  Byte (uint8 under
159
+// reflection) arrays and slices are dumped in hexdump -C fashion.
160
+func (d *dumpState) dumpSlice(v reflect.Value) {
161
+	// Determine whether this type should be hex dumped or not.  Also,
162
+	// for types which should be hexdumped, try to use the underlying data
163
+	// first, then fall back to trying to convert them to a uint8 slice.
164
+	var buf []uint8
165
+	doConvert := false
166
+	doHexDump := false
167
+	numEntries := v.Len()
168
+	if numEntries > 0 {
169
+		vt := v.Index(0).Type()
170
+		vts := vt.String()
171
+		switch {
172
+		// C types that need to be converted.
173
+		case cCharRE.MatchString(vts):
174
+			fallthrough
175
+		case cUnsignedCharRE.MatchString(vts):
176
+			fallthrough
177
+		case cUint8tCharRE.MatchString(vts):
178
+			doConvert = true
179
+
180
+		// Try to use existing uint8 slices and fall back to converting
181
+		// and copying if that fails.
182
+		case vt.Kind() == reflect.Uint8:
183
+			// We need an addressable interface to convert the type
184
+			// to a byte slice.  However, the reflect package won't
185
+			// give us an interface on certain things like
186
+			// unexported struct fields in order to enforce
187
+			// visibility rules.  We use unsafe, when available, to
188
+			// bypass these restrictions since this package does not
189
+			// mutate the values.
190
+			vs := v
191
+			if !vs.CanInterface() || !vs.CanAddr() {
192
+				vs = unsafeReflectValue(vs)
193
+			}
194
+			if !UnsafeDisabled {
195
+				vs = vs.Slice(0, numEntries)
196
+
197
+				// Use the existing uint8 slice if it can be
198
+				// type asserted.
199
+				iface := vs.Interface()
200
+				if slice, ok := iface.([]uint8); ok {
201
+					buf = slice
202
+					doHexDump = true
203
+					break
204
+				}
205
+			}
206
+
207
+			// The underlying data needs to be converted if it can't
208
+			// be type asserted to a uint8 slice.
209
+			doConvert = true
210
+		}
211
+
212
+		// Copy and convert the underlying type if needed.
213
+		if doConvert && vt.ConvertibleTo(uint8Type) {
214
+			// Convert and copy each element into a uint8 byte
215
+			// slice.
216
+			buf = make([]uint8, numEntries)
217
+			for i := 0; i < numEntries; i++ {
218
+				vv := v.Index(i)
219
+				buf[i] = uint8(vv.Convert(uint8Type).Uint())
220
+			}
221
+			doHexDump = true
222
+		}
223
+	}
224
+
225
+	// Hexdump the entire slice as needed.
226
+	if doHexDump {
227
+		indent := strings.Repeat(d.cs.Indent, d.depth)
228
+		str := indent + hex.Dump(buf)
229
+		str = strings.Replace(str, "\n", "\n"+indent, -1)
230
+		str = strings.TrimRight(str, d.cs.Indent)
231
+		d.w.Write([]byte(str))
232
+		return
233
+	}
234
+
235
+	// Recursively call dump for each item.
236
+	for i := 0; i < numEntries; i++ {
237
+		d.dump(d.unpackValue(v.Index(i)))
238
+		if i < (numEntries - 1) {
239
+			d.w.Write(commaNewlineBytes)
240
+		} else {
241
+			d.w.Write(newlineBytes)
242
+		}
243
+	}
244
+}
245
+
246
+// dump is the main workhorse for dumping a value.  It uses the passed reflect
247
+// value to figure out what kind of object we are dealing with and formats it
248
+// appropriately.  It is a recursive function, however circular data structures
249
+// are detected and handled properly.
250
+func (d *dumpState) dump(v reflect.Value) {
251
+	// Handle invalid reflect values immediately.
252
+	kind := v.Kind()
253
+	if kind == reflect.Invalid {
254
+		d.w.Write(invalidAngleBytes)
255
+		return
256
+	}
257
+
258
+	// Handle pointers specially.
259
+	if kind == reflect.Ptr {
260
+		d.indent()
261
+		d.dumpPtr(v)
262
+		return
263
+	}
264
+
265
+	// Print type information unless already handled elsewhere.
266
+	if !d.ignoreNextType {
267
+		d.indent()
268
+		d.w.Write(openParenBytes)
269
+		d.w.Write([]byte(v.Type().String()))
270
+		d.w.Write(closeParenBytes)
271
+		d.w.Write(spaceBytes)
272
+	}
273
+	d.ignoreNextType = false
274
+
275
+	// Display length and capacity if the built-in len and cap functions
276
+	// work with the value's kind and the len/cap itself is non-zero.
277
+	valueLen, valueCap := 0, 0
278
+	switch v.Kind() {
279
+	case reflect.Array, reflect.Slice, reflect.Chan:
280
+		valueLen, valueCap = v.Len(), v.Cap()
281
+	case reflect.Map, reflect.String:
282
+		valueLen = v.Len()
283
+	}
284
+	if valueLen != 0 || valueCap != 0 {
285
+		d.w.Write(openParenBytes)
286
+		if valueLen != 0 {
287
+			d.w.Write(lenEqualsBytes)
288
+			printInt(d.w, int64(valueLen), 10)
289
+		}
290
+		if valueCap != 0 {
291
+			if valueLen != 0 {
292
+				d.w.Write(spaceBytes)
293
+			}
294
+			d.w.Write(capEqualsBytes)
295
+			printInt(d.w, int64(valueCap), 10)
296
+		}
297
+		d.w.Write(closeParenBytes)
298
+		d.w.Write(spaceBytes)
299
+	}
300
+
301
+	// Call Stringer/error interfaces if they exist and the handle methods flag
302
+	// is enabled
303
+	if !d.cs.DisableMethods {
304
+		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
305
+			if handled := handleMethods(d.cs, d.w, v); handled {
306
+				return
307
+			}
308
+		}
309
+	}
310
+
311
+	switch kind {
312
+	case reflect.Invalid:
313
+		// Do nothing.  We should never get here since invalid has already
314
+		// been handled above.
315
+
316
+	case reflect.Bool:
317
+		printBool(d.w, v.Bool())
318
+
319
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
320
+		printInt(d.w, v.Int(), 10)
321
+
322
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
323
+		printUint(d.w, v.Uint(), 10)
324
+
325
+	case reflect.Float32:
326
+		printFloat(d.w, v.Float(), 32)
327
+
328
+	case reflect.Float64:
329
+		printFloat(d.w, v.Float(), 64)
330
+
331
+	case reflect.Complex64:
332
+		printComplex(d.w, v.Complex(), 32)
333
+
334
+	case reflect.Complex128:
335
+		printComplex(d.w, v.Complex(), 64)
336
+
337
+	case reflect.Slice:
338
+		if v.IsNil() {
339
+			d.w.Write(nilAngleBytes)
340
+			break
341
+		}
342
+		fallthrough
343
+
344
+	case reflect.Array:
345
+		d.w.Write(openBraceNewlineBytes)
346
+		d.depth++
347
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
348
+			d.indent()
349
+			d.w.Write(maxNewlineBytes)
350
+		} else {
351
+			d.dumpSlice(v)
352
+		}
353
+		d.depth--
354
+		d.indent()
355
+		d.w.Write(closeBraceBytes)
356
+
357
+	case reflect.String:
358
+		d.w.Write([]byte(strconv.Quote(v.String())))
359
+
360
+	case reflect.Interface:
361
+		// The only time we should get here is for nil interfaces due to
362
+		// unpackValue calls.
363
+		if v.IsNil() {
364
+			d.w.Write(nilAngleBytes)
365
+		}
366
+
367
+	case reflect.Ptr:
368
+		// Do nothing.  We should never get here since pointers have already
369
+		// been handled above.
370
+
371
+	case reflect.Map:
372
+		// nil maps should be indicated as different than empty maps
373
+		if v.IsNil() {
374
+			d.w.Write(nilAngleBytes)
375
+			break
376
+		}
377
+
378
+		d.w.Write(openBraceNewlineBytes)
379
+		d.depth++
380
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
381
+			d.indent()
382
+			d.w.Write(maxNewlineBytes)
383
+		} else {
384
+			numEntries := v.Len()
385
+			keys := v.MapKeys()
386
+			if d.cs.SortKeys {
387
+				sortValues(keys, d.cs)
388
+			}
389
+			for i, key := range keys {
390
+				d.dump(d.unpackValue(key))
391
+				d.w.Write(colonSpaceBytes)
392
+				d.ignoreNextIndent = true
393
+				d.dump(d.unpackValue(v.MapIndex(key)))
394
+				if i < (numEntries - 1) {
395
+					d.w.Write(commaNewlineBytes)
396
+				} else {
397
+					d.w.Write(newlineBytes)
398
+				}
399
+			}
400
+		}
401
+		d.depth--
402
+		d.indent()
403
+		d.w.Write(closeBraceBytes)
404
+
405
+	case reflect.Struct:
406
+		d.w.Write(openBraceNewlineBytes)
407
+		d.depth++
408
+		if (d.cs.MaxDepth != 0) && (d.depth > d.cs.MaxDepth) {
409
+			d.indent()
410
+			d.w.Write(maxNewlineBytes)
411
+		} else {
412
+			vt := v.Type()
413
+			numFields := v.NumField()
414
+			for i := 0; i < numFields; i++ {
415
+				d.indent()
416
+				vtf := vt.Field(i)
417
+				d.w.Write([]byte(vtf.Name))
418
+				d.w.Write(colonSpaceBytes)
419
+				d.ignoreNextIndent = true
420
+				d.dump(d.unpackValue(v.Field(i)))
421
+				if i < (numFields - 1) {
422
+					d.w.Write(commaNewlineBytes)
423
+				} else {
424
+					d.w.Write(newlineBytes)
425
+				}
426
+			}
427
+		}
428
+		d.depth--
429
+		d.indent()
430
+		d.w.Write(closeBraceBytes)
431
+
432
+	case reflect.Uintptr:
433
+		printHexPtr(d.w, uintptr(v.Uint()))
434
+
435
+	case reflect.UnsafePointer, reflect.Chan, reflect.Func:
436
+		printHexPtr(d.w, v.Pointer())
437
+
438
+	// There were not any other types at the time this code was written, but
439
+	// fall back to letting the default fmt package handle it in case any new
440
+	// types are added.
441
+	default:
442
+		if v.CanInterface() {
443
+			fmt.Fprintf(d.w, "%v", v.Interface())
444
+		} else {
445
+			fmt.Fprintf(d.w, "%v", v.String())
446
+		}
447
+	}
448
+}
449
+
450
+// fdump is a helper function to consolidate the logic from the various public
451
+// methods which take varying writers and config states.
452
+func fdump(cs *ConfigState, w io.Writer, a ...interface{}) {
453
+	for _, arg := range a {
454
+		if arg == nil {
455
+			w.Write(interfaceBytes)
456
+			w.Write(spaceBytes)
457
+			w.Write(nilAngleBytes)
458
+			w.Write(newlineBytes)
459
+			continue
460
+		}
461
+
462
+		d := dumpState{w: w, cs: cs}
463
+		d.pointers = make(map[uintptr]int)
464
+		d.dump(reflect.ValueOf(arg))
465
+		d.w.Write(newlineBytes)
466
+	}
467
+}
468
+
469
+// Fdump formats and displays the passed arguments to io.Writer w.  It formats
470
+// exactly the same as Dump.
471
+func Fdump(w io.Writer, a ...interface{}) {
472
+	fdump(&Config, w, a...)
473
+}
474
+
475
+// Sdump returns a string with the passed arguments formatted exactly the same
476
+// as Dump.
477
+func Sdump(a ...interface{}) string {
478
+	var buf bytes.Buffer
479
+	fdump(&Config, &buf, a...)
480
+	return buf.String()
481
+}
482
+
483
+/*
484
+Dump displays the passed parameters to standard out with newlines, customizable
485
+indentation, and additional debug information such as complete types and all
486
+pointer addresses used to indirect to the final value.  It provides the
487
+following features over the built-in printing facilities provided by the fmt
488
+package:
489
+
490
+	* Pointers are dereferenced and followed
491
+	* Circular data structures are detected and handled properly
492
+	* Custom Stringer/error interfaces are optionally invoked, including
493
+	  on unexported types
494
+	* Custom types which only implement the Stringer/error interfaces via
495
+	  a pointer receiver are optionally invoked when passing non-pointer
496
+	  variables
497
+	* Byte arrays and slices are dumped like the hexdump -C command which
498
+	  includes offsets, byte values in hex, and ASCII output
499
+
500
+The configuration options are controlled by an exported package global,
501
+spew.Config.  See ConfigState for options documentation.
502
+
503
+See Fdump if you would prefer dumping to an arbitrary io.Writer or Sdump to
504
+get the formatted result as a string.
505
+*/
506
+func Dump(a ...interface{}) {
507
+	fdump(&Config, os.Stdout, a...)
508
+}
0 509
new file mode 100644
... ...
@@ -0,0 +1,419 @@
0
+/*
1
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
2
+ *
3
+ * Permission to use, copy, modify, and distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ */
15
+
16
+package spew
17
+
18
+import (
19
+	"bytes"
20
+	"fmt"
21
+	"reflect"
22
+	"strconv"
23
+	"strings"
24
+)
25
+
26
+// supportedFlags is a list of all the character flags supported by fmt package.
27
+const supportedFlags = "0-+# "
28
+
29
+// formatState implements the fmt.Formatter interface and contains information
30
+// about the state of a formatting operation.  The NewFormatter function can
31
+// be used to get a new Formatter which can be used directly as arguments
32
+// in standard fmt package printing calls.
33
+type formatState struct {
34
+	value          interface{}
35
+	fs             fmt.State
36
+	depth          int
37
+	pointers       map[uintptr]int
38
+	ignoreNextType bool
39
+	cs             *ConfigState
40
+}
41
+
42
+// buildDefaultFormat recreates the original format string without precision
43
+// and width information to pass in to fmt.Sprintf in the case of an
44
+// unrecognized type.  Unless new types are added to the language, this
45
+// function won't ever be called.
46
+func (f *formatState) buildDefaultFormat() (format string) {
47
+	buf := bytes.NewBuffer(percentBytes)
48
+
49
+	for _, flag := range supportedFlags {
50
+		if f.fs.Flag(int(flag)) {
51
+			buf.WriteRune(flag)
52
+		}
53
+	}
54
+
55
+	buf.WriteRune('v')
56
+
57
+	format = buf.String()
58
+	return format
59
+}
60
+
61
+// constructOrigFormat recreates the original format string including precision
62
+// and width information to pass along to the standard fmt package.  This allows
63
+// automatic deferral of all format strings this package doesn't support.
64
+func (f *formatState) constructOrigFormat(verb rune) (format string) {
65
+	buf := bytes.NewBuffer(percentBytes)
66
+
67
+	for _, flag := range supportedFlags {
68
+		if f.fs.Flag(int(flag)) {
69
+			buf.WriteRune(flag)
70
+		}
71
+	}
72
+
73
+	if width, ok := f.fs.Width(); ok {
74
+		buf.WriteString(strconv.Itoa(width))
75
+	}
76
+
77
+	if precision, ok := f.fs.Precision(); ok {
78
+		buf.Write(precisionBytes)
79
+		buf.WriteString(strconv.Itoa(precision))
80
+	}
81
+
82
+	buf.WriteRune(verb)
83
+
84
+	format = buf.String()
85
+	return format
86
+}
87
+
88
+// unpackValue returns values inside of non-nil interfaces when possible and
89
+// ensures that types for values which have been unpacked from an interface
90
+// are displayed when the show types flag is also set.
91
+// This is useful for data types like structs, arrays, slices, and maps which
92
+// can contain varying types packed inside an interface.
93
+func (f *formatState) unpackValue(v reflect.Value) reflect.Value {
94
+	if v.Kind() == reflect.Interface {
95
+		f.ignoreNextType = false
96
+		if !v.IsNil() {
97
+			v = v.Elem()
98
+		}
99
+	}
100
+	return v
101
+}
102
+
103
+// formatPtr handles formatting of pointers by indirecting them as necessary.
104
+func (f *formatState) formatPtr(v reflect.Value) {
105
+	// Display nil if top level pointer is nil.
106
+	showTypes := f.fs.Flag('#')
107
+	if v.IsNil() && (!showTypes || f.ignoreNextType) {
108
+		f.fs.Write(nilAngleBytes)
109
+		return
110
+	}
111
+
112
+	// Remove pointers at or below the current depth from map used to detect
113
+	// circular refs.
114
+	for k, depth := range f.pointers {
115
+		if depth >= f.depth {
116
+			delete(f.pointers, k)
117
+		}
118
+	}
119
+
120
+	// Keep list of all dereferenced pointers to possibly show later.
121
+	pointerChain := make([]uintptr, 0)
122
+
123
+	// Figure out how many levels of indirection there are by derferencing
124
+	// pointers and unpacking interfaces down the chain while detecting circular
125
+	// references.
126
+	nilFound := false
127
+	cycleFound := false
128
+	indirects := 0
129
+	ve := v
130
+	for ve.Kind() == reflect.Ptr {
131
+		if ve.IsNil() {
132
+			nilFound = true
133
+			break
134
+		}
135
+		indirects++
136
+		addr := ve.Pointer()
137
+		pointerChain = append(pointerChain, addr)
138
+		if pd, ok := f.pointers[addr]; ok && pd < f.depth {
139
+			cycleFound = true
140
+			indirects--
141
+			break
142
+		}
143
+		f.pointers[addr] = f.depth
144
+
145
+		ve = ve.Elem()
146
+		if ve.Kind() == reflect.Interface {
147
+			if ve.IsNil() {
148
+				nilFound = true
149
+				break
150
+			}
151
+			ve = ve.Elem()
152
+		}
153
+	}
154
+
155
+	// Display type or indirection level depending on flags.
156
+	if showTypes && !f.ignoreNextType {
157
+		f.fs.Write(openParenBytes)
158
+		f.fs.Write(bytes.Repeat(asteriskBytes, indirects))
159
+		f.fs.Write([]byte(ve.Type().String()))
160
+		f.fs.Write(closeParenBytes)
161
+	} else {
162
+		if nilFound || cycleFound {
163
+			indirects += strings.Count(ve.Type().String(), "*")
164
+		}
165
+		f.fs.Write(openAngleBytes)
166
+		f.fs.Write([]byte(strings.Repeat("*", indirects)))
167
+		f.fs.Write(closeAngleBytes)
168
+	}
169
+
170
+	// Display pointer information depending on flags.
171
+	if f.fs.Flag('+') && (len(pointerChain) > 0) {
172
+		f.fs.Write(openParenBytes)
173
+		for i, addr := range pointerChain {
174
+			if i > 0 {
175
+				f.fs.Write(pointerChainBytes)
176
+			}
177
+			printHexPtr(f.fs, addr)
178
+		}
179
+		f.fs.Write(closeParenBytes)
180
+	}
181
+
182
+	// Display dereferenced value.
183
+	switch {
184
+	case nilFound == true:
185
+		f.fs.Write(nilAngleBytes)
186
+
187
+	case cycleFound == true:
188
+		f.fs.Write(circularShortBytes)
189
+
190
+	default:
191
+		f.ignoreNextType = true
192
+		f.format(ve)
193
+	}
194
+}
195
+
196
+// format is the main workhorse for providing the Formatter interface.  It
197
+// uses the passed reflect value to figure out what kind of object we are
198
+// dealing with and formats it appropriately.  It is a recursive function,
199
+// however circular data structures are detected and handled properly.
200
+func (f *formatState) format(v reflect.Value) {
201
+	// Handle invalid reflect values immediately.
202
+	kind := v.Kind()
203
+	if kind == reflect.Invalid {
204
+		f.fs.Write(invalidAngleBytes)
205
+		return
206
+	}
207
+
208
+	// Handle pointers specially.
209
+	if kind == reflect.Ptr {
210
+		f.formatPtr(v)
211
+		return
212
+	}
213
+
214
+	// Print type information unless already handled elsewhere.
215
+	if !f.ignoreNextType && f.fs.Flag('#') {
216
+		f.fs.Write(openParenBytes)
217
+		f.fs.Write([]byte(v.Type().String()))
218
+		f.fs.Write(closeParenBytes)
219
+	}
220
+	f.ignoreNextType = false
221
+
222
+	// Call Stringer/error interfaces if they exist and the handle methods
223
+	// flag is enabled.
224
+	if !f.cs.DisableMethods {
225
+		if (kind != reflect.Invalid) && (kind != reflect.Interface) {
226
+			if handled := handleMethods(f.cs, f.fs, v); handled {
227
+				return
228
+			}
229
+		}
230
+	}
231
+
232
+	switch kind {
233
+	case reflect.Invalid:
234
+		// Do nothing.  We should never get here since invalid has already
235
+		// been handled above.
236
+
237
+	case reflect.Bool:
238
+		printBool(f.fs, v.Bool())
239
+
240
+	case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64, reflect.Int:
241
+		printInt(f.fs, v.Int(), 10)
242
+
243
+	case reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uint:
244
+		printUint(f.fs, v.Uint(), 10)
245
+
246
+	case reflect.Float32:
247
+		printFloat(f.fs, v.Float(), 32)
248
+
249
+	case reflect.Float64:
250
+		printFloat(f.fs, v.Float(), 64)
251
+
252
+	case reflect.Complex64:
253
+		printComplex(f.fs, v.Complex(), 32)
254
+
255
+	case reflect.Complex128:
256
+		printComplex(f.fs, v.Complex(), 64)
257
+
258
+	case reflect.Slice:
259
+		if v.IsNil() {
260
+			f.fs.Write(nilAngleBytes)
261
+			break
262
+		}
263
+		fallthrough
264
+
265
+	case reflect.Array:
266
+		f.fs.Write(openBracketBytes)
267
+		f.depth++
268
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
269
+			f.fs.Write(maxShortBytes)
270
+		} else {
271
+			numEntries := v.Len()
272
+			for i := 0; i < numEntries; i++ {
273
+				if i > 0 {
274
+					f.fs.Write(spaceBytes)
275
+				}
276
+				f.ignoreNextType = true
277
+				f.format(f.unpackValue(v.Index(i)))
278
+			}
279
+		}
280
+		f.depth--
281
+		f.fs.Write(closeBracketBytes)
282
+
283
+	case reflect.String:
284
+		f.fs.Write([]byte(v.String()))
285
+
286
+	case reflect.Interface:
287
+		// The only time we should get here is for nil interfaces due to
288
+		// unpackValue calls.
289
+		if v.IsNil() {
290
+			f.fs.Write(nilAngleBytes)
291
+		}
292
+
293
+	case reflect.Ptr:
294
+		// Do nothing.  We should never get here since pointers have already
295
+		// been handled above.
296
+
297
+	case reflect.Map:
298
+		// nil maps should be indicated as different than empty maps
299
+		if v.IsNil() {
300
+			f.fs.Write(nilAngleBytes)
301
+			break
302
+		}
303
+
304
+		f.fs.Write(openMapBytes)
305
+		f.depth++
306
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
307
+			f.fs.Write(maxShortBytes)
308
+		} else {
309
+			keys := v.MapKeys()
310
+			if f.cs.SortKeys {
311
+				sortValues(keys, f.cs)
312
+			}
313
+			for i, key := range keys {
314
+				if i > 0 {
315
+					f.fs.Write(spaceBytes)
316
+				}
317
+				f.ignoreNextType = true
318
+				f.format(f.unpackValue(key))
319
+				f.fs.Write(colonBytes)
320
+				f.ignoreNextType = true
321
+				f.format(f.unpackValue(v.MapIndex(key)))
322
+			}
323
+		}
324
+		f.depth--
325
+		f.fs.Write(closeMapBytes)
326
+
327
+	case reflect.Struct:
328
+		numFields := v.NumField()
329
+		f.fs.Write(openBraceBytes)
330
+		f.depth++
331
+		if (f.cs.MaxDepth != 0) && (f.depth > f.cs.MaxDepth) {
332
+			f.fs.Write(maxShortBytes)
333
+		} else {
334
+			vt := v.Type()
335
+			for i := 0; i < numFields; i++ {
336
+				if i > 0 {
337
+					f.fs.Write(spaceBytes)
338
+				}
339
+				vtf := vt.Field(i)
340
+				if f.fs.Flag('+') || f.fs.Flag('#') {
341
+					f.fs.Write([]byte(vtf.Name))
342
+					f.fs.Write(colonBytes)
343
+				}
344
+				f.format(f.unpackValue(v.Field(i)))
345
+			}
346
+		}
347
+		f.depth--
348
+		f.fs.Write(closeBraceBytes)
349
+
350
+	case reflect.Uintptr:
351
+		printHexPtr(f.fs, uintptr(v.Uint()))
352
+
353
+	case reflect.UnsafePointer, reflect.Chan, reflect.Func:
354
+		printHexPtr(f.fs, v.Pointer())
355
+
356
+	// There were not any other types at the time this code was written, but
357
+	// fall back to letting the default fmt package handle it if any get added.
358
+	default:
359
+		format := f.buildDefaultFormat()
360
+		if v.CanInterface() {
361
+			fmt.Fprintf(f.fs, format, v.Interface())
362
+		} else {
363
+			fmt.Fprintf(f.fs, format, v.String())
364
+		}
365
+	}
366
+}
367
+
368
+// Format satisfies the fmt.Formatter interface. See NewFormatter for usage
369
+// details.
370
+func (f *formatState) Format(fs fmt.State, verb rune) {
371
+	f.fs = fs
372
+
373
+	// Use standard formatting for verbs that are not v.
374
+	if verb != 'v' {
375
+		format := f.constructOrigFormat(verb)
376
+		fmt.Fprintf(fs, format, f.value)
377
+		return
378
+	}
379
+
380
+	if f.value == nil {
381
+		if fs.Flag('#') {
382
+			fs.Write(interfaceBytes)
383
+		}
384
+		fs.Write(nilAngleBytes)
385
+		return
386
+	}
387
+
388
+	f.format(reflect.ValueOf(f.value))
389
+}
390
+
391
+// newFormatter is a helper function to consolidate the logic from the various
392
+// public methods which take varying config states.
393
+func newFormatter(cs *ConfigState, v interface{}) fmt.Formatter {
394
+	fs := &formatState{value: v, cs: cs}
395
+	fs.pointers = make(map[uintptr]int)
396
+	return fs
397
+}
398
+
399
+/*
400
+NewFormatter returns a custom formatter that satisfies the fmt.Formatter
401
+interface.  As a result, it integrates cleanly with standard fmt package
402
+printing functions.  The formatter is useful for inline printing of smaller data
403
+types similar to the standard %v format specifier.
404
+
405
+The custom formatter only responds to the %v (most compact), %+v (adds pointer
406
+addresses), %#v (adds types), or %#+v (adds types and pointer addresses) verb
407
+combinations.  Any other verbs such as %x and %q will be sent to the the
408
+standard fmt package for formatting.  In addition, the custom formatter ignores
409
+the width and precision arguments (however they will still work on the format
410
+specifiers not handled by the custom formatter).
411
+
412
+Typically this function shouldn't be called directly.  It is much easier to make
413
+use of the custom formatter by calling one of the convenience functions such as
414
+Printf, Println, or Fprintf.
415
+*/
416
+func NewFormatter(v interface{}) fmt.Formatter {
417
+	return newFormatter(&Config, v)
418
+}
0 419
new file mode 100644
... ...
@@ -0,0 +1,148 @@
0
+/*
1
+ * Copyright (c) 2013 Dave Collins <dave@davec.name>
2
+ *
3
+ * Permission to use, copy, modify, and distribute this software for any
4
+ * purpose with or without fee is hereby granted, provided that the above
5
+ * copyright notice and this permission notice appear in all copies.
6
+ *
7
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
10
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
12
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
13
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
14
+ */
15
+
16
+package spew
17
+
18
+import (
19
+	"fmt"
20
+	"io"
21
+)
22
+
23
+// Errorf is a wrapper for fmt.Errorf that treats each argument as if it were
24
+// passed with a default Formatter interface returned by NewFormatter.  It
25
+// returns the formatted string as a value that satisfies error.  See
26
+// NewFormatter for formatting details.
27
+//
28
+// This function is shorthand for the following syntax:
29
+//
30
+//	fmt.Errorf(format, spew.NewFormatter(a), spew.NewFormatter(b))
31
+func Errorf(format string, a ...interface{}) (err error) {
32
+	return fmt.Errorf(format, convertArgs(a)...)
33
+}
34
+
35
+// Fprint is a wrapper for fmt.Fprint that treats each argument as if it were
36
+// passed with a default Formatter interface returned by NewFormatter.  It
37
+// returns the number of bytes written and any write error encountered.  See
38
+// NewFormatter for formatting details.
39
+//
40
+// This function is shorthand for the following syntax:
41
+//
42
+//	fmt.Fprint(w, spew.NewFormatter(a), spew.NewFormatter(b))
43
+func Fprint(w io.Writer, a ...interface{}) (n int, err error) {
44
+	return fmt.Fprint(w, convertArgs(a)...)
45
+}
46
+
47
+// Fprintf is a wrapper for fmt.Fprintf that treats each argument as if it were
48
+// passed with a default Formatter interface returned by NewFormatter.  It
49
+// returns the number of bytes written and any write error encountered.  See
50
+// NewFormatter for formatting details.
51
+//
52
+// This function is shorthand for the following syntax:
53
+//
54
+//	fmt.Fprintf(w, format, spew.NewFormatter(a), spew.NewFormatter(b))
55
+func Fprintf(w io.Writer, format string, a ...interface{}) (n int, err error) {
56
+	return fmt.Fprintf(w, format, convertArgs(a)...)
57
+}
58
+
59
+// Fprintln is a wrapper for fmt.Fprintln that treats each argument as if it
60
+// passed with a default Formatter interface returned by NewFormatter.  See
61
+// NewFormatter for formatting details.
62
+//
63
+// This function is shorthand for the following syntax:
64
+//
65
+//	fmt.Fprintln(w, spew.NewFormatter(a), spew.NewFormatter(b))
66
+func Fprintln(w io.Writer, a ...interface{}) (n int, err error) {
67
+	return fmt.Fprintln(w, convertArgs(a)...)
68
+}
69
+
70
+// Print is a wrapper for fmt.Print that treats each argument as if it were
71
+// passed with a default Formatter interface returned by NewFormatter.  It
72
+// returns the number of bytes written and any write error encountered.  See
73
+// NewFormatter for formatting details.
74
+//
75
+// This function is shorthand for the following syntax:
76
+//
77
+//	fmt.Print(spew.NewFormatter(a), spew.NewFormatter(b))
78
+func Print(a ...interface{}) (n int, err error) {
79
+	return fmt.Print(convertArgs(a)...)
80
+}
81
+
82
+// Printf is a wrapper for fmt.Printf that treats each argument as if it were
83
+// passed with a default Formatter interface returned by NewFormatter.  It
84
+// returns the number of bytes written and any write error encountered.  See
85
+// NewFormatter for formatting details.
86
+//
87
+// This function is shorthand for the following syntax:
88
+//
89
+//	fmt.Printf(format, spew.NewFormatter(a), spew.NewFormatter(b))
90
+func Printf(format string, a ...interface{}) (n int, err error) {
91
+	return fmt.Printf(format, convertArgs(a)...)
92
+}
93
+
94
+// Println is a wrapper for fmt.Println that treats each argument as if it were
95
+// passed with a default Formatter interface returned by NewFormatter.  It
96
+// returns the number of bytes written and any write error encountered.  See
97
+// NewFormatter for formatting details.
98
+//
99
+// This function is shorthand for the following syntax:
100
+//
101
+//	fmt.Println(spew.NewFormatter(a), spew.NewFormatter(b))
102
+func Println(a ...interface{}) (n int, err error) {
103
+	return fmt.Println(convertArgs(a)...)
104
+}
105
+
106
+// Sprint is a wrapper for fmt.Sprint that treats each argument as if it were
107
+// passed with a default Formatter interface returned by NewFormatter.  It
108
+// returns the resulting string.  See NewFormatter for formatting details.
109
+//
110
+// This function is shorthand for the following syntax:
111
+//
112
+//	fmt.Sprint(spew.NewFormatter(a), spew.NewFormatter(b))
113
+func Sprint(a ...interface{}) string {
114
+	return fmt.Sprint(convertArgs(a)...)
115
+}
116
+
117
+// Sprintf is a wrapper for fmt.Sprintf that treats each argument as if it were
118
+// passed with a default Formatter interface returned by NewFormatter.  It
119
+// returns the resulting string.  See NewFormatter for formatting details.
120
+//
121
+// This function is shorthand for the following syntax:
122
+//
123
+//	fmt.Sprintf(format, spew.NewFormatter(a), spew.NewFormatter(b))
124
+func Sprintf(format string, a ...interface{}) string {
125
+	return fmt.Sprintf(format, convertArgs(a)...)
126
+}
127
+
128
+// Sprintln is a wrapper for fmt.Sprintln that treats each argument as if it
129
+// were passed with a default Formatter interface returned by NewFormatter.  It
130
+// returns the resulting string.  See NewFormatter for formatting details.
131
+//
132
+// This function is shorthand for the following syntax:
133
+//
134
+//	fmt.Sprintln(spew.NewFormatter(a), spew.NewFormatter(b))
135
+func Sprintln(a ...interface{}) string {
136
+	return fmt.Sprintln(convertArgs(a)...)
137
+}
138
+
139
+// convertArgs accepts a slice of arguments and returns a slice of the same
140
+// length with each argument converted to a default spew Formatter interface.
141
+func convertArgs(args []interface{}) (formatters []interface{}) {
142
+	formatters = make([]interface{}, len(args))
143
+	for index, arg := range args {
144
+		formatters[index] = NewFormatter(arg)
145
+	}
146
+	return formatters
147
+}