Skip to content

Commit

Permalink
Add pointer chain representation back conditionally
Browse files Browse the repository at this point in the history
Now we represent pointer chains in a comment, which actually is legal if
the address taking syntax is legal (OK for structs).
  • Loading branch information
kortschak committed Mar 23, 2015
1 parent 48ec2f9 commit 84cfc1c
Show file tree
Hide file tree
Showing 6 changed files with 47 additions and 0 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,10 @@ options. See the ConfigState documentation for more details.
Specifies whether ASCII comment annotations are attached to byte
slice and array dumps.
* CommentPointers
CommentPointer specifies whether pointer information will be added
as comments.
* IgnoreUnexported
Specifies that unexported fields should be ignored.
Expand Down
3 changes: 3 additions & 0 deletions common.go
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,9 @@ var (
hexZeroBytes = []byte("0x")
zeroBytes = []byte("0")
pointZeroBytes = []byte(".0")
openCommentBytes = []byte(" /*")
closeCommentBytes = []byte("*/ ")
pointerChainBytes = []byte("->")
circularBytes = []byte("(<already shown>)")
invalidAngleBytes = []byte("<invalid>")
)
Expand Down
5 changes: 5 additions & 0 deletions config.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ type ConfigState struct {
// comment annotations.
CommentBytes bool

// CommentPointer specifies whether pointer information will be added
// as comments.
CommentPointers bool

// IgnoreUnexported specifies that unexported struct fields should be
// ignored during a dump.
IgnoreUnexported bool
Expand Down Expand Up @@ -110,6 +114,7 @@ func (c *ConfigState) Sdump(a interface{}) string {
// Indent: " "
// BytesWidth: 16
// CommentBytes: true
// CommentPointers: false
// IgnoreUnexported: false
// ElideType: false
// SortKeys: false
Expand Down
4 changes: 4 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ The following configuration options are available:
Specifies whether ASCII comment annotations are attached to byte
slice and array dumps.
* CommentPointers
CommentPointer specifies whether pointer information will be added
as comments.
* IgnoreUnexported
Specifies that unexported fields should be ignored.
Expand Down
18 changes: 18 additions & 0 deletions dump.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,9 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
}
}

// Keep list of all dereferenced pointers to show later.
var pointerChain []uintptr

// Figure out how many levels of indirection there are by dereferencing
// pointers and unpacking interfaces down the chain while detecting circular
// references.
Expand All @@ -101,6 +104,9 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
}
indirects++
addr := ve.Pointer()
if d.cs.CommentPointers {
pointerChain = append(pointerChain, addr)
}
if pd, ok := d.pointers[addr]; ok && pd < d.depth {
cycleFound = true
indirects--
Expand Down Expand Up @@ -129,6 +135,18 @@ func (d *dumpState) dumpPtr(v reflect.Value) {
d.w.Write(closeParenBytes)
}

// Display pointer information.
if len(pointerChain) > 0 {
d.w.Write(openCommentBytes)
for i, addr := range pointerChain {
if i > 0 {
d.w.Write(pointerChainBytes)
}
printHexPtr(d.w, addr, true)
}
d.w.Write(closeCommentBytes)
}

// Display dereferenced value.
switch {
case nilFound == true:
Expand Down
13 changes: 13 additions & 0 deletions spew_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ func initSpewTests() {
noComDefault := utter.NewDefaultConfig()
noComDefault.CommentBytes = false

// Byte slice without comments.
comPtrDefault := utter.NewDefaultConfig()
comPtrDefault.CommentPointers = true

// Byte slice with 8 columns.
bs8Default := utter.NewDefaultConfig()
bs8Default.BytesWidth = 8
Expand All @@ -116,13 +120,22 @@ func initSpewTests() {
m map[string]int
}

v := new(int)
*v = 10
s := struct{ *int }{v}
sp := &s
spp := &sp

utterTests = []utterTest{
{scsDefault, fCSFdump, int8(127), "int8(127)\n"},
{scsDefault, fCSSdump, uint8(64), "uint8(0x40)\n"},
{scsDefault, fSdump, complex(-10, -20), "complex128(-10-20i)\n"},
{noComDefault, fCSFdump, []byte{1, 2, 3, 4, 5, 0},
"[]uint8{\n 0x01, 0x02, 0x03, 0x04, 0x05, 0x00,\n}\n",
},
{comPtrDefault, fCSFdump, s, fmt.Sprintf("struct { *int }{\n int: &int /*%p*/ (10),\n}\n", v)},
{comPtrDefault, fCSFdump, sp, fmt.Sprintf("&struct { *int } /*%p*/ {\n int: &int /*%p*/ (10),\n}\n", sp, v)},
{comPtrDefault, fCSFdump, spp, fmt.Sprintf("&&struct { *int } /*%p->%p*/ {\n int: &int /*%p*/ (10),\n}\n", spp, sp, v)},
{bs8Default, fCSFdump, []byte{1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5, 0}, "[]uint8{\n" +
" 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x01, 0x02, // |........|\n" +
" 0x03, 0x04, 0x05, 0x00, // |....|\n}\n",
Expand Down

0 comments on commit 84cfc1c

Please sign in to comment.