]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/go: add $GOLINE to generate
authorRob Pike <r@golang.org>
Fri, 17 Apr 2015 18:21:02 +0000 (11:21 -0700)
committerRob Pike <r@golang.org>
Fri, 17 Apr 2015 20:33:01 +0000 (20:33 +0000)
Also use os.Expand for variable substitution so ${x}y works.

Fixes #9960.

Change-Id: Ic8239b2e737d1f41910dde8ee9524ac48907cb03
Reviewed-on: https://go-review.googlesource.com/9007
Reviewed-by: Russ Cox <rsc@golang.org>
src/cmd/go/doc.go
src/cmd/go/generate.go
src/cmd/go/test.bash
src/cmd/go/testdata/generate/test3.go

index f327330e98d765b6b7d6b1bc86ae9fc777eb7817..39eb7867c7684bbee5b4179085a45e3ec3fbda84 100644 (file)
@@ -276,6 +276,8 @@ Go generate sets several variables when it runs the generator:
                The execution operating system (linux, windows, etc.)
        $GOFILE
                The base name of the file.
+       $GOLINE
+               The line number of the directive in the source file.
        $GOPACKAGE
                The name of the package of the file containing the directive.
        $DOLLAR
index 1877acdeb625929382d7effd5929de885aec0e9b..a17f6e7747935926bf5f1948892436553a3c3eb2 100644 (file)
@@ -18,7 +18,6 @@ import (
        "strconv"
        "strings"
        "unicode"
-       "unicode/utf8"
 )
 
 var cmdGenerate = &Command{
@@ -63,6 +62,8 @@ Go generate sets several variables when it runs the generator:
                The execution operating system (linux, windows, etc.)
        $GOFILE
                The base name of the file.
+       $GOLINE
+               The line number of the directive in the source file.
        $GOPACKAGE
                The name of the package of the file containing the directive.
        $DOLLAR
@@ -177,7 +178,7 @@ type Generator struct {
        file     string // base name of file.
        pkg      string
        commands map[string][]string
-       lineNum  int
+       lineNum  int // current line number.
 }
 
 // run runs the generators in the current file.
@@ -325,7 +326,7 @@ Words:
        }
        // Substitute environment variables.
        for i, word := range words {
-               words[i] = g.expandEnv(word)
+               words[i] = os.Expand(word, g.expandVar)
        }
        return words
 }
@@ -341,40 +342,25 @@ func (g *Generator) errorf(format string, args ...interface{}) {
        panic(stop)
 }
 
-// expandEnv expands any $XXX invocations in word.
-func (g *Generator) expandEnv(word string) string {
-       if !strings.ContainsRune(word, '$') {
-               return word
+// expandVar expands the $XXX invocation in word. It is called
+// by os.Expand.
+func (g *Generator) expandVar(word string) string {
+       switch word {
+       case "GOARCH":
+               return runtime.GOARCH
+       case "GOOS":
+               return runtime.GOOS
+       case "GOFILE":
+               return g.file
+       case "GOLINE":
+               return fmt.Sprint(g.lineNum)
+       case "GOPACKAGE":
+               return g.pkg
+       case "DOLLAR":
+               return "$"
+       default:
+               return os.Getenv(word)
        }
-       var buf bytes.Buffer
-       var w int
-       var r rune
-       for i := 0; i < len(word); i += w {
-               r, w = utf8.DecodeRuneInString(word[i:])
-               if r != '$' {
-                       buf.WriteRune(r)
-                       continue
-               }
-               w += g.identLength(word[i+w:])
-               envVar := word[i+1 : i+w]
-               var sub string
-               switch envVar {
-               case "GOARCH":
-                       sub = runtime.GOARCH
-               case "GOOS":
-                       sub = runtime.GOOS
-               case "GOFILE":
-                       sub = g.file
-               case "GOPACKAGE":
-                       sub = g.pkg
-               case "DOLLAR":
-                       sub = "$"
-               default:
-                       sub = os.Getenv(envVar)
-               }
-               buf.WriteString(sub)
-       }
-       return buf.String()
 }
 
 // identLength returns the length of the identifier beginning the string.
index ca3c9241da8e897ff9c78b499186c651bd844943..e1809b4e65e778b1495a310e48770c3b918008b5 100755 (executable)
@@ -1089,20 +1089,20 @@ TEST 'go generate variable substitution'
 if ! ./testgo generate ./testdata/generate/test3.go > testdata/std.out; then
        echo "go generate ./testdata/generate/test3.go failed to run"
        ok=false
-elif ! grep "$GOARCH test3.go p xyzp/test3.go/123" testdata/std.out > /dev/null; then
+elif ! grep "$GOARCH test3.go:7 pabc xyzp/test3.go/123" testdata/std.out > /dev/null; then
        echo "go generate ./testdata/generate/test3.go generated wrong output"
        ok=false
 fi
 
 TEST 'go generate run flag'
 if ! ./testgo generate -run y.s ./testdata/generate/test4.go > testdata/std.out; then
-       echo "go test -run y.s ./testdata/generate/test4.go failed to run"
+       echo "go test -run yes ./testdata/generate/test4.go failed to run"
        ok=false
 elif ! grep "yes" testdata/std.out > /dev/null; then
-       echo "go generate -run y.s ./testdata/generate/test4.go did not select yes"
+       echo "go generate -run yes ./testdata/generate/test4.go did not select yes"
        ok=false
 elif grep "no" testdata/std.out > /dev/null; then
-       echo "go generate -run y.s ./testdata/generate/test4.go selected no"
+       echo "go generate -run yes ./testdata/generate/test4.go selected no"
        ok=false
 fi
 
index 41ffb7ea87f3c214e8c69d6ac01005ad06289b35..3d6a8a5c7420fe33031ced2907aa1f89eed3a15c 100644 (file)
@@ -4,6 +4,6 @@
 
 // Test go generate variable substitution.
 
-//go:generate echo $GOARCH $GOFILE $GOPACKAGE xyz$GOPACKAGE/$GOFILE/123
+//go:generate echo $GOARCH $GOFILE:$GOLINE ${GOPACKAGE}abc xyz$GOPACKAGE/$GOFILE/123
 
 package p