"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "tpl/internal/go_templates/texttemplate/exec.go" between
hugo-0.80.0.tar.gz and hugo-0.81.0.tar.gz

About: Hugo is a static site generator that takes a source directory of Markdown files and templates and uses these as input to create a complete website (written in Go).

exec.go  (hugo-0.80.0):exec.go  (hugo-0.81.0)
// Copyright 2011 The Go Authors. All rights reserved. // Copyright 2011 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style // Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file. // license that can be found in the LICENSE file.
package template package template
import ( import (
"fmt" "fmt"
"github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort"
"github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse"
"io" "io"
"reflect" "reflect"
"runtime" "runtime"
"strings" "strings"
"github.com/gohugoio/hugo/tpl/internal/go_templates/fmtsort"
"github.com/gohugoio/hugo/tpl/internal/go_templates/texttemplate/parse"
) )
// maxExecDepth specifies the maximum stack depth of templates within // maxExecDepth specifies the maximum stack depth of templates within
// templates. This limit is only practically reached by accidentally // templates. This limit is only practically reached by accidentally
// recursive template invocations. This limit allows us to return // recursive template invocations. This limit allows us to return
// an error instead of triggering a stack overflow. // an error instead of triggering a stack overflow.
var maxExecDepth = initMaxExecDepth() var maxExecDepth = initMaxExecDepth()
func initMaxExecDepth() int { func initMaxExecDepth() int {
if runtime.GOARCH == "wasm" { if runtime.GOARCH == "wasm" {
skipping to change at line 182 skipping to change at line 183
} }
// ExecuteTemplate applies the template associated with t that has the given nam e // ExecuteTemplate applies the template associated with t that has the given nam e
// to the specified data object and writes the output to wr. // to the specified data object and writes the output to wr.
// If an error occurs executing the template or writing its output, // If an error occurs executing the template or writing its output,
// execution stops, but partial results may already have been written to // execution stops, but partial results may already have been written to
// the output writer. // the output writer.
// A template may be executed safely in parallel, although if parallel // A template may be executed safely in parallel, although if parallel
// executions share a Writer the output may be interleaved. // executions share a Writer the output may be interleaved.
func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error { func (t *Template) ExecuteTemplate(wr io.Writer, name string, data interface{}) error {
var tmpl *Template tmpl := t.Lookup(name)
if t.common != nil {
tmpl = t.tmpl[name]
}
if tmpl == nil { if tmpl == nil {
return fmt.Errorf("template: no template %q associated with templ ate %q", name, t.name) return fmt.Errorf("template: no template %q associated with templ ate %q", name, t.name)
} }
return tmpl.Execute(wr, data) return tmpl.Execute(wr, data)
} }
// Execute applies a parsed template to the specified data object, // Execute applies a parsed template to the specified data object,
// and writes the output to wr. // and writes the output to wr.
// If an error occurs executing the template or writing its output, // If an error occurs executing the template or writing its output,
// execution stops, but partial results may already have been written to // execution stops, but partial results may already have been written to
skipping to change at line 233 skipping to change at line 231
// DefinedTemplates returns a string listing the defined templates, // DefinedTemplates returns a string listing the defined templates,
// prefixed by the string "; defined templates are: ". If there are none, // prefixed by the string "; defined templates are: ". If there are none,
// it returns the empty string. For generating an error message here // it returns the empty string. For generating an error message here
// and in html/template. // and in html/template.
func (t *Template) DefinedTemplates() string { func (t *Template) DefinedTemplates() string {
if t.common == nil { if t.common == nil {
return "" return ""
} }
var b strings.Builder var b strings.Builder
// temporary Hugo-fix
t.muTmpl.RLock()
defer t.muTmpl.RUnlock()
for name, tmpl := range t.tmpl { for name, tmpl := range t.tmpl {
if tmpl.Tree == nil || tmpl.Root == nil { if tmpl.Tree == nil || tmpl.Root == nil {
continue continue
} }
if b.Len() == 0 { if b.Len() == 0 {
b.WriteString("; defined templates are: ") b.WriteString("; defined templates are: ")
} else { } else {
b.WriteString(", ") b.WriteString(", ")
} }
fmt.Fprintf(&b, "%q", name) fmt.Fprintf(&b, "%q", name)
skipping to change at line 259 skipping to change at line 260
func (s *state) walk(dot reflect.Value, node parse.Node) { func (s *state) walk(dot reflect.Value, node parse.Node) {
s.at(node) s.at(node)
switch node := node.(type) { switch node := node.(type) {
case *parse.ActionNode: case *parse.ActionNode:
// Do not pop variables so they persist until next end. // Do not pop variables so they persist until next end.
// Also, if the action declares variables, don't print the result . // Also, if the action declares variables, don't print the result .
val := s.evalPipeline(dot, node.Pipe) val := s.evalPipeline(dot, node.Pipe)
if len(node.Pipe.Decl) == 0 { if len(node.Pipe.Decl) == 0 {
s.printValue(node, val) s.printValue(node, val)
} }
case *parse.CommentNode:
case *parse.IfNode: case *parse.IfNode:
s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.Else List) s.walkIfOrWith(parse.NodeIf, dot, node.Pipe, node.List, node.Else List)
case *parse.ListNode: case *parse.ListNode:
for _, node := range node.Nodes { for _, node := range node.Nodes {
s.walk(dot, node) s.walk(dot, node)
} }
case *parse.RangeNode: case *parse.RangeNode:
s.walkRange(dot, node) s.walkRange(dot, node)
case *parse.TemplateNode: case *parse.TemplateNode:
s.walkTemplate(dot, node) s.walkTemplate(dot, node)
skipping to change at line 375 skipping to change at line 377
} }
om := fmtsort.Sort(val) om := fmtsort.Sort(val)
for i, key := range om.Key { for i, key := range om.Key {
oneIteration(key, om.Value[i]) oneIteration(key, om.Value[i])
} }
return return
case reflect.Chan: case reflect.Chan:
if val.IsNil() { if val.IsNil() {
break break
} }
if val.Type().ChanDir() == reflect.SendDir {
s.errorf("range over send-only channel %v", val)
break
}
i := 0 i := 0
for ; ; i++ { for ; ; i++ {
elem, ok := val.Recv() elem, ok := val.Recv()
if !ok { if !ok {
break break
} }
oneIteration(reflect.ValueOf(i), elem) oneIteration(reflect.ValueOf(i), elem)
} }
if i == 0 { if i == 0 {
break break
skipping to change at line 399 skipping to change at line 405
default: default:
s.errorf("range can't iterate over %v", val) s.errorf("range can't iterate over %v", val)
} }
if r.ElseList != nil { if r.ElseList != nil {
s.walk(dot, r.ElseList) s.walk(dot, r.ElseList)
} }
} }
func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) { func (s *state) walkTemplate(dot reflect.Value, t *parse.TemplateNode) {
s.at(t) s.at(t)
tmpl := s.tmpl.tmpl[t.Name] tmpl := s.tmpl.Lookup(t.Name)
if tmpl == nil { if tmpl == nil {
s.errorf("template %q not defined", t.Name) s.errorf("template %q not defined", t.Name)
} }
if s.depth == maxExecDepth { if s.depth == maxExecDepth {
s.errorf("exceeded maximum template depth (%v)", maxExecDepth) s.errorf("exceeded maximum template depth (%v)", maxExecDepth)
} }
// Variables declared by the pipeline persist. // Variables declared by the pipeline persist.
dot = s.evalPipeline(dot, t.Pipe) dot = s.evalPipeline(dot, t.Pipe)
newState := *s newState := *s
newState.depth++ newState.depth++
 End of changes. 7 change blocks. 
7 lines changed or deleted 13 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)