Commit 0197cc49 authored by Rob Pike's avatar Rob Pike

text/template: fix bug in Clone

Cloned template copied the root template incorrectly.
Add test of self-consistency.

R=golang-dev, dsymonds
CC=golang-dev
https://golang.org/cl/5436063
parent d1324d8a
...@@ -230,6 +230,15 @@ func TestClone(t *testing.T) { ...@@ -230,6 +230,15 @@ func TestClone(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
// Verify that the clone is self-consistent.
for k, v := range clone.tmpl {
if k == clone.name && v.tmpl[k] != clone {
t.Error("clone does not contain root")
}
if v != v.tmpl[v.name] {
t.Errorf("clone does not contain self for %q", k)
}
}
// Execute root. // Execute root.
var b bytes.Buffer var b bytes.Buffer
err = root.ExecuteTemplate(&b, "a", 0) err = root.ExecuteTemplate(&b, "a", 0)
......
...@@ -73,12 +73,15 @@ func (t *Template) init() { ...@@ -73,12 +73,15 @@ func (t *Template) init() {
// common templates and use them with variant definitions for other templates by // common templates and use them with variant definitions for other templates by
// adding the variants after the clone is made. // adding the variants after the clone is made.
func (t *Template) Clone() *Template { func (t *Template) Clone() *Template {
nt := t.copy() nt := t.copy(nil)
nt.init() nt.init()
nt.tmpl[t.name] = nt
for k, v := range t.tmpl { for k, v := range t.tmpl {
if k == t.name { // Already installed.
continue
}
// The associated templates share nt's common structure. // The associated templates share nt's common structure.
tmpl := v.copy() tmpl := v.copy(nt.common)
tmpl.common = nt.common
nt.tmpl[k] = tmpl nt.tmpl[k] = tmpl
} }
for k, v := range t.parseFuncs { for k, v := range t.parseFuncs {
...@@ -90,10 +93,11 @@ func (t *Template) Clone() *Template { ...@@ -90,10 +93,11 @@ func (t *Template) Clone() *Template {
return nt return nt
} }
// copy returns a shallow copy of t, with common set to nil. // copy returns a shallow copy of t, with common set to the argument.
func (t *Template) copy() *Template { func (t *Template) copy(c *common) *Template {
nt := New(t.name) nt := New(t.name)
nt.Tree = t.Tree nt.Tree = t.Tree
nt.common = c
nt.leftDelim = t.leftDelim nt.leftDelim = t.leftDelim
nt.rightDelim = t.rightDelim nt.rightDelim = t.rightDelim
return nt return nt
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment