diff options
author | Rob Pike <r@golang.org> | 2012-01-29 09:19:05 -0800 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2012-01-29 09:19:05 -0800 |
commit | e783e9ee47804dbd6d8d48a0b99570060b478231 (patch) | |
tree | 054a496d4b2500a4f558091fab9c3ffc7c4dab00 /src/cmd | |
parent | 1fd238ff924cd14f34773ad4c9983b19347dd4d3 (diff) | |
download | go-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/Makefile | 2 | ||||
-rw-r--r-- | src/cmd/go/Makefile | 1 | ||||
-rw-r--r-- | src/cmd/go/main.go | 1 | ||||
-rw-r--r-- | src/cmd/go/tool.go | 100 | ||||
-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) } |