summaryrefslogtreecommitdiff
path: root/src/cmd
diff options
context:
space:
mode:
authorRob Pike <r@golang.org>2012-01-29 09:19:05 -0800
committerRob Pike <r@golang.org>2012-01-29 09:19:05 -0800
commite783e9ee47804dbd6d8d48a0b99570060b478231 (patch)
tree054a496d4b2500a4f558091fab9c3ffc7c4dab00 /src/cmd
parent1fd238ff924cd14f34773ad4c9983b19347dd4d3 (diff)
downloadgo-e783e9ee47804dbd6d8d48a0b99570060b478231.tar.gz
cmd/go: first piece of tool rearrangement
1) create go-tool dir in make.bash 2) clean up stale binaries in make.bash 3) add 'tool' command to go 4) convert goyacc->yacc as a first test tool Since goyacc stands alone, it's a safe trial. R=rsc CC=golang-dev http://codereview.appspot.com/5576061
Diffstat (limited to 'src/cmd')
-rw-r--r--src/cmd/Makefile2
-rw-r--r--src/cmd/go/Makefile1
-rw-r--r--src/cmd/go/main.go1
-rw-r--r--src/cmd/go/tool.go100
-rw-r--r--src/cmd/yacc/Makefile (renamed from src/cmd/goyacc/Makefile)10
-rw-r--r--src/cmd/yacc/doc.go (renamed from src/cmd/goyacc/doc.go)10
-rw-r--r--src/cmd/yacc/units.txt (renamed from src/cmd/goyacc/units.txt)0
-rw-r--r--src/cmd/yacc/units.y (renamed from src/cmd/goyacc/units.y)10
-rw-r--r--src/cmd/yacc/yacc.go (renamed from src/cmd/goyacc/goyacc.go)2
9 files changed, 120 insertions, 16 deletions
diff --git a/src/cmd/Makefile b/src/cmd/Makefile
index ee82b8311..089739d05 100644
--- a/src/cmd/Makefile
+++ b/src/cmd/Makefile
@@ -42,7 +42,7 @@ CLEANDIRS=\
gofmt\
goinstall\
gotest\
- goyacc\
+ yacc\
install: $(patsubst %,%.install,$(DIRS))
clean: $(patsubst %,%.clean,$(CLEANDIRS))
diff --git a/src/cmd/go/Makefile b/src/cmd/go/Makefile
index 295a14498..3e19d2e3d 100644
--- a/src/cmd/go/Makefile
+++ b/src/cmd/go/Makefile
@@ -18,6 +18,7 @@ GOFILES=\
run.go\
test.go\
testflag.go\
+ tool.go\
version.go\
vet.go\
vcs.go\
diff --git a/src/cmd/go/main.go b/src/cmd/go/main.go
index ca3b1188a..b69c66d3e 100644
--- a/src/cmd/go/main.go
+++ b/src/cmd/go/main.go
@@ -75,6 +75,7 @@ var commands = []*Command{
cmdList,
cmdRun,
cmdTest,
+ cmdTool,
cmdVersion,
cmdVet,
diff --git a/src/cmd/go/tool.go b/src/cmd/go/tool.go
new file mode 100644
index 000000000..24ed78bda
--- /dev/null
+++ b/src/cmd/go/tool.go
@@ -0,0 +1,100 @@
+// Copyright 2011 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+import (
+ "fmt"
+ "go/build"
+ "os"
+ "os/exec"
+ "sort"
+ "strings"
+)
+
+var cmdTool = &Command{
+ Run: runTool,
+ UsageLine: "tool command [args...]",
+ Short: "run specified go tool",
+ Long: `
+Tool runs the go tool command identified by the arguments.
+With no arguments it prints the list of known tools.
+
+For more about each tool command, see 'go tool command -h'.
+`,
+}
+
+var (
+ toolGoos = build.DefaultContext.GOOS
+ toolIsWindows = toolGoos == "windows"
+ toolBinToolDir = build.Path[0].BinDir() + "/go-tool"
+)
+
+const toolWindowsExtension = ".exe"
+
+func runTool(cmd *Command, args []string) {
+ if len(args) == 0 {
+ listTools()
+ return
+ }
+ tool := args[0]
+ // The tool name must be lower-case letters and numbers.
+ for _, c := range tool {
+ switch {
+ case 'a' <= c && c <= 'z', '0' <= c && c <= '9':
+ default:
+ fmt.Fprintf(os.Stderr, "go tool: bad tool name %q\n", tool)
+ exitStatus = 2
+ return
+ }
+ }
+ toolPath := toolBinToolDir + "/" + tool
+ if toolIsWindows {
+ toolPath += toolWindowsExtension
+ }
+ // Give a nice message if there is no tool with that name.
+ if _, err := os.Stat(toolPath); err != nil {
+ fmt.Fprintf(os.Stderr, "go tool: no such tool %q\n", tool)
+ exitStatus = 3
+ return
+ }
+ toolCmd := &exec.Cmd{
+ Path: toolPath,
+ Args: args,
+ Stdout: os.Stdout,
+ Stderr: os.Stderr,
+ }
+ err := toolCmd.Run()
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "go tool %s failed: %s\n", tool, err)
+ exitStatus = 1
+ return
+ }
+}
+
+// listTools prints a list of the available tools in the go-tools directory.
+func listTools() {
+ toolDir, err := os.Open(toolBinToolDir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "go tool: no tool directory: %s\n", err)
+ exitStatus = 2
+ return
+ }
+ names, err := toolDir.Readdirnames(-1)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "go tool: can't read directory: %s\n", err)
+ exitStatus = 2
+ return
+ }
+ sort.StringSlice(names).Sort()
+ for _, name := range names {
+ // Unify presentation by going to lower case.
+ name = strings.ToLower(name)
+ // If it's windows, don't show the .exe suffix.
+ if toolIsWindows && strings.HasSuffix(name, toolWindowsExtension) {
+ name = name[:len(name)-len(toolWindowsExtension)]
+ }
+ fmt.Println(name)
+ }
+}
diff --git a/src/cmd/goyacc/Makefile b/src/cmd/yacc/Makefile
index a616e8534..6ce9d54fb 100644
--- a/src/cmd/goyacc/Makefile
+++ b/src/cmd/yacc/Makefile
@@ -4,14 +4,14 @@
include ../../Make.inc
-TARG=goyacc
+TARG=yacc
GOFILES=\
- goyacc.go\
+ yacc.go\
-include ../../Make.cmd
+include ../../Make.tool
-units: goyacc units.y
- ./goyacc -p units_ units.y
+units: yacc units.y
+ ./yacc -p units_ units.y
$(GC) $(GCFLAGS) $(GCIMPORTS) y.go
$(LD) -o units y.$O
diff --git a/src/cmd/goyacc/doc.go b/src/cmd/yacc/doc.go
index 5dd6abe69..9874a2ae2 100644
--- a/src/cmd/goyacc/doc.go
+++ b/src/cmd/yacc/doc.go
@@ -4,7 +4,8 @@
/*
-Goyacc is a version of yacc for Go.
+Yacc is a version of yacc for Go. It is run with the command
+ go tool yacc args...
It is written in Go and generates parsers written in Go.
It is largely transliterated from the Inferno version written in Limbo
@@ -13,7 +14,8 @@ written in C and documented at
http://plan9.bell-labs.com/magic/man2html/1/yacc
-Yacc adepts will have no trouble adapting to this form of the tool.
+Adepts of the original yacc will have no trouble adapting to this
+form of the tool.
The file units.y in this directory is a yacc grammar for a version of
the Unix tool units, also written in Go and largely transliterated
@@ -37,9 +39,9 @@ which holds the yyLexer passed to Parse.
Multiple grammars compiled into a single program should be placed in
distinct packages. If that is impossible, the "-p prefix" flag to
-goyacc sets the prefix, by default yy, that begins the names of
+yacc sets the prefix, by default yy, that begins the names of
symbols, including types, the parser, and the lexer, generated and
-referenced by goyacc's generated code. Setting it to distinct values
+referenced by yacc's generated code. Setting it to distinct values
allows multiple grammars to be placed in a single package.
*/
diff --git a/src/cmd/goyacc/units.txt b/src/cmd/yacc/units.txt
index ddb2bc294..ddb2bc294 100644
--- a/src/cmd/goyacc/units.txt
+++ b/src/cmd/yacc/units.txt
diff --git a/src/cmd/goyacc/units.y b/src/cmd/yacc/units.y
index 3833486ad..f10cb7c7d 100644
--- a/src/cmd/goyacc/units.y
+++ b/src/cmd/yacc/units.y
@@ -7,17 +7,17 @@
// See http://plan9.bell-labs.com/plan9/license.html
// Generate parser with prefix "units_":
-// goyacc -p "units_"
+// go tool yacc -p "units_"
%{
// units.y
-// example of a goyacc program
+// example of a Go yacc program
// usage is
-// goyacc -p "units_" units.y (produces y.go)
+// go tool yacc -p "units_" units.y (produces y.go)
// 6g y.go
// 6l y.6
-// ./6.out $GOROOT/src/cmd/goyacc/units
+// ./6.out $GOROOT/src/cmd/yacc/units
// you have: c
// you want: furlongs/fortnight
// * 1.8026178e+12
@@ -288,7 +288,7 @@ func main() {
flag.Parse()
- file = os.Getenv("GOROOT") + "/src/cmd/goyacc/units.txt"
+ file = os.Getenv("GOROOT") + "/src/cmd/yacc/units.txt"
if flag.NArg() > 0 {
file = flag.Arg(0)
}
diff --git a/src/cmd/goyacc/goyacc.go b/src/cmd/yacc/yacc.go
index e1b99bed2..c91a72123 100644
--- a/src/cmd/goyacc/goyacc.go
+++ b/src/cmd/yacc/yacc.go
@@ -2933,7 +2933,7 @@ func chcopy(q string) string {
}
func usage() {
- fmt.Fprintf(stderr, "usage: goyacc [-o output] [-v parsetable] input\n")
+ fmt.Fprintf(stderr, "usage: yacc [-o output] [-v parsetable] input\n")
exit(1)
}