diff options
Diffstat (limited to 'misc')
| -rw-r--r--[-rwxr-xr-x] | misc/bbedit/Go.plist | 0 | ||||
| -rw-r--r-- | misc/cgo/test/cthread.go | 1 | ||||
| -rw-r--r-- | misc/cgo/test/issue4029.go | 9 | ||||
| -rw-r--r-- | misc/dashboard/README | 4 | ||||
| -rw-r--r-- | misc/dashboard/app/build/init.go | 3 | ||||
| -rw-r--r-- | misc/dashboard/codereview/dashboard/cl.go | 18 | ||||
| -rw-r--r-- | misc/dashboard/codereview/dashboard/people.go | 19 | ||||
| -rw-r--r-- | misc/dist/bindist.go | 13 | ||||
| -rw-r--r-- | misc/emacs/go-mode.el | 421 | ||||
| -rw-r--r--[-rwxr-xr-x] | misc/notepadplus/README | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | misc/notepadplus/go.xml | 0 | ||||
| -rw-r--r--[-rwxr-xr-x] | misc/notepadplus/userDefineLang.xml | 0 | ||||
| -rwxr-xr-x | misc/pprof | 35 | ||||
| -rw-r--r-- | misc/swig/stdio/Makefile | 17 | 
14 files changed, 369 insertions, 171 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/test/cthread.go b/misc/cgo/test/cthread.go index d918d033f..bdfd1103d 100644 --- a/misc/cgo/test/cthread.go +++ b/misc/cgo/test/cthread.go @@ -35,6 +35,7 @@ func testCthread(t *testing.T) {  		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/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/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..45de03b1e 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,24 @@ 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", +		"mikioh":   "mikioh.mikioh@gmail.com", +		"minux":    "minux.ma@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..2d633bef9 100644 --- a/misc/dist/bindist.go +++ b/misc/dist/bindist.go @@ -386,9 +386,13 @@ func (b *Build) tour() error {  	}  	// Copy gotour binary to tool directory as "tour"; invoked as "go tool tour". +	gotour := "gotour" +	if runtime.GOOS == "windows" { +		gotour = "gotour.exe" +	}  	return cp(  		filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"), -		filepath.Join(b.gopath, "bin", "gotour"), +		filepath.Join(b.gopath, "bin", gotour),  	)  } @@ -620,8 +624,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/emacs/go-mode.el b/misc/emacs/go-mode.el index 8a16d8a4f..9b6ea74f3 100644 --- a/misc/emacs/go-mode.el +++ b/misc/emacs/go-mode.el @@ -5,18 +5,71 @@  ;; 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)) + + +(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 +88,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 +111,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 +140,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 +165,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 +200,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 +237,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 +271,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 +298,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 +309,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)))))) @@ -299,12 +395,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,99 +470,93 @@ 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)) +    (while (search-forward-regexp (concat "^\\(" (regexp-quote tmpfile) "\\):") nil t) +      (replace-match (file-name-nondirectory filename) t t nil 1))      (display-buffer errbuf)      (compilation-mode))) @@ -476,10 +580,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 +732,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 +757,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 +794,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 +839,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/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 | 
