summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
Diffstat (limited to 'misc')
-rw-r--r--[-rwxr-xr-x]misc/bbedit/Go.plist0
-rw-r--r--misc/cgo/gmp/gmp.go2
-rw-r--r--misc/cgo/test/callback.go43
-rw-r--r--misc/cgo/test/cflags.go32
-rw-r--r--misc/cgo/test/cgo_test.go3
-rw-r--r--misc/cgo/test/cthread.go6
-rw-r--r--misc/cgo/test/issue4029.go9
-rw-r--r--misc/cgo/test/issue5227.go38
-rw-r--r--misc/cgo/testso/cgoso.c14
-rw-r--r--misc/cgo/testso/cgoso.go2
-rw-r--r--misc/cgo/testso/cgoso_c.c16
-rw-r--r--misc/cgo/testso/test.bat18
-rw-r--r--misc/cgo/testtls/tls.go28
-rw-r--r--misc/cgo/testtls/tls_test.go13
-rw-r--r--misc/cgo/testtls/tls_unix.c19
-rw-r--r--misc/dashboard/README4
-rw-r--r--misc/dashboard/app/build/init.go3
-rw-r--r--misc/dashboard/builder/main.go20
-rw-r--r--misc/dashboard/codereview/dashboard/cl.go18
-rw-r--r--misc/dashboard/codereview/dashboard/people.go20
-rw-r--r--misc/dist/bindist.go83
-rwxr-xr-x[-rw-r--r--]misc/dist/darwin/scripts/preinstall0
-rw-r--r--misc/emacs/go-mode.el435
-rw-r--r--misc/kate/go.xml2
-rw-r--r--[-rwxr-xr-x]misc/notepadplus/README0
-rw-r--r--[-rwxr-xr-x]misc/notepadplus/go.xml0
-rw-r--r--[-rwxr-xr-x]misc/notepadplus/userDefineLang.xml0
-rwxr-xr-xmisc/pprof35
-rw-r--r--misc/swig/stdio/Makefile17
-rw-r--r--misc/vim/plugin/godoc.vim17
-rw-r--r--misc/zsh/go23
31 files changed, 712 insertions, 208 deletions
diff --git a/misc/bbedit/Go.plist b/misc/bbedit/Go.plist
index 791f93d16..791f93d16 100755..100644
--- a/misc/bbedit/Go.plist
+++ b/misc/bbedit/Go.plist
diff --git a/misc/cgo/gmp/gmp.go b/misc/cgo/gmp/gmp.go
index 3bcf99151..7b7a9b3c9 100644
--- a/misc/cgo/gmp/gmp.go
+++ b/misc/cgo/gmp/gmp.go
@@ -33,7 +33,7 @@ field; unrepresentable fields are replaced with opaque byte arrays. A
C union translates into a struct containing the first union member and
perhaps additional padding. C arrays become Go arrays. C pointers
become Go pointers. C function pointers become Go's uintptr.
-C void pointer's become Go's unsafe.Pointer.
+C void pointers become Go's unsafe.Pointer.
For example, mpz_t is defined in <gmp.h> as:
diff --git a/misc/cgo/test/callback.go b/misc/cgo/test/callback.go
index 4f5d3f855..b6e2e3c1c 100644
--- a/misc/cgo/test/callback.go
+++ b/misc/cgo/test/callback.go
@@ -12,7 +12,9 @@ import "C"
import (
"./backdoor"
+ "path"
"runtime"
+ "strings"
"testing"
"unsafe"
)
@@ -136,3 +138,44 @@ func testBlocking(t *testing.T) {
}
})
}
+
+// Test that the stack can be unwound through a call out and call back
+// into Go.
+func testCallbackCallers(t *testing.T) {
+ pc := make([]uintptr, 100)
+ n := 0
+ name := []string{
+ "test.goCallback",
+ "runtime.cgocallbackg",
+ "runtime.cgocallback_gofunc",
+ "return",
+ "runtime.cgocall",
+ "test._Cfunc_callback",
+ "test.nestedCall",
+ "test.testCallbackCallers",
+ "test.TestCallbackCallers",
+ "testing.tRunner",
+ "runtime.goexit",
+ }
+ nestedCall(func() {
+ n = runtime.Callers(2, pc)
+ })
+ if n != len(name) {
+ t.Errorf("expected %d frames, got %d", len(name), n)
+ }
+ for i := 0; i < n; i++ {
+ f := runtime.FuncForPC(pc[i])
+ if f == nil {
+ t.Fatalf("expected non-nil Func for pc %p", pc[i])
+ }
+ fname := f.Name()
+ // Remove the prepended pathname from automatically
+ // generated cgo function names.
+ if strings.HasPrefix(fname, "_") {
+ fname = path.Base(f.Name()[1:])
+ }
+ if fname != name[i] {
+ t.Errorf("expected function name %s, got %s", name[i], fname)
+ }
+ }
+}
diff --git a/misc/cgo/test/cflags.go b/misc/cgo/test/cflags.go
new file mode 100644
index 000000000..24caab471
--- /dev/null
+++ b/misc/cgo/test/cflags.go
@@ -0,0 +1,32 @@
+// Copyright 2013 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.
+
+// Test that the #cgo CFLAGS directive works,
+// with and without platform filters.
+// See http://code.google.com/p/go/issues/detail?id=5224 for details.
+package cgotest
+
+/*
+#cgo CFLAGS: -DCOMMON_VALUE=123
+#cgo windows CFLAGS: -DIS_WINDOWS=1
+#cgo !windows CFLAGS: -DIS_WINDOWS=0
+int common = COMMON_VALUE;
+int is_windows = IS_WINDOWS;
+*/
+import "C"
+
+import (
+ "runtime"
+ "testing"
+)
+
+func testCflags(t *testing.T) {
+ is_windows := C.is_windows == 1
+ if is_windows != (runtime.GOOS == "windows") {
+ t.Errorf("is_windows: %v, runtime.GOOS: %s", is_windows, runtime.GOOS)
+ }
+ if C.common != 123 {
+ t.Errorf("common: %v (expected 123)", C.common)
+ }
+}
diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go
index 536fa507a..56e1a0625 100644
--- a/misc/cgo/test/cgo_test.go
+++ b/misc/cgo/test/cgo_test.go
@@ -36,5 +36,8 @@ func TestBoolAlign(t *testing.T) { testBoolAlign(t) }
func Test3729(t *testing.T) { test3729(t) }
func Test3775(t *testing.T) { test3775(t) }
func TestCthread(t *testing.T) { testCthread(t) }
+func TestCallbackCallers(t *testing.T) { testCallbackCallers(t) }
+func Test5227(t *testing.T) { test5227(t) }
+func TestCflags(t *testing.T) { testCflags(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
diff --git a/misc/cgo/test/cthread.go b/misc/cgo/test/cthread.go
index d918d033f..68d4a03ea 100644
--- a/misc/cgo/test/cthread.go
+++ b/misc/cgo/test/cthread.go
@@ -8,7 +8,6 @@ package cgotest
import "C"
import (
- "runtime"
"sync"
"testing"
)
@@ -31,10 +30,7 @@ func Add(x int) {
}
func testCthread(t *testing.T) {
- if runtime.GOARCH == "arm" {
- t.Skip("testCthread disabled on arm")
- }
-
+ sum.i = 0
C.doAdd(10, 6)
want := 10 * (10 - 1) / 2 * 6
diff --git a/misc/cgo/test/issue4029.go b/misc/cgo/test/issue4029.go
index 7495d38fe..b0385eb85 100644
--- a/misc/cgo/test/issue4029.go
+++ b/misc/cgo/test/issue4029.go
@@ -47,14 +47,15 @@ func test4029(t *testing.T) {
func loadThySelf(t *testing.T, symbol string) {
this_process := C.dlopen(nil, C.RTLD_NOW)
if this_process == nil {
- t.Fatal("dlopen:", C.GoString(C.dlerror()))
+ t.Error("dlopen:", C.GoString(C.dlerror()))
+ return
}
defer C.dlclose(this_process)
symbol_address := C.dlsym(this_process, C.CString(symbol))
if symbol_address == nil {
- t.Fatal("dlsym:", C.GoString(C.dlerror()))
- } else {
- t.Log(symbol, symbol_address)
+ t.Error("dlsym:", C.GoString(C.dlerror()))
+ return
}
+ t.Log(symbol, symbol_address)
}
diff --git a/misc/cgo/test/issue5227.go b/misc/cgo/test/issue5227.go
new file mode 100644
index 000000000..336c4c609
--- /dev/null
+++ b/misc/cgo/test/issue5227.go
@@ -0,0 +1,38 @@
+// Copyright 2013 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.
+
+// Issue 5227: linker incorrectly treats common symbols and
+// leaves them undefined.
+
+package cgotest
+
+/*
+typedef struct {
+ int Count;
+} Fontinfo;
+
+Fontinfo SansTypeface;
+
+extern void init();
+
+Fontinfo loadfont() {
+ Fontinfo f = {0};
+ return f;
+}
+
+void init() {
+ SansTypeface = loadfont();
+}
+*/
+import "C"
+
+import "testing"
+
+func test5227(t *testing.T) {
+ C.init()
+}
+
+func selectfont() C.Fontinfo {
+ return C.SansTypeface
+}
diff --git a/misc/cgo/testso/cgoso.c b/misc/cgo/testso/cgoso.c
new file mode 100644
index 000000000..917f472d3
--- /dev/null
+++ b/misc/cgo/testso/cgoso.c
@@ -0,0 +1,14 @@
+// Copyright 2013 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.
+
+#include "_cgo_export.h"
+
+#ifdef WIN32
+extern void setCallback(void *);
+void init() {
+ setCallback(goCallback);
+}
+#else
+void init() {}
+#endif
diff --git a/misc/cgo/testso/cgoso.go b/misc/cgo/testso/cgoso.go
index 44fb616c1..216cb1f05 100644
--- a/misc/cgo/testso/cgoso.go
+++ b/misc/cgo/testso/cgoso.go
@@ -6,11 +6,13 @@ package cgosotest
/*
#cgo LDFLAGS: -L. -lcgosotest
+void init(void);
void sofunc(void);
*/
import "C"
func Test() {
+ C.init()
C.sofunc()
}
diff --git a/misc/cgo/testso/cgoso_c.c b/misc/cgo/testso/cgoso_c.c
index 8c15a6b9f..27155c27f 100644
--- a/misc/cgo/testso/cgoso_c.c
+++ b/misc/cgo/testso/cgoso_c.c
@@ -4,8 +4,22 @@
// +build ignore
+#ifdef WIN32
+// A Windows DLL is unable to call an arbitrary function in
+// the main executable. Work around that by making the main
+// executable pass the callback function pointer to us.
+void (*goCallback)(void);
+__declspec(dllexport) void setCallback(void *f)
+{
+ goCallback = (void (*)())f;
+}
+__declspec(dllexport) void sofunc(void);
+#else
+extern void goCallback(void);
+void setCallback(void *f) { (void)f; }
+#endif
+
void sofunc(void)
{
- extern void goCallback(void);
goCallback();
}
diff --git a/misc/cgo/testso/test.bat b/misc/cgo/testso/test.bat
new file mode 100644
index 000000000..b8cc3842b
--- /dev/null
+++ b/misc/cgo/testso/test.bat
@@ -0,0 +1,18 @@
+:: Copyright 2013 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.
+
+@echo off
+
+gcc -c cgoso_c.c
+gcc -shared -o libcgosotest.dll cgoso_c.o
+if not exist libcgosotest.dll goto fail
+go build main.go
+if not exist main.exe goto fail
+main.exe
+goto :end
+
+:fail
+set FAIL=1
+:end
+del /F cgoso_c.o libcgosotest.dll main.exe 2>NUL
diff --git a/misc/cgo/testtls/tls.go b/misc/cgo/testtls/tls.go
new file mode 100644
index 000000000..a9546a61c
--- /dev/null
+++ b/misc/cgo/testtls/tls.go
@@ -0,0 +1,28 @@
+// Copyright 2013 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 cgotlstest
+
+// #include <pthread.h>
+// extern void setTLS(int);
+// extern int getTLS();
+import "C"
+
+import (
+ "runtime"
+ "testing"
+)
+
+func testTLS(t *testing.T) {
+ var keyVal C.int = 1234
+
+ runtime.LockOSThread()
+ defer runtime.UnlockOSThread()
+ C.setTLS(C.int(keyVal))
+ storedVal := C.getTLS()
+
+ if storedVal != keyVal {
+ t.Fatalf("stored %d want %d", storedVal, keyVal)
+ }
+}
diff --git a/misc/cgo/testtls/tls_test.go b/misc/cgo/testtls/tls_test.go
new file mode 100644
index 000000000..3076c2d59
--- /dev/null
+++ b/misc/cgo/testtls/tls_test.go
@@ -0,0 +1,13 @@
+// Copyright 2013 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.
+
+// +build !windows
+
+package cgotlstest
+
+import "testing"
+
+func TestTLS(t *testing.T) {
+ testTLS(t)
+}
diff --git a/misc/cgo/testtls/tls_unix.c b/misc/cgo/testtls/tls_unix.c
new file mode 100644
index 000000000..545951631
--- /dev/null
+++ b/misc/cgo/testtls/tls_unix.c
@@ -0,0 +1,19 @@
+// Copyright 2013 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.
+
+#include <pthread.h>
+
+static __thread int tls;
+
+void
+setTLS(int v)
+{
+ tls = v;
+}
+
+int
+getTLS()
+{
+ return tls;
+}
diff --git a/misc/dashboard/README b/misc/dashboard/README
index c00311ef7..d599f3d06 100644
--- a/misc/dashboard/README
+++ b/misc/dashboard/README
@@ -4,8 +4,8 @@
The files in this directory constitute the continuous builder:
-godashboard/: an AppEngine server
-builder/: gobuilder, a Go continuous build client
+app/: an AppEngine server
+builder/: gobuilder, a Go continuous build client
If you wish to run a Go builder, please email golang-dev@googlegroups.com
diff --git a/misc/dashboard/app/build/init.go b/misc/dashboard/app/build/init.go
index 85a766b9d..505f96fc4 100644
--- a/misc/dashboard/app/build/init.go
+++ b/misc/dashboard/app/build/init.go
@@ -20,12 +20,13 @@ var defaultPackages = []*Package{
// subRepos specifies the Go project sub-repositories.
var subRepos = []string{
+ "blog",
"codereview",
"crypto",
+ "exp",
"image",
"net",
"talks",
- "exp",
}
// Put subRepos into defaultPackages.
diff --git a/misc/dashboard/builder/main.go b/misc/dashboard/builder/main.go
index b2b8f43a6..9a155bd0c 100644
--- a/misc/dashboard/builder/main.go
+++ b/misc/dashboard/builder/main.go
@@ -33,10 +33,9 @@ const (
var extraEnv = []string{
"CC",
"GOARM",
- "GOHOSTARCH",
- "GOHOSTOS",
"PATH",
"TMPDIR",
+ "USER",
}
type Builder struct {
@@ -64,6 +63,7 @@ var (
binaryTagRe = regexp.MustCompile(`^(release\.r|weekly\.)[0-9\-.]+`)
releaseRe = regexp.MustCompile(`^release\.r[0-9\-.]+`)
allCmd = "all" + suffix
+ raceCmd = "race" + suffix
cleanCmd = "clean" + suffix
suffix = defaultSuffix()
)
@@ -211,6 +211,16 @@ func NewBuilder(goroot *Repo, name string) (*Builder, error) {
return b, nil
}
+// buildCmd returns the build command to invoke.
+// Builders which contain the string '-race' in their
+// name will override *buildCmd and return raceCmd.
+func (b *Builder) buildCmd() string {
+ if strings.Contains(b.name, "-race") {
+ return raceCmd
+ }
+ return *buildCmd
+}
+
// build checks for a new commit for this builder
// and builds it if one is found.
// It returns true if a build was attempted.
@@ -262,7 +272,7 @@ func (b *Builder) buildHash(hash string) error {
defer f.Close()
w := io.MultiWriter(f, &buildlog)
- cmd := *buildCmd
+ cmd := b.buildCmd()
if !filepath.IsAbs(cmd) {
cmd = filepath.Join(srcDir, cmd)
}
@@ -397,7 +407,9 @@ func (b *Builder) envv() []string {
}
e := []string{
"GOOS=" + b.goos,
+ "GOHOSTOS=" + b.goos,
"GOARCH=" + b.goarch,
+ "GOHOSTARCH=" + b.goarch,
"GOROOT_FINAL=/usr/local/go",
}
for _, k := range extraEnv {
@@ -412,7 +424,9 @@ func (b *Builder) envv() []string {
func (b *Builder) envvWindows() []string {
start := map[string]string{
"GOOS": b.goos,
+ "GOHOSTOS": b.goos,
"GOARCH": b.goarch,
+ "GOHOSTARCH": b.goarch,
"GOROOT_FINAL": `c:\go`,
"GOBUILDEXIT": "1", // exit all.bat with completion status.
}
diff --git a/misc/dashboard/codereview/dashboard/cl.go b/misc/dashboard/codereview/dashboard/cl.go
index e150ea123..0ef3303e9 100644
--- a/misc/dashboard/codereview/dashboard/cl.go
+++ b/misc/dashboard/codereview/dashboard/cl.go
@@ -178,8 +178,14 @@ func handleAssign(w http.ResponseWriter, r *http.Request) {
return
}
defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ c.Errorf("Failed reading body: %v", err)
+ http.Error(w, err.Error(), 500)
+ return
+ }
if resp.StatusCode != 200 {
- c.Errorf("Retrieving CL reviewer list failed: got HTTP response %d", resp.StatusCode)
+ c.Errorf("Retrieving CL reviewer list failed: got HTTP response %d\nBody: %s", resp.StatusCode, body)
http.Error(w, "Failed contacting Rietveld", 500)
return
}
@@ -187,7 +193,7 @@ func handleAssign(w http.ResponseWriter, r *http.Request) {
var apiResp struct {
Reviewers []string `json:"reviewers"`
}
- if err := json.NewDecoder(resp.Body).Decode(&apiResp); err != nil {
+ if err := json.Unmarshal(body, &apiResp); err != nil {
// probably can't be retried
msg := fmt.Sprintf("Malformed JSON from %v: %v", url, err)
c.Errorf("%s", msg)
@@ -212,8 +218,14 @@ func handleAssign(w http.ResponseWriter, r *http.Request) {
return
}
defer resp.Body.Close()
+ body, err := ioutil.ReadAll(resp.Body)
+ if err != nil {
+ c.Errorf("Failed reading Gobot body: %v", err)
+ http.Error(w, err.Error(), 500)
+ return
+ }
if resp.StatusCode != 200 {
- c.Errorf("Gobot GET failed: got HTTP response %d", resp.StatusCode)
+ c.Errorf("Gobot GET failed: got HTTP response %d\nBody: %s", resp.StatusCode, body)
http.Error(w, "Failed contacting Gobot", 500)
return
}
diff --git a/misc/dashboard/codereview/dashboard/people.go b/misc/dashboard/codereview/dashboard/people.go
index facda7baf..21bd8f89c 100644
--- a/misc/dashboard/codereview/dashboard/people.go
+++ b/misc/dashboard/codereview/dashboard/people.go
@@ -21,6 +21,7 @@ func init() {
// and prefer to use their golang.org address for code review.
gophers := [...]string{
"adg",
+ "agl",
"bradfitz",
"campoy",
"dsymonds",
@@ -37,6 +38,25 @@ func init() {
emailToPerson[p+"@google.com"] = p
preferredEmail[p] = p + "@golang.org"
}
+ // Other people.
+ others := map[string]string{
+ "adonovan": "adonovan@google.com",
+ "brainman": "alex.brainman@gmail.com",
+ "ality": "ality@pbrane.org",
+ "dfc": "dave@cheney.net",
+ "dvyukov": "dvyukov@google.com",
+ "gustavo": "gustavo@niemeyer.net",
+ "jsing": "jsing@google.com",
+ "mikio": "mikioh.mikioh@gmail.com",
+ "minux": "minux.ma@gmail.com",
+ "remy": "remyoudompheng@gmail.com",
+ "rminnich": "rminnich@gmail.com",
+ }
+ for p, e := range others {
+ personList = append(personList, p)
+ emailToPerson[e] = p
+ preferredEmail[p] = e
+ }
sort.Strings(personList)
}
diff --git a/misc/dist/bindist.go b/misc/dist/bindist.go
index 29454c73c..19b0baac2 100644
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -29,13 +29,15 @@ import (
)
var (
- tag = flag.String("tag", "release", "mercurial tag to check out")
- repo = flag.String("repo", "https://code.google.com/p/go", "repo URL")
- tourPath = flag.String("tour", "code.google.com/p/go-tour", "Go tour repo import path")
- verbose = flag.Bool("v", false, "verbose output")
- upload = flag.Bool("upload", true, "upload resulting files to Google Code")
- wxsFile = flag.String("wxs", "", "path to custom installer.wxs")
- addLabel = flag.String("label", "", "additional label to apply to file when uploading")
+ tag = flag.String("tag", "release", "mercurial tag to check out")
+ repo = flag.String("repo", "https://code.google.com/p/go", "repo URL")
+ tourPath = flag.String("tour", "code.google.com/p/go-tour", "Go tour repo import path")
+ verbose = flag.Bool("v", false, "verbose output")
+ upload = flag.Bool("upload", true, "upload resulting files to Google Code")
+ wxsFile = flag.String("wxs", "", "path to custom installer.wxs")
+ addLabel = flag.String("label", "", "additional label to apply to file when uploading")
+ includeRace = flag.Bool("race", true, "build race detector packages")
+ versionOverride = flag.String("version", "", "override version name")
username, password string // for Google Code upload
)
@@ -72,6 +74,7 @@ var tourPackages = []string{
}
var tourContent = []string{
+ "js",
"prog",
"solutions",
"static",
@@ -79,7 +82,14 @@ var tourContent = []string{
"tour.article",
}
-var fileRe = regexp.MustCompile(`^go\.([a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+))\.`)
+// The os-arches that support the race toolchain.
+var raceAvailable = []string{
+ "darwin-amd64",
+ "linux-amd64",
+ "windows-amd64",
+}
+
+var fileRe = regexp.MustCompile(`^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+))\.`)
func main() {
flag.Usage = func() {
@@ -130,6 +140,13 @@ func main() {
}
b.OS = p[0]
b.Arch = p[1]
+ if *includeRace {
+ for _, t := range raceAvailable {
+ if t == targ {
+ b.Race = true
+ }
+ }
+ }
}
if err := b.Do(); err != nil {
log.Printf("%s: %v", targ, err)
@@ -139,6 +156,7 @@ func main() {
type Build struct {
Source bool // if true, OS and Arch must be empty
+ Race bool // build race toolchain
OS string
Arch string
root string
@@ -183,15 +201,31 @@ func (b *Build) Do() error {
} else {
_, err = b.run(src, "bash", "make.bash")
}
+ if b.Race {
+ if err != nil {
+ return err
+ }
+ goCmd := filepath.Join(b.root, "bin", "go")
+ if b.OS == "windows" {
+ goCmd += ".exe"
+ }
+ _, err = b.run(src, goCmd, "install", "-race", "std")
+ if err != nil {
+ return err
+ }
+ // Re-install std without -race, so that we're not left
+ // with a slower, race-enabled cmd/go, cmd/godoc, etc.
+ _, err = b.run(src, goCmd, "install", "-a", "std")
+ }
+ if err != nil {
+ return err
+ }
+ err = b.tour()
}
if err != nil {
return err
}
- if err := b.tour(); err != nil {
- return err
- }
-
// Get version strings.
var (
version string // "weekly.2012-03-04"
@@ -212,6 +246,9 @@ func (b *Build) Do() error {
fullVersion = bytes.TrimSpace(fullVersion)
v := bytes.SplitN(fullVersion, []byte(" "), 2)
version = string(v[0])
+ if *versionOverride != "" {
+ version = *versionOverride
+ }
// Write VERSION file.
err = ioutil.WriteFile(filepath.Join(b.root, "VERSION"), fullVersion, 0644)
@@ -386,9 +423,13 @@ func (b *Build) tour() error {
}
// Copy gotour binary to tool directory as "tour"; invoked as "go tool tour".
+ ext := ""
+ if runtime.GOOS == "windows" {
+ ext = ".exe"
+ }
return cp(
- filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"),
- filepath.Join(b.gopath, "bin", "gotour"),
+ filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"+ext),
+ filepath.Join(b.gopath, "bin", "gotour"+ext),
)
}
@@ -501,7 +542,12 @@ func (b *Build) Upload(version string, filename string) error {
ftype = "Source"
summary = fmt.Sprintf("%s (source only)", version)
}
- labels = append(labels, "OpSys-"+opsys, "Type-"+ftype)
+ if opsys != "" {
+ labels = append(labels, "OpSys-"+opsys)
+ }
+ if ftype != "" {
+ labels = append(labels, "Type-"+ftype)
+ }
if *addLabel != "" {
labels = append(labels, *addLabel)
}
@@ -620,8 +666,11 @@ func cp(dst, src string) error {
return err
}
defer df.Close()
- if err := df.Chmod(fi.Mode()); err != nil {
- return err
+ // Windows doesn't currently implement Fchmod
+ if runtime.GOOS != "windows" {
+ if err := df.Chmod(fi.Mode()); err != nil {
+ return err
+ }
}
_, err = io.Copy(df, sf)
return err
diff --git a/misc/dist/darwin/scripts/preinstall b/misc/dist/darwin/scripts/preinstall
index 4cdaaa4bc..4cdaaa4bc 100644..100755
--- a/misc/dist/darwin/scripts/preinstall
+++ b/misc/dist/darwin/scripts/preinstall
diff --git a/misc/emacs/go-mode.el b/misc/emacs/go-mode.el
index 8a16d8a4f..6f0442aff 100644
--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -5,18 +5,79 @@
;; license that can be found in the LICENSE file.
(require 'cl)
-(require 'diff-mode)
(require 'ffap)
-(require 'find-lisp)
(require 'url)
+;; XEmacs compatibility guidelines
+;; - Minimum required version of XEmacs: 21.5.32
+;; - Feature that cannot be backported: POSIX character classes in
+;; regular expressions
+;; - Functions that could be backported but won't because 21.5.32
+;; covers them: plenty.
+;; - Features that are still partly broken:
+;; - godef will not work correctly if multibyte characters are
+;; being used
+;; - Fontification will not handle unicode correctly
+;;
+;; - Do not use \_< and \_> regexp delimiters directly; use
+;; go--regexp-enclose-in-symbol
+;;
+;; - The character `_` must not be a symbol constituent but a
+;; character constituent
+;;
+;; - Do not use process-lines
+;;
+;; - Use go--old-completion-list-style when using a plain list as the
+;; collection for completing-read
+;;
+;; - Use go--kill-whole-line instead of kill-whole-line (called
+;; kill-entire-line in XEmacs)
+;;
+;; - Use go--position-bytes instead of position-bytes
+(defmacro go--xemacs-p ()
+ `(featurep 'xemacs))
+
+(defalias 'go--kill-whole-line
+ (if (fboundp 'kill-whole-line)
+ 'kill-whole-line
+ 'kill-entire-line))
+
+;; XEmacs unfortunately does not offer position-bytes. We can fall
+;; back to just using (point), but it will be incorrect as soon as
+;; multibyte characters are being used.
+(if (fboundp 'position-bytes)
+ (defalias 'go--position-bytes 'position-bytes)
+ (defun go--position-bytes (point) point))
+
+(defun go--old-completion-list-style (list)
+ (mapcar (lambda (x) (cons x nil)) list))
+
+;; GNU Emacs 24 has prog-mode, older GNU Emacs and XEmacs do not.
+;; Ideally we'd use defalias instead, but that breaks in XEmacs.
+;;
+;; TODO: If XEmacs decides to add prog-mode, change this to use
+;; defalias to alias prog-mode or fundamental-mode to go--prog-mode
+;; and use that in define-derived-mode.
+(if (not (fboundp 'prog-mode))
+ (define-derived-mode prog-mode fundamental-mode "" ""))
+
+(defun go--regexp-enclose-in-symbol (s)
+ ;; XEmacs does not support \_<, GNU Emacs does. In GNU Emacs we make
+ ;; extensive use of \_< to support unicode in identifiers. Until we
+ ;; come up with a better solution for XEmacs, this solution will
+ ;; break fontification in XEmacs for identifiers such as "typeµ".
+ ;; XEmacs will consider "type" a keyword, GNU Emacs won't.
+
+ (if (go--xemacs-p)
+ (concat "\\<" s "\\>")
+ (concat "\\_<" s "\\_>")))
+
(defconst go-dangling-operators-regexp "[^-]-\\|[^+]\\+\\|[/*&><.=|^]")
-(defconst gofmt-stdin-tag "<standard input>")
-(defconst go-identifier-regexp "[[:word:][:multibyte:]_]+")
+(defconst go-identifier-regexp "[[:word:][:multibyte:]]+")
(defconst go-label-regexp go-identifier-regexp)
-(defconst go-type-regexp "[[:word:][:multibyte:]_*]+")
-(defconst go-func-regexp (concat "\\<func\\>\\s *\\(" go-identifier-regexp "\\)"))
-(defconst go-func-meth-regexp (concat "\\<func\\>\\s *\\(?:(\\s *" go-identifier-regexp "\\s +" go-type-regexp "\\s *)\\s *\\)?\\(" go-identifier-regexp "\\)("))
+(defconst go-type-regexp "[[:word:][:multibyte:]*]+")
+(defconst go-func-regexp (concat (go--regexp-enclose-in-symbol "func") "\\s *\\(" go-identifier-regexp "\\)"))
+(defconst go-func-meth-regexp (concat (go--regexp-enclose-in-symbol "func") "\\s *\\(?:(\\s *" go-identifier-regexp "\\s +" go-type-regexp "\\s *)\\s *\\)?\\(" go-identifier-regexp "\\)("))
(defconst go-builtins
'("append" "cap" "close" "complex" "copy"
"delete" "imag" "len" "make" "new"
@@ -35,6 +96,7 @@
(defconst go-type-name-regexp (concat "\\(?:[*(]\\)*\\(?:" go-identifier-regexp "\\.\\)?\\(" go-identifier-regexp "\\)"))
(defvar go-dangling-cache)
+(defvar go-godoc-history nil)
(defgroup go nil
"Major mode for editing Go code"
@@ -57,23 +119,27 @@
(modify-syntax-entry ?= "." st)
(modify-syntax-entry ?< "." st)
(modify-syntax-entry ?> "." st)
- (modify-syntax-entry ?/ ". 124b" st)
+ (modify-syntax-entry ?/ (if (go--xemacs-p) ". 1456" ". 124b") st)
(modify-syntax-entry ?* ". 23" st)
(modify-syntax-entry ?\n "> b" st)
(modify-syntax-entry ?\" "\"" st)
(modify-syntax-entry ?\' "\"" st)
(modify-syntax-entry ?` "\"" st)
(modify-syntax-entry ?\\ "\\" st)
- (modify-syntax-entry ?_ "_" st)
+ ;; It would be nicer to have _ as a symbol constituent, but that
+ ;; would trip up XEmacs, which does not support the \_< anchor
+ (modify-syntax-entry ?_ "w" st)
st)
"Syntax table for Go mode.")
(defun go--build-font-lock-keywords ()
+ ;; we cannot use 'symbols in regexp-opt because emacs <24 doesn't
+ ;; understand that
(append
- `((,(regexp-opt go-mode-keywords 'symbols) . font-lock-keyword-face)
- (,(regexp-opt go-builtins 'symbols) . font-lock-builtin-face)
- (,(regexp-opt go-constants 'symbols) . font-lock-constant-face)
+ `((,(go--regexp-enclose-in-symbol (regexp-opt go-mode-keywords t)) . font-lock-keyword-face)
+ (,(go--regexp-enclose-in-symbol (regexp-opt go-builtins t)) . font-lock-builtin-face)
+ (,(go--regexp-enclose-in-symbol (regexp-opt go-constants t)) . font-lock-constant-face)
(,go-func-regexp 1 font-lock-function-name-face)) ;; function (not method) name
(if go-fontify-function-calls
@@ -82,22 +148,22 @@
`((,go-func-meth-regexp 1 font-lock-function-name-face))) ;; method name
`(
- ("\\<type\\>[[:space:]]*\\([^[:space:]]+\\)" 1 font-lock-type-face) ;; types
- (,(concat "\\<type\\>[[:space:]]*" go-identifier-regexp "[[:space:]]*" go-type-name-regexp) 1 font-lock-type-face) ;; types
- (,(concat "\\(?:[[:space:]]+\\|\\]\\)\\[\\([[:digit:]]+\\|\\.\\.\\.\\)?\\]" go-type-name-regexp) 2 font-lock-type-face) ;; Arrays/slices
- (,(concat "map\\[[^]]+\\]" go-type-name-regexp) 1 font-lock-type-face) ;; map value type
+ (,(concat (go--regexp-enclose-in-symbol "type") "[[:space:]]*\\([^[:space:]]+\\)") 1 font-lock-type-face) ;; types
+ (,(concat (go--regexp-enclose-in-symbol "type") "[[:space:]]*" go-identifier-regexp "[[:space:]]*" go-type-name-regexp) 1 font-lock-type-face) ;; types
+ (,(concat "[^[:word:][:multibyte:]]\\[\\([[:digit:]]+\\|\\.\\.\\.\\)?\\]" go-type-name-regexp) 2 font-lock-type-face) ;; Arrays/slices
(,(concat "\\(" go-identifier-regexp "\\)" "{") 1 font-lock-type-face)
- (,(concat "\\<map\\[" go-type-name-regexp) 1 font-lock-type-face) ;; map key type
- (,(concat "\\<chan\\>[[:space:]]*\\(?:<-\\)?" go-type-name-regexp) 1 font-lock-type-face) ;; channel type
- (,(concat "\\<\\(?:new\\|make\\)\\>\\(?:[[:space:]]\\|)\\)*(" go-type-name-regexp) 1 font-lock-type-face) ;; new/make type
+ (,(concat (go--regexp-enclose-in-symbol "map") "\\[[^]]+\\]" go-type-name-regexp) 1 font-lock-type-face) ;; map value type
+ (,(concat (go--regexp-enclose-in-symbol "map") "\\[" go-type-name-regexp) 1 font-lock-type-face) ;; map key type
+ (,(concat (go--regexp-enclose-in-symbol "chan") "[[:space:]]*\\(?:<-\\)?" go-type-name-regexp) 1 font-lock-type-face) ;; channel type
+ (,(concat (go--regexp-enclose-in-symbol "\\(?:new\\|make\\)") "\\(?:[[:space:]]\\|)\\)*(" go-type-name-regexp) 1 font-lock-type-face) ;; new/make type
;; TODO do we actually need this one or isn't it just a function call?
(,(concat "\\.\\s *(" go-type-name-regexp) 1 font-lock-type-face) ;; Type conversion
- (,(concat "\\<func\\>[[:space:]]+(" go-identifier-regexp "[[:space:]]+" go-type-name-regexp ")") 1 font-lock-type-face) ;; Method receiver
+ (,(concat (go--regexp-enclose-in-symbol "func") "[[:space:]]+(" go-identifier-regexp "[[:space:]]+" go-type-name-regexp ")") 1 font-lock-type-face) ;; Method receiver
;; Like the original go-mode this also marks compound literal
;; fields. There, it was marked as to fix, but I grew quite
;; accustomed to it, so it'll stay for now.
(,(concat "^[[:space:]]*\\(" go-label-regexp "\\)[[:space:]]*:\\(\\S.\\|$\\)") 1 font-lock-constant-face) ;; Labels and compound literal fields
- (,(concat "\\<\\(goto\\|break\\|continue\\)\\>[[:space:]]*\\(" go-label-regexp "\\)") 2 font-lock-constant-face)))) ;; labels in goto/break/continue
+ (,(concat (go--regexp-enclose-in-symbol "\\(goto\\|break\\|continue\\)") "[[:space:]]*\\(" go-label-regexp "\\)") 2 font-lock-constant-face)))) ;; labels in goto/break/continue
(defvar go-mode-map
(let ((m (make-sparse-keymap)))
@@ -107,6 +173,8 @@
(define-key m ":" 'go-mode-insert-and-indent)
(define-key m "=" 'go-mode-insert-and-indent)
(define-key m (kbd "C-c C-a") 'go-import-add)
+ (define-key m (kbd "C-c C-j") 'godef-jump)
+ (define-key m (kbd "C-c C-d") 'godef-describe)
m)
"Keymap used by Go mode to implement electric keys.")
@@ -140,7 +208,7 @@ It skips over whitespace, comments, cases and labels and, if
STOP-AT-STRING is not true, over strings."
(let (pos (start-pos (point)))
- (skip-chars-backward "\n[:blank:]")
+ (skip-chars-backward "\n\s\t")
(if (and (save-excursion (beginning-of-line) (go-in-string-p)) (looking-back "`") (not stop-at-string))
(backward-char))
(if (and (go-in-string-p) (not stop-at-string))
@@ -177,6 +245,28 @@ STOP-AT-STRING is not true, over strings."
(puthash cur-line val go-dangling-cache))))
val))
+(defun go--at-function-definition ()
+ "Return non-nil if point is on the opening curly brace of a
+function definition.
+
+We do this by first calling (beginning-of-defun), which will take
+us to the start of *some* function. We then look for the opening
+curly brace of that function and compare its position against the
+curly brace we are checking. If they match, we return non-nil."
+ (if (= (char-after) ?\{)
+ (save-excursion
+ (let ((old-point (point))
+ start-nesting)
+ (beginning-of-defun)
+ (when (looking-at "func ")
+ (setq start-nesting (go-paren-level))
+ (skip-chars-forward "^{")
+ (while (> (go-paren-level) start-nesting)
+ (forward-char)
+ (skip-chars-forward "^{") 0)
+ (if (and (= (go-paren-level) start-nesting) (= old-point (point)))
+ t))))))
+
(defun go-goto-opening-parenthesis (&optional char)
(let ((start-nesting (go-paren-level)))
(while (and (not (bobp))
@@ -189,6 +279,20 @@ STOP-AT-STRING is not true, over strings."
(go-goto-beginning-of-string-or-comment)
(backward-char))))))
+(defun go--indentation-for-opening-parenthesis ()
+ "Return the semantic indentation for the current opening parenthesis.
+
+If point is on an opening curly brace and said curly brace
+belongs to a function declaration, the indentation of the func
+keyword will be returned. Otherwise the indentation of the
+current line will be returned."
+ (save-excursion
+ (if (go--at-function-definition)
+ (progn
+ (beginning-of-defun)
+ (current-indentation))
+ (current-indentation))))
+
(defun go-indentation-at-point ()
(save-excursion
(let (start-nesting (outindent 0))
@@ -202,7 +306,7 @@ STOP-AT-STRING is not true, over strings."
(go-goto-opening-parenthesis (char-after))
(if (go-previous-line-has-dangling-op-p)
(- (current-indentation) tab-width)
- (current-indentation)))
+ (go--indentation-for-opening-parenthesis)))
((progn (go--backward-irrelevant t) (looking-back go-dangling-operators-regexp))
;; only one nesting for all dangling operators in one operation
(if (go-previous-line-has-dangling-op-p)
@@ -213,7 +317,7 @@ STOP-AT-STRING is not true, over strings."
((progn (go-goto-opening-parenthesis) (< (go-paren-level) start-nesting))
(if (go-previous-line-has-dangling-op-p)
(current-indentation)
- (+ (current-indentation) tab-width)))
+ (+ (go--indentation-for-opening-parenthesis) tab-width)))
(t
(current-indentation))))))
@@ -274,7 +378,7 @@ STOP-AT-STRING is not true, over strings."
(forward-char))))
;;;###autoload
-(define-derived-mode go-mode fundamental-mode "Go"
+(define-derived-mode go-mode prog-mode "Go"
"Major mode for editing Go source text.
This mode provides (not just) basic editing capabilities for
@@ -299,12 +403,26 @@ The following extra functions are defined:
- `go-goto-imports'
- `go-play-buffer' and `go-play-region'
- `go-download-play'
+- `godef-describe' and `godef-jump'
If you want to automatically run `gofmt' before saving a file,
add the following hook to your emacs configuration:
\(add-hook 'before-save-hook 'gofmt-before-save)
+If you want to use `godef-jump' instead of etags (or similar),
+consider binding godef-jump to `M-.', which is the default key
+for `find-tag':
+
+\(add-hook 'go-mode-hook (lambda ()
+ (local-set-key (kbd \"M-.\") 'godef-jump)))
+
+Please note that godef is an external dependency. You can install
+it with
+
+go get code.google.com/p/rog-go/exp/cmd/godef
+
+
If you're looking for even more integration with Go, namely
on-the-fly syntax checking, auto-completion and snippets, it is
recommended that you look at goflymake
@@ -360,101 +478,95 @@ recommended that you look at goflymake
;;;###autoload
(add-to-list 'auto-mode-alist (cons "\\.go\\'" 'go-mode))
+(defun go--apply-rcs-patch (patch-buffer)
+ "Apply an RCS-formatted diff from PATCH-BUFFER to the current
+buffer."
+ (let ((target-buffer (current-buffer))
+ ;; Relative offset between buffer line numbers and line numbers
+ ;; in patch.
+ ;;
+ ;; Line numbers in the patch are based on the source file, so
+ ;; we have to keep an offset when making changes to the
+ ;; buffer.
+ ;;
+ ;; Appending lines decrements the offset (possibly making it
+ ;; negative), deleting lines increments it. This order
+ ;; simplifies the forward-line invocations.
+ (line-offset 0))
+ (save-excursion
+ (with-current-buffer patch-buffer
+ (goto-char (point-min))
+ (while (not (eobp))
+ (unless (looking-at "^\\([ad]\\)\\([0-9]+\\) \\([0-9]+\\)")
+ (error "invalid rcs patch or internal error in go--apply-rcs-patch"))
+ (forward-line)
+ (let ((action (match-string 1))
+ (from (string-to-number (match-string 2)))
+ (len (string-to-number (match-string 3))))
+ (cond
+ ((equal action "a")
+ (let ((start (point)))
+ (forward-line len)
+ (let ((text (buffer-substring start (point))))
+ (with-current-buffer target-buffer
+ (decf line-offset len)
+ (goto-char (point-min))
+ (forward-line (- from len line-offset))
+ (insert text)))))
+ ((equal action "d")
+ (with-current-buffer target-buffer
+ (goto-char (point-min))
+ (forward-line (- from line-offset 1))
+ (incf line-offset len)
+ (go--kill-whole-line len)))
+ (t
+ (error "invalid rcs patch or internal error in go--apply-rcs-patch")))))))))
+
(defun gofmt ()
- "Pipe the current buffer through the external tool `gofmt`.
-Replace the current buffer on success; display errors on failure."
+ "Formats the current buffer according to the gofmt tool."
(interactive)
- (let ((currconf (current-window-configuration)))
- (let ((srcbuf (current-buffer))
- (filename buffer-file-name)
- (patchbuf (get-buffer-create "*Gofmt patch*")))
- (with-current-buffer patchbuf
- (let ((errbuf (get-buffer-create "*Gofmt Errors*"))
- ;; use utf-8 with subprocesses
- (coding-system-for-read 'utf-8)
- (coding-system-for-write 'utf-8))
- (with-current-buffer errbuf
- (setq buffer-read-only nil)
- (erase-buffer))
- (with-current-buffer srcbuf
- (save-restriction
- (let (deactivate-mark)
- (widen)
- ;; If this is a new file, diff-mode can't apply a
- ;; patch to a non-exisiting file, so replace the buffer
- ;; completely with the output of 'gofmt'.
- ;; If the file exists, patch it to keep the 'undo' list happy.
- (let* ((newfile (not (file-exists-p filename)))
- (flag (if newfile "" " -d")))
-
- ;; diff-mode doesn't work too well with missing
- ;; end-of-file newline, so add one
- (if (/= (char-after (1- (point-max))) ?\n)
- (save-excursion
- (goto-char (point-max))
- (insert ?\n)))
-
- (if (zerop (shell-command-on-region (point-min) (point-max)
- (concat "gofmt" flag)
- patchbuf nil errbuf))
- ;; gofmt succeeded: replace buffer or apply patch hunks.
- (let ((old-point (point))
- (old-mark (mark t)))
- (kill-buffer errbuf)
- (if newfile
- ;; New file, replace it (diff-mode won't work)
- (gofmt--replace-buffer srcbuf patchbuf)
- ;; Existing file, patch it
- (gofmt--apply-patch filename srcbuf patchbuf))
- (goto-char (min old-point (point-max)))
- ;; Restore the mark and point
- (if old-mark (push-mark (min old-mark (point-max)) t))
- (set-window-configuration currconf))
-
- ;; gofmt failed: display the errors
- (message "Could not apply gofmt. Check errors for details")
- (gofmt--process-errors filename errbuf))))))
-
- ;; Collapse any window opened on outbuf if shell-command-on-region
- ;; displayed it.
- (delete-windows-on patchbuf)))
- (kill-buffer patchbuf))))
-
-(defun gofmt--replace-buffer (srcbuf patchbuf)
- (with-current-buffer srcbuf
- (erase-buffer)
- (insert-buffer-substring patchbuf))
- (message "Applied gofmt"))
-
-(defun gofmt--apply-patch (filename srcbuf patchbuf)
- ;; apply all the patch hunks
- (let (changed)
+ (let ((tmpfile (make-temp-file "gofmt" nil ".go"))
+ (patchbuf (get-buffer-create "*Gofmt patch*"))
+ (errbuf (get-buffer-create "*Gofmt Errors*"))
+ (coding-system-for-read 'utf-8)
+ (coding-system-for-write 'utf-8))
+
+ (with-current-buffer errbuf
+ (setq buffer-read-only nil)
+ (erase-buffer))
(with-current-buffer patchbuf
- (goto-char (point-min))
- ;; The .* is for TMPDIR, but to avoid dealing with TMPDIR
- ;; having a trailing / or not, it's easier to just search for .*
- ;; especially as we're only replacing the first instance.
- (if (re-search-forward "^--- \\(.*/gofmt[0-9]*\\)" nil t)
- (replace-match filename nil nil nil 1))
- (condition-case nil
- (while t
- (diff-hunk-next)
- (diff-apply-hunk)
- (setq changed t))
- ;; When there's no more hunks, diff-hunk-next signals an error, ignore it
- (error nil)))
- (if changed (message "Applied gofmt") (message "Buffer was already gofmted"))))
-
-(defun gofmt--process-errors (filename errbuf)
+ (erase-buffer))
+
+ (write-region nil nil tmpfile)
+
+ ;; We're using errbuf for the mixed stdout and stderr output. This
+ ;; is not an issue because gofmt -w does not produce any stdout
+ ;; output in case of success.
+ (if (zerop (call-process "gofmt" nil errbuf nil "-w" tmpfile))
+ (if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
+ (progn
+ (kill-buffer errbuf)
+ (message "Buffer is already gofmted"))
+ (go--apply-rcs-patch patchbuf)
+ (kill-buffer errbuf)
+ (message "Applied gofmt"))
+ (message "Could not apply gofmt. Check errors for details")
+ (gofmt--process-errors (buffer-file-name) tmpfile errbuf))
+
+ (kill-buffer patchbuf)
+ (delete-file tmpfile)))
+
+
+(defun gofmt--process-errors (filename tmpfile errbuf)
;; Convert the gofmt stderr to something understood by the compilation mode.
(with-current-buffer errbuf
(goto-char (point-min))
(insert "gofmt errors:\n")
- (if (search-forward gofmt-stdin-tag nil t)
- (replace-match (file-name-nondirectory filename) nil t))
- (display-buffer errbuf)
- (compilation-mode)))
+ (while (search-forward-regexp (concat "^\\(" (regexp-quote tmpfile) "\\):") nil t)
+ (replace-match (file-name-nondirectory filename) t t nil 1))
+ (compilation-mode)
+ (display-buffer errbuf)))
;;;###autoload
(defun gofmt-before-save ()
@@ -476,10 +588,10 @@ you save any file, kind of defeating the point of autoloading."
(symbol (if bounds
(buffer-substring-no-properties (car bounds)
(cdr bounds)))))
- (read-string (if symbol
- (format "godoc (default %s): " symbol)
- "godoc: ")
- nil nil symbol)))
+ (completing-read (if symbol
+ (format "godoc (default %s): " symbol)
+ "godoc: ")
+ (go--old-completion-list-style (go-packages)) nil nil nil 'go-godoc-history symbol)))
(defun godoc--get-buffer (query)
"Get an empty buffer for a godoc query."
@@ -628,7 +740,7 @@ uncommented, otherwise a new import will be added."
(interactive
(list
current-prefix-arg
- (replace-regexp-in-string "^[\"']\\|[\"']$" "" (completing-read "Package: " (go-packages)))))
+ (replace-regexp-in-string "^[\"']\\|[\"']$" "" (completing-read "Package: " (go--old-completion-list-style (go-packages))))))
(save-excursion
(let (as line import-start)
(if arg
@@ -653,11 +765,34 @@ uncommented, otherwise a new import will be added."
('none (insert "\nimport (\n\t" line "\n)\n")))))))
(defun go-root-and-paths ()
- (let* ((output (process-lines "go" "env" "GOROOT" "GOPATH"))
+ (let* ((output (split-string (shell-command-to-string "go env GOROOT GOPATH") "\n"))
(root (car output))
- (paths (split-string (car (cdr output)) ":")))
+ (paths (split-string (cadr output) ":")))
(append (list root) paths)))
+(defun go--string-prefix-p (s1 s2 &optional ignore-case)
+ "Return non-nil if S1 is a prefix of S2.
+If IGNORE-CASE is non-nil, the comparison is case-insensitive."
+ (eq t (compare-strings s1 nil nil
+ s2 0 (length s1) ignore-case)))
+
+(defun go--directory-dirs (dir)
+ "Recursively return all subdirectories in DIR."
+ (if (file-directory-p dir)
+ (let ((dir (directory-file-name dir))
+ (dirs '())
+ (files (directory-files dir nil nil t)))
+ (dolist (file files)
+ (unless (member file '("." ".."))
+ (let ((file (concat dir "/" file)))
+ (if (file-directory-p file)
+ (setq dirs (append (cons file
+ (go--directory-dirs file))
+ dirs))))))
+ dirs)
+ '()))
+
+
(defun go-packages ()
(sort
(delete-dups
@@ -667,12 +802,12 @@ uncommented, otherwise a new import will be added."
(mapcan (lambda (dir)
(mapcar (lambda (file)
(let ((sub (substring file (length pkgdir) -2)))
- (unless (or (string-prefix-p "obj/" sub) (string-prefix-p "tool/" sub))
+ (unless (or (go--string-prefix-p "obj/" sub) (go--string-prefix-p "tool/" sub))
(mapconcat 'identity (cdr (split-string sub "/")) "/"))))
(if (file-directory-p dir)
(directory-files dir t "\\.a$"))))
(if (file-directory-p pkgdir)
- (find-lisp-find-files-internal pkgdir 'find-lisp-file-predicate-is-directory 'find-lisp-default-directory-predicate)))))
+ (go--directory-dirs pkgdir)))))
(go-root-and-paths)))
'string<))
@@ -712,9 +847,63 @@ will be commented, otherwise they will be removed completely."
(beginning-of-line)
(if arg
(comment-region (line-beginning-position) (line-end-position))
- (let ((kill-whole-line t))
- (kill-line))))
+ (go--kill-whole-line)))
(message "Removed %d imports" (length lines)))
(if flymake-state (flymake-mode-on)))))
+(defun godef--find-file-line-column (specifier)
+ "Given a file name in the format of `filename:line:column',
+visit FILENAME and go to line LINE and column COLUMN."
+ (let* ((components (split-string specifier ":"))
+ (line (string-to-number (nth 1 components)))
+ (column (string-to-number (nth 2 components))))
+ (with-current-buffer (find-file (car components))
+ (goto-char (point-min))
+ (forward-line (1- line))
+ (beginning-of-line)
+ (forward-char (1- column))
+ (if (buffer-modified-p)
+ (message "Buffer is modified, file position might not have been correct")))))
+
+(defun godef--call (point)
+ "Call godef, acquiring definition position and expression
+description at POINT."
+ (if (go--xemacs-p)
+ (message "godef does not reliably work in XEmacs, expect bad results"))
+ (if (not buffer-file-name)
+ (message "Cannot use godef on a buffer without a file name")
+ (let ((outbuf (get-buffer-create "*godef*")))
+ (with-current-buffer outbuf
+ (erase-buffer))
+ (call-process-region (point-min) (point-max) "godef" nil outbuf nil "-i" "-t" "-f" (file-truename buffer-file-name) "-o" (number-to-string (go--position-bytes (point))))
+ (with-current-buffer outbuf
+ (split-string (buffer-substring-no-properties (point-min) (point-max)) "\n")))))
+
+(defun godef-describe (point)
+ "Describe the expression at POINT."
+ (interactive "d")
+ (condition-case nil
+ (let ((description (nth 1 (godef--call point))))
+ (if (string= "" description)
+ (message "No description found for expression at point")
+ (message "%s" description)))
+ (file-error (message "Could not run godef binary"))))
+
+(defun godef-jump (point)
+ "Jump to the definition of the expression at POINT."
+ (interactive "d")
+ (condition-case nil
+ (let ((file (car (godef--call point))))
+ (cond
+ ((string= "-" file)
+ (message "godef: expression is not defined anywhere"))
+ ((string= "godef: no identifier found" file)
+ (message "%s" file))
+ ((go--string-prefix-p "godef: no declaration found for " file)
+ (message "%s" file))
+ (t
+ (push-mark)
+ (godef--find-file-line-column file))))
+ (file-error (message "Could not run godef binary"))))
+
(provide 'go-mode)
diff --git a/misc/kate/go.xml b/misc/kate/go.xml
index 1e00cfcbf..c187eda82 100644
--- a/misc/kate/go.xml
+++ b/misc/kate/go.xml
@@ -95,7 +95,7 @@
<HlCHex attribute="Hex" context="#stay"/>
<HlCChar attribute="Char" context="#stay"/>
<DetectChar attribute="String" context="String" char="&quot;"/>
- <DetectChar attribute="Multiline String" context="Multiline String" char="`"/>
+ <DetectChar attribute="String" context="Multiline String" char="`"/>
<Detect2Chars attribute="Comment" context="Comment 1" char="/" char1="/"/>
<Detect2Chars attribute="Comment" context="Comment 2" char="/" char1="*" beginRegion="Comment"/>
<AnyChar attribute="Symbol" context="#stay" String=":!%&amp;()+,-/.*&lt;=&gt;?[]|~^&#59;"/>
diff --git a/misc/notepadplus/README b/misc/notepadplus/README
index 000d31746..000d31746 100755..100644
--- a/misc/notepadplus/README
+++ b/misc/notepadplus/README
diff --git a/misc/notepadplus/go.xml b/misc/notepadplus/go.xml
index 237ef6b4b..237ef6b4b 100755..100644
--- a/misc/notepadplus/go.xml
+++ b/misc/notepadplus/go.xml
diff --git a/misc/notepadplus/userDefineLang.xml b/misc/notepadplus/userDefineLang.xml
index 2954aad48..2954aad48 100755..100644
--- a/misc/notepadplus/userDefineLang.xml
+++ b/misc/notepadplus/userDefineLang.xml
diff --git a/misc/pprof b/misc/pprof
index 7c379acbe..f471c7395 100755
--- a/misc/pprof
+++ b/misc/pprof
@@ -81,6 +81,11 @@ use Getopt::Long;
my $PPROF_VERSION = "1.5";
+# NOTE: All mentions of c++filt have been expunged from this script
+# because (1) we don't use C++, and (2) the copy of c++filt that ships
+# on OS X is from 2007 and destroys nm output by "demangling" the
+# first two columns (address and symbol type).
+
# These are the object tools we use which can come from a
# user-specified location using --tools, from the PPROF_TOOLS
# environment variable, or from the environment.
@@ -88,7 +93,6 @@ my %obj_tool_map = (
"objdump" => "objdump",
"nm" => "nm",
"addr2line" => "addr2line",
- "c++filt" => "c++filt",
## ConfigureObjTools may add architecture-specific entries:
#"nm_pdb" => "nm-pdb", # for reading windows (PDB-format) executables
#"addr2line_pdb" => "addr2line-pdb", # ditto
@@ -3093,9 +3097,7 @@ sub FetchSymbols {
my $url = SymbolPageURL();
$url = ResolveRedirectionForCurl($url);
my $command_line = "$CURL -sd '\@$main::tmpfile_sym' '$url'";
- # We use c++filt in case $SYMBOL_PAGE gives us mangled symbols.
- my $cppfilt = $obj_tool_map{"c++filt"};
- open(SYMBOL, "$command_line | $cppfilt |") or error($command_line);
+ open(SYMBOL, "$command_line |") or error($command_line);
ReadSymbols(*SYMBOL{IO}, $symbol_map);
close(SYMBOL);
}
@@ -4415,11 +4417,9 @@ sub MapToSymbols {
$cmd = "$addr2line --demangle -f -C -e $image";
}
- if (system("$addr2line --help >/dev/null 2>&1") != 0) {
- # addr2line must not exist. Fall back to go tool addr2line.
- $addr2line = "go tool addr2line";
- $cmd = "$addr2line $image";
- }
+ # Use the go version because we know it works on all platforms
+ $addr2line = "go tool addr2line";
+ $cmd = "$addr2line $image";
# If "addr2line" isn't installed on the system at all, just use
# nm to get what info we can (function names, but not line numbers).
@@ -4790,7 +4790,6 @@ sub GetProcedureBoundaries {
}
my $nm = $obj_tool_map{"nm"};
- my $cppfilt = $obj_tool_map{"c++filt"};
# nm can fail for two reasons: 1) $image isn't a debug library; 2) nm
# binary doesn't support --demangle. In addition, for OS X we need
@@ -4799,27 +4798,21 @@ sub GetProcedureBoundaries {
# in an incompatible way. So first we test whether our nm supports
# --demangle and -f.
my $demangle_flag = "";
- my $cppfilt_flag = "";
if (system("$nm --demangle $image >/dev/null 2>&1") == 0) {
# In this mode, we do "nm --demangle <foo>"
$demangle_flag = "--demangle";
- $cppfilt_flag = "";
- } elsif (system("$cppfilt $image >/dev/null 2>&1") == 0) {
- # In this mode, we do "nm <foo> | c++filt"
- $cppfilt_flag = " | $cppfilt";
- };
+ }
my $flatten_flag = "";
if (system("$nm -f $image >/dev/null 2>&1") == 0) {
$flatten_flag = "-f";
}
- # Finally, in the case $imagie isn't a debug library, we try again with
- # -D to at least get *exported* symbols. If we can't use --demangle,
- # we use c++filt instead, if it exists on this system.
+ # Finally, in the case $image isn't a debug library, we try again with
+ # -D to at least get *exported* symbols. If we can't use --demangle, too bad.
my @nm_commands = ("$nm -n $flatten_flag $demangle_flag" .
- " $image 2>/dev/null $cppfilt_flag",
+ " $image 2>/dev/null",
"$nm -D -n $flatten_flag $demangle_flag" .
- " $image 2>/dev/null $cppfilt_flag",
+ " $image 2>/dev/null",
# go tool nm is for Go binaries
"go tool nm $image 2>/dev/null | sort");
diff --git a/misc/swig/stdio/Makefile b/misc/swig/stdio/Makefile
deleted file mode 100644
index 0f23345e4..000000000
--- a/misc/swig/stdio/Makefile
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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.
-
-include ../../../src/Make.inc
-
-TARG=swig/file
-SWIGFILES=\
- file.swig
-
-CLEANFILES+=hello
-
-include ../../../src/Make.pkg
-
-%: install %.go
- $(GC) $(GCFLAGS) $(GCIMPORTS) $*.go
- $(LD) $(SWIG_RPATH) -o $@ $*.$O
diff --git a/misc/vim/plugin/godoc.vim b/misc/vim/plugin/godoc.vim
index a9abb7ae6..a7b84de74 100644
--- a/misc/vim/plugin/godoc.vim
+++ b/misc/vim/plugin/godoc.vim
@@ -70,13 +70,26 @@ endfunction
function! s:Godoc(...)
let word = join(a:000, ' ')
if !len(word)
+ let oldiskeyword = &iskeyword
+ setlocal iskeyword+=.
let word = expand('<cword>')
+ let &iskeyword = oldiskeyword
endif
let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g')
- if !len(word)
+ let words = split(word, '\.')
+ if !len(words)
return
endif
- call s:GodocWord(word)
+ call s:GodocWord(words[0])
+ if len(words) > 1
+ if search('^\%(const\|var\|type\|\s\+\) ' . words[1] . '\s\+=\s')
+ return
+ endif
+ if search('^func ' . words[1] . '(')
+ return
+ endif
+ echo 'No documentation found for "' . word . '".'
+ endif
endfunction
command! -nargs=* -range -complete=customlist,go#complete#Package Godoc :call s:Godoc(<q-args>)
diff --git a/misc/zsh/go b/misc/zsh/go
index dce25547d..18bcaaff2 100644
--- a/misc/zsh/go
+++ b/misc/zsh/go
@@ -20,6 +20,7 @@ __go_tool_complete() {
'build[compile packages and dependencies]'
'clean[remove object files]'
'doc[run godoc on package sources]'
+ 'env[print Go environment information]'
'fix[run go tool fix on packages]'
'fmt[run gofmt on package sources]'
'get[download and install packages and dependencies]'
@@ -40,12 +41,17 @@ __go_tool_complete() {
build_flags=(
'-a[force reinstallation of packages that are already up-to-date]'
'-n[print the commands but do not run them]'
- "-p[number of parallel builds]:number"
+ '-p[number of parallel builds]:number'
+ '-race[enable data race detection]'
'-x[print the commands]'
- "-work[print temporary directory name and keep it]"
- "-gcflags[flags for 5g/6g/8g]:flags"
- "-ldflags[flags for 5l/6l/8l]:flags"
- "-gccgoflags[flags for gccgo]:flags"
+ '-work[print temporary directory name and keep it]'
+ '-ccflags[flags for 5c/6c/8c]:flags'
+ '-gcflags[flags for 5g/6g/8g]:flags'
+ '-ldflags[flags for 5l/6l/8l]:flags'
+ '-gccgoflags[flags for gccgo]:flags'
+ '-compiler[name of compiler to use]:name'
+ '-installsuffix[suffix to add to package directory]:suffix'
+ '-tags[list of build tags to consider satisfied]:tags'
)
__go_list() {
local expl importpaths
@@ -63,7 +69,7 @@ __go_tool_complete() {
install)
_arguments -s -w : ${build_flags[@]} \
"-v[show package names]" \
- '*:importpaths:__go_list'
+ '*:importpaths:__go_list'
;;
get)
_arguments -s -w : \
@@ -88,7 +94,10 @@ __go_tool_complete() {
"-cpu[values of GOMAXPROCS to use]:number list" \
"-run[run tests and examples matching regexp]:regexp" \
"-bench[run benchmarks matching regexp]:regexp" \
+ "-benchmem[print memory allocation stats]" \
"-benchtime[run each benchmark until taking this long]:duration" \
+ "-blockprofile[write goroutine blocking profile to file]:file" \
+ "-blockprofilerate[set sampling rate of goroutine blocking profile]:number" \
"-timeout[kill test after that duration]:duration" \
"-cpuprofile[write CPU profile to file]:file:_files" \
"-memprofile[write heap profile to file]:file:_files" \
@@ -98,7 +107,7 @@ __go_tool_complete() {
help)
_values "${commands[@]}" \
'gopath[GOPATH environment variable]' \
- 'importpath[description of import paths]' \
+ 'packages[description of package lists]' \
'remote[remote import path syntax]' \
'testflag[description of testing flags]' \
'testfunc[description of testing functions]'