Commit 9c3bf097 authored by Rob Pike's avatar Rob Pike

cmd/go: add $GOLINE to generate

Also use os.Expand for variable substitution so ${x}y works.

Fixes #9960.

Change-Id: Ic8239b2e737d1f41910dde8ee9524ac48907cb03
Reviewed-on: https://go-review.googlesource.com/9007Reviewed-by: default avatarRuss Cox <rsc@golang.org>
parent 13cb62c7
......@@ -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
......
......@@ -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
}
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 {
// expandVar expands the $XXX invocation in word. It is called
// by os.Expand.
func (g *Generator) expandVar(word string) string {
switch word {
case "GOARCH":
sub = runtime.GOARCH
return runtime.GOARCH
case "GOOS":
sub = runtime.GOOS
return runtime.GOOS
case "GOFILE":
sub = g.file
return g.file
case "GOLINE":
return fmt.Sprint(g.lineNum)
case "GOPACKAGE":
sub = g.pkg
return g.pkg
case "DOLLAR":
sub = "$"
return "$"
default:
sub = os.Getenv(envVar)
}
buf.WriteString(sub)
return os.Getenv(word)
}
return buf.String()
}
// identLength returns the length of the identifier beginning the string.
......
......@@ -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
......
......@@ -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
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment