OSDN Git Service

Add Go frontend, libgo library, and Go testsuite.
[pf3gnuchains/gcc-fork.git] / libgo / go / template / template.go
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 /*
6         Data-driven templates for generating textual output such as
7         HTML.
8
9         Templates are executed by applying them to a data structure.
10         Annotations in the template refer to elements of the data
11         structure (typically a field of a struct or a key in a map)
12         to control execution and derive values to be displayed.
13         The template walks the structure as it executes and the
14         "cursor" @ represents the value at the current location
15         in the structure.
16
17         Data items may be values or pointers; the interface hides the
18         indirection.
19
20         In the following, 'field' is one of several things, according to the data.
21
22                 - The name of a field of a struct (result = data.field),
23                 - The value stored in a map under that key (result = data[field]), or
24                 - The result of invoking a niladic single-valued method with that name
25                   (result = data.field())
26
27         Major constructs ({} are metacharacters; [] marks optional elements):
28
29                 {# comment }
30
31         A one-line comment.
32
33                 {.section field} XXX [ {.or} YYY ] {.end}
34
35         Set @ to the value of the field.  It may be an explicit @
36         to stay at the same point in the data. If the field is nil
37         or empty, execute YYY; otherwise execute XXX.
38
39                 {.repeated section field} XXX [ {.alternates with} ZZZ ] [ {.or} YYY ] {.end}
40
41         Like .section, but field must be an array or slice.  XXX
42         is executed for each element.  If the array is nil or empty,
43         YYY is executed instead.  If the {.alternates with} marker
44         is present, ZZZ is executed between iterations of XXX.
45
46                 {field}
47                 {field|formatter}
48
49         Insert the value of the field into the output. Field is
50         first looked for in the cursor, as in .section and .repeated.
51         If it is not found, the search continues in outer sections
52         until the top level is reached.
53
54         If a formatter is specified, it must be named in the formatter
55         map passed to the template set up routines or in the default
56         set ("html","str","") and is used to process the data for
57         output.  The formatter function has signature
58                 func(wr io.Writer, data interface{}, formatter string)
59         where wr is the destination for output, data is the field
60         value, and formatter is its name at the invocation site.
61 */
62 package template
63
64 import (
65         "container/vector"
66         "fmt"
67         "io"
68         "io/ioutil"
69         "os"
70         "reflect"
71         "strings"
72 )
73
74 // Errors returned during parsing and execution.  Users may extract the information and reformat
75 // if they desire.
76 type Error struct {
77         Line int
78         Msg  string
79 }
80
81 func (e *Error) String() string { return fmt.Sprintf("line %d: %s", e.Line, e.Msg) }
82
83 // Most of the literals are aces.
84 var lbrace = []byte{'{'}
85 var rbrace = []byte{'}'}
86 var space = []byte{' '}
87 var tab = []byte{'\t'}
88
89 // The various types of "tokens", which are plain text or (usually) brace-delimited descriptors
90 const (
91         tokAlternates = iota
92         tokComment
93         tokEnd
94         tokLiteral
95         tokOr
96         tokRepeated
97         tokSection
98         tokText
99         tokVariable
100 )
101
102 // FormatterMap is the type describing the mapping from formatter
103 // names to the functions that implement them.
104 type FormatterMap map[string]func(io.Writer, interface{}, string)
105
106 // Built-in formatters.
107 var builtins = FormatterMap{
108         "html": HTMLFormatter,
109         "str":  StringFormatter,
110         "":     StringFormatter,
111 }
112
113 // The parsed state of a template is a vector of xxxElement structs.
114 // Sections have line numbers so errors can be reported better during execution.
115
116 // Plain text.
117 type textElement struct {
118         text []byte
119 }
120
121 // A literal such as .meta-left or .meta-right
122 type literalElement struct {
123         text []byte
124 }
125
126 // A variable to be evaluated
127 type variableElement struct {
128         linenum   int
129         name      string
130         formatter string // TODO(r): implement pipelines
131 }
132
133 // A .section block, possibly with a .or
134 type sectionElement struct {
135         linenum int    // of .section itself
136         field   string // cursor field for this block
137         start   int    // first element
138         or      int    // first element of .or block
139         end     int    // one beyond last element
140 }
141
142 // A .repeated block, possibly with a .or and a .alternates
143 type repeatedElement struct {
144         sectionElement     // It has the same structure...
145         altstart       int // ... except for alternates
146         altend         int
147 }
148
149 // Template is the type that represents a template definition.
150 // It is unchanged after parsing.
151 type Template struct {
152         fmap FormatterMap // formatters for variables
153         // Used during parsing:
154         ldelim, rdelim []byte // delimiters; default {}
155         buf            []byte // input text to process
156         p              int    // position in buf
157         linenum        int    // position in input
158         // Parsed results:
159         elems *vector.Vector
160 }
161
162 // Internal state for executing a Template.  As we evaluate the struct,
163 // the data item descends into the fields associated with sections, etc.
164 // Parent is used to walk upwards to find variables higher in the tree.
165 type state struct {
166         parent *state        // parent in hierarchy
167         data   reflect.Value // the driver data for this section etc.
168         wr     io.Writer     // where to send output
169 }
170
171 func (parent *state) clone(data reflect.Value) *state {
172         return &state{parent, data, parent.wr}
173 }
174
175 // New creates a new template with the specified formatter map (which
176 // may be nil) to define auxiliary functions for formatting variables.
177 func New(fmap FormatterMap) *Template {
178         t := new(Template)
179         t.fmap = fmap
180         t.ldelim = lbrace
181         t.rdelim = rbrace
182         t.elems = new(vector.Vector)
183         return t
184 }
185
186 // Report error and stop executing.  The line number must be provided explicitly.
187 func (t *Template) execError(st *state, line int, err string, args ...interface{}) {
188         panic(&Error{line, fmt.Sprintf(err, args...)})
189 }
190
191 // Report error, panic to terminate parsing.
192 // The line number comes from the template state.
193 func (t *Template) parseError(err string, args ...interface{}) {
194         panic(&Error{t.linenum, fmt.Sprintf(err, args...)})
195 }
196
197 // -- Lexical analysis
198
199 // Is c a white space character?
200 func white(c uint8) bool { return c == ' ' || c == '\t' || c == '\r' || c == '\n' }
201
202 // Safely, does s[n:n+len(t)] == t?
203 func equal(s []byte, n int, t []byte) bool {
204         b := s[n:]
205         if len(t) > len(b) { // not enough space left for a match.
206                 return false
207         }
208         for i, c := range t {
209                 if c != b[i] {
210                         return false
211                 }
212         }
213         return true
214 }
215
216 // nextItem returns the next item from the input buffer.  If the returned
217 // item is empty, we are at EOF.  The item will be either a
218 // delimited string or a non-empty string between delimited
219 // strings. Tokens stop at (but include, if plain text) a newline.
220 // Action tokens on a line by themselves drop any space on
221 // either side, up to and including the newline.
222 func (t *Template) nextItem() []byte {
223         startOfLine := t.p == 0 || t.buf[t.p-1] == '\n'
224         start := t.p
225         var i int
226         newline := func() {
227                 t.linenum++
228                 i++
229         }
230         // Leading white space up to but not including newline
231         for i = start; i < len(t.buf); i++ {
232                 if t.buf[i] == '\n' || !white(t.buf[i]) {
233                         break
234                 }
235         }
236         leadingSpace := i > start
237         // What's left is nothing, newline, delimited string, or plain text
238 Switch:
239         switch {
240         case i == len(t.buf):
241                 // EOF; nothing to do
242         case t.buf[i] == '\n':
243                 newline()
244         case equal(t.buf, i, t.ldelim):
245                 left := i         // Start of left delimiter.
246                 right := -1       // Will be (immediately after) right delimiter.
247                 haveText := false // Delimiters contain text.
248                 i += len(t.ldelim)
249                 // Find the end of the action.
250                 for ; i < len(t.buf); i++ {
251                         if t.buf[i] == '\n' {
252                                 break
253                         }
254                         if equal(t.buf, i, t.rdelim) {
255                                 i += len(t.rdelim)
256                                 right = i
257                                 break
258                         }
259                         haveText = true
260                 }
261                 if right < 0 {
262                         t.parseError("unmatched opening delimiter")
263                         return nil
264                 }
265                 // Is this a special action (starts with '.' or '#') and the only thing on the line?
266                 if startOfLine && haveText {
267                         firstChar := t.buf[left+len(t.ldelim)]
268                         if firstChar == '.' || firstChar == '#' {
269                                 // It's special and the first thing on the line. Is it the last?
270                                 for j := right; j < len(t.buf) && white(t.buf[j]); j++ {
271                                         if t.buf[j] == '\n' {
272                                                 // Yes it is. Drop the surrounding space and return the {.foo}
273                                                 t.linenum++
274                                                 t.p = j + 1
275                                                 return t.buf[left:right]
276                                         }
277                                 }
278                         }
279                 }
280                 // No it's not. If there's leading space, return that.
281                 if leadingSpace {
282                         // not trimming space: return leading white space if there is some.
283                         t.p = left
284                         return t.buf[start:left]
285                 }
286                 // Return the word, leave the trailing space.
287                 start = left
288                 break
289         default:
290                 for ; i < len(t.buf); i++ {
291                         if t.buf[i] == '\n' {
292                                 newline()
293                                 break
294                         }
295                         if equal(t.buf, i, t.ldelim) {
296                                 break
297                         }
298                 }
299         }
300         item := t.buf[start:i]
301         t.p = i
302         return item
303 }
304
305 // Turn a byte array into a white-space-split array of strings.
306 func words(buf []byte) []string {
307         s := make([]string, 0, 5)
308         p := 0 // position in buf
309         // one word per loop
310         for i := 0; ; i++ {
311                 // skip white space
312                 for ; p < len(buf) && white(buf[p]); p++ {
313                 }
314                 // grab word
315                 start := p
316                 for ; p < len(buf) && !white(buf[p]); p++ {
317                 }
318                 if start == p { // no text left
319                         break
320                 }
321                 s = append(s, string(buf[start:p]))
322         }
323         return s
324 }
325
326 // Analyze an item and return its token type and, if it's an action item, an array of
327 // its constituent words.
328 func (t *Template) analyze(item []byte) (tok int, w []string) {
329         // item is known to be non-empty
330         if !equal(item, 0, t.ldelim) { // doesn't start with left delimiter
331                 tok = tokText
332                 return
333         }
334         if !equal(item, len(item)-len(t.rdelim), t.rdelim) { // doesn't end with right delimiter
335                 t.parseError("internal error: unmatched opening delimiter") // lexing should prevent this
336                 return
337         }
338         if len(item) <= len(t.ldelim)+len(t.rdelim) { // no contents
339                 t.parseError("empty directive")
340                 return
341         }
342         // Comment
343         if item[len(t.ldelim)] == '#' {
344                 tok = tokComment
345                 return
346         }
347         // Split into words
348         w = words(item[len(t.ldelim) : len(item)-len(t.rdelim)]) // drop final delimiter
349         if len(w) == 0 {
350                 t.parseError("empty directive")
351                 return
352         }
353         if len(w) == 1 && w[0][0] != '.' {
354                 tok = tokVariable
355                 return
356         }
357         switch w[0] {
358         case ".meta-left", ".meta-right", ".space", ".tab":
359                 tok = tokLiteral
360                 return
361         case ".or":
362                 tok = tokOr
363                 return
364         case ".end":
365                 tok = tokEnd
366                 return
367         case ".section":
368                 if len(w) != 2 {
369                         t.parseError("incorrect fields for .section: %s", item)
370                         return
371                 }
372                 tok = tokSection
373                 return
374         case ".repeated":
375                 if len(w) != 3 || w[1] != "section" {
376                         t.parseError("incorrect fields for .repeated: %s", item)
377                         return
378                 }
379                 tok = tokRepeated
380                 return
381         case ".alternates":
382                 if len(w) != 2 || w[1] != "with" {
383                         t.parseError("incorrect fields for .alternates: %s", item)
384                         return
385                 }
386                 tok = tokAlternates
387                 return
388         }
389         t.parseError("bad directive: %s", item)
390         return
391 }
392
393 // -- Parsing
394
395 // Allocate a new variable-evaluation element.
396 func (t *Template) newVariable(name_formatter string) (v *variableElement) {
397         name := name_formatter
398         formatter := ""
399         bar := strings.Index(name_formatter, "|")
400         if bar >= 0 {
401                 name = name_formatter[0:bar]
402                 formatter = name_formatter[bar+1:]
403         }
404         // Probably ok, so let's build it.
405         v = &variableElement{t.linenum, name, formatter}
406
407         // We could remember the function address here and avoid the lookup later,
408         // but it's more dynamic to let the user change the map contents underfoot.
409         // We do require the name to be present, though.
410
411         // Is it in user-supplied map?
412         if t.fmap != nil {
413                 if _, ok := t.fmap[formatter]; ok {
414                         return
415                 }
416         }
417         // Is it in builtin map?
418         if _, ok := builtins[formatter]; ok {
419                 return
420         }
421         t.parseError("unknown formatter: %s", formatter)
422         return
423 }
424
425 // Grab the next item.  If it's simple, just append it to the template.
426 // Otherwise return its details.
427 func (t *Template) parseSimple(item []byte) (done bool, tok int, w []string) {
428         tok, w = t.analyze(item)
429         done = true // assume for simplicity
430         switch tok {
431         case tokComment:
432                 return
433         case tokText:
434                 t.elems.Push(&textElement{item})
435                 return
436         case tokLiteral:
437                 switch w[0] {
438                 case ".meta-left":
439                         t.elems.Push(&literalElement{t.ldelim})
440                 case ".meta-right":
441                         t.elems.Push(&literalElement{t.rdelim})
442                 case ".space":
443                         t.elems.Push(&literalElement{space})
444                 case ".tab":
445                         t.elems.Push(&literalElement{tab})
446                 default:
447                         t.parseError("internal error: unknown literal: %s", w[0])
448                 }
449                 return
450         case tokVariable:
451                 t.elems.Push(t.newVariable(w[0]))
452                 return
453         }
454         return false, tok, w
455 }
456
457 // parseRepeated and parseSection are mutually recursive
458
459 func (t *Template) parseRepeated(words []string) *repeatedElement {
460         r := new(repeatedElement)
461         t.elems.Push(r)
462         r.linenum = t.linenum
463         r.field = words[2]
464         // Scan section, collecting true and false (.or) blocks.
465         r.start = t.elems.Len()
466         r.or = -1
467         r.altstart = -1
468         r.altend = -1
469 Loop:
470         for {
471                 item := t.nextItem()
472                 if len(item) == 0 {
473                         t.parseError("missing .end for .repeated section")
474                         break
475                 }
476                 done, tok, w := t.parseSimple(item)
477                 if done {
478                         continue
479                 }
480                 switch tok {
481                 case tokEnd:
482                         break Loop
483                 case tokOr:
484                         if r.or >= 0 {
485                                 t.parseError("extra .or in .repeated section")
486                                 break Loop
487                         }
488                         r.altend = t.elems.Len()
489                         r.or = t.elems.Len()
490                 case tokSection:
491                         t.parseSection(w)
492                 case tokRepeated:
493                         t.parseRepeated(w)
494                 case tokAlternates:
495                         if r.altstart >= 0 {
496                                 t.parseError("extra .alternates in .repeated section")
497                                 break Loop
498                         }
499                         if r.or >= 0 {
500                                 t.parseError(".alternates inside .or block in .repeated section")
501                                 break Loop
502                         }
503                         r.altstart = t.elems.Len()
504                 default:
505                         t.parseError("internal error: unknown repeated section item: %s", item)
506                         break Loop
507                 }
508         }
509         if r.altend < 0 {
510                 r.altend = t.elems.Len()
511         }
512         r.end = t.elems.Len()
513         return r
514 }
515
516 func (t *Template) parseSection(words []string) *sectionElement {
517         s := new(sectionElement)
518         t.elems.Push(s)
519         s.linenum = t.linenum
520         s.field = words[1]
521         // Scan section, collecting true and false (.or) blocks.
522         s.start = t.elems.Len()
523         s.or = -1
524 Loop:
525         for {
526                 item := t.nextItem()
527                 if len(item) == 0 {
528                         t.parseError("missing .end for .section")
529                         break
530                 }
531                 done, tok, w := t.parseSimple(item)
532                 if done {
533                         continue
534                 }
535                 switch tok {
536                 case tokEnd:
537                         break Loop
538                 case tokOr:
539                         if s.or >= 0 {
540                                 t.parseError("extra .or in .section")
541                                 break Loop
542                         }
543                         s.or = t.elems.Len()
544                 case tokSection:
545                         t.parseSection(w)
546                 case tokRepeated:
547                         t.parseRepeated(w)
548                 case tokAlternates:
549                         t.parseError(".alternates not in .repeated")
550                 default:
551                         t.parseError("internal error: unknown section item: %s", item)
552                 }
553         }
554         s.end = t.elems.Len()
555         return s
556 }
557
558 func (t *Template) parse() {
559         for {
560                 item := t.nextItem()
561                 if len(item) == 0 {
562                         break
563                 }
564                 done, tok, w := t.parseSimple(item)
565                 if done {
566                         continue
567                 }
568                 switch tok {
569                 case tokOr, tokEnd, tokAlternates:
570                         t.parseError("unexpected %s", w[0])
571                 case tokSection:
572                         t.parseSection(w)
573                 case tokRepeated:
574                         t.parseRepeated(w)
575                 default:
576                         t.parseError("internal error: bad directive in parse: %s", item)
577                 }
578         }
579 }
580
581 // -- Execution
582
583 // Evaluate interfaces and pointers looking for a value that can look up the name, via a
584 // struct field, method, or map key, and return the result of the lookup.
585 func lookup(v reflect.Value, name string) reflect.Value {
586         for v != nil {
587                 typ := v.Type()
588                 if n := v.Type().NumMethod(); n > 0 {
589                         for i := 0; i < n; i++ {
590                                 m := typ.Method(i)
591                                 mtyp := m.Type
592                                 if m.Name == name && mtyp.NumIn() == 1 && mtyp.NumOut() == 1 {
593                                         return v.Method(i).Call(nil)[0]
594                                 }
595                         }
596                 }
597                 switch av := v.(type) {
598                 case *reflect.PtrValue:
599                         v = av.Elem()
600                 case *reflect.InterfaceValue:
601                         v = av.Elem()
602                 case *reflect.StructValue:
603                         return av.FieldByName(name)
604                 case *reflect.MapValue:
605                         return av.Elem(reflect.NewValue(name))
606                 default:
607                         return nil
608                 }
609         }
610         return v
611 }
612
613 // Walk v through pointers and interfaces, extracting the elements within.
614 func indirect(v reflect.Value) reflect.Value {
615 loop:
616         for v != nil {
617                 switch av := v.(type) {
618                 case *reflect.PtrValue:
619                         v = av.Elem()
620                 case *reflect.InterfaceValue:
621                         v = av.Elem()
622                 default:
623                         break loop
624                 }
625         }
626         return v
627 }
628
629 // If the data for this template is a struct, find the named variable.
630 // Names of the form a.b.c are walked down the data tree.
631 // The special name "@" (the "cursor") denotes the current data.
632 // The value coming in (st.data) might need indirecting to reach
633 // a struct while the return value is not indirected - that is,
634 // it represents the actual named field.
635 func (st *state) findVar(s string) reflect.Value {
636         if s == "@" {
637                 return st.data
638         }
639         data := st.data
640         for _, elem := range strings.Split(s, ".", -1) {
641                 // Look up field; data must be a struct or map.
642                 data = lookup(data, elem)
643                 if data == nil {
644                         return nil
645                 }
646         }
647         return data
648 }
649
650 // Is there no data to look at?
651 func empty(v reflect.Value) bool {
652         v = indirect(v)
653         if v == nil {
654                 return true
655         }
656         switch v := v.(type) {
657         case *reflect.BoolValue:
658                 return v.Get() == false
659         case *reflect.StringValue:
660                 return v.Get() == ""
661         case *reflect.StructValue:
662                 return false
663         case *reflect.MapValue:
664                 return false
665         case *reflect.ArrayValue:
666                 return v.Len() == 0
667         case *reflect.SliceValue:
668                 return v.Len() == 0
669         }
670         return true
671 }
672
673 // Look up a variable or method, up through the parent if necessary.
674 func (t *Template) varValue(name string, st *state) reflect.Value {
675         field := st.findVar(name)
676         if field == nil {
677                 if st.parent == nil {
678                         t.execError(st, t.linenum, "name not found: %s in type %s", name, st.data.Type())
679                 }
680                 return t.varValue(name, st.parent)
681         }
682         return field
683 }
684
685 // Evaluate a variable, looking up through the parent if necessary.
686 // If it has a formatter attached ({var|formatter}) run that too.
687 func (t *Template) writeVariable(v *variableElement, st *state) {
688         formatter := v.formatter
689         val := t.varValue(v.name, st).Interface()
690         // is it in user-supplied map?
691         if t.fmap != nil {
692                 if fn, ok := t.fmap[formatter]; ok {
693                         fn(st.wr, val, formatter)
694                         return
695                 }
696         }
697         // is it in builtin map?
698         if fn, ok := builtins[formatter]; ok {
699                 fn(st.wr, val, formatter)
700                 return
701         }
702         t.execError(st, v.linenum, "missing formatter %s for variable %s", formatter, v.name)
703 }
704
705 // Execute element i.  Return next index to execute.
706 func (t *Template) executeElement(i int, st *state) int {
707         switch elem := t.elems.At(i).(type) {
708         case *textElement:
709                 st.wr.Write(elem.text)
710                 return i + 1
711         case *literalElement:
712                 st.wr.Write(elem.text)
713                 return i + 1
714         case *variableElement:
715                 t.writeVariable(elem, st)
716                 return i + 1
717         case *sectionElement:
718                 t.executeSection(elem, st)
719                 return elem.end
720         case *repeatedElement:
721                 t.executeRepeated(elem, st)
722                 return elem.end
723         }
724         e := t.elems.At(i)
725         t.execError(st, 0, "internal error: bad directive in execute: %v %T\n", reflect.NewValue(e).Interface(), e)
726         return 0
727 }
728
729 // Execute the template.
730 func (t *Template) execute(start, end int, st *state) {
731         for i := start; i < end; {
732                 i = t.executeElement(i, st)
733         }
734 }
735
736 // Execute a .section
737 func (t *Template) executeSection(s *sectionElement, st *state) {
738         // Find driver data for this section.  It must be in the current struct.
739         field := t.varValue(s.field, st)
740         if field == nil {
741                 t.execError(st, s.linenum, ".section: cannot find field %s in %s", s.field, st.data.Type())
742         }
743         st = st.clone(field)
744         start, end := s.start, s.or
745         if !empty(field) {
746                 // Execute the normal block.
747                 if end < 0 {
748                         end = s.end
749                 }
750         } else {
751                 // Execute the .or block.  If it's missing, do nothing.
752                 start, end = s.or, s.end
753                 if start < 0 {
754                         return
755                 }
756         }
757         for i := start; i < end; {
758                 i = t.executeElement(i, st)
759         }
760 }
761
762 // Return the result of calling the Iter method on v, or nil.
763 func iter(v reflect.Value) *reflect.ChanValue {
764         for j := 0; j < v.Type().NumMethod(); j++ {
765                 mth := v.Type().Method(j)
766                 fv := v.Method(j)
767                 ft := fv.Type().(*reflect.FuncType)
768                 // TODO(rsc): NumIn() should return 0 here, because ft is from a curried FuncValue.
769                 if mth.Name != "Iter" || ft.NumIn() != 1 || ft.NumOut() != 1 {
770                         continue
771                 }
772                 ct, ok := ft.Out(0).(*reflect.ChanType)
773                 if !ok || ct.Dir()&reflect.RecvDir == 0 {
774                         continue
775                 }
776                 return fv.Call(nil)[0].(*reflect.ChanValue)
777         }
778         return nil
779 }
780
781 // Execute a .repeated section
782 func (t *Template) executeRepeated(r *repeatedElement, st *state) {
783         // Find driver data for this section.  It must be in the current struct.
784         field := t.varValue(r.field, st)
785         if field == nil {
786                 t.execError(st, r.linenum, ".repeated: cannot find field %s in %s", r.field, st.data.Type())
787         }
788         field = indirect(field)
789
790         start, end := r.start, r.or
791         if end < 0 {
792                 end = r.end
793         }
794         if r.altstart >= 0 {
795                 end = r.altstart
796         }
797         first := true
798
799         // Code common to all the loops.
800         loopBody := func(newst *state) {
801                 // .alternates between elements
802                 if !first && r.altstart >= 0 {
803                         for i := r.altstart; i < r.altend; {
804                                 i = t.executeElement(i, newst)
805                         }
806                 }
807                 first = false
808                 for i := start; i < end; {
809                         i = t.executeElement(i, newst)
810                 }
811         }
812
813         if array, ok := field.(reflect.ArrayOrSliceValue); ok {
814                 for j := 0; j < array.Len(); j++ {
815                         loopBody(st.clone(array.Elem(j)))
816                 }
817         } else if m, ok := field.(*reflect.MapValue); ok {
818                 for _, key := range m.Keys() {
819                         loopBody(st.clone(m.Elem(key)))
820                 }
821         } else if ch := iter(field); ch != nil {
822                 for {
823                         e := ch.Recv()
824                         if ch.Closed() {
825                                 break
826                         }
827                         loopBody(st.clone(e))
828                 }
829         } else {
830                 t.execError(st, r.linenum, ".repeated: cannot repeat %s (type %s)",
831                         r.field, field.Type())
832         }
833
834         if first {
835                 // Empty. Execute the .or block, once.  If it's missing, do nothing.
836                 start, end := r.or, r.end
837                 if start >= 0 {
838                         newst := st.clone(field)
839                         for i := start; i < end; {
840                                 i = t.executeElement(i, newst)
841                         }
842                 }
843                 return
844         }
845 }
846
847 // A valid delimiter must contain no white space and be non-empty.
848 func validDelim(d []byte) bool {
849         if len(d) == 0 {
850                 return false
851         }
852         for _, c := range d {
853                 if white(c) {
854                         return false
855                 }
856         }
857         return true
858 }
859
860 // checkError is a deferred function to turn a panic with type *Error into a plain error return.
861 // Other panics are unexpected and so are re-enabled.
862 func checkError(error *os.Error) {
863         if v := recover(); v != nil {
864                 if e, ok := v.(*Error); ok {
865                         *error = e
866                 } else {
867                         // runtime errors should crash
868                         panic(v)
869                 }
870         }
871 }
872
873 // -- Public interface
874
875 // Parse initializes a Template by parsing its definition.  The string
876 // s contains the template text.  If any errors occur, Parse returns
877 // the error.
878 func (t *Template) Parse(s string) (err os.Error) {
879         if t.elems == nil {
880                 return &Error{1, "template not allocated with New"}
881         }
882         if !validDelim(t.ldelim) || !validDelim(t.rdelim) {
883                 return &Error{1, fmt.Sprintf("bad delimiter strings %q %q", t.ldelim, t.rdelim)}
884         }
885         defer checkError(&err)
886         t.buf = []byte(s)
887         t.p = 0
888         t.linenum = 1
889         t.parse()
890         return nil
891 }
892
893 // ParseFile is like Parse but reads the template definition from the
894 // named file.
895 func (t *Template) ParseFile(filename string) (err os.Error) {
896         b, err := ioutil.ReadFile(filename)
897         if err != nil {
898                 return err
899         }
900         return t.Parse(string(b))
901 }
902
903 // Execute applies a parsed template to the specified data object,
904 // generating output to wr.
905 func (t *Template) Execute(data interface{}, wr io.Writer) (err os.Error) {
906         // Extract the driver data.
907         val := reflect.NewValue(data)
908         defer checkError(&err)
909         t.p = 0
910         t.execute(0, t.elems.Len(), &state{nil, val, wr})
911         return nil
912 }
913
914 // SetDelims sets the left and right delimiters for operations in the
915 // template.  They are validated during parsing.  They could be
916 // validated here but it's better to keep the routine simple.  The
917 // delimiters are very rarely invalid and Parse has the necessary
918 // error-handling interface already.
919 func (t *Template) SetDelims(left, right string) {
920         t.ldelim = []byte(left)
921         t.rdelim = []byte(right)
922 }
923
924 // Parse creates a Template with default parameters (such as {} for
925 // metacharacters).  The string s contains the template text while
926 // the formatter map fmap, which may be nil, defines auxiliary functions
927 // for formatting variables.  The template is returned. If any errors
928 // occur, err will be non-nil.
929 func Parse(s string, fmap FormatterMap) (t *Template, err os.Error) {
930         t = New(fmap)
931         err = t.Parse(s)
932         if err != nil {
933                 t = nil
934         }
935         return
936 }
937
938 // ParseFile is a wrapper function that creates a Template with default
939 // parameters (such as {} for metacharacters).  The filename identifies
940 // a file containing the template text, while the formatter map fmap, which
941 // may be nil, defines auxiliary functions for formatting variables.
942 // The template is returned. If any errors occur, err will be non-nil.
943 func ParseFile(filename string, fmap FormatterMap) (t *Template, err os.Error) {
944         b, err := ioutil.ReadFile(filename)
945         if err != nil {
946                 return nil, err
947         }
948         return Parse(string(b), fmap)
949 }
950
951 // MustParse is like Parse but panics if the template cannot be parsed.
952 func MustParse(s string, fmap FormatterMap) *Template {
953         t, err := Parse(s, fmap)
954         if err != nil {
955                 panic("template.MustParse error: " + err.String())
956         }
957         return t
958 }
959
960 // MustParseFile is like ParseFile but panics if the file cannot be read
961 // or the template cannot be parsed.
962 func MustParseFile(filename string, fmap FormatterMap) *Template {
963         b, err := ioutil.ReadFile(filename)
964         if err != nil {
965                 panic("template.MustParseFile error: " + err.String())
966         }
967         return MustParse(string(b), fmap)
968 }