Skip to content

Commit e042962

Browse files
committed
add printer.clone and test code
1 parent e2a49b7 commit e042962

2 files changed

Lines changed: 49 additions & 4 deletions

File tree

formatter.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ type formatter struct {
2121
// breaks and tabs. Object f responds to the "%v" formatting verb when both the
2222
// "#" and " " (space) flags are set, for example:
2323
//
24-
// fmt.Sprintf("%# v", Formatter(x))
24+
// fmt.Sprintf("%# v", Formatter(x))
2525
//
2626
// If one of these two flags is not set, or any other verb is used, f will
2727
// format x according to the usual rules of package fmt.
@@ -69,8 +69,21 @@ type printer struct {
6969
depth int
7070
}
7171

72+
func (p *printer) clone() printer {
73+
visited := make(map[visit]int, len(p.visited))
74+
for k, v := range p.visited {
75+
visited[k] = v
76+
}
77+
return printer{
78+
Writer: p.Writer,
79+
tw: p.tw,
80+
visited: visited,
81+
depth: p.depth,
82+
}
83+
}
84+
7285
func (p *printer) indent() *printer {
73-
q := *p
86+
q := p.clone()
7487
q.tw = tabwriter.NewWriter(p.Writer, 4, 4, 1, ' ', 0)
7588
q.Writer = text.NewIndentWriter(q.tw, []byte{'\t'})
7689
return &q
@@ -223,7 +236,7 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) {
223236
case e.Kind() == reflect.Invalid:
224237
io.WriteString(p, "nil")
225238
case e.IsValid():
226-
pp := *p
239+
pp := p.clone()
227240
pp.depth++
228241
pp.printValue(e, showType, true)
229242
default:
@@ -270,7 +283,7 @@ func (p *printer) printValue(v reflect.Value, showType, quote bool) {
270283
io.WriteString(p, v.Type().String())
271284
io.WriteString(p, ")(nil)")
272285
} else {
273-
pp := *p
286+
pp := p.clone()
274287
pp.depth++
275288
writeByte(pp, '&')
276289
pp.printValue(e, true, true)

formatter_test.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -364,3 +364,35 @@ func TestReuseVisitMap(t *testing.T) {
364364
t.Error("there should not cycle in ComplexValue ", s)
365365
}
366366
}
367+
368+
type Tree struct {
369+
Left *Tree
370+
Value interface{}
371+
Right *Tree
372+
}
373+
374+
func TestCycleRefer(t *testing.T) {
375+
var tree = &Tree{
376+
Left: nil,
377+
Value: 1,
378+
Right: &Tree{
379+
Left: nil,
380+
Value: 2,
381+
Right: nil,
382+
},
383+
}
384+
var s = Sprint(tree)
385+
if strings.Contains(s, "CYCLIC") {
386+
t.Error("tree should have no cycle in Tree", s)
387+
}
388+
389+
tree.Right.Value = []interface{}{
390+
map[string]interface{}{
391+
"refer": tree,
392+
},
393+
}
394+
var s2 = Sprint(tree)
395+
if !strings.Contains(s2, "CYCLIC") {
396+
t.Error("tree should have no cycle in Tree", s2)
397+
}
398+
}

0 commit comments

Comments
 (0)