summaryrefslogtreecommitdiff
path: root/src/pkg/go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/go')
-rw-r--r--src/pkg/go/ast/print_test.go2
-rw-r--r--src/pkg/go/build/Makefile2
-rw-r--r--src/pkg/go/build/build.go234
-rw-r--r--src/pkg/go/build/build_test.go76
-rw-r--r--src/pkg/go/build/cgotest/cgotest.go12
-rw-r--r--src/pkg/go/build/cgotest/file.go45
-rw-r--r--src/pkg/go/build/cmdtest/main.go12
-rw-r--r--src/pkg/go/build/dir.go15
-rw-r--r--src/pkg/go/build/path.go3
-rw-r--r--src/pkg/go/build/pkgtest/pkgtest.go9
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_386.s10
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_amd64.s9
-rw-r--r--src/pkg/go/build/pkgtest/sqrt_arm.s10
-rw-r--r--src/pkg/go/doc/comment.go2
-rw-r--r--src/pkg/go/doc/doc.go2
-rw-r--r--src/pkg/go/parser/interface.go2
-rw-r--r--src/pkg/go/printer/nodes.go10
-rw-r--r--src/pkg/go/printer/testdata/statements.golden15
-rw-r--r--src/pkg/go/printer/testdata/statements.input13
-rw-r--r--src/pkg/go/scanner/scanner.go3
-rw-r--r--src/pkg/go/scanner/scanner_test.go6
-rw-r--r--src/pkg/go/types/exportdata.go8
-rw-r--r--src/pkg/go/types/gcimporter.go4
-rw-r--r--src/pkg/go/types/testdata/exports.go2
24 files changed, 360 insertions, 146 deletions
diff --git a/src/pkg/go/ast/print_test.go b/src/pkg/go/ast/print_test.go
index 0820dcfce..30b396fcf 100644
--- a/src/pkg/go/ast/print_test.go
+++ b/src/pkg/go/ast/print_test.go
@@ -53,7 +53,7 @@ var tests = []struct {
// Split s into lines, trim whitespace from all lines, and return
// the concatenated non-empty lines.
func trim(s string) string {
- lines := strings.Split(s, "\n", -1)
+ lines := strings.Split(s, "\n")
i := 0
for _, line := range lines {
line = strings.TrimSpace(line)
diff --git a/src/pkg/go/build/Makefile b/src/pkg/go/build/Makefile
index 4411940ae..349e00e80 100644
--- a/src/pkg/go/build/Makefile
+++ b/src/pkg/go/build/Makefile
@@ -11,7 +11,7 @@ GOFILES=\
path.go\
syslist.go\
-CLEANFILES+=syslist.go
+CLEANFILES+=syslist.go pkgtest/_obj cmdtest/_obj cgotest/_obj
include ../../../Make.pkg
diff --git a/src/pkg/go/build/build.go b/src/pkg/go/build/build.go
index 3cb8efe47..d83a6666e 100644
--- a/src/pkg/go/build/build.go
+++ b/src/pkg/go/build/build.go
@@ -11,34 +11,61 @@ import (
"fmt"
"os"
"path/filepath"
+ "regexp"
"runtime"
"strings"
)
-func (d *DirInfo) Build(targ string) ([]*Cmd, os.Error) {
- b := &build{obj: "_obj/"}
+// Build produces a build Script for the given package.
+func Build(tree *Tree, pkg string, info *DirInfo) (*Script, os.Error) {
+ s := &Script{}
+ b := &build{
+ script: s,
+ path: filepath.Join(tree.SrcDir(), pkg),
+ }
+ b.obj = b.abs("_obj") + string(filepath.Separator)
- goarch := runtime.GOARCH
+ b.goarch = runtime.GOARCH
if g := os.Getenv("GOARCH"); g != "" {
- goarch = g
+ b.goarch = g
}
var err os.Error
- b.arch, err = ArchChar(goarch)
+ b.arch, err = ArchChar(b.goarch)
if err != nil {
return nil, err
}
- var gofiles = d.GoFiles // .go files to be built with gc
- var ofiles []string // *.GOARCH files to be linked or packed
+ // add import object files to list of Inputs
+ for _, pkg := range info.Imports {
+ t, p, err := FindTree(pkg)
+ if err != nil && err != ErrNotFound {
+ // FindTree should always be able to suggest an import
+ // path and tree. The path must be malformed
+ // (for example, an absolute or relative path).
+ return nil, os.NewError("build: invalid import: " + pkg)
+ }
+ s.addInput(filepath.Join(t.PkgDir(), p+".a"))
+ }
+
+ // .go files to be built with gc
+ gofiles := b.abss(info.GoFiles...)
+ s.addInput(gofiles...)
+
+ var ofiles []string // object files to be linked or packed
// make build directory
b.mkdir(b.obj)
+ s.addIntermediate(b.obj)
// cgo
- if len(d.CgoFiles) > 0 {
- outGo, outObj := b.cgo(d.CgoFiles)
+ if len(info.CgoFiles) > 0 {
+ cgoFiles := b.abss(info.CgoFiles...)
+ s.addInput(cgoFiles...)
+ outGo, outObj := b.cgo(cgoFiles)
gofiles = append(gofiles, outGo...)
ofiles = append(ofiles, outObj...)
+ s.addIntermediate(outGo...)
+ s.addIntermediate(outObj...)
}
// compile
@@ -46,31 +73,136 @@ func (d *DirInfo) Build(targ string) ([]*Cmd, os.Error) {
ofile := b.obj + "_go_." + b.arch
b.gc(ofile, gofiles...)
ofiles = append(ofiles, ofile)
+ s.addIntermediate(ofile)
}
// assemble
- for _, sfile := range d.SFiles {
+ for _, sfile := range info.SFiles {
ofile := b.obj + sfile[:len(sfile)-1] + b.arch
+ sfile = b.abs(sfile)
+ s.addInput(sfile)
b.asm(ofile, sfile)
ofiles = append(ofiles, ofile)
+ s.addIntermediate(ofile)
}
if len(ofiles) == 0 {
return nil, os.NewError("make: no object files to build")
}
- if d.IsCommand() {
+ // choose target file
+ var targ string
+ if info.IsCommand() {
+ // use the last part of the import path as binary name
+ _, bin := filepath.Split(pkg)
+ if runtime.GOOS == "windows" {
+ bin += ".exe"
+ }
+ targ = filepath.Join(tree.BinDir(), bin)
+ } else {
+ targ = filepath.Join(tree.PkgDir(), pkg+".a")
+ }
+
+ // make target directory
+ targDir, _ := filepath.Split(targ)
+ b.mkdir(targDir)
+
+ // link binary or pack object
+ if info.IsCommand() {
b.ld(targ, ofiles...)
} else {
b.gopack(targ, ofiles...)
}
+ s.Output = append(s.Output, targ)
+
+ return b.script, nil
+}
+
+// A Script describes the build process for a Go package.
+// The Input, Intermediate, and Output fields are lists of absolute paths.
+type Script struct {
+ Cmd []*Cmd
+ Input []string
+ Intermediate []string
+ Output []string
+}
+
+func (s *Script) addInput(file ...string) {
+ s.Input = append(s.Input, file...)
+}
+
+func (s *Script) addIntermediate(file ...string) {
+ s.Intermediate = append(s.Intermediate, file...)
+}
+
+// Run runs the Script's Cmds in order.
+func (s *Script) Run() os.Error {
+ for _, c := range s.Cmd {
+ if err := c.Run(); err != nil {
+ return err
+ }
+ }
+ return nil
+}
+
+// Stale returns true if the build's inputs are newer than its outputs.
+func (s *Script) Stale() bool {
+ var latest int64
+ // get latest mtime of outputs
+ for _, file := range s.Output {
+ fi, err := os.Stat(file)
+ if err != nil {
+ // any error reading output files means stale
+ return true
+ }
+ if m := fi.Mtime_ns; m > latest {
+ latest = m
+ }
+ }
+ for _, file := range s.Input {
+ fi, err := os.Stat(file)
+ if err != nil || fi.Mtime_ns > latest {
+ // any error reading input files means stale
+ // (attempt to rebuild to figure out why)
+ return true
+ }
+ }
+ return false
+}
+
+// Clean removes the Script's Intermediate files.
+// It tries to remove every file and returns the first error it encounters.
+func (s *Script) Clean() (err os.Error) {
+ // Reverse order so that directories get removed after the files they contain.
+ for i := len(s.Intermediate) - 1; i >= 0; i-- {
+ if e := os.Remove(s.Intermediate[i]); err == nil {
+ err = e
+ }
+ }
+ return
+}
- return b.cmds, nil
+// Clean removes the Script's Intermediate and Output files.
+// It tries to remove every file and returns the first error it encounters.
+func (s *Script) Nuke() (err os.Error) {
+ // Reverse order so that directories get removed after the files they contain.
+ for i := len(s.Output) - 1; i >= 0; i-- {
+ if e := os.Remove(s.Output[i]); err == nil {
+ err = e
+ }
+ }
+ if e := s.Clean(); err == nil {
+ err = e
+ }
+ return
}
+// A Cmd describes an individual build command.
type Cmd struct {
Args []string // command-line
Stdout string // write standard output to this file, "" is passthrough
+ Dir string // working directory
+ Env []string // environment
Input []string // file paths (dependencies)
Output []string // file paths
}
@@ -79,14 +211,16 @@ func (c *Cmd) String() string {
return strings.Join(c.Args, " ")
}
-func (c *Cmd) Run(dir string) os.Error {
+// Run executes the Cmd.
+func (c *Cmd) Run() os.Error {
out := new(bytes.Buffer)
cmd := exec.Command(c.Args[0], c.Args[1:]...)
- cmd.Dir = dir
+ cmd.Dir = c.Dir
+ cmd.Env = c.Env
cmd.Stdout = out
cmd.Stderr = out
if c.Stdout != "" {
- f, err := os.Create(filepath.Join(dir, c.Stdout))
+ f, err := os.Create(c.Stdout)
if err != nil {
return err
}
@@ -99,15 +233,6 @@ func (c *Cmd) Run(dir string) os.Error {
return nil
}
-func (c *Cmd) Clean(dir string) (err os.Error) {
- for _, fn := range c.Output {
- if e := os.RemoveAll(fn); err == nil {
- err = e
- }
- }
- return
-}
-
// ArchChar returns the architecture character for the given goarch.
// For example, ArchChar("amd64") returns "6".
func ArchChar(goarch string) (string, os.Error) {
@@ -123,13 +248,30 @@ func ArchChar(goarch string) (string, os.Error) {
}
type build struct {
- cmds []*Cmd
- obj string
- arch string
+ script *Script
+ path string
+ obj string
+ goarch string
+ arch string
+}
+
+func (b *build) abs(file string) string {
+ if filepath.IsAbs(file) {
+ return file
+ }
+ return filepath.Join(b.path, file)
+}
+
+func (b *build) abss(file ...string) []string {
+ s := make([]string, len(file))
+ for i, f := range file {
+ s[i] = b.abs(f)
+ }
+ return s
}
func (b *build) add(c Cmd) {
- b.cmds = append(b.cmds, &c)
+ b.script.Cmd = append(b.script.Cmd, &c)
}
func (b *build) mkdir(name string) {
@@ -192,7 +334,7 @@ func (b *build) cc(ofile string, cfiles ...string) {
func (b *build) gccCompile(ofile, cfile string) {
b.add(Cmd{
- Args: gccArgs(b.arch, "-o", ofile, "-c", cfile),
+ Args: b.gccArgs("-o", ofile, "-c", cfile),
Input: []string{cfile},
Output: []string{ofile},
})
@@ -200,21 +342,26 @@ func (b *build) gccCompile(ofile, cfile string) {
func (b *build) gccLink(ofile string, ofiles ...string) {
b.add(Cmd{
- Args: append(gccArgs(b.arch, "-o", ofile), ofiles...),
+ Args: append(b.gccArgs("-o", ofile), ofiles...),
Input: ofiles,
Output: []string{ofile},
})
}
-func gccArgs(arch string, args ...string) []string {
+func (b *build) gccArgs(args ...string) []string {
// TODO(adg): HOST_CC
- m := "-m32"
- if arch == "6" {
- m = "-m64"
+ a := []string{"gcc", "-I", b.path, "-g", "-fPIC", "-O2"}
+ switch b.arch {
+ case "8":
+ a = append(a, "-m32")
+ case "6":
+ a = append(a, "-m64")
}
- return append([]string{"gcc", m, "-I", ".", "-g", "-fPIC", "-O2"}, args...)
+ return append(a, args...)
}
+var cgoRe = regexp.MustCompile(`[/\\:]`)
+
func (b *build) cgo(cgofiles []string) (outGo, outObj []string) {
// cgo
// TODO(adg): CGOPKGPATH
@@ -222,19 +369,24 @@ func (b *build) cgo(cgofiles []string) (outGo, outObj []string) {
gofiles := []string{b.obj + "_cgo_gotypes.go"}
cfiles := []string{b.obj + "_cgo_main.c", b.obj + "_cgo_export.c"}
for _, fn := range cgofiles {
- f := b.obj + fn[:len(fn)-2]
+ f := b.obj + cgoRe.ReplaceAllString(fn[:len(fn)-2], "_")
gofiles = append(gofiles, f+"cgo1.go")
cfiles = append(cfiles, f+"cgo2.c")
}
defunC := b.obj + "_cgo_defun.c"
- output := append([]string{defunC}, gofiles...)
- output = append(output, cfiles...)
+ output := append([]string{defunC}, cfiles...)
+ output = append(output, gofiles...)
b.add(Cmd{
Args: append([]string{"cgo", "--"}, cgofiles...),
+ Dir: b.path,
+ Env: append(os.Environ(), "GOARCH="+b.goarch),
Input: cgofiles,
Output: output,
})
outGo = append(outGo, gofiles...)
+ exportH := filepath.Join(b.path, "_cgo_export.h")
+ b.script.addIntermediate(defunC, exportH, b.obj+"_cgo_flags")
+ b.script.addIntermediate(cfiles...)
// cc _cgo_defun.c
defunObj := b.obj + "_cgo_defun." + b.arch
@@ -249,10 +401,13 @@ func (b *build) cgo(cgofiles []string) (outGo, outObj []string) {
linkobj = append(linkobj, ofile)
if !strings.HasSuffix(ofile, "_cgo_main.o") {
outObj = append(outObj, ofile)
+ } else {
+ b.script.addIntermediate(ofile)
}
}
- dynObj := b.obj + "_cgo1_.o"
+ dynObj := b.obj + "_cgo_.o"
b.gccLink(dynObj, linkobj...)
+ b.script.addIntermediate(dynObj)
// cgo -dynimport
importC := b.obj + "_cgo_import.c"
@@ -262,6 +417,7 @@ func (b *build) cgo(cgofiles []string) (outGo, outObj []string) {
Input: []string{dynObj},
Output: []string{importC},
})
+ b.script.addIntermediate(importC)
// cc _cgo_import.ARCH
importObj := b.obj + "_cgo_import." + b.arch
diff --git a/src/pkg/go/build/build_test.go b/src/pkg/go/build/build_test.go
index c543eddbd..e59d87672 100644
--- a/src/pkg/go/build/build_test.go
+++ b/src/pkg/go/build/build_test.go
@@ -5,53 +5,57 @@
package build
import (
- "os"
+ "exec"
"path/filepath"
- "runtime"
- "strings"
"testing"
)
-var buildDirs = []string{
- "pkg/path",
- "cmd/gofix",
- "pkg/big",
- "pkg/go/build/cgotest",
+var buildPkgs = []string{
+ "go/build/pkgtest",
+ "go/build/cmdtest",
+ "go/build/cgotest",
}
+const cmdtestOutput = "3"
+
func TestBuild(t *testing.T) {
- out, err := filepath.Abs("_test/out")
- if err != nil {
- t.Fatal(err)
- }
- for _, d := range buildDirs {
- if runtime.GOARCH == "arm" && strings.Contains(d, "/cgo") {
- // no cgo for arm, yet.
+ for _, pkg := range buildPkgs {
+ tree := Path[0] // Goroot
+ dir := filepath.Join(tree.SrcDir(), pkg)
+
+ info, err := ScanDir(dir, true)
+ if err != nil {
+ t.Error("ScanDir:", err)
continue
}
- dir := filepath.Join(runtime.GOROOT(), "src", d)
- testBuild(t, dir, out)
- }
-}
-func testBuild(t *testing.T, dir, targ string) {
- d, err := ScanDir(dir, true)
- if err != nil {
- t.Error(err)
- return
- }
- defer os.Remove(targ)
- cmds, err := d.Build(targ)
- if err != nil {
- t.Error(err)
- return
- }
- for _, c := range cmds {
- t.Log("Run:", c)
- err = c.Run(dir)
+ s, err := Build(tree, pkg, info)
if err != nil {
- t.Error(c, err)
- return
+ t.Error("Build:", err)
+ continue
+ }
+
+ if err := s.Run(); err != nil {
+ t.Error("Run:", err)
+ continue
}
+
+ if pkg == "go/build/cmdtest" {
+ bin := s.Output[0]
+ b, err := exec.Command(bin).CombinedOutput()
+ if err != nil {
+ t.Errorf("exec: %s: %v", bin, err)
+ continue
+ }
+ if string(b) != cmdtestOutput {
+ t.Errorf("cmdtest output: %s want: %s", b, cmdtestOutput)
+ }
+ }
+
+ defer func(s *Script) {
+ if err := s.Nuke(); err != nil {
+ t.Errorf("nuking: %v", err)
+ }
+ }(s)
}
}
diff --git a/src/pkg/go/build/cgotest/cgotest.go b/src/pkg/go/build/cgotest/cgotest.go
new file mode 100644
index 000000000..32b931861
--- /dev/null
+++ b/src/pkg/go/build/cgotest/cgotest.go
@@ -0,0 +1,12 @@
+// 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 cgotest
+
+/*
+char* greeting = "hello, world";
+*/
+import "C"
+
+var Greeting = C.GoString(C.greeting)
diff --git a/src/pkg/go/build/cgotest/file.go b/src/pkg/go/build/cgotest/file.go
deleted file mode 100644
index 3b2a2e7d9..000000000
--- a/src/pkg/go/build/cgotest/file.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2009 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.
-
-/*
-A trivial example of wrapping a C library in Go.
-For a more complex example and explanation,
-see ../gmp/gmp.go.
-*/
-
-package stdio
-
-/*
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/stat.h>
-#include <errno.h>
-
-char* greeting = "hello, world";
-*/
-import "C"
-import "unsafe"
-
-type File C.FILE
-
-// TODO(brainman): uncomment once stdout and stderr references are working on Windows.
-//var Stdout = (*File)(C.stdout)
-//var Stderr = (*File)(C.stderr)
-
-// Test reference to library symbol.
-// Stdout and stderr are too special to be a reliable test.
-var myerr = C.sys_errlist
-
-func (f *File) WriteString(s string) {
- p := C.CString(s)
- C.fputs(p, (*C.FILE)(f))
- C.free(unsafe.Pointer(p))
- f.Flush()
-}
-
-func (f *File) Flush() {
- C.fflush((*C.FILE)(f))
-}
-
-var Greeting = C.GoString(C.greeting)
diff --git a/src/pkg/go/build/cmdtest/main.go b/src/pkg/go/build/cmdtest/main.go
new file mode 100644
index 000000000..bed4f485a
--- /dev/null
+++ b/src/pkg/go/build/cmdtest/main.go
@@ -0,0 +1,12 @@
+// 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 "go/build/pkgtest"
+
+func main() {
+ pkgtest.Foo()
+ print(int(pkgtest.Sqrt(9)))
+}
diff --git a/src/pkg/go/build/dir.go b/src/pkg/go/build/dir.go
index 77e80bff0..e0000b534 100644
--- a/src/pkg/go/build/dir.go
+++ b/src/pkg/go/build/dir.go
@@ -50,7 +50,6 @@ func ScanDir(dir string, allowMain bool) (info *DirInfo, err os.Error) {
var di DirInfo
imported := make(map[string]bool)
- pkgName := ""
fset := token.NewFileSet()
for i := range dirs {
d := &dirs[i]
@@ -89,17 +88,17 @@ func ScanDir(dir string, allowMain bool) (info *DirInfo, err os.Error) {
if s == "documentation" {
continue
}
- if pkgName == "" {
- pkgName = s
- } else if pkgName != s {
+ if di.PkgName == "" {
+ di.PkgName = s
+ } else if di.PkgName != s {
// Only if all files in the directory are in package main
- // do we return pkgName=="main".
+ // do we return PkgName=="main".
// A mix of main and another package reverts
// to the original (allowMain=false) behaviour.
- if s == "main" || pkgName == "main" {
+ if s == "main" || di.PkgName == "main" {
return ScanDir(dir, false)
}
- return nil, os.ErrorString("multiple package names in " + dir)
+ return nil, os.NewError("multiple package names in " + dir)
}
isCgo := false
for _, spec := range pf.Imports {
@@ -140,7 +139,7 @@ func goodOSArch(filename string) bool {
if dot := strings.Index(filename, "."); dot != -1 {
filename = filename[:dot]
}
- l := strings.Split(filename, "_", -1)
+ l := strings.Split(filename, "_")
n := len(l)
if n == 0 {
return true
diff --git a/src/pkg/go/build/path.go b/src/pkg/go/build/path.go
index 8ad39fb0f..ea588abbd 100644
--- a/src/pkg/go/build/path.go
+++ b/src/pkg/go/build/path.go
@@ -88,6 +88,9 @@ func FindTree(path string) (tree *Tree, pkg string, err os.Error) {
if path, err = filepath.Abs(path); err != nil {
return
}
+ if path, err = filepath.EvalSymlinks(path); err != nil {
+ return
+ }
for _, t := range Path {
tpath := t.SrcDir() + string(filepath.Separator)
if !strings.HasPrefix(path, tpath) {
diff --git a/src/pkg/go/build/pkgtest/pkgtest.go b/src/pkg/go/build/pkgtest/pkgtest.go
new file mode 100644
index 000000000..9322f5ebd
--- /dev/null
+++ b/src/pkg/go/build/pkgtest/pkgtest.go
@@ -0,0 +1,9 @@
+// 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 pkgtest
+
+func Foo() {}
+
+func Sqrt(x float64) float64
diff --git a/src/pkg/go/build/pkgtest/sqrt_386.s b/src/pkg/go/build/pkgtest/sqrt_386.s
new file mode 100644
index 000000000..d0a428d52
--- /dev/null
+++ b/src/pkg/go/build/pkgtest/sqrt_386.s
@@ -0,0 +1,10 @@
+// Copyright 2009 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.
+
+// func Sqrt(x float64) float64
+TEXT ·Sqrt(SB),7,$0
+ FMOVD x+0(FP),F0
+ FSQRT
+ FMOVDP F0,r+8(FP)
+ RET
diff --git a/src/pkg/go/build/pkgtest/sqrt_amd64.s b/src/pkg/go/build/pkgtest/sqrt_amd64.s
new file mode 100644
index 000000000..f5b329e70
--- /dev/null
+++ b/src/pkg/go/build/pkgtest/sqrt_amd64.s
@@ -0,0 +1,9 @@
+// Copyright 2009 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.
+
+// func Sqrt(x float64) float64
+TEXT ·Sqrt(SB),7,$0
+ SQRTSD x+0(FP), X0
+ MOVSD X0, r+8(FP)
+ RET
diff --git a/src/pkg/go/build/pkgtest/sqrt_arm.s b/src/pkg/go/build/pkgtest/sqrt_arm.s
new file mode 100644
index 000000000..befbb8a89
--- /dev/null
+++ b/src/pkg/go/build/pkgtest/sqrt_arm.s
@@ -0,0 +1,10 @@
+// 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.
+
+// func Sqrt(x float64) float64
+TEXT ·Sqrt(SB),7,$0
+ MOVD x+0(FP),F0
+ SQRTD F0,F0
+ MOVD F0,r+8(FP)
+ RET
diff --git a/src/pkg/go/doc/comment.go b/src/pkg/go/doc/comment.go
index f1ebfa97b..85640af79 100644
--- a/src/pkg/go/doc/comment.go
+++ b/src/pkg/go/doc/comment.go
@@ -58,7 +58,7 @@ func CommentText(comment *ast.CommentGroup) string {
}
// Split on newlines.
- cl := strings.Split(c, "\n", -1)
+ cl := strings.Split(c, "\n")
// Walk lines, stripping trailing white space and adding to list.
for _, l := range cl {
diff --git a/src/pkg/go/doc/doc.go b/src/pkg/go/doc/doc.go
index a7a7e0a32..b26cd2bed 100644
--- a/src/pkg/go/doc/doc.go
+++ b/src/pkg/go/doc/doc.go
@@ -551,7 +551,7 @@ func (doc *docReader) newDoc(importpath string, filenames []string) *PackageDoc
p := new(PackageDoc)
p.PackageName = doc.pkgName
p.ImportPath = importpath
- sort.SortStrings(filenames)
+ sort.Strings(filenames)
p.Filenames = filenames
p.Doc = CommentText(doc.doc)
// makeTypeDocs may extend the list of doc.values and
diff --git a/src/pkg/go/parser/interface.go b/src/pkg/go/parser/interface.go
index b4780e057..1764c38e4 100644
--- a/src/pkg/go/parser/interface.go
+++ b/src/pkg/go/parser/interface.go
@@ -42,7 +42,7 @@ func readSource(filename string, src interface{}) ([]byte, os.Error) {
}
return buf.Bytes(), nil
default:
- return nil, os.ErrorString("invalid source")
+ return nil, os.NewError("invalid source")
}
}
diff --git a/src/pkg/go/printer/nodes.go b/src/pkg/go/printer/nodes.go
index 0fca8a161..f2b79d810 100644
--- a/src/pkg/go/printer/nodes.go
+++ b/src/pkg/go/printer/nodes.go
@@ -1158,8 +1158,14 @@ func (p *printer) stmt(stmt ast.Stmt, nextIsRBrace bool, multiLine *bool) {
case *ast.SelectStmt:
p.print(token.SELECT, blank)
- p.block(s.Body, 0)
- *multiLine = true
+ body := s.Body
+ if len(body.List) == 0 && !p.commentBefore(p.fset.Position(body.Rbrace)) {
+ // print empty select statement w/o comments on one line
+ p.print(body.Lbrace, token.LBRACE, body.Rbrace, token.RBRACE)
+ } else {
+ p.block(body, 0)
+ *multiLine = true
+ }
case *ast.ForStmt:
p.print(token.FOR)
diff --git a/src/pkg/go/printer/testdata/statements.golden b/src/pkg/go/printer/testdata/statements.golden
index 290060269..0e4840441 100644
--- a/src/pkg/go/printer/testdata/statements.golden
+++ b/src/pkg/go/printer/testdata/statements.golden
@@ -111,6 +111,21 @@ func _() {
}
+// Formatting of selected select statements.
+func _() {
+ select {}
+ select { /* this comment should not be tab-aligned because the closing } is on the same line */
+ }
+ select { /* this comment should be tab-aligned */
+ }
+ select { // this comment should be tab-aligned
+ }
+ select {
+ case <-c:
+ }
+}
+
+
// Formatting of for-statement headers.
func _() {
for {
diff --git a/src/pkg/go/printer/testdata/statements.input b/src/pkg/go/printer/testdata/statements.input
index 21e61efc4..86a753c5a 100644
--- a/src/pkg/go/printer/testdata/statements.input
+++ b/src/pkg/go/printer/testdata/statements.input
@@ -91,6 +91,19 @@ func _() {
}
+// Formatting of selected select statements.
+func _() {
+ select {
+ }
+ select { /* this comment should not be tab-aligned because the closing } is on the same line */ }
+ select { /* this comment should be tab-aligned */
+ }
+ select { // this comment should be tab-aligned
+ }
+ select { case <-c: }
+}
+
+
// Formatting of for-statement headers.
func _() {
for{}
diff --git a/src/pkg/go/scanner/scanner.go b/src/pkg/go/scanner/scanner.go
index 509abeca5..795f0ac15 100644
--- a/src/pkg/go/scanner/scanner.go
+++ b/src/pkg/go/scanner/scanner.go
@@ -22,6 +22,7 @@ package scanner
import (
"bytes"
+ "fmt"
"go/token"
"path/filepath"
"strconv"
@@ -674,7 +675,7 @@ scanAgain:
tok = S.switch3(token.OR, token.OR_ASSIGN, '|', token.LOR)
default:
if S.mode&AllowIllegalChars == 0 {
- S.error(offs, "illegal character "+strconv.QuoteRune(ch))
+ S.error(offs, fmt.Sprintf("illegal character %#U", ch))
}
insertSemi = S.insertSemi // preserve insertSemi info
}
diff --git a/src/pkg/go/scanner/scanner_test.go b/src/pkg/go/scanner/scanner_test.go
index ee1e830a1..c096e2725 100644
--- a/src/pkg/go/scanner/scanner_test.go
+++ b/src/pkg/go/scanner/scanner_test.go
@@ -650,9 +650,9 @@ var errors = []struct {
pos int
err string
}{
- {"\a", token.ILLEGAL, 0, "illegal character '\\a'"},
- {`#`, token.ILLEGAL, 0, "illegal character '#'"},
- {`…`, token.ILLEGAL, 0, "illegal character '…'"},
+ {"\a", token.ILLEGAL, 0, "illegal character U+0007"},
+ {`#`, token.ILLEGAL, 0, "illegal character U+0023 '#'"},
+ {`…`, token.ILLEGAL, 0, "illegal character U+2026 '…'"},
{`' '`, token.CHAR, 0, ""},
{`''`, token.CHAR, 0, "illegal character literal"},
{`'\8'`, token.CHAR, 2, "unknown escape sequence"},
diff --git a/src/pkg/go/types/exportdata.go b/src/pkg/go/types/exportdata.go
index cb08ffe18..f68133761 100644
--- a/src/pkg/go/types/exportdata.go
+++ b/src/pkg/go/types/exportdata.go
@@ -29,7 +29,7 @@ func readGopackHeader(buf *bufio.Reader) (name string, size int, err os.Error) {
s := strings.TrimSpace(string(hdr[64+12+6+6+8:][:10]))
size, err = strconv.Atoi(s)
if err != nil || hdr[len(hdr)-2] != '`' || hdr[len(hdr)-1] != '\n' {
- err = os.ErrorString("invalid archive header")
+ err = os.NewError("invalid archive header")
return
}
name = strings.TrimSpace(string(hdr[:64]))
@@ -80,7 +80,7 @@ func ExportData(filename string) (rc io.ReadCloser, err os.Error) {
return
}
if name != "__.SYMDEF" {
- err = os.ErrorString("go archive does not begin with __.SYMDEF")
+ err = os.NewError("go archive does not begin with __.SYMDEF")
return
}
const block = 4096
@@ -102,7 +102,7 @@ func ExportData(filename string) (rc io.ReadCloser, err os.Error) {
return
}
if name != "__.PKGDEF" {
- err = os.ErrorString("go archive is missing __.PKGDEF")
+ err = os.NewError("go archive is missing __.PKGDEF")
return
}
@@ -117,7 +117,7 @@ func ExportData(filename string) (rc io.ReadCloser, err os.Error) {
// Now at __.PKGDEF in archive or still at beginning of file.
// Either way, line should begin with "go object ".
if !strings.HasPrefix(string(line), "go object ") {
- err = os.ErrorString("not a go object file")
+ err = os.NewError("not a go object file")
return
}
diff --git a/src/pkg/go/types/gcimporter.go b/src/pkg/go/types/gcimporter.go
index 2cfed7726..aa0bb9160 100644
--- a/src/pkg/go/types/gcimporter.go
+++ b/src/pkg/go/types/gcimporter.go
@@ -124,7 +124,7 @@ func GcImporter(imports map[string]*ast.Object, path string) (pkg *ast.Object, e
filename, id := findPkg(path)
if filename == "" {
- err = os.ErrorString("can't find import: " + id)
+ err = os.NewError("can't find import: " + id)
return
}
@@ -166,7 +166,7 @@ func (e importError) String() string {
func (p *gcParser) error(err interface{}) {
if s, ok := err.(string); ok {
- err = os.ErrorString(s)
+ err = os.NewError(s)
}
// panic with a runtime.Error if err is not an os.Error
panic(importError{p.scanner.Pos(), err.(os.Error)})
diff --git a/src/pkg/go/types/testdata/exports.go b/src/pkg/go/types/testdata/exports.go
index 1de2e00ad..035a13fb7 100644
--- a/src/pkg/go/types/testdata/exports.go
+++ b/src/pkg/go/types/testdata/exports.go
@@ -38,7 +38,7 @@ type (
T9 struct {
a int
b, c float32
- d []string "tag"
+ d []string `go:"tag"`
}
T10 struct {
T8