]> Cypherpunks repositories - gostls13.git/commitdiff
template: fix and clean interaction between quotes and formatters
authorGustavo Niemeyer <gustavo@niemeyer.net>
Mon, 30 May 2011 14:53:09 +0000 (11:53 -0300)
committerGustavo Niemeyer <gustavo@niemeyer.net>
Mon, 30 May 2011 14:53:09 +0000 (11:53 -0300)
Fixes issue #1897.

R=r, gustavo, r
CC=golang-dev
https://golang.org/cl/4561049

src/pkg/template/template.go
src/pkg/template/template_test.go

index 0706c93fe2c4690a3c37ac22dc9206849ea9a5af..1011190044509554be483e02b6bc252b91ba25ec 100644 (file)
@@ -491,20 +491,9 @@ func (t *Template) formatter(name string) func(io.Writer, string, ...interface{}
 
 // -- Parsing
 
-// Allocate a new variable-evaluation element.
+// newVariable allocates a new variable-evaluation element.
 func (t *Template) newVariable(words []string) *variableElement {
-       // After the final space-separated argument, formatters may be specified separated
-       // by pipe symbols, for example: {a b c|d|e}
-
-       // Until we learn otherwise, formatters contains a single name: "", the default formatter.
-       formatters := []string{""}
-       lastWord := words[len(words)-1]
-       bar := strings.IndexRune(lastWord, '|')
-       if bar >= 0 {
-               words[len(words)-1] = lastWord[0:bar]
-               formatters = strings.Split(lastWord[bar+1:], "|", -1)
-       }
-
+       formatters := extractFormatters(words)
        args := make([]interface{}, len(words))
 
        // Build argument list, processing any literals
@@ -550,6 +539,38 @@ func (t *Template) newVariable(words []string) *variableElement {
        return &variableElement{t.linenum, args, formatters}
 }
 
+// extractFormatters extracts a list of formatters from words.
+// After the final space-separated argument in a variable, formatters may be
+// specified separated by pipe symbols. For example: {a b c|d|e}
+// The words parameter still has the formatters joined by '|' in the last word.
+// extractFormatters splits formatters, replaces the last word with the content
+// found before the first '|' within it, and returns the formatters obtained.
+// If no formatters are found in words, the default formatter is returned.
+func extractFormatters(words []string) (formatters []string) {
+       // "" is the default formatter.
+       formatters = []string{""}
+       if len(words) == 0 {
+               return
+       }
+       var bar int
+       lastWord := words[len(words)-1]
+       if isQuote(lastWord[0]) {
+               end := endQuote([]byte(lastWord), 0)
+               if end < 0 || end+1 == len(lastWord) || lastWord[end+1] != '|' {
+                       return
+               }
+               bar = end + 1
+       } else {
+               bar = strings.IndexRune(lastWord, '|')
+               if bar < 0 {
+                       return
+               }
+       }
+       words[len(words)-1] = lastWord[0:bar]
+       formatters = strings.Split(lastWord[bar+1:], "|", -1)
+       return
+}
+
 // Grab the next item.  If it's simple, just append it to the template.
 // Otherwise return its details.
 func (t *Template) parseSimple(item []byte) (done bool, tok int, w []string) {
index 147a1ca2178569e631afd76e2e38db97812d4e93..99b23c2883608a4fc44189c416db76bd447e99e0 100644 (file)
@@ -144,21 +144,21 @@ var tests = []*Test{
        },
 
        &Test{
-               in: `{"Strings" ":"} {""} {"\t\u0123 \x23\\"} {"\"}{\\"}`,
+               in: `{"Strings" ":"} {""} {"|"} {"\t\u0123 \x23\\"} {"\"}{\\"}`,
 
-               out: "Strings:  \t\u0123 \x23\\ \"}{\\",
+               out: "Strings:  \t\u0123 \x23\\ \"}{\\",
        },
 
        &Test{
-               in: "{`Raw strings` `:`} {``} {`\\t\\u0123 \\x23\\`} {`}{\\`}",
+               in: "{`Raw strings` `:`} {``} {`|`} {`\\t\\u0123 \\x23\\`} {`}{\\`}",
 
-               out: "Raw strings:  \\t\\u0123 \\x23\\ }{\\",
+               out: "Raw strings:  \\t\\u0123 \\x23\\ }{\\",
        },
 
        &Test{
-               in: "Characters: {'a'} {'\\u0123'} {' '} {'}'} {'{'}",
+               in: "Characters: {'a'} {'\\u0123'} {' '} {'{'} {'|'} {'}'}",
 
-               out: "Characters: 97 291 32 125 123",
+               out: "Characters: 97 291 32 123 124 125",
        },
 
        &Test{