]> git.ipfire.org Git - thirdparty/gcc.git/blob - libgo/go/template/template.go
Add Go frontend, libgo library, and Go testsuite.
[thirdparty/gcc.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 }