Commit 96da3e96 authored by Rob Pike's avatar Rob Pike

implement .repeats for maps.

Fixes #309.

R=rsc
CC=golang-dev
https://golang.org/cl/181044
parent 8c557962
...@@ -833,41 +833,35 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) { ...@@ -833,41 +833,35 @@ func (t *Template) executeRepeated(r *repeatedElement, st *state) {
} }
first := true first := true
if array, ok := field.(reflect.ArrayOrSliceValue); ok { // Code common to all the loops.
for j := 0; j < array.Len(); j++ { loopBody := func(newst *state) {
newst := st.clone(array.Elem(j)) // .alternates between elements
if !first && r.altstart >= 0 {
// .alternates between elements for i := r.altstart; i < r.altend; {
if !first && r.altstart >= 0 {
for i := r.altstart; i < r.altend; {
i = t.executeElement(i, newst)
}
}
first = false
for i := start; i < end; {
i = t.executeElement(i, newst) i = t.executeElement(i, newst)
} }
} }
first = false
for i := start; i < end; {
i = t.executeElement(i, newst)
}
}
if array, ok := field.(reflect.ArrayOrSliceValue); ok {
for j := 0; j < array.Len(); j++ {
loopBody(st.clone(array.Elem(j)))
}
} else if m, ok := field.(*reflect.MapValue); ok {
for _, key := range m.Keys() {
loopBody(st.clone(m.Elem(key)))
}
} else if ch := iter(field); ch != nil { } else if ch := iter(field); ch != nil {
for { for {
e := ch.Recv() e := ch.Recv()
if ch.Closed() { if ch.Closed() {
break break
} }
newst := st.clone(e) loopBody(st.clone(e))
// .alternates between elements
if !first && r.altstart >= 0 {
for i := r.altstart; i < r.altend; {
i = t.executeElement(i, newst)
}
}
first = false
for i := start; i < end; {
i = t.executeElement(i, newst)
}
} }
} else { } else {
t.execError(st, r.linenum, ".repeated: cannot repeat %s (type %s)", t.execError(st, r.linenum, ".repeated: cannot repeat %s (type %s)",
......
...@@ -42,6 +42,7 @@ type S struct { ...@@ -42,6 +42,7 @@ type S struct {
false bool false bool
mp map[string]string mp map[string]string
innermap U innermap U
stringmap map[string]string
bytes []byte bytes []byte
} }
...@@ -314,12 +315,24 @@ var tests = []*Test{ ...@@ -314,12 +315,24 @@ var tests = []*Test{
out: "Ahoy!\n", out: "Ahoy!\n",
}, },
&Test{ &Test{
in: "{innermap.mp.innerkey}\n", in: "{innermap.mp.innerkey}\n",
out: "55\n", out: "55\n",
}, },
&Test{
in: "{stringmap.stringkey1}\n",
out: "stringresult\n",
},
&Test{
in: "{.repeated section stringmap}\n" +
"{@}\n" +
"{.end}",
out: "stringresult\n" +
"stringresult\n",
},
} }
func TestAll(t *testing.T) { func TestAll(t *testing.T) {
...@@ -342,6 +355,9 @@ func TestAll(t *testing.T) { ...@@ -342,6 +355,9 @@ func TestAll(t *testing.T) {
s.mp["mapkey"] = "Ahoy!" s.mp["mapkey"] = "Ahoy!"
s.innermap.mp = make(map[string]int) s.innermap.mp = make(map[string]int)
s.innermap.mp["innerkey"] = 55 s.innermap.mp["innerkey"] = 55
s.stringmap = make(map[string]string)
s.stringmap["stringkey1"] = "stringresult" // the same value so repeated section is order-independent
s.stringmap["stringkey2"] = "stringresult"
s.bytes = strings.Bytes("hello") s.bytes = strings.Bytes("hello")
var buf bytes.Buffer var buf bytes.Buffer
......
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