summaryrefslogtreecommitdiff
path: root/misc
diff options
context:
space:
mode:
authorMichael Stapelberg <stapelberg@debian.org>2013-12-03 09:43:15 +0100
committerMichael Stapelberg <stapelberg@debian.org>2013-12-03 09:43:15 +0100
commit64d2a7c8945ba05af859901f5e248f1befdd8621 (patch)
tree013fcb7e9e3296ecdda876012252c36bd6bcb063 /misc
parentb901efe83e212f0c34c769c079e41373da12d723 (diff)
downloadgolang-64d2a7c8945ba05af859901f5e248f1befdd8621.tar.gz
Imported Upstream version 1.2upstream/1.2
Diffstat (limited to 'misc')
-rw-r--r--misc/IntelliJIDEA/Go.xml1
-rw-r--r--misc/bbedit/Go.plist5
-rw-r--r--misc/cgo/errors/err1.go18
-rw-r--r--misc/cgo/errors/err2.go13
-rwxr-xr-xmisc/cgo/errors/test.bash31
-rw-r--r--misc/cgo/test/api.go24
-rw-r--r--misc/cgo/test/callback.go1505
-rw-r--r--misc/cgo/test/callback_c.c33
-rw-r--r--misc/cgo/test/callback_c_gc.c21
-rw-r--r--misc/cgo/test/callback_c_gccgo.c17
-rw-r--r--misc/cgo/test/cgo_test.go11
-rw-r--r--misc/cgo/test/cthread_unix.c2
-rw-r--r--misc/cgo/test/fpvar.go50
-rw-r--r--misc/cgo/test/issue1560.go63
-rw-r--r--misc/cgo/test/issue3250.go95
-rw-r--r--misc/cgo/test/issue3250w.go11
-rw-r--r--misc/cgo/test/issue3775.go8
-rw-r--r--misc/cgo/test/issue4339.c18
-rw-r--r--misc/cgo/test/issue4339.go16
-rw-r--r--misc/cgo/test/issue4339.h9
-rw-r--r--misc/cgo/test/issue4857.go15
-rw-r--r--misc/cgo/test/issue5337.go31
-rw-r--r--misc/cgo/test/issue5337w.go11
-rw-r--r--misc/cgo/test/issue5548.go26
-rw-r--r--misc/cgo/test/issue5548_c.c24
-rw-r--r--misc/cgo/test/issue5603.go32
-rw-r--r--misc/cgo/test/issue5740.go15
-rw-r--r--misc/cgo/test/issue5740a.c9
-rw-r--r--misc/cgo/test/issue5740b.c9
-rw-r--r--misc/cgo/test/issue5986.go32
-rw-r--r--misc/cgo/test/issue6128.go20
-rw-r--r--misc/cgo/test/issue6390.go23
-rw-r--r--misc/cgo/test/issue6472.go22
-rw-r--r--misc/cgo/test/issue6506.go36
-rw-r--r--misc/cgo/test/issue6612.go93
-rw-r--r--misc/cgo/testasan/main.go49
-rw-r--r--misc/cgo/testcdefs/cdefstest.c8
-rw-r--r--misc/cgo/testcdefs/cdefstest.go41
-rw-r--r--misc/cgo/testcdefs/main.c48
-rw-r--r--misc/cgo/testcdefs/main.go13
-rwxr-xr-xmisc/cgo/testcdefs/test.bash16
-rw-r--r--misc/cgo/testso/cgoso.go11
-rwxr-xr-xmisc/cgo/testso/test.bash20
-rw-r--r--misc/dashboard/README26
-rw-r--r--misc/dashboard/app/app.yaml20
-rw-r--r--misc/dashboard/app/build/build.go330
-rw-r--r--misc/dashboard/app/build/handler.go446
-rw-r--r--misc/dashboard/app/build/init.go65
-rw-r--r--misc/dashboard/app/build/key.go62
-rw-r--r--misc/dashboard/app/build/notify.go166
-rw-r--r--misc/dashboard/app/build/notify.txt9
-rw-r--r--misc/dashboard/app/build/test.go256
-rw-r--r--misc/dashboard/app/build/ui.go319
-rw-r--r--misc/dashboard/app/build/ui.html209
-rw-r--r--misc/dashboard/app/cache/cache.go82
-rw-r--r--misc/dashboard/app/static/status_alert.gifbin570 -> 0 bytes
-rw-r--r--misc/dashboard/app/static/status_good.gifbin328 -> 0 bytes
-rw-r--r--misc/dashboard/builder/Makefile9
-rw-r--r--misc/dashboard/builder/doc.go58
-rw-r--r--misc/dashboard/builder/exec.go79
-rw-r--r--misc/dashboard/builder/http.go167
-rw-r--r--misc/dashboard/builder/main.go642
-rw-r--r--misc/dashboard/builder/vcs.go148
-rw-r--r--misc/dashboard/codereview/dashboard/front.go2
-rw-r--r--misc/dashboard/codereview/dashboard/people.go3
-rw-r--r--misc/dist/bindist.go184
-rwxr-xr-xmisc/dist/darwin/scripts/postinstall8
-rw-r--r--misc/emacs/go-mode.el420
-rw-r--r--misc/goplay/goplay.go14
-rw-r--r--misc/kate/go.xml1
-rw-r--r--misc/linkcheck/linkcheck.go193
-rw-r--r--misc/notepadplus/README63
-rw-r--r--misc/notepadplus/functionList.xml43
-rw-r--r--misc/notepadplus/go.xml177
-rw-r--r--misc/notepadplus/userDefineLang.xml82
-rwxr-xr-xmisc/pprof191
-rw-r--r--misc/swig/callback/callback.cc15
-rw-r--r--misc/swig/callback/callback.h6
-rw-r--r--misc/vim/autoload/go/complete.vim70
-rw-r--r--misc/vim/compiler/go.vim30
-rw-r--r--misc/vim/ftplugin/go.vim17
-rw-r--r--misc/vim/ftplugin/go/fmt.vim24
-rw-r--r--misc/vim/ftplugin/go/import.vim35
-rwxr-xr-xmisc/vim/ftplugin/go/test.sh4
-rw-r--r--misc/vim/plugin/godoc.vim66
-rw-r--r--misc/vim/readme.txt28
-rw-r--r--misc/vim/syntax/godoc.vim2
-rwxr-xr-xmisc/xcode/4/go4xcode.sh26
88 files changed, 3848 insertions, 3504 deletions
diff --git a/misc/IntelliJIDEA/Go.xml b/misc/IntelliJIDEA/Go.xml
index 09265a2e0..51abdf412 100644
--- a/misc/IntelliJIDEA/Go.xml
+++ b/misc/IntelliJIDEA/Go.xml
@@ -75,6 +75,7 @@ Copy this custom language definition & configuration file to
<keyword name="close"/>
<keyword name="complex"/>
<keyword name="copy"/>
+ <keyword name="delete"/>
<keyword name="imag"/>
<keyword name="len"/>
<keyword name="make"/>
diff --git a/misc/bbedit/Go.plist b/misc/bbedit/Go.plist
index 791f93d16..1220d6efb 100644
--- a/misc/bbedit/Go.plist
+++ b/misc/bbedit/Go.plist
@@ -11,7 +11,7 @@
break,
byte,
cap,
- case,
+ case,
chan,
close,
complex,
@@ -20,8 +20,9 @@
const,
continue,
copy,
- default,
+ default,
defer,
+ delete,
else,
error,
fallthrough,
diff --git a/misc/cgo/errors/err1.go b/misc/cgo/errors/err1.go
new file mode 100644
index 000000000..8e674dce7
--- /dev/null
+++ b/misc/cgo/errors/err1.go
@@ -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.
+
+package main
+
+/*
+#cgo LDFLAGS: -c
+
+void test() {
+ xxx; // ERROR HERE
+}
+*/
+import "C"
+
+func main() {
+ C.test()
+}
diff --git a/misc/cgo/errors/err2.go b/misc/cgo/errors/err2.go
new file mode 100644
index 000000000..0c64ffeeb
--- /dev/null
+++ b/misc/cgo/errors/err2.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.
+
+package main
+
+import "C"
+
+func main() {
+ s := ""
+ _ = s
+ C.malloc(s) // ERROR HERE
+}
diff --git a/misc/cgo/errors/test.bash b/misc/cgo/errors/test.bash
new file mode 100755
index 000000000..697ae2fed
--- /dev/null
+++ b/misc/cgo/errors/test.bash
@@ -0,0 +1,31 @@
+# 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.
+
+check() {
+ file=$1
+ line=$(grep -n 'ERROR HERE' $file | sed 's/:.*//')
+ if [ "$line" = "" ]; then
+ echo 1>&2 misc/cgo/errors/test.bash: BUG: cannot find ERROR HERE in $file
+ exit 1
+ fi
+ if go build $file >errs 2>&1; then
+ echo 1>&2 misc/cgo/errors/test.bash: BUG: expected cgo to fail but it succeeded
+ exit 1
+ fi
+ if ! test -s errs; then
+ echo 1>&2 misc/cgo/errors/test.bash: BUG: expected error output but saw none
+ exit 1
+ fi
+ if ! fgrep $file:$line: errs >/dev/null 2>&1; then
+ echo 1>&2 misc/cgo/errors/test.bash: BUG: expected error on line $line but saw:
+ cat 1>&2 errs
+ exit 1
+ fi
+}
+
+check err1.go
+check err2.go
+
+rm -rf errs _obj
+exit 0
diff --git a/misc/cgo/test/api.go b/misc/cgo/test/api.go
new file mode 100644
index 000000000..f5a85946f
--- /dev/null
+++ b/misc/cgo/test/api.go
@@ -0,0 +1,24 @@
+// 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.
+
+// API Compatibility Checks for cgo
+
+package cgotest
+
+// #include <stdlib.h>
+// const char *api_hello = "hello!";
+import "C"
+import "unsafe"
+
+func testAPI() {
+ var cs *C.char
+ cs = C.CString("hello")
+ defer C.free(unsafe.Pointer(cs))
+ var s string
+ s = C.GoString((*C.char)(C.api_hello))
+ s = C.GoStringN((*C.char)(C.api_hello), C.int(6))
+ var b []byte
+ b = C.GoBytes(unsafe.Pointer(C.api_hello), C.int(6))
+ _, _ = s, b
+}
diff --git a/misc/cgo/test/callback.go b/misc/cgo/test/callback.go
index c642d5f0f..82ed015bd 100644
--- a/misc/cgo/test/callback.go
+++ b/misc/cgo/test/callback.go
@@ -7,6 +7,8 @@ package cgotest
/*
void callback(void *f);
void callGoFoo(void);
+void callGoStackCheck(void);
+void callPanic(void);
*/
import "C"
@@ -150,9 +152,10 @@ func testCallbackCallers(t *testing.T) {
n := 0
name := []string{
"test.goCallback",
+ "runtime.cgocallbackg1",
"runtime.cgocallbackg",
"runtime.cgocallback_gofunc",
- "return",
+ "runtime.asmcgocall",
"runtime.cgocall",
"test._Cfunc_callback",
"test.nestedCall",
@@ -183,3 +186,1503 @@ func testCallbackCallers(t *testing.T) {
}
}
}
+
+func testPanicFromC(t *testing.T) {
+ defer func() {
+ r := recover()
+ if r == nil {
+ t.Fatal("did not panic")
+ }
+ if r.(string) != "panic from C" {
+ t.Fatal("wrong panic:", r)
+ }
+ }()
+ C.callPanic()
+}
+
+func testCallbackStack(t *testing.T) {
+ // Make cgo call and callback with different amount of stack stack available.
+ // We do not do any explicit checks, just ensure that it does not crash.
+ for _, f := range splitTests {
+ f()
+ }
+}
+
+//export goStackCheck
+func goStackCheck() {
+ // use some stack memory to trigger split stack check
+ var buf [256]byte
+ use(buf[:])
+}
+
+var Used byte
+
+func use(buf []byte) {
+ for _, c := range buf {
+ Used += c
+ }
+}
+
+var splitTests = []func(){
+ // Edit .+1,/^}/-1|seq 4 4 5000 | sed 's/.*/ stack&,/' | fmt
+ stack4, stack8, stack12, stack16, stack20, stack24, stack28,
+ stack32, stack36, stack40, stack44, stack48, stack52, stack56,
+ stack60, stack64, stack68, stack72, stack76, stack80, stack84,
+ stack88, stack92, stack96, stack100, stack104, stack108, stack112,
+ stack116, stack120, stack124, stack128, stack132, stack136,
+ stack140, stack144, stack148, stack152, stack156, stack160,
+ stack164, stack168, stack172, stack176, stack180, stack184,
+ stack188, stack192, stack196, stack200, stack204, stack208,
+ stack212, stack216, stack220, stack224, stack228, stack232,
+ stack236, stack240, stack244, stack248, stack252, stack256,
+ stack260, stack264, stack268, stack272, stack276, stack280,
+ stack284, stack288, stack292, stack296, stack300, stack304,
+ stack308, stack312, stack316, stack320, stack324, stack328,
+ stack332, stack336, stack340, stack344, stack348, stack352,
+ stack356, stack360, stack364, stack368, stack372, stack376,
+ stack380, stack384, stack388, stack392, stack396, stack400,
+ stack404, stack408, stack412, stack416, stack420, stack424,
+ stack428, stack432, stack436, stack440, stack444, stack448,
+ stack452, stack456, stack460, stack464, stack468, stack472,
+ stack476, stack480, stack484, stack488, stack492, stack496,
+ stack500, stack504, stack508, stack512, stack516, stack520,
+ stack524, stack528, stack532, stack536, stack540, stack544,
+ stack548, stack552, stack556, stack560, stack564, stack568,
+ stack572, stack576, stack580, stack584, stack588, stack592,
+ stack596, stack600, stack604, stack608, stack612, stack616,
+ stack620, stack624, stack628, stack632, stack636, stack640,
+ stack644, stack648, stack652, stack656, stack660, stack664,
+ stack668, stack672, stack676, stack680, stack684, stack688,
+ stack692, stack696, stack700, stack704, stack708, stack712,
+ stack716, stack720, stack724, stack728, stack732, stack736,
+ stack740, stack744, stack748, stack752, stack756, stack760,
+ stack764, stack768, stack772, stack776, stack780, stack784,
+ stack788, stack792, stack796, stack800, stack804, stack808,
+ stack812, stack816, stack820, stack824, stack828, stack832,
+ stack836, stack840, stack844, stack848, stack852, stack856,
+ stack860, stack864, stack868, stack872, stack876, stack880,
+ stack884, stack888, stack892, stack896, stack900, stack904,
+ stack908, stack912, stack916, stack920, stack924, stack928,
+ stack932, stack936, stack940, stack944, stack948, stack952,
+ stack956, stack960, stack964, stack968, stack972, stack976,
+ stack980, stack984, stack988, stack992, stack996, stack1000,
+ stack1004, stack1008, stack1012, stack1016, stack1020, stack1024,
+ stack1028, stack1032, stack1036, stack1040, stack1044, stack1048,
+ stack1052, stack1056, stack1060, stack1064, stack1068, stack1072,
+ stack1076, stack1080, stack1084, stack1088, stack1092, stack1096,
+ stack1100, stack1104, stack1108, stack1112, stack1116, stack1120,
+ stack1124, stack1128, stack1132, stack1136, stack1140, stack1144,
+ stack1148, stack1152, stack1156, stack1160, stack1164, stack1168,
+ stack1172, stack1176, stack1180, stack1184, stack1188, stack1192,
+ stack1196, stack1200, stack1204, stack1208, stack1212, stack1216,
+ stack1220, stack1224, stack1228, stack1232, stack1236, stack1240,
+ stack1244, stack1248, stack1252, stack1256, stack1260, stack1264,
+ stack1268, stack1272, stack1276, stack1280, stack1284, stack1288,
+ stack1292, stack1296, stack1300, stack1304, stack1308, stack1312,
+ stack1316, stack1320, stack1324, stack1328, stack1332, stack1336,
+ stack1340, stack1344, stack1348, stack1352, stack1356, stack1360,
+ stack1364, stack1368, stack1372, stack1376, stack1380, stack1384,
+ stack1388, stack1392, stack1396, stack1400, stack1404, stack1408,
+ stack1412, stack1416, stack1420, stack1424, stack1428, stack1432,
+ stack1436, stack1440, stack1444, stack1448, stack1452, stack1456,
+ stack1460, stack1464, stack1468, stack1472, stack1476, stack1480,
+ stack1484, stack1488, stack1492, stack1496, stack1500, stack1504,
+ stack1508, stack1512, stack1516, stack1520, stack1524, stack1528,
+ stack1532, stack1536, stack1540, stack1544, stack1548, stack1552,
+ stack1556, stack1560, stack1564, stack1568, stack1572, stack1576,
+ stack1580, stack1584, stack1588, stack1592, stack1596, stack1600,
+ stack1604, stack1608, stack1612, stack1616, stack1620, stack1624,
+ stack1628, stack1632, stack1636, stack1640, stack1644, stack1648,
+ stack1652, stack1656, stack1660, stack1664, stack1668, stack1672,
+ stack1676, stack1680, stack1684, stack1688, stack1692, stack1696,
+ stack1700, stack1704, stack1708, stack1712, stack1716, stack1720,
+ stack1724, stack1728, stack1732, stack1736, stack1740, stack1744,
+ stack1748, stack1752, stack1756, stack1760, stack1764, stack1768,
+ stack1772, stack1776, stack1780, stack1784, stack1788, stack1792,
+ stack1796, stack1800, stack1804, stack1808, stack1812, stack1816,
+ stack1820, stack1824, stack1828, stack1832, stack1836, stack1840,
+ stack1844, stack1848, stack1852, stack1856, stack1860, stack1864,
+ stack1868, stack1872, stack1876, stack1880, stack1884, stack1888,
+ stack1892, stack1896, stack1900, stack1904, stack1908, stack1912,
+ stack1916, stack1920, stack1924, stack1928, stack1932, stack1936,
+ stack1940, stack1944, stack1948, stack1952, stack1956, stack1960,
+ stack1964, stack1968, stack1972, stack1976, stack1980, stack1984,
+ stack1988, stack1992, stack1996, stack2000, stack2004, stack2008,
+ stack2012, stack2016, stack2020, stack2024, stack2028, stack2032,
+ stack2036, stack2040, stack2044, stack2048, stack2052, stack2056,
+ stack2060, stack2064, stack2068, stack2072, stack2076, stack2080,
+ stack2084, stack2088, stack2092, stack2096, stack2100, stack2104,
+ stack2108, stack2112, stack2116, stack2120, stack2124, stack2128,
+ stack2132, stack2136, stack2140, stack2144, stack2148, stack2152,
+ stack2156, stack2160, stack2164, stack2168, stack2172, stack2176,
+ stack2180, stack2184, stack2188, stack2192, stack2196, stack2200,
+ stack2204, stack2208, stack2212, stack2216, stack2220, stack2224,
+ stack2228, stack2232, stack2236, stack2240, stack2244, stack2248,
+ stack2252, stack2256, stack2260, stack2264, stack2268, stack2272,
+ stack2276, stack2280, stack2284, stack2288, stack2292, stack2296,
+ stack2300, stack2304, stack2308, stack2312, stack2316, stack2320,
+ stack2324, stack2328, stack2332, stack2336, stack2340, stack2344,
+ stack2348, stack2352, stack2356, stack2360, stack2364, stack2368,
+ stack2372, stack2376, stack2380, stack2384, stack2388, stack2392,
+ stack2396, stack2400, stack2404, stack2408, stack2412, stack2416,
+ stack2420, stack2424, stack2428, stack2432, stack2436, stack2440,
+ stack2444, stack2448, stack2452, stack2456, stack2460, stack2464,
+ stack2468, stack2472, stack2476, stack2480, stack2484, stack2488,
+ stack2492, stack2496, stack2500, stack2504, stack2508, stack2512,
+ stack2516, stack2520, stack2524, stack2528, stack2532, stack2536,
+ stack2540, stack2544, stack2548, stack2552, stack2556, stack2560,
+ stack2564, stack2568, stack2572, stack2576, stack2580, stack2584,
+ stack2588, stack2592, stack2596, stack2600, stack2604, stack2608,
+ stack2612, stack2616, stack2620, stack2624, stack2628, stack2632,
+ stack2636, stack2640, stack2644, stack2648, stack2652, stack2656,
+ stack2660, stack2664, stack2668, stack2672, stack2676, stack2680,
+ stack2684, stack2688, stack2692, stack2696, stack2700, stack2704,
+ stack2708, stack2712, stack2716, stack2720, stack2724, stack2728,
+ stack2732, stack2736, stack2740, stack2744, stack2748, stack2752,
+ stack2756, stack2760, stack2764, stack2768, stack2772, stack2776,
+ stack2780, stack2784, stack2788, stack2792, stack2796, stack2800,
+ stack2804, stack2808, stack2812, stack2816, stack2820, stack2824,
+ stack2828, stack2832, stack2836, stack2840, stack2844, stack2848,
+ stack2852, stack2856, stack2860, stack2864, stack2868, stack2872,
+ stack2876, stack2880, stack2884, stack2888, stack2892, stack2896,
+ stack2900, stack2904, stack2908, stack2912, stack2916, stack2920,
+ stack2924, stack2928, stack2932, stack2936, stack2940, stack2944,
+ stack2948, stack2952, stack2956, stack2960, stack2964, stack2968,
+ stack2972, stack2976, stack2980, stack2984, stack2988, stack2992,
+ stack2996, stack3000, stack3004, stack3008, stack3012, stack3016,
+ stack3020, stack3024, stack3028, stack3032, stack3036, stack3040,
+ stack3044, stack3048, stack3052, stack3056, stack3060, stack3064,
+ stack3068, stack3072, stack3076, stack3080, stack3084, stack3088,
+ stack3092, stack3096, stack3100, stack3104, stack3108, stack3112,
+ stack3116, stack3120, stack3124, stack3128, stack3132, stack3136,
+ stack3140, stack3144, stack3148, stack3152, stack3156, stack3160,
+ stack3164, stack3168, stack3172, stack3176, stack3180, stack3184,
+ stack3188, stack3192, stack3196, stack3200, stack3204, stack3208,
+ stack3212, stack3216, stack3220, stack3224, stack3228, stack3232,
+ stack3236, stack3240, stack3244, stack3248, stack3252, stack3256,
+ stack3260, stack3264, stack3268, stack3272, stack3276, stack3280,
+ stack3284, stack3288, stack3292, stack3296, stack3300, stack3304,
+ stack3308, stack3312, stack3316, stack3320, stack3324, stack3328,
+ stack3332, stack3336, stack3340, stack3344, stack3348, stack3352,
+ stack3356, stack3360, stack3364, stack3368, stack3372, stack3376,
+ stack3380, stack3384, stack3388, stack3392, stack3396, stack3400,
+ stack3404, stack3408, stack3412, stack3416, stack3420, stack3424,
+ stack3428, stack3432, stack3436, stack3440, stack3444, stack3448,
+ stack3452, stack3456, stack3460, stack3464, stack3468, stack3472,
+ stack3476, stack3480, stack3484, stack3488, stack3492, stack3496,
+ stack3500, stack3504, stack3508, stack3512, stack3516, stack3520,
+ stack3524, stack3528, stack3532, stack3536, stack3540, stack3544,
+ stack3548, stack3552, stack3556, stack3560, stack3564, stack3568,
+ stack3572, stack3576, stack3580, stack3584, stack3588, stack3592,
+ stack3596, stack3600, stack3604, stack3608, stack3612, stack3616,
+ stack3620, stack3624, stack3628, stack3632, stack3636, stack3640,
+ stack3644, stack3648, stack3652, stack3656, stack3660, stack3664,
+ stack3668, stack3672, stack3676, stack3680, stack3684, stack3688,
+ stack3692, stack3696, stack3700, stack3704, stack3708, stack3712,
+ stack3716, stack3720, stack3724, stack3728, stack3732, stack3736,
+ stack3740, stack3744, stack3748, stack3752, stack3756, stack3760,
+ stack3764, stack3768, stack3772, stack3776, stack3780, stack3784,
+ stack3788, stack3792, stack3796, stack3800, stack3804, stack3808,
+ stack3812, stack3816, stack3820, stack3824, stack3828, stack3832,
+ stack3836, stack3840, stack3844, stack3848, stack3852, stack3856,
+ stack3860, stack3864, stack3868, stack3872, stack3876, stack3880,
+ stack3884, stack3888, stack3892, stack3896, stack3900, stack3904,
+ stack3908, stack3912, stack3916, stack3920, stack3924, stack3928,
+ stack3932, stack3936, stack3940, stack3944, stack3948, stack3952,
+ stack3956, stack3960, stack3964, stack3968, stack3972, stack3976,
+ stack3980, stack3984, stack3988, stack3992, stack3996, stack4000,
+ stack4004, stack4008, stack4012, stack4016, stack4020, stack4024,
+ stack4028, stack4032, stack4036, stack4040, stack4044, stack4048,
+ stack4052, stack4056, stack4060, stack4064, stack4068, stack4072,
+ stack4076, stack4080, stack4084, stack4088, stack4092, stack4096,
+ stack4100, stack4104, stack4108, stack4112, stack4116, stack4120,
+ stack4124, stack4128, stack4132, stack4136, stack4140, stack4144,
+ stack4148, stack4152, stack4156, stack4160, stack4164, stack4168,
+ stack4172, stack4176, stack4180, stack4184, stack4188, stack4192,
+ stack4196, stack4200, stack4204, stack4208, stack4212, stack4216,
+ stack4220, stack4224, stack4228, stack4232, stack4236, stack4240,
+ stack4244, stack4248, stack4252, stack4256, stack4260, stack4264,
+ stack4268, stack4272, stack4276, stack4280, stack4284, stack4288,
+ stack4292, stack4296, stack4300, stack4304, stack4308, stack4312,
+ stack4316, stack4320, stack4324, stack4328, stack4332, stack4336,
+ stack4340, stack4344, stack4348, stack4352, stack4356, stack4360,
+ stack4364, stack4368, stack4372, stack4376, stack4380, stack4384,
+ stack4388, stack4392, stack4396, stack4400, stack4404, stack4408,
+ stack4412, stack4416, stack4420, stack4424, stack4428, stack4432,
+ stack4436, stack4440, stack4444, stack4448, stack4452, stack4456,
+ stack4460, stack4464, stack4468, stack4472, stack4476, stack4480,
+ stack4484, stack4488, stack4492, stack4496, stack4500, stack4504,
+ stack4508, stack4512, stack4516, stack4520, stack4524, stack4528,
+ stack4532, stack4536, stack4540, stack4544, stack4548, stack4552,
+ stack4556, stack4560, stack4564, stack4568, stack4572, stack4576,
+ stack4580, stack4584, stack4588, stack4592, stack4596, stack4600,
+ stack4604, stack4608, stack4612, stack4616, stack4620, stack4624,
+ stack4628, stack4632, stack4636, stack4640, stack4644, stack4648,
+ stack4652, stack4656, stack4660, stack4664, stack4668, stack4672,
+ stack4676, stack4680, stack4684, stack4688, stack4692, stack4696,
+ stack4700, stack4704, stack4708, stack4712, stack4716, stack4720,
+ stack4724, stack4728, stack4732, stack4736, stack4740, stack4744,
+ stack4748, stack4752, stack4756, stack4760, stack4764, stack4768,
+ stack4772, stack4776, stack4780, stack4784, stack4788, stack4792,
+ stack4796, stack4800, stack4804, stack4808, stack4812, stack4816,
+ stack4820, stack4824, stack4828, stack4832, stack4836, stack4840,
+ stack4844, stack4848, stack4852, stack4856, stack4860, stack4864,
+ stack4868, stack4872, stack4876, stack4880, stack4884, stack4888,
+ stack4892, stack4896, stack4900, stack4904, stack4908, stack4912,
+ stack4916, stack4920, stack4924, stack4928, stack4932, stack4936,
+ stack4940, stack4944, stack4948, stack4952, stack4956, stack4960,
+ stack4964, stack4968, stack4972, stack4976, stack4980, stack4984,
+ stack4988, stack4992, stack4996, stack5000,
+}
+
+// Edit .+1,$ | seq 4 4 5000 | sed 's/.*/func stack&() { var buf [&]byte; use(buf[:]); C.callGoStackCheck() }/'
+func stack4() { var buf [4]byte; use(buf[:]); C.callGoStackCheck() }
+func stack8() { var buf [8]byte; use(buf[:]); C.callGoStackCheck() }
+func stack12() { var buf [12]byte; use(buf[:]); C.callGoStackCheck() }
+func stack16() { var buf [16]byte; use(buf[:]); C.callGoStackCheck() }
+func stack20() { var buf [20]byte; use(buf[:]); C.callGoStackCheck() }
+func stack24() { var buf [24]byte; use(buf[:]); C.callGoStackCheck() }
+func stack28() { var buf [28]byte; use(buf[:]); C.callGoStackCheck() }
+func stack32() { var buf [32]byte; use(buf[:]); C.callGoStackCheck() }
+func stack36() { var buf [36]byte; use(buf[:]); C.callGoStackCheck() }
+func stack40() { var buf [40]byte; use(buf[:]); C.callGoStackCheck() }
+func stack44() { var buf [44]byte; use(buf[:]); C.callGoStackCheck() }
+func stack48() { var buf [48]byte; use(buf[:]); C.callGoStackCheck() }
+func stack52() { var buf [52]byte; use(buf[:]); C.callGoStackCheck() }
+func stack56() { var buf [56]byte; use(buf[:]); C.callGoStackCheck() }
+func stack60() { var buf [60]byte; use(buf[:]); C.callGoStackCheck() }
+func stack64() { var buf [64]byte; use(buf[:]); C.callGoStackCheck() }
+func stack68() { var buf [68]byte; use(buf[:]); C.callGoStackCheck() }
+func stack72() { var buf [72]byte; use(buf[:]); C.callGoStackCheck() }
+func stack76() { var buf [76]byte; use(buf[:]); C.callGoStackCheck() }
+func stack80() { var buf [80]byte; use(buf[:]); C.callGoStackCheck() }
+func stack84() { var buf [84]byte; use(buf[:]); C.callGoStackCheck() }
+func stack88() { var buf [88]byte; use(buf[:]); C.callGoStackCheck() }
+func stack92() { var buf [92]byte; use(buf[:]); C.callGoStackCheck() }
+func stack96() { var buf [96]byte; use(buf[:]); C.callGoStackCheck() }
+func stack100() { var buf [100]byte; use(buf[:]); C.callGoStackCheck() }
+func stack104() { var buf [104]byte; use(buf[:]); C.callGoStackCheck() }
+func stack108() { var buf [108]byte; use(buf[:]); C.callGoStackCheck() }
+func stack112() { var buf [112]byte; use(buf[:]); C.callGoStackCheck() }
+func stack116() { var buf [116]byte; use(buf[:]); C.callGoStackCheck() }
+func stack120() { var buf [120]byte; use(buf[:]); C.callGoStackCheck() }
+func stack124() { var buf [124]byte; use(buf[:]); C.callGoStackCheck() }
+func stack128() { var buf [128]byte; use(buf[:]); C.callGoStackCheck() }
+func stack132() { var buf [132]byte; use(buf[:]); C.callGoStackCheck() }
+func stack136() { var buf [136]byte; use(buf[:]); C.callGoStackCheck() }
+func stack140() { var buf [140]byte; use(buf[:]); C.callGoStackCheck() }
+func stack144() { var buf [144]byte; use(buf[:]); C.callGoStackCheck() }
+func stack148() { var buf [148]byte; use(buf[:]); C.callGoStackCheck() }
+func stack152() { var buf [152]byte; use(buf[:]); C.callGoStackCheck() }
+func stack156() { var buf [156]byte; use(buf[:]); C.callGoStackCheck() }
+func stack160() { var buf [160]byte; use(buf[:]); C.callGoStackCheck() }
+func stack164() { var buf [164]byte; use(buf[:]); C.callGoStackCheck() }
+func stack168() { var buf [168]byte; use(buf[:]); C.callGoStackCheck() }
+func stack172() { var buf [172]byte; use(buf[:]); C.callGoStackCheck() }
+func stack176() { var buf [176]byte; use(buf[:]); C.callGoStackCheck() }
+func stack180() { var buf [180]byte; use(buf[:]); C.callGoStackCheck() }
+func stack184() { var buf [184]byte; use(buf[:]); C.callGoStackCheck() }
+func stack188() { var buf [188]byte; use(buf[:]); C.callGoStackCheck() }
+func stack192() { var buf [192]byte; use(buf[:]); C.callGoStackCheck() }
+func stack196() { var buf [196]byte; use(buf[:]); C.callGoStackCheck() }
+func stack200() { var buf [200]byte; use(buf[:]); C.callGoStackCheck() }
+func stack204() { var buf [204]byte; use(buf[:]); C.callGoStackCheck() }
+func stack208() { var buf [208]byte; use(buf[:]); C.callGoStackCheck() }
+func stack212() { var buf [212]byte; use(buf[:]); C.callGoStackCheck() }
+func stack216() { var buf [216]byte; use(buf[:]); C.callGoStackCheck() }
+func stack220() { var buf [220]byte; use(buf[:]); C.callGoStackCheck() }
+func stack224() { var buf [224]byte; use(buf[:]); C.callGoStackCheck() }
+func stack228() { var buf [228]byte; use(buf[:]); C.callGoStackCheck() }
+func stack232() { var buf [232]byte; use(buf[:]); C.callGoStackCheck() }
+func stack236() { var buf [236]byte; use(buf[:]); C.callGoStackCheck() }
+func stack240() { var buf [240]byte; use(buf[:]); C.callGoStackCheck() }
+func stack244() { var buf [244]byte; use(buf[:]); C.callGoStackCheck() }
+func stack248() { var buf [248]byte; use(buf[:]); C.callGoStackCheck() }
+func stack252() { var buf [252]byte; use(buf[:]); C.callGoStackCheck() }
+func stack256() { var buf [256]byte; use(buf[:]); C.callGoStackCheck() }
+func stack260() { var buf [260]byte; use(buf[:]); C.callGoStackCheck() }
+func stack264() { var buf [264]byte; use(buf[:]); C.callGoStackCheck() }
+func stack268() { var buf [268]byte; use(buf[:]); C.callGoStackCheck() }
+func stack272() { var buf [272]byte; use(buf[:]); C.callGoStackCheck() }
+func stack276() { var buf [276]byte; use(buf[:]); C.callGoStackCheck() }
+func stack280() { var buf [280]byte; use(buf[:]); C.callGoStackCheck() }
+func stack284() { var buf [284]byte; use(buf[:]); C.callGoStackCheck() }
+func stack288() { var buf [288]byte; use(buf[:]); C.callGoStackCheck() }
+func stack292() { var buf [292]byte; use(buf[:]); C.callGoStackCheck() }
+func stack296() { var buf [296]byte; use(buf[:]); C.callGoStackCheck() }
+func stack300() { var buf [300]byte; use(buf[:]); C.callGoStackCheck() }
+func stack304() { var buf [304]byte; use(buf[:]); C.callGoStackCheck() }
+func stack308() { var buf [308]byte; use(buf[:]); C.callGoStackCheck() }
+func stack312() { var buf [312]byte; use(buf[:]); C.callGoStackCheck() }
+func stack316() { var buf [316]byte; use(buf[:]); C.callGoStackCheck() }
+func stack320() { var buf [320]byte; use(buf[:]); C.callGoStackCheck() }
+func stack324() { var buf [324]byte; use(buf[:]); C.callGoStackCheck() }
+func stack328() { var buf [328]byte; use(buf[:]); C.callGoStackCheck() }
+func stack332() { var buf [332]byte; use(buf[:]); C.callGoStackCheck() }
+func stack336() { var buf [336]byte; use(buf[:]); C.callGoStackCheck() }
+func stack340() { var buf [340]byte; use(buf[:]); C.callGoStackCheck() }
+func stack344() { var buf [344]byte; use(buf[:]); C.callGoStackCheck() }
+func stack348() { var buf [348]byte; use(buf[:]); C.callGoStackCheck() }
+func stack352() { var buf [352]byte; use(buf[:]); C.callGoStackCheck() }
+func stack356() { var buf [356]byte; use(buf[:]); C.callGoStackCheck() }
+func stack360() { var buf [360]byte; use(buf[:]); C.callGoStackCheck() }
+func stack364() { var buf [364]byte; use(buf[:]); C.callGoStackCheck() }
+func stack368() { var buf [368]byte; use(buf[:]); C.callGoStackCheck() }
+func stack372() { var buf [372]byte; use(buf[:]); C.callGoStackCheck() }
+func stack376() { var buf [376]byte; use(buf[:]); C.callGoStackCheck() }
+func stack380() { var buf [380]byte; use(buf[:]); C.callGoStackCheck() }
+func stack384() { var buf [384]byte; use(buf[:]); C.callGoStackCheck() }
+func stack388() { var buf [388]byte; use(buf[:]); C.callGoStackCheck() }
+func stack392() { var buf [392]byte; use(buf[:]); C.callGoStackCheck() }
+func stack396() { var buf [396]byte; use(buf[:]); C.callGoStackCheck() }
+func stack400() { var buf [400]byte; use(buf[:]); C.callGoStackCheck() }
+func stack404() { var buf [404]byte; use(buf[:]); C.callGoStackCheck() }
+func stack408() { var buf [408]byte; use(buf[:]); C.callGoStackCheck() }
+func stack412() { var buf [412]byte; use(buf[:]); C.callGoStackCheck() }
+func stack416() { var buf [416]byte; use(buf[:]); C.callGoStackCheck() }
+func stack420() { var buf [420]byte; use(buf[:]); C.callGoStackCheck() }
+func stack424() { var buf [424]byte; use(buf[:]); C.callGoStackCheck() }
+func stack428() { var buf [428]byte; use(buf[:]); C.callGoStackCheck() }
+func stack432() { var buf [432]byte; use(buf[:]); C.callGoStackCheck() }
+func stack436() { var buf [436]byte; use(buf[:]); C.callGoStackCheck() }
+func stack440() { var buf [440]byte; use(buf[:]); C.callGoStackCheck() }
+func stack444() { var buf [444]byte; use(buf[:]); C.callGoStackCheck() }
+func stack448() { var buf [448]byte; use(buf[:]); C.callGoStackCheck() }
+func stack452() { var buf [452]byte; use(buf[:]); C.callGoStackCheck() }
+func stack456() { var buf [456]byte; use(buf[:]); C.callGoStackCheck() }
+func stack460() { var buf [460]byte; use(buf[:]); C.callGoStackCheck() }
+func stack464() { var buf [464]byte; use(buf[:]); C.callGoStackCheck() }
+func stack468() { var buf [468]byte; use(buf[:]); C.callGoStackCheck() }
+func stack472() { var buf [472]byte; use(buf[:]); C.callGoStackCheck() }
+func stack476() { var buf [476]byte; use(buf[:]); C.callGoStackCheck() }
+func stack480() { var buf [480]byte; use(buf[:]); C.callGoStackCheck() }
+func stack484() { var buf [484]byte; use(buf[:]); C.callGoStackCheck() }
+func stack488() { var buf [488]byte; use(buf[:]); C.callGoStackCheck() }
+func stack492() { var buf [492]byte; use(buf[:]); C.callGoStackCheck() }
+func stack496() { var buf [496]byte; use(buf[:]); C.callGoStackCheck() }
+func stack500() { var buf [500]byte; use(buf[:]); C.callGoStackCheck() }
+func stack504() { var buf [504]byte; use(buf[:]); C.callGoStackCheck() }
+func stack508() { var buf [508]byte; use(buf[:]); C.callGoStackCheck() }
+func stack512() { var buf [512]byte; use(buf[:]); C.callGoStackCheck() }
+func stack516() { var buf [516]byte; use(buf[:]); C.callGoStackCheck() }
+func stack520() { var buf [520]byte; use(buf[:]); C.callGoStackCheck() }
+func stack524() { var buf [524]byte; use(buf[:]); C.callGoStackCheck() }
+func stack528() { var buf [528]byte; use(buf[:]); C.callGoStackCheck() }
+func stack532() { var buf [532]byte; use(buf[:]); C.callGoStackCheck() }
+func stack536() { var buf [536]byte; use(buf[:]); C.callGoStackCheck() }
+func stack540() { var buf [540]byte; use(buf[:]); C.callGoStackCheck() }
+func stack544() { var buf [544]byte; use(buf[:]); C.callGoStackCheck() }
+func stack548() { var buf [548]byte; use(buf[:]); C.callGoStackCheck() }
+func stack552() { var buf [552]byte; use(buf[:]); C.callGoStackCheck() }
+func stack556() { var buf [556]byte; use(buf[:]); C.callGoStackCheck() }
+func stack560() { var buf [560]byte; use(buf[:]); C.callGoStackCheck() }
+func stack564() { var buf [564]byte; use(buf[:]); C.callGoStackCheck() }
+func stack568() { var buf [568]byte; use(buf[:]); C.callGoStackCheck() }
+func stack572() { var buf [572]byte; use(buf[:]); C.callGoStackCheck() }
+func stack576() { var buf [576]byte; use(buf[:]); C.callGoStackCheck() }
+func stack580() { var buf [580]byte; use(buf[:]); C.callGoStackCheck() }
+func stack584() { var buf [584]byte; use(buf[:]); C.callGoStackCheck() }
+func stack588() { var buf [588]byte; use(buf[:]); C.callGoStackCheck() }
+func stack592() { var buf [592]byte; use(buf[:]); C.callGoStackCheck() }
+func stack596() { var buf [596]byte; use(buf[:]); C.callGoStackCheck() }
+func stack600() { var buf [600]byte; use(buf[:]); C.callGoStackCheck() }
+func stack604() { var buf [604]byte; use(buf[:]); C.callGoStackCheck() }
+func stack608() { var buf [608]byte; use(buf[:]); C.callGoStackCheck() }
+func stack612() { var buf [612]byte; use(buf[:]); C.callGoStackCheck() }
+func stack616() { var buf [616]byte; use(buf[:]); C.callGoStackCheck() }
+func stack620() { var buf [620]byte; use(buf[:]); C.callGoStackCheck() }
+func stack624() { var buf [624]byte; use(buf[:]); C.callGoStackCheck() }
+func stack628() { var buf [628]byte; use(buf[:]); C.callGoStackCheck() }
+func stack632() { var buf [632]byte; use(buf[:]); C.callGoStackCheck() }
+func stack636() { var buf [636]byte; use(buf[:]); C.callGoStackCheck() }
+func stack640() { var buf [640]byte; use(buf[:]); C.callGoStackCheck() }
+func stack644() { var buf [644]byte; use(buf[:]); C.callGoStackCheck() }
+func stack648() { var buf [648]byte; use(buf[:]); C.callGoStackCheck() }
+func stack652() { var buf [652]byte; use(buf[:]); C.callGoStackCheck() }
+func stack656() { var buf [656]byte; use(buf[:]); C.callGoStackCheck() }
+func stack660() { var buf [660]byte; use(buf[:]); C.callGoStackCheck() }
+func stack664() { var buf [664]byte; use(buf[:]); C.callGoStackCheck() }
+func stack668() { var buf [668]byte; use(buf[:]); C.callGoStackCheck() }
+func stack672() { var buf [672]byte; use(buf[:]); C.callGoStackCheck() }
+func stack676() { var buf [676]byte; use(buf[:]); C.callGoStackCheck() }
+func stack680() { var buf [680]byte; use(buf[:]); C.callGoStackCheck() }
+func stack684() { var buf [684]byte; use(buf[:]); C.callGoStackCheck() }
+func stack688() { var buf [688]byte; use(buf[:]); C.callGoStackCheck() }
+func stack692() { var buf [692]byte; use(buf[:]); C.callGoStackCheck() }
+func stack696() { var buf [696]byte; use(buf[:]); C.callGoStackCheck() }
+func stack700() { var buf [700]byte; use(buf[:]); C.callGoStackCheck() }
+func stack704() { var buf [704]byte; use(buf[:]); C.callGoStackCheck() }
+func stack708() { var buf [708]byte; use(buf[:]); C.callGoStackCheck() }
+func stack712() { var buf [712]byte; use(buf[:]); C.callGoStackCheck() }
+func stack716() { var buf [716]byte; use(buf[:]); C.callGoStackCheck() }
+func stack720() { var buf [720]byte; use(buf[:]); C.callGoStackCheck() }
+func stack724() { var buf [724]byte; use(buf[:]); C.callGoStackCheck() }
+func stack728() { var buf [728]byte; use(buf[:]); C.callGoStackCheck() }
+func stack732() { var buf [732]byte; use(buf[:]); C.callGoStackCheck() }
+func stack736() { var buf [736]byte; use(buf[:]); C.callGoStackCheck() }
+func stack740() { var buf [740]byte; use(buf[:]); C.callGoStackCheck() }
+func stack744() { var buf [744]byte; use(buf[:]); C.callGoStackCheck() }
+func stack748() { var buf [748]byte; use(buf[:]); C.callGoStackCheck() }
+func stack752() { var buf [752]byte; use(buf[:]); C.callGoStackCheck() }
+func stack756() { var buf [756]byte; use(buf[:]); C.callGoStackCheck() }
+func stack760() { var buf [760]byte; use(buf[:]); C.callGoStackCheck() }
+func stack764() { var buf [764]byte; use(buf[:]); C.callGoStackCheck() }
+func stack768() { var buf [768]byte; use(buf[:]); C.callGoStackCheck() }
+func stack772() { var buf [772]byte; use(buf[:]); C.callGoStackCheck() }
+func stack776() { var buf [776]byte; use(buf[:]); C.callGoStackCheck() }
+func stack780() { var buf [780]byte; use(buf[:]); C.callGoStackCheck() }
+func stack784() { var buf [784]byte; use(buf[:]); C.callGoStackCheck() }
+func stack788() { var buf [788]byte; use(buf[:]); C.callGoStackCheck() }
+func stack792() { var buf [792]byte; use(buf[:]); C.callGoStackCheck() }
+func stack796() { var buf [796]byte; use(buf[:]); C.callGoStackCheck() }
+func stack800() { var buf [800]byte; use(buf[:]); C.callGoStackCheck() }
+func stack804() { var buf [804]byte; use(buf[:]); C.callGoStackCheck() }
+func stack808() { var buf [808]byte; use(buf[:]); C.callGoStackCheck() }
+func stack812() { var buf [812]byte; use(buf[:]); C.callGoStackCheck() }
+func stack816() { var buf [816]byte; use(buf[:]); C.callGoStackCheck() }
+func stack820() { var buf [820]byte; use(buf[:]); C.callGoStackCheck() }
+func stack824() { var buf [824]byte; use(buf[:]); C.callGoStackCheck() }
+func stack828() { var buf [828]byte; use(buf[:]); C.callGoStackCheck() }
+func stack832() { var buf [832]byte; use(buf[:]); C.callGoStackCheck() }
+func stack836() { var buf [836]byte; use(buf[:]); C.callGoStackCheck() }
+func stack840() { var buf [840]byte; use(buf[:]); C.callGoStackCheck() }
+func stack844() { var buf [844]byte; use(buf[:]); C.callGoStackCheck() }
+func stack848() { var buf [848]byte; use(buf[:]); C.callGoStackCheck() }
+func stack852() { var buf [852]byte; use(buf[:]); C.callGoStackCheck() }
+func stack856() { var buf [856]byte; use(buf[:]); C.callGoStackCheck() }
+func stack860() { var buf [860]byte; use(buf[:]); C.callGoStackCheck() }
+func stack864() { var buf [864]byte; use(buf[:]); C.callGoStackCheck() }
+func stack868() { var buf [868]byte; use(buf[:]); C.callGoStackCheck() }
+func stack872() { var buf [872]byte; use(buf[:]); C.callGoStackCheck() }
+func stack876() { var buf [876]byte; use(buf[:]); C.callGoStackCheck() }
+func stack880() { var buf [880]byte; use(buf[:]); C.callGoStackCheck() }
+func stack884() { var buf [884]byte; use(buf[:]); C.callGoStackCheck() }
+func stack888() { var buf [888]byte; use(buf[:]); C.callGoStackCheck() }
+func stack892() { var buf [892]byte; use(buf[:]); C.callGoStackCheck() }
+func stack896() { var buf [896]byte; use(buf[:]); C.callGoStackCheck() }
+func stack900() { var buf [900]byte; use(buf[:]); C.callGoStackCheck() }
+func stack904() { var buf [904]byte; use(buf[:]); C.callGoStackCheck() }
+func stack908() { var buf [908]byte; use(buf[:]); C.callGoStackCheck() }
+func stack912() { var buf [912]byte; use(buf[:]); C.callGoStackCheck() }
+func stack916() { var buf [916]byte; use(buf[:]); C.callGoStackCheck() }
+func stack920() { var buf [920]byte; use(buf[:]); C.callGoStackCheck() }
+func stack924() { var buf [924]byte; use(buf[:]); C.callGoStackCheck() }
+func stack928() { var buf [928]byte; use(buf[:]); C.callGoStackCheck() }
+func stack932() { var buf [932]byte; use(buf[:]); C.callGoStackCheck() }
+func stack936() { var buf [936]byte; use(buf[:]); C.callGoStackCheck() }
+func stack940() { var buf [940]byte; use(buf[:]); C.callGoStackCheck() }
+func stack944() { var buf [944]byte; use(buf[:]); C.callGoStackCheck() }
+func stack948() { var buf [948]byte; use(buf[:]); C.callGoStackCheck() }
+func stack952() { var buf [952]byte; use(buf[:]); C.callGoStackCheck() }
+func stack956() { var buf [956]byte; use(buf[:]); C.callGoStackCheck() }
+func stack960() { var buf [960]byte; use(buf[:]); C.callGoStackCheck() }
+func stack964() { var buf [964]byte; use(buf[:]); C.callGoStackCheck() }
+func stack968() { var buf [968]byte; use(buf[:]); C.callGoStackCheck() }
+func stack972() { var buf [972]byte; use(buf[:]); C.callGoStackCheck() }
+func stack976() { var buf [976]byte; use(buf[:]); C.callGoStackCheck() }
+func stack980() { var buf [980]byte; use(buf[:]); C.callGoStackCheck() }
+func stack984() { var buf [984]byte; use(buf[:]); C.callGoStackCheck() }
+func stack988() { var buf [988]byte; use(buf[:]); C.callGoStackCheck() }
+func stack992() { var buf [992]byte; use(buf[:]); C.callGoStackCheck() }
+func stack996() { var buf [996]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1000() { var buf [1000]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1004() { var buf [1004]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1008() { var buf [1008]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1012() { var buf [1012]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1016() { var buf [1016]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1020() { var buf [1020]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1024() { var buf [1024]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1028() { var buf [1028]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1032() { var buf [1032]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1036() { var buf [1036]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1040() { var buf [1040]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1044() { var buf [1044]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1048() { var buf [1048]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1052() { var buf [1052]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1056() { var buf [1056]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1060() { var buf [1060]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1064() { var buf [1064]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1068() { var buf [1068]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1072() { var buf [1072]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1076() { var buf [1076]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1080() { var buf [1080]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1084() { var buf [1084]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1088() { var buf [1088]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1092() { var buf [1092]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1096() { var buf [1096]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1100() { var buf [1100]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1104() { var buf [1104]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1108() { var buf [1108]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1112() { var buf [1112]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1116() { var buf [1116]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1120() { var buf [1120]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1124() { var buf [1124]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1128() { var buf [1128]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1132() { var buf [1132]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1136() { var buf [1136]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1140() { var buf [1140]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1144() { var buf [1144]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1148() { var buf [1148]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1152() { var buf [1152]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1156() { var buf [1156]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1160() { var buf [1160]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1164() { var buf [1164]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1168() { var buf [1168]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1172() { var buf [1172]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1176() { var buf [1176]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1180() { var buf [1180]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1184() { var buf [1184]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1188() { var buf [1188]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1192() { var buf [1192]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1196() { var buf [1196]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1200() { var buf [1200]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1204() { var buf [1204]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1208() { var buf [1208]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1212() { var buf [1212]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1216() { var buf [1216]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1220() { var buf [1220]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1224() { var buf [1224]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1228() { var buf [1228]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1232() { var buf [1232]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1236() { var buf [1236]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1240() { var buf [1240]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1244() { var buf [1244]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1248() { var buf [1248]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1252() { var buf [1252]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1256() { var buf [1256]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1260() { var buf [1260]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1264() { var buf [1264]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1268() { var buf [1268]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1272() { var buf [1272]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1276() { var buf [1276]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1280() { var buf [1280]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1284() { var buf [1284]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1288() { var buf [1288]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1292() { var buf [1292]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1296() { var buf [1296]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1300() { var buf [1300]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1304() { var buf [1304]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1308() { var buf [1308]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1312() { var buf [1312]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1316() { var buf [1316]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1320() { var buf [1320]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1324() { var buf [1324]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1328() { var buf [1328]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1332() { var buf [1332]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1336() { var buf [1336]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1340() { var buf [1340]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1344() { var buf [1344]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1348() { var buf [1348]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1352() { var buf [1352]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1356() { var buf [1356]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1360() { var buf [1360]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1364() { var buf [1364]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1368() { var buf [1368]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1372() { var buf [1372]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1376() { var buf [1376]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1380() { var buf [1380]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1384() { var buf [1384]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1388() { var buf [1388]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1392() { var buf [1392]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1396() { var buf [1396]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1400() { var buf [1400]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1404() { var buf [1404]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1408() { var buf [1408]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1412() { var buf [1412]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1416() { var buf [1416]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1420() { var buf [1420]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1424() { var buf [1424]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1428() { var buf [1428]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1432() { var buf [1432]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1436() { var buf [1436]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1440() { var buf [1440]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1444() { var buf [1444]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1448() { var buf [1448]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1452() { var buf [1452]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1456() { var buf [1456]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1460() { var buf [1460]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1464() { var buf [1464]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1468() { var buf [1468]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1472() { var buf [1472]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1476() { var buf [1476]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1480() { var buf [1480]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1484() { var buf [1484]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1488() { var buf [1488]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1492() { var buf [1492]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1496() { var buf [1496]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1500() { var buf [1500]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1504() { var buf [1504]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1508() { var buf [1508]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1512() { var buf [1512]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1516() { var buf [1516]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1520() { var buf [1520]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1524() { var buf [1524]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1528() { var buf [1528]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1532() { var buf [1532]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1536() { var buf [1536]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1540() { var buf [1540]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1544() { var buf [1544]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1548() { var buf [1548]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1552() { var buf [1552]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1556() { var buf [1556]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1560() { var buf [1560]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1564() { var buf [1564]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1568() { var buf [1568]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1572() { var buf [1572]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1576() { var buf [1576]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1580() { var buf [1580]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1584() { var buf [1584]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1588() { var buf [1588]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1592() { var buf [1592]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1596() { var buf [1596]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1600() { var buf [1600]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1604() { var buf [1604]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1608() { var buf [1608]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1612() { var buf [1612]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1616() { var buf [1616]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1620() { var buf [1620]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1624() { var buf [1624]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1628() { var buf [1628]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1632() { var buf [1632]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1636() { var buf [1636]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1640() { var buf [1640]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1644() { var buf [1644]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1648() { var buf [1648]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1652() { var buf [1652]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1656() { var buf [1656]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1660() { var buf [1660]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1664() { var buf [1664]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1668() { var buf [1668]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1672() { var buf [1672]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1676() { var buf [1676]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1680() { var buf [1680]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1684() { var buf [1684]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1688() { var buf [1688]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1692() { var buf [1692]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1696() { var buf [1696]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1700() { var buf [1700]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1704() { var buf [1704]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1708() { var buf [1708]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1712() { var buf [1712]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1716() { var buf [1716]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1720() { var buf [1720]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1724() { var buf [1724]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1728() { var buf [1728]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1732() { var buf [1732]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1736() { var buf [1736]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1740() { var buf [1740]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1744() { var buf [1744]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1748() { var buf [1748]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1752() { var buf [1752]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1756() { var buf [1756]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1760() { var buf [1760]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1764() { var buf [1764]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1768() { var buf [1768]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1772() { var buf [1772]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1776() { var buf [1776]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1780() { var buf [1780]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1784() { var buf [1784]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1788() { var buf [1788]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1792() { var buf [1792]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1796() { var buf [1796]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1800() { var buf [1800]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1804() { var buf [1804]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1808() { var buf [1808]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1812() { var buf [1812]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1816() { var buf [1816]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1820() { var buf [1820]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1824() { var buf [1824]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1828() { var buf [1828]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1832() { var buf [1832]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1836() { var buf [1836]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1840() { var buf [1840]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1844() { var buf [1844]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1848() { var buf [1848]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1852() { var buf [1852]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1856() { var buf [1856]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1860() { var buf [1860]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1864() { var buf [1864]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1868() { var buf [1868]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1872() { var buf [1872]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1876() { var buf [1876]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1880() { var buf [1880]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1884() { var buf [1884]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1888() { var buf [1888]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1892() { var buf [1892]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1896() { var buf [1896]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1900() { var buf [1900]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1904() { var buf [1904]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1908() { var buf [1908]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1912() { var buf [1912]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1916() { var buf [1916]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1920() { var buf [1920]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1924() { var buf [1924]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1928() { var buf [1928]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1932() { var buf [1932]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1936() { var buf [1936]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1940() { var buf [1940]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1944() { var buf [1944]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1948() { var buf [1948]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1952() { var buf [1952]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1956() { var buf [1956]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1960() { var buf [1960]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1964() { var buf [1964]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1968() { var buf [1968]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1972() { var buf [1972]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1976() { var buf [1976]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1980() { var buf [1980]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1984() { var buf [1984]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1988() { var buf [1988]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1992() { var buf [1992]byte; use(buf[:]); C.callGoStackCheck() }
+func stack1996() { var buf [1996]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2000() { var buf [2000]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2004() { var buf [2004]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2008() { var buf [2008]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2012() { var buf [2012]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2016() { var buf [2016]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2020() { var buf [2020]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2024() { var buf [2024]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2028() { var buf [2028]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2032() { var buf [2032]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2036() { var buf [2036]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2040() { var buf [2040]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2044() { var buf [2044]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2048() { var buf [2048]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2052() { var buf [2052]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2056() { var buf [2056]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2060() { var buf [2060]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2064() { var buf [2064]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2068() { var buf [2068]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2072() { var buf [2072]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2076() { var buf [2076]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2080() { var buf [2080]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2084() { var buf [2084]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2088() { var buf [2088]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2092() { var buf [2092]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2096() { var buf [2096]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2100() { var buf [2100]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2104() { var buf [2104]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2108() { var buf [2108]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2112() { var buf [2112]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2116() { var buf [2116]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2120() { var buf [2120]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2124() { var buf [2124]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2128() { var buf [2128]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2132() { var buf [2132]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2136() { var buf [2136]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2140() { var buf [2140]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2144() { var buf [2144]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2148() { var buf [2148]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2152() { var buf [2152]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2156() { var buf [2156]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2160() { var buf [2160]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2164() { var buf [2164]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2168() { var buf [2168]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2172() { var buf [2172]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2176() { var buf [2176]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2180() { var buf [2180]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2184() { var buf [2184]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2188() { var buf [2188]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2192() { var buf [2192]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2196() { var buf [2196]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2200() { var buf [2200]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2204() { var buf [2204]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2208() { var buf [2208]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2212() { var buf [2212]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2216() { var buf [2216]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2220() { var buf [2220]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2224() { var buf [2224]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2228() { var buf [2228]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2232() { var buf [2232]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2236() { var buf [2236]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2240() { var buf [2240]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2244() { var buf [2244]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2248() { var buf [2248]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2252() { var buf [2252]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2256() { var buf [2256]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2260() { var buf [2260]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2264() { var buf [2264]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2268() { var buf [2268]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2272() { var buf [2272]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2276() { var buf [2276]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2280() { var buf [2280]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2284() { var buf [2284]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2288() { var buf [2288]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2292() { var buf [2292]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2296() { var buf [2296]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2300() { var buf [2300]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2304() { var buf [2304]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2308() { var buf [2308]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2312() { var buf [2312]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2316() { var buf [2316]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2320() { var buf [2320]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2324() { var buf [2324]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2328() { var buf [2328]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2332() { var buf [2332]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2336() { var buf [2336]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2340() { var buf [2340]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2344() { var buf [2344]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2348() { var buf [2348]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2352() { var buf [2352]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2356() { var buf [2356]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2360() { var buf [2360]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2364() { var buf [2364]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2368() { var buf [2368]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2372() { var buf [2372]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2376() { var buf [2376]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2380() { var buf [2380]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2384() { var buf [2384]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2388() { var buf [2388]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2392() { var buf [2392]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2396() { var buf [2396]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2400() { var buf [2400]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2404() { var buf [2404]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2408() { var buf [2408]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2412() { var buf [2412]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2416() { var buf [2416]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2420() { var buf [2420]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2424() { var buf [2424]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2428() { var buf [2428]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2432() { var buf [2432]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2436() { var buf [2436]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2440() { var buf [2440]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2444() { var buf [2444]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2448() { var buf [2448]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2452() { var buf [2452]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2456() { var buf [2456]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2460() { var buf [2460]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2464() { var buf [2464]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2468() { var buf [2468]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2472() { var buf [2472]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2476() { var buf [2476]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2480() { var buf [2480]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2484() { var buf [2484]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2488() { var buf [2488]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2492() { var buf [2492]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2496() { var buf [2496]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2500() { var buf [2500]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2504() { var buf [2504]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2508() { var buf [2508]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2512() { var buf [2512]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2516() { var buf [2516]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2520() { var buf [2520]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2524() { var buf [2524]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2528() { var buf [2528]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2532() { var buf [2532]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2536() { var buf [2536]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2540() { var buf [2540]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2544() { var buf [2544]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2548() { var buf [2548]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2552() { var buf [2552]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2556() { var buf [2556]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2560() { var buf [2560]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2564() { var buf [2564]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2568() { var buf [2568]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2572() { var buf [2572]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2576() { var buf [2576]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2580() { var buf [2580]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2584() { var buf [2584]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2588() { var buf [2588]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2592() { var buf [2592]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2596() { var buf [2596]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2600() { var buf [2600]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2604() { var buf [2604]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2608() { var buf [2608]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2612() { var buf [2612]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2616() { var buf [2616]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2620() { var buf [2620]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2624() { var buf [2624]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2628() { var buf [2628]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2632() { var buf [2632]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2636() { var buf [2636]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2640() { var buf [2640]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2644() { var buf [2644]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2648() { var buf [2648]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2652() { var buf [2652]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2656() { var buf [2656]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2660() { var buf [2660]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2664() { var buf [2664]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2668() { var buf [2668]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2672() { var buf [2672]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2676() { var buf [2676]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2680() { var buf [2680]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2684() { var buf [2684]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2688() { var buf [2688]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2692() { var buf [2692]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2696() { var buf [2696]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2700() { var buf [2700]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2704() { var buf [2704]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2708() { var buf [2708]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2712() { var buf [2712]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2716() { var buf [2716]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2720() { var buf [2720]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2724() { var buf [2724]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2728() { var buf [2728]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2732() { var buf [2732]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2736() { var buf [2736]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2740() { var buf [2740]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2744() { var buf [2744]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2748() { var buf [2748]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2752() { var buf [2752]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2756() { var buf [2756]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2760() { var buf [2760]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2764() { var buf [2764]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2768() { var buf [2768]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2772() { var buf [2772]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2776() { var buf [2776]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2780() { var buf [2780]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2784() { var buf [2784]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2788() { var buf [2788]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2792() { var buf [2792]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2796() { var buf [2796]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2800() { var buf [2800]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2804() { var buf [2804]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2808() { var buf [2808]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2812() { var buf [2812]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2816() { var buf [2816]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2820() { var buf [2820]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2824() { var buf [2824]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2828() { var buf [2828]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2832() { var buf [2832]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2836() { var buf [2836]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2840() { var buf [2840]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2844() { var buf [2844]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2848() { var buf [2848]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2852() { var buf [2852]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2856() { var buf [2856]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2860() { var buf [2860]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2864() { var buf [2864]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2868() { var buf [2868]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2872() { var buf [2872]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2876() { var buf [2876]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2880() { var buf [2880]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2884() { var buf [2884]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2888() { var buf [2888]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2892() { var buf [2892]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2896() { var buf [2896]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2900() { var buf [2900]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2904() { var buf [2904]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2908() { var buf [2908]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2912() { var buf [2912]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2916() { var buf [2916]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2920() { var buf [2920]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2924() { var buf [2924]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2928() { var buf [2928]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2932() { var buf [2932]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2936() { var buf [2936]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2940() { var buf [2940]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2944() { var buf [2944]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2948() { var buf [2948]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2952() { var buf [2952]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2956() { var buf [2956]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2960() { var buf [2960]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2964() { var buf [2964]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2968() { var buf [2968]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2972() { var buf [2972]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2976() { var buf [2976]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2980() { var buf [2980]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2984() { var buf [2984]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2988() { var buf [2988]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2992() { var buf [2992]byte; use(buf[:]); C.callGoStackCheck() }
+func stack2996() { var buf [2996]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3000() { var buf [3000]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3004() { var buf [3004]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3008() { var buf [3008]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3012() { var buf [3012]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3016() { var buf [3016]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3020() { var buf [3020]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3024() { var buf [3024]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3028() { var buf [3028]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3032() { var buf [3032]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3036() { var buf [3036]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3040() { var buf [3040]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3044() { var buf [3044]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3048() { var buf [3048]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3052() { var buf [3052]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3056() { var buf [3056]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3060() { var buf [3060]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3064() { var buf [3064]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3068() { var buf [3068]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3072() { var buf [3072]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3076() { var buf [3076]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3080() { var buf [3080]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3084() { var buf [3084]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3088() { var buf [3088]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3092() { var buf [3092]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3096() { var buf [3096]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3100() { var buf [3100]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3104() { var buf [3104]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3108() { var buf [3108]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3112() { var buf [3112]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3116() { var buf [3116]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3120() { var buf [3120]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3124() { var buf [3124]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3128() { var buf [3128]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3132() { var buf [3132]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3136() { var buf [3136]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3140() { var buf [3140]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3144() { var buf [3144]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3148() { var buf [3148]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3152() { var buf [3152]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3156() { var buf [3156]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3160() { var buf [3160]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3164() { var buf [3164]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3168() { var buf [3168]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3172() { var buf [3172]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3176() { var buf [3176]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3180() { var buf [3180]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3184() { var buf [3184]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3188() { var buf [3188]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3192() { var buf [3192]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3196() { var buf [3196]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3200() { var buf [3200]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3204() { var buf [3204]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3208() { var buf [3208]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3212() { var buf [3212]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3216() { var buf [3216]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3220() { var buf [3220]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3224() { var buf [3224]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3228() { var buf [3228]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3232() { var buf [3232]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3236() { var buf [3236]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3240() { var buf [3240]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3244() { var buf [3244]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3248() { var buf [3248]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3252() { var buf [3252]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3256() { var buf [3256]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3260() { var buf [3260]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3264() { var buf [3264]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3268() { var buf [3268]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3272() { var buf [3272]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3276() { var buf [3276]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3280() { var buf [3280]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3284() { var buf [3284]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3288() { var buf [3288]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3292() { var buf [3292]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3296() { var buf [3296]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3300() { var buf [3300]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3304() { var buf [3304]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3308() { var buf [3308]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3312() { var buf [3312]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3316() { var buf [3316]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3320() { var buf [3320]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3324() { var buf [3324]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3328() { var buf [3328]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3332() { var buf [3332]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3336() { var buf [3336]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3340() { var buf [3340]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3344() { var buf [3344]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3348() { var buf [3348]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3352() { var buf [3352]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3356() { var buf [3356]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3360() { var buf [3360]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3364() { var buf [3364]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3368() { var buf [3368]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3372() { var buf [3372]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3376() { var buf [3376]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3380() { var buf [3380]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3384() { var buf [3384]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3388() { var buf [3388]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3392() { var buf [3392]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3396() { var buf [3396]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3400() { var buf [3400]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3404() { var buf [3404]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3408() { var buf [3408]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3412() { var buf [3412]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3416() { var buf [3416]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3420() { var buf [3420]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3424() { var buf [3424]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3428() { var buf [3428]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3432() { var buf [3432]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3436() { var buf [3436]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3440() { var buf [3440]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3444() { var buf [3444]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3448() { var buf [3448]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3452() { var buf [3452]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3456() { var buf [3456]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3460() { var buf [3460]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3464() { var buf [3464]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3468() { var buf [3468]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3472() { var buf [3472]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3476() { var buf [3476]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3480() { var buf [3480]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3484() { var buf [3484]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3488() { var buf [3488]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3492() { var buf [3492]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3496() { var buf [3496]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3500() { var buf [3500]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3504() { var buf [3504]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3508() { var buf [3508]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3512() { var buf [3512]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3516() { var buf [3516]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3520() { var buf [3520]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3524() { var buf [3524]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3528() { var buf [3528]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3532() { var buf [3532]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3536() { var buf [3536]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3540() { var buf [3540]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3544() { var buf [3544]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3548() { var buf [3548]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3552() { var buf [3552]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3556() { var buf [3556]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3560() { var buf [3560]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3564() { var buf [3564]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3568() { var buf [3568]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3572() { var buf [3572]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3576() { var buf [3576]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3580() { var buf [3580]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3584() { var buf [3584]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3588() { var buf [3588]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3592() { var buf [3592]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3596() { var buf [3596]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3600() { var buf [3600]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3604() { var buf [3604]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3608() { var buf [3608]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3612() { var buf [3612]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3616() { var buf [3616]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3620() { var buf [3620]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3624() { var buf [3624]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3628() { var buf [3628]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3632() { var buf [3632]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3636() { var buf [3636]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3640() { var buf [3640]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3644() { var buf [3644]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3648() { var buf [3648]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3652() { var buf [3652]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3656() { var buf [3656]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3660() { var buf [3660]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3664() { var buf [3664]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3668() { var buf [3668]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3672() { var buf [3672]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3676() { var buf [3676]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3680() { var buf [3680]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3684() { var buf [3684]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3688() { var buf [3688]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3692() { var buf [3692]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3696() { var buf [3696]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3700() { var buf [3700]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3704() { var buf [3704]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3708() { var buf [3708]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3712() { var buf [3712]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3716() { var buf [3716]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3720() { var buf [3720]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3724() { var buf [3724]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3728() { var buf [3728]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3732() { var buf [3732]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3736() { var buf [3736]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3740() { var buf [3740]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3744() { var buf [3744]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3748() { var buf [3748]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3752() { var buf [3752]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3756() { var buf [3756]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3760() { var buf [3760]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3764() { var buf [3764]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3768() { var buf [3768]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3772() { var buf [3772]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3776() { var buf [3776]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3780() { var buf [3780]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3784() { var buf [3784]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3788() { var buf [3788]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3792() { var buf [3792]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3796() { var buf [3796]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3800() { var buf [3800]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3804() { var buf [3804]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3808() { var buf [3808]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3812() { var buf [3812]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3816() { var buf [3816]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3820() { var buf [3820]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3824() { var buf [3824]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3828() { var buf [3828]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3832() { var buf [3832]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3836() { var buf [3836]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3840() { var buf [3840]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3844() { var buf [3844]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3848() { var buf [3848]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3852() { var buf [3852]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3856() { var buf [3856]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3860() { var buf [3860]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3864() { var buf [3864]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3868() { var buf [3868]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3872() { var buf [3872]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3876() { var buf [3876]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3880() { var buf [3880]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3884() { var buf [3884]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3888() { var buf [3888]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3892() { var buf [3892]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3896() { var buf [3896]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3900() { var buf [3900]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3904() { var buf [3904]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3908() { var buf [3908]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3912() { var buf [3912]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3916() { var buf [3916]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3920() { var buf [3920]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3924() { var buf [3924]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3928() { var buf [3928]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3932() { var buf [3932]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3936() { var buf [3936]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3940() { var buf [3940]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3944() { var buf [3944]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3948() { var buf [3948]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3952() { var buf [3952]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3956() { var buf [3956]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3960() { var buf [3960]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3964() { var buf [3964]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3968() { var buf [3968]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3972() { var buf [3972]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3976() { var buf [3976]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3980() { var buf [3980]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3984() { var buf [3984]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3988() { var buf [3988]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3992() { var buf [3992]byte; use(buf[:]); C.callGoStackCheck() }
+func stack3996() { var buf [3996]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4000() { var buf [4000]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4004() { var buf [4004]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4008() { var buf [4008]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4012() { var buf [4012]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4016() { var buf [4016]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4020() { var buf [4020]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4024() { var buf [4024]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4028() { var buf [4028]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4032() { var buf [4032]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4036() { var buf [4036]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4040() { var buf [4040]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4044() { var buf [4044]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4048() { var buf [4048]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4052() { var buf [4052]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4056() { var buf [4056]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4060() { var buf [4060]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4064() { var buf [4064]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4068() { var buf [4068]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4072() { var buf [4072]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4076() { var buf [4076]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4080() { var buf [4080]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4084() { var buf [4084]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4088() { var buf [4088]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4092() { var buf [4092]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4096() { var buf [4096]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4100() { var buf [4100]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4104() { var buf [4104]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4108() { var buf [4108]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4112() { var buf [4112]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4116() { var buf [4116]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4120() { var buf [4120]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4124() { var buf [4124]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4128() { var buf [4128]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4132() { var buf [4132]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4136() { var buf [4136]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4140() { var buf [4140]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4144() { var buf [4144]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4148() { var buf [4148]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4152() { var buf [4152]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4156() { var buf [4156]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4160() { var buf [4160]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4164() { var buf [4164]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4168() { var buf [4168]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4172() { var buf [4172]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4176() { var buf [4176]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4180() { var buf [4180]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4184() { var buf [4184]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4188() { var buf [4188]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4192() { var buf [4192]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4196() { var buf [4196]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4200() { var buf [4200]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4204() { var buf [4204]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4208() { var buf [4208]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4212() { var buf [4212]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4216() { var buf [4216]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4220() { var buf [4220]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4224() { var buf [4224]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4228() { var buf [4228]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4232() { var buf [4232]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4236() { var buf [4236]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4240() { var buf [4240]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4244() { var buf [4244]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4248() { var buf [4248]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4252() { var buf [4252]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4256() { var buf [4256]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4260() { var buf [4260]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4264() { var buf [4264]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4268() { var buf [4268]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4272() { var buf [4272]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4276() { var buf [4276]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4280() { var buf [4280]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4284() { var buf [4284]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4288() { var buf [4288]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4292() { var buf [4292]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4296() { var buf [4296]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4300() { var buf [4300]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4304() { var buf [4304]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4308() { var buf [4308]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4312() { var buf [4312]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4316() { var buf [4316]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4320() { var buf [4320]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4324() { var buf [4324]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4328() { var buf [4328]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4332() { var buf [4332]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4336() { var buf [4336]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4340() { var buf [4340]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4344() { var buf [4344]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4348() { var buf [4348]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4352() { var buf [4352]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4356() { var buf [4356]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4360() { var buf [4360]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4364() { var buf [4364]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4368() { var buf [4368]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4372() { var buf [4372]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4376() { var buf [4376]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4380() { var buf [4380]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4384() { var buf [4384]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4388() { var buf [4388]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4392() { var buf [4392]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4396() { var buf [4396]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4400() { var buf [4400]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4404() { var buf [4404]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4408() { var buf [4408]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4412() { var buf [4412]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4416() { var buf [4416]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4420() { var buf [4420]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4424() { var buf [4424]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4428() { var buf [4428]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4432() { var buf [4432]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4436() { var buf [4436]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4440() { var buf [4440]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4444() { var buf [4444]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4448() { var buf [4448]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4452() { var buf [4452]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4456() { var buf [4456]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4460() { var buf [4460]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4464() { var buf [4464]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4468() { var buf [4468]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4472() { var buf [4472]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4476() { var buf [4476]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4480() { var buf [4480]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4484() { var buf [4484]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4488() { var buf [4488]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4492() { var buf [4492]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4496() { var buf [4496]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4500() { var buf [4500]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4504() { var buf [4504]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4508() { var buf [4508]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4512() { var buf [4512]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4516() { var buf [4516]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4520() { var buf [4520]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4524() { var buf [4524]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4528() { var buf [4528]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4532() { var buf [4532]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4536() { var buf [4536]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4540() { var buf [4540]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4544() { var buf [4544]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4548() { var buf [4548]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4552() { var buf [4552]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4556() { var buf [4556]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4560() { var buf [4560]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4564() { var buf [4564]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4568() { var buf [4568]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4572() { var buf [4572]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4576() { var buf [4576]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4580() { var buf [4580]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4584() { var buf [4584]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4588() { var buf [4588]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4592() { var buf [4592]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4596() { var buf [4596]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4600() { var buf [4600]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4604() { var buf [4604]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4608() { var buf [4608]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4612() { var buf [4612]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4616() { var buf [4616]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4620() { var buf [4620]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4624() { var buf [4624]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4628() { var buf [4628]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4632() { var buf [4632]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4636() { var buf [4636]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4640() { var buf [4640]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4644() { var buf [4644]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4648() { var buf [4648]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4652() { var buf [4652]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4656() { var buf [4656]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4660() { var buf [4660]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4664() { var buf [4664]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4668() { var buf [4668]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4672() { var buf [4672]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4676() { var buf [4676]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4680() { var buf [4680]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4684() { var buf [4684]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4688() { var buf [4688]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4692() { var buf [4692]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4696() { var buf [4696]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4700() { var buf [4700]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4704() { var buf [4704]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4708() { var buf [4708]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4712() { var buf [4712]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4716() { var buf [4716]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4720() { var buf [4720]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4724() { var buf [4724]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4728() { var buf [4728]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4732() { var buf [4732]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4736() { var buf [4736]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4740() { var buf [4740]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4744() { var buf [4744]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4748() { var buf [4748]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4752() { var buf [4752]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4756() { var buf [4756]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4760() { var buf [4760]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4764() { var buf [4764]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4768() { var buf [4768]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4772() { var buf [4772]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4776() { var buf [4776]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4780() { var buf [4780]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4784() { var buf [4784]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4788() { var buf [4788]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4792() { var buf [4792]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4796() { var buf [4796]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4800() { var buf [4800]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4804() { var buf [4804]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4808() { var buf [4808]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4812() { var buf [4812]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4816() { var buf [4816]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4820() { var buf [4820]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4824() { var buf [4824]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4828() { var buf [4828]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4832() { var buf [4832]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4836() { var buf [4836]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4840() { var buf [4840]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4844() { var buf [4844]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4848() { var buf [4848]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4852() { var buf [4852]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4856() { var buf [4856]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4860() { var buf [4860]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4864() { var buf [4864]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4868() { var buf [4868]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4872() { var buf [4872]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4876() { var buf [4876]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4880() { var buf [4880]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4884() { var buf [4884]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4888() { var buf [4888]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4892() { var buf [4892]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4896() { var buf [4896]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4900() { var buf [4900]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4904() { var buf [4904]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4908() { var buf [4908]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4912() { var buf [4912]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4916() { var buf [4916]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4920() { var buf [4920]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4924() { var buf [4924]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4928() { var buf [4928]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4932() { var buf [4932]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4936() { var buf [4936]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4940() { var buf [4940]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4944() { var buf [4944]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4948() { var buf [4948]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4952() { var buf [4952]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4956() { var buf [4956]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4960() { var buf [4960]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4964() { var buf [4964]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4968() { var buf [4968]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4972() { var buf [4972]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4976() { var buf [4976]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4980() { var buf [4980]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4984() { var buf [4984]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4988() { var buf [4988]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4992() { var buf [4992]byte; use(buf[:]); C.callGoStackCheck() }
+func stack4996() { var buf [4996]byte; use(buf[:]); C.callGoStackCheck() }
+func stack5000() { var buf [5000]byte; use(buf[:]); C.callGoStackCheck() }
diff --git a/misc/cgo/test/callback_c.c b/misc/cgo/test/callback_c.c
index 47f07301b..dcd4ddd4e 100644
--- a/misc/cgo/test/callback_c.c
+++ b/misc/cgo/test/callback_c.c
@@ -3,6 +3,7 @@
// license that can be found in the LICENSE file.
#include <sys/types.h>
+#include <unistd.h>
#include "_cgo_export.h"
void
@@ -29,9 +30,37 @@ IntoC(void)
BackIntoGo();
}
-void
+#ifdef WIN32
+#include <windows.h>
+long long
+mysleep(int seconds) {
+ long long st = GetTickCount();
+ sleep(seconds);
+ return st;
+}
+#else
+#include <sys/time.h>
+long long
+mysleep(int seconds) {
+ long long st;
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ st = tv.tv_sec * 1000 + tv.tv_usec / 1000;
+ sleep(seconds);
+ return st;
+}
+#endif
+
+long long
twoSleep(int n)
{
BackgroundSleep(n);
- sleep(n);
+ return mysleep(n);
+}
+
+void
+callGoStackCheck(void)
+{
+ extern void goStackCheck(void);
+ goStackCheck();
}
diff --git a/misc/cgo/test/callback_c_gc.c b/misc/cgo/test/callback_c_gc.c
new file mode 100644
index 000000000..8953b74a6
--- /dev/null
+++ b/misc/cgo/test/callback_c_gc.c
@@ -0,0 +1,21 @@
+// 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 gc
+
+#include "_cgo_export.h"
+
+/* Test calling panic from C. This is what SWIG does. */
+
+extern void crosscall2(void (*fn)(void *, int), void *, int);
+extern void _cgo_panic(void *, int);
+
+void
+callPanic(void)
+{
+ struct { const char *p; } a;
+ a.p = "panic from C";
+ crosscall2(_cgo_panic, &a, sizeof a);
+ *(int*)1 = 1;
+}
diff --git a/misc/cgo/test/callback_c_gccgo.c b/misc/cgo/test/callback_c_gccgo.c
new file mode 100644
index 000000000..0ea7296c6
--- /dev/null
+++ b/misc/cgo/test/callback_c_gccgo.c
@@ -0,0 +1,17 @@
+// 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 gccgo
+
+#include "_cgo_export.h"
+
+/* Test calling panic from C. This is what SWIG does. */
+
+extern void _cgo_panic(const char *);
+
+void
+callPanic(void)
+{
+ _cgo_panic("panic from C");
+}
diff --git a/misc/cgo/test/cgo_test.go b/misc/cgo/test/cgo_test.go
index 56e1a0625..b7c6d2876 100644
--- a/misc/cgo/test/cgo_test.go
+++ b/misc/cgo/test/cgo_test.go
@@ -22,6 +22,7 @@ func TestCallbackGC(t *testing.T) { testCallbackGC(t) }
func TestCallbackPanic(t *testing.T) { testCallbackPanic(t) }
func TestCallbackPanicLoop(t *testing.T) { testCallbackPanicLoop(t) }
func TestCallbackPanicLocked(t *testing.T) { testCallbackPanicLocked(t) }
+func TestPanicFromC(t *testing.T) { testPanicFromC(t) }
func TestZeroArgCallback(t *testing.T) { testZeroArgCallback(t) }
func TestBlocking(t *testing.T) { testBlocking(t) }
func Test1328(t *testing.T) { test1328(t) }
@@ -39,5 +40,15 @@ 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 Test5337(t *testing.T) { test5337(t) }
+func Test5548(t *testing.T) { test5548(t) }
+func Test5603(t *testing.T) { test5603(t) }
+func Test3250(t *testing.T) { test3250(t) }
+func TestCallbackStack(t *testing.T) { testCallbackStack(t) }
+func TestFpVar(t *testing.T) { testFpVar(t) }
+func Test4339(t *testing.T) { test4339(t) }
+func Test6390(t *testing.T) { test6390(t) }
+func Test5986(t *testing.T) { test5986(t) }
+func TestNaming(t *testing.T) { testNaming(t) }
func BenchmarkCgoCall(b *testing.B) { benchCgoCall(b) }
diff --git a/misc/cgo/test/cthread_unix.c b/misc/cgo/test/cthread_unix.c
index 998bc00cb..3f39c15e0 100644
--- a/misc/cgo/test/cthread_unix.c
+++ b/misc/cgo/test/cthread_unix.c
@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
-// +build darwin freebsd linux netbsd openbsd
+// +build darwin dragonfly freebsd linux netbsd openbsd
#include <pthread.h>
#include "_cgo_export.h"
diff --git a/misc/cgo/test/fpvar.go b/misc/cgo/test/fpvar.go
new file mode 100644
index 000000000..c0ec6f68d
--- /dev/null
+++ b/misc/cgo/test/fpvar.go
@@ -0,0 +1,50 @@
+// 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.
+
+// This file contains test cases for cgo with function pointer variables.
+
+package cgotest
+
+/*
+typedef int (*intFunc) ();
+
+int
+bridge_int_func(intFunc f)
+{
+ return f();
+}
+
+int fortytwo()
+{
+ return 42;
+}
+
+*/
+import "C"
+import "testing"
+
+func callBridge(f C.intFunc) int {
+ return int(C.bridge_int_func(f))
+}
+
+func callCBridge(f C.intFunc) C.int {
+ return C.bridge_int_func(f)
+}
+
+func testFpVar(t *testing.T) {
+ const expected = 42
+ f := C.intFunc(C.fortytwo)
+ res1 := C.bridge_int_func(f)
+ if r1 := int(res1); r1 != expected {
+ t.Errorf("got %d, want %d", r1, expected)
+ }
+ res2 := callCBridge(f)
+ if r2 := int(res2); r2 != expected {
+ t.Errorf("got %d, want %d", r2, expected)
+ }
+ r3 := callBridge(f)
+ if r3 != expected {
+ t.Errorf("got %d, want %d", r3, expected)
+ }
+}
diff --git a/misc/cgo/test/issue1560.go b/misc/cgo/test/issue1560.go
index 147ce94b5..c46954b07 100644
--- a/misc/cgo/test/issue1560.go
+++ b/misc/cgo/test/issue1560.go
@@ -5,71 +5,46 @@
package cgotest
/*
-#include <unistd.h>
+// mysleep returns the absolute start time in ms.
+long long mysleep(int seconds);
-unsigned int sleep(unsigned int seconds);
-
-extern void BackgroundSleep(int);
-void twoSleep(int);
+// twoSleep returns the absolute start time of the first sleep
+// in ms.
+long long twoSleep(int);
*/
import "C"
import (
- "runtime"
"testing"
"time"
)
-var sleepDone = make(chan bool)
+var sleepDone = make(chan int64)
-func parallelSleep(n int) {
- C.twoSleep(C.int(n))
- <-sleepDone
+// parallelSleep returns the absolute difference between the start time
+// of the two sleeps.
+func parallelSleep(n int) int64 {
+ t := int64(C.twoSleep(C.int(n))) - <-sleepDone
+ if t < 0 {
+ return -t
+ }
+ return t
}
//export BackgroundSleep
func BackgroundSleep(n int32) {
go func() {
- C.sleep(C.uint(n))
- sleepDone <- true
- }()
-}
-
-// wasteCPU starts a background goroutine to waste CPU
-// to cause the power management to raise the CPU frequency.
-// On ARM this has the side effect of making sleep more accurate.
-func wasteCPU() chan struct{} {
- done := make(chan struct{})
- go func() {
- for {
- select {
- case <-done:
- return
- default:
- }
- }
+ sleepDone <- int64(C.mysleep(C.int(n)))
}()
- // pause for a short amount of time to allow the
- // power management to recognise load has risen.
- <-time.After(300 * time.Millisecond)
- return done
}
func testParallelSleep(t *testing.T) {
- if runtime.GOARCH == "arm" {
- // on ARM, the 1.3s deadline is frequently missed,
- // and burning cpu seems to help
- defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2))
- defer close(wasteCPU())
- }
-
sleepSec := 1
- start := time.Now()
- parallelSleep(sleepSec)
- dt := time.Since(start)
- t.Logf("sleep(%d) slept for %v", sleepSec, dt)
+ dt := time.Duration(parallelSleep(sleepSec)) * time.Millisecond
+ t.Logf("difference in start time for two sleep(%d) is %v", sleepSec, dt)
// bug used to run sleeps in serial, producing a 2*sleepSec-second delay.
- if dt >= time.Duration(sleepSec)*1300*time.Millisecond {
+ // we detect if the start times of those sleeps are > 0.5*sleepSec-second.
+ if dt >= time.Duration(sleepSec)*time.Second/2 {
t.Fatalf("parallel %d-second sleeps slept for %f seconds", sleepSec, dt.Seconds())
}
}
diff --git a/misc/cgo/test/issue3250.go b/misc/cgo/test/issue3250.go
new file mode 100644
index 000000000..b1ff03941
--- /dev/null
+++ b/misc/cgo/test/issue3250.go
@@ -0,0 +1,95 @@
+// 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 cgotest
+
+/*
+#include <signal.h>
+#include <pthread.h>
+#include <unistd.h>
+#include <stdlib.h>
+
+static void *thread(void *p) {
+ (void)p;
+ const int M = 100;
+ int i;
+ for (i = 0; i < M; i++) {
+ pthread_kill(pthread_self(), SIGCHLD);
+ usleep(rand() % 20 + 5);
+ }
+ return NULL;
+}
+void testSendSIG() {
+ const int N = 20;
+ int i;
+ pthread_t tid[N];
+ for (i = 0; i < N; i++) {
+ usleep(rand() % 200 + 100);
+ pthread_create(&tid[i], 0, thread, NULL);
+ }
+ for (i = 0; i < N; i++)
+ pthread_join(tid[i], 0);
+}
+*/
+import "C"
+
+import (
+ "os"
+ "os/signal"
+ "syscall"
+ "testing"
+ "time"
+)
+
+func test3250(t *testing.T) {
+ t.Skip("skipped, see golang.org/issue/5885")
+ const (
+ thres = 1
+ sig = syscall.SIGCHLD
+ )
+ type result struct {
+ n int
+ sig os.Signal
+ }
+ var (
+ sigCh = make(chan os.Signal, 10)
+ waitStart = make(chan struct{})
+ waitDone = make(chan result)
+ )
+
+ signal.Notify(sigCh, sig)
+
+ go func() {
+ n := 0
+ alarm := time.After(time.Second * 3)
+ for {
+ select {
+ case <-waitStart:
+ waitStart = nil
+ case v := <-sigCh:
+ n++
+ if v != sig || n > thres {
+ waitDone <- result{n, v}
+ return
+ }
+ case <-alarm:
+ waitDone <- result{n, sig}
+ return
+ }
+ }
+ }()
+
+ waitStart <- struct{}{}
+ C.testSendSIG()
+ r := <-waitDone
+ if r.sig != sig {
+ t.Fatalf("received signal %v, but want %v", r.sig, sig)
+ }
+ t.Logf("got %d signals\n", r.n)
+ if r.n <= thres {
+ t.Fatalf("expected more than %d", thres)
+ }
+}
diff --git a/misc/cgo/test/issue3250w.go b/misc/cgo/test/issue3250w.go
new file mode 100644
index 000000000..e3cb161db
--- /dev/null
+++ b/misc/cgo/test/issue3250w.go
@@ -0,0 +1,11 @@
+// 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 cgotest
+
+import "testing"
+
+func test3250(t *testing.T) {}
diff --git a/misc/cgo/test/issue3775.go b/misc/cgo/test/issue3775.go
index c05a5d4be..8f8185419 100644
--- a/misc/cgo/test/issue3775.go
+++ b/misc/cgo/test/issue3775.go
@@ -15,6 +15,14 @@ import (
"testing"
)
+func init() {
+ // Same as test3775 but run during init so that
+ // there are two levels of internal runtime lock
+ // (1 for init, 1 for cgo).
+ // This would have been broken by CL 11663043.
+ C.lockOSThreadC()
+}
+
func test3775(t *testing.T) {
// Used to panic because of the UnlockOSThread below.
C.lockOSThreadC()
diff --git a/misc/cgo/test/issue4339.c b/misc/cgo/test/issue4339.c
new file mode 100644
index 000000000..15d000407
--- /dev/null
+++ b/misc/cgo/test/issue4339.c
@@ -0,0 +1,18 @@
+#include <stdio.h>
+#include "issue4339.h"
+
+static void
+impl(void)
+{
+ //printf("impl\n");
+}
+
+Issue4339 exported4339 = {"bar", impl};
+
+void
+handle4339(Issue4339 *x)
+{
+ //printf("handle\n");
+ x->bar();
+ //printf("done\n");
+}
diff --git a/misc/cgo/test/issue4339.go b/misc/cgo/test/issue4339.go
new file mode 100644
index 000000000..f734a25da
--- /dev/null
+++ b/misc/cgo/test/issue4339.go
@@ -0,0 +1,16 @@
+// 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 cgotest
+
+/*
+#include "issue4339.h"
+*/
+import "C"
+
+import "testing"
+
+func test4339(t *testing.T) {
+ C.handle4339(&C.exported4339)
+}
diff --git a/misc/cgo/test/issue4339.h b/misc/cgo/test/issue4339.h
new file mode 100644
index 000000000..20f6cebb6
--- /dev/null
+++ b/misc/cgo/test/issue4339.h
@@ -0,0 +1,9 @@
+typedef struct Issue4339 Issue4339;
+
+struct Issue4339 {
+ char *name;
+ void (*bar)(void);
+};
+
+extern Issue4339 exported4339;
+void handle4339(Issue4339*);
diff --git a/misc/cgo/test/issue4857.go b/misc/cgo/test/issue4857.go
new file mode 100644
index 000000000..54dc39f8d
--- /dev/null
+++ b/misc/cgo/test/issue4857.go
@@ -0,0 +1,15 @@
+// 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 cgotest
+
+/*
+#cgo CFLAGS: -Werror
+const struct { int a; } *issue4857() { return (void *)0; }
+*/
+import "C"
+
+func test4857() {
+ _ = C.issue4857()
+}
diff --git a/misc/cgo/test/issue5337.go b/misc/cgo/test/issue5337.go
new file mode 100644
index 000000000..8013b66a7
--- /dev/null
+++ b/misc/cgo/test/issue5337.go
@@ -0,0 +1,31 @@
+// 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 cgotest
+
+/*
+#include <signal.h>
+#include <pthread.h>
+
+static void *thread1(void *p) {
+ (void)p;
+ pthread_kill(pthread_self(), SIGPROF);
+ return NULL;
+}
+void test5337() {
+ pthread_t tid;
+ pthread_create(&tid, 0, thread1, NULL);
+ pthread_join(tid, 0);
+}
+*/
+import "C"
+
+import "testing"
+
+// Verify that we can withstand SIGPROF received on foreign threads
+func test5337(t *testing.T) {
+ C.test5337()
+}
diff --git a/misc/cgo/test/issue5337w.go b/misc/cgo/test/issue5337w.go
new file mode 100644
index 000000000..14720a94d
--- /dev/null
+++ b/misc/cgo/test/issue5337w.go
@@ -0,0 +1,11 @@
+// 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 cgotest
+
+import "testing"
+
+func test5337(t *testing.T) {}
diff --git a/misc/cgo/test/issue5548.go b/misc/cgo/test/issue5548.go
new file mode 100644
index 000000000..b41f46562
--- /dev/null
+++ b/misc/cgo/test/issue5548.go
@@ -0,0 +1,26 @@
+// 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 cgotest
+
+import "testing"
+
+/*
+extern int issue5548_in_c(void);
+*/
+import "C"
+
+//export issue5548FromC
+func issue5548FromC(s string, i int) int {
+ if len(s) == 4 && s == "test" && i == 42 {
+ return 1
+ }
+ return 0
+}
+
+func test5548(t *testing.T) {
+ if C.issue5548_in_c() == 0 {
+ t.Fail()
+ }
+}
diff --git a/misc/cgo/test/issue5548_c.c b/misc/cgo/test/issue5548_c.c
new file mode 100644
index 000000000..ee9c45934
--- /dev/null
+++ b/misc/cgo/test/issue5548_c.c
@@ -0,0 +1,24 @@
+// 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"
+
+static void clobber_stack() {
+ volatile char a[1024];
+ int i;
+ for(i = 0; i < sizeof a; i++)
+ a[i] = 0xff;
+}
+
+static int call_go() {
+ GoString s;
+ s.p = "test";
+ s.n = 4;
+ return issue5548FromC(s, 42);
+}
+
+int issue5548_in_c() {
+ clobber_stack();
+ return call_go();
+}
diff --git a/misc/cgo/test/issue5603.go b/misc/cgo/test/issue5603.go
new file mode 100644
index 000000000..ecb2aa32e
--- /dev/null
+++ b/misc/cgo/test/issue5603.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.
+
+package cgotest
+
+/*
+const long long issue5603exp = 0x12345678;
+long long issue5603foo0() { return issue5603exp; }
+long long issue5603foo1(void *p) { return issue5603exp; }
+long long issue5603foo2(void *p, void *q) { return issue5603exp; }
+long long issue5603foo3(void *p, void *q, void *r) { return issue5603exp; }
+long long issue5603foo4(void *p, void *q, void *r, void *s) { return issue5603exp; }
+*/
+import "C"
+
+import "testing"
+
+func test5603(t *testing.T) {
+ var x [5]int64
+ exp := int64(C.issue5603exp)
+ x[0] = int64(C.issue5603foo0())
+ x[1] = int64(C.issue5603foo1(nil))
+ x[2] = int64(C.issue5603foo2(nil, nil))
+ x[3] = int64(C.issue5603foo3(nil, nil, nil))
+ x[4] = int64(C.issue5603foo4(nil, nil, nil, nil))
+ for i, v := range x {
+ if v != exp {
+ t.Errorf("issue5603foo%d() returns %v, expected %v", i, v, exp)
+ }
+ }
+}
diff --git a/misc/cgo/test/issue5740.go b/misc/cgo/test/issue5740.go
new file mode 100644
index 000000000..25c86153f
--- /dev/null
+++ b/misc/cgo/test/issue5740.go
@@ -0,0 +1,15 @@
+// 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 cgotest
+
+// int test5740a(void), test5740b(void);
+import "C"
+import "testing"
+
+func test5740(t *testing.T) {
+ if v := C.test5740a() + C.test5740b(); v != 5 {
+ t.Errorf("expected 5, got %v", v)
+ }
+}
diff --git a/misc/cgo/test/issue5740a.c b/misc/cgo/test/issue5740a.c
new file mode 100644
index 000000000..25f18e2a4
--- /dev/null
+++ b/misc/cgo/test/issue5740a.c
@@ -0,0 +1,9 @@
+// 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.
+
+static int volatile val = 2;
+
+int test5740a() {
+ return val;
+}
diff --git a/misc/cgo/test/issue5740b.c b/misc/cgo/test/issue5740b.c
new file mode 100644
index 000000000..22893f35b
--- /dev/null
+++ b/misc/cgo/test/issue5740b.c
@@ -0,0 +1,9 @@
+// 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.
+
+static int volatile val = 3;
+
+int test5740b() {
+ return val;
+}
diff --git a/misc/cgo/test/issue5986.go b/misc/cgo/test/issue5986.go
new file mode 100644
index 000000000..4f772cdb9
--- /dev/null
+++ b/misc/cgo/test/issue5986.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.
+
+package cgotest
+
+/*
+#cgo LDFLAGS: -lm
+#include <stdio.h>
+#include <math.h>
+
+static void output5986()
+{
+ int current_row = 0, row_count = 0;
+ double sum_squares = 0;
+ do {
+ if (current_row == 10) {
+ current_row = 0;
+ }
+ ++row_count;
+ }
+ while (current_row++ != 1);
+ double d = sqrt(sum_squares / row_count);
+ printf("sqrt is: %g\n", d);
+}
+*/
+import "C"
+import "testing"
+
+func test5986(t *testing.T) {
+ C.output5986()
+}
diff --git a/misc/cgo/test/issue6128.go b/misc/cgo/test/issue6128.go
new file mode 100644
index 000000000..4afba244f
--- /dev/null
+++ b/misc/cgo/test/issue6128.go
@@ -0,0 +1,20 @@
+// 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 cgotest
+
+// Test handling of #defined names in clang.
+// golang.org/issue/6128.
+
+/*
+// NOTE: Must use hex, or else a shortcut for decimals
+// in cgo avoids trying to pass this to clang.
+#define X 0x1
+*/
+import "C"
+
+func test6128() {
+ // nothing to run, just make sure this compiles.
+ _ = C.X
+}
diff --git a/misc/cgo/test/issue6390.go b/misc/cgo/test/issue6390.go
new file mode 100644
index 000000000..6f5715b05
--- /dev/null
+++ b/misc/cgo/test/issue6390.go
@@ -0,0 +1,23 @@
+// 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 cgotest
+
+// #include <stdlib.h>
+import "C"
+
+import "testing"
+
+func test6390(t *testing.T) {
+ p1 := C.malloc(1024)
+ if p1 == nil {
+ t.Fatalf("C.malloc(1024) returned nil")
+ }
+ p2 := C.malloc(0)
+ if p2 == nil {
+ t.Fatalf("C.malloc(0) returned nil")
+ }
+ C.free(p1)
+ C.free(p2)
+}
diff --git a/misc/cgo/test/issue6472.go b/misc/cgo/test/issue6472.go
new file mode 100644
index 000000000..cd94cac37
--- /dev/null
+++ b/misc/cgo/test/issue6472.go
@@ -0,0 +1,22 @@
+// 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 cgotest
+
+/*
+typedef struct
+{
+ struct
+ {
+ int x;
+ } y[16];
+} z;
+*/
+import "C"
+
+func test6472() {
+ // nothing to run, just make sure this compiles
+ s := new(C.z)
+ println(s.y[0].x)
+}
diff --git a/misc/cgo/test/issue6506.go b/misc/cgo/test/issue6506.go
new file mode 100644
index 000000000..b79e242e9
--- /dev/null
+++ b/misc/cgo/test/issue6506.go
@@ -0,0 +1,36 @@
+// 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 cgotest
+
+// Test handling of size_t in the face of incorrect clang debug information.
+// golang.org/issue/6506.
+
+/*
+#include <stdlib.h>
+#include <string.h>
+*/
+import "C"
+
+func test6506() {
+ // nothing to run, just make sure this compiles
+ var x C.size_t
+
+ C.calloc(x, x)
+ C.malloc(x)
+ C.realloc(nil, x)
+ C.memcpy(nil, nil, x)
+ C.memcmp(nil, nil, x)
+ C.memmove(nil, nil, x)
+ C.strncpy(nil, nil, x)
+ C.strncmp(nil, nil, x)
+ C.strncat(nil, nil, x)
+ x = C.strxfrm(nil, nil, x)
+ C.memchr(nil, 0, x)
+ x = C.strcspn(nil, nil)
+ x = C.strspn(nil, nil)
+ C.memset(nil, 0, x)
+ x = C.strlen(nil)
+ _ = x
+}
diff --git a/misc/cgo/test/issue6612.go b/misc/cgo/test/issue6612.go
new file mode 100644
index 000000000..902878c25
--- /dev/null
+++ b/misc/cgo/test/issue6612.go
@@ -0,0 +1,93 @@
+// 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.
+
+// golang.org/issue/6612
+// Test new scheme for deciding whether C.name is an expression, type, constant.
+// Clang silences some warnings when the name is a #defined macro, so test those too
+// (even though we now use errors exclusively, not warnings).
+
+package cgotest
+
+/*
+void myfunc(void) {}
+int myvar = 5;
+const char *mytext = "abcdef";
+typedef int mytype;
+enum {
+ myenum = 1234,
+};
+
+#define myfunc_def myfunc
+#define myvar_def myvar
+#define mytext_def mytext
+#define mytype_def mytype
+#define myenum_def myenum
+#define myint_def 12345
+#define myfloat_def 1.5
+#define mystring_def "hello"
+*/
+import "C"
+
+import "testing"
+
+func testNaming(t *testing.T) {
+ C.myfunc()
+ C.myfunc_def()
+ if v := C.myvar; v != 5 {
+ t.Errorf("C.myvar = %d, want 5", v)
+ }
+ if v := C.myvar_def; v != 5 {
+ t.Errorf("C.myvar_def = %d, want 5", v)
+ }
+ if s := C.GoString(C.mytext); s != "abcdef" {
+ t.Errorf("C.mytext = %q, want %q", s, "abcdef")
+ }
+ if s := C.GoString(C.mytext_def); s != "abcdef" {
+ t.Errorf("C.mytext_def = %q, want %q", s, "abcdef")
+ }
+ if c := C.myenum; c != 1234 {
+ t.Errorf("C.myenum = %v, want 1234", c)
+ }
+ if c := C.myenum_def; c != 1234 {
+ t.Errorf("C.myenum_def = %v, want 1234", c)
+ }
+ {
+ const c = C.myenum
+ if c != 1234 {
+ t.Errorf("C.myenum as const = %v, want 1234", c)
+ }
+ }
+ {
+ const c = C.myenum_def
+ if c != 1234 {
+ t.Errorf("C.myenum as const = %v, want 1234", c)
+ }
+ }
+ if c := C.myint_def; c != 12345 {
+ t.Errorf("C.myint_def = %v, want 12345", c)
+ }
+ {
+ const c = C.myint_def
+ if c != 12345 {
+ t.Errorf("C.myint as const = %v, want 12345", c)
+ }
+ }
+
+ // This would be nice, but it has never worked.
+ /*
+ if c := C.myfloat_def; c != 1.5 {
+ t.Errorf("C.myint_def = %v, want 1.5", c)
+ }
+ {
+ const c = C.myfloat_def
+ if c != 1.5 {
+ t.Errorf("C.myint as const = %v, want 1.5", c)
+ }
+ }
+ */
+
+ if s := C.mystring_def; s != "hello" {
+ t.Errorf("C.mystring_def = %q, want %q", s, "hello")
+ }
+}
diff --git a/misc/cgo/testasan/main.go b/misc/cgo/testasan/main.go
new file mode 100644
index 000000000..1837c6cc8
--- /dev/null
+++ b/misc/cgo/testasan/main.go
@@ -0,0 +1,49 @@
+// 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 main
+
+/*
+#include <sys/mman.h>
+#include <pthread.h>
+#include <unistd.h>
+
+void ctor(void) __attribute__((constructor));
+static void* thread(void*);
+
+void
+ctor(void)
+{
+ // occupy memory where Go runtime would normally map heap
+ mmap((void*)0x00c000000000, 64<<10, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0);
+
+ // allocate 4K every 10us
+ pthread_t t;
+ pthread_create(&t, 0, thread, 0);
+}
+
+static void*
+thread(void *p)
+{
+ for(;;) {
+ usleep(10000);
+ mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+ }
+ return 0;
+}
+*/
+import "C"
+
+import (
+ "time"
+)
+
+func main() {
+ // ensure that we can function normally
+ var v [][]byte
+ for i := 0; i < 1000; i++ {
+ time.Sleep(10 * time.Microsecond)
+ v = append(v, make([]byte, 64<<10))
+ }
+}
diff --git a/misc/cgo/testcdefs/cdefstest.c b/misc/cgo/testcdefs/cdefstest.c
new file mode 100644
index 000000000..10cdd66b6
--- /dev/null
+++ b/misc/cgo/testcdefs/cdefstest.c
@@ -0,0 +1,8 @@
+// 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 "runtime.h"
+#include "cdefstest.h"
+
+struct CdefsTest test;
diff --git a/misc/cgo/testcdefs/cdefstest.go b/misc/cgo/testcdefs/cdefstest.go
new file mode 100644
index 000000000..e6305b77d
--- /dev/null
+++ b/misc/cgo/testcdefs/cdefstest.go
@@ -0,0 +1,41 @@
+// 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 ignore
+
+package cgotest
+
+/*
+// This file tests a bug found in the cgo -cdefs tool that incorrectly
+// translated Go pointer arrays generated by the cgo godefs tool back into C
+// pointer arrays.
+//
+// The comments below show how the type is translated from gcc-style C into Go
+// and back into C for both the buggy version and the correct version
+
+struct cdefsTest {
+ // This was already being handled correctly
+ // Correct: -> Array [20]int8 -> int8 array[20]
+ char array1[20];
+
+ // Buggy: -> Array [20][20]int8 -> [20]int8 array[20]
+ // Correct: -> Array [20][20]int8 -> int8 array[20][20]
+ char array2[20][20];
+
+ // Buggy: -> Array [20]*int8 -> *int8 array[20]
+ // Correct: -> Array [20]*int8 -> int8 *array[20]
+ char *array3[20];
+
+ // Buggy: -> Array [20][20]*int8 -> [20]*int8 array[20]
+ // Correct: -> Array [20]**int8 -> int8 *array[20][20]
+ char *array4[20][20];
+
+ // Buggy: -> Array [20][20]**int8 -> [20]**int8 array[20]
+ // Correct: -> Array [20][20]**int8 -> int8 **array[20][20]
+ char **array5[20][20];
+};
+*/
+import "C"
+
+type CdefsTest C.struct_cdefsTest
diff --git a/misc/cgo/testcdefs/main.c b/misc/cgo/testcdefs/main.c
new file mode 100644
index 000000000..2d3ee4dbe
--- /dev/null
+++ b/misc/cgo/testcdefs/main.c
@@ -0,0 +1,48 @@
+// 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 "runtime.h"
+#include "cdefstest.h"
+
+void runtime·printf(int8*, ...);
+
+// From cdefstest.go.
+typedef struct CdefsOrig CdefsOrig;
+struct CdefsOrig {
+ int8 array1[20];
+ int8 array2[20][20];
+ int8 *array3[20];
+ int8 *array4[20][20];
+ int8 **array5[20][20];
+};
+
+void
+main·test(int32 ret)
+{
+ CdefsOrig o;
+ CdefsTest t;
+
+ ret = 0;
+ if(sizeof(t.array1) != sizeof(o.array1) || offsetof(CdefsTest, array1[0]) != offsetof(CdefsOrig, array1[0])) {
+ runtime·printf("array1: size, offset = %d, %d, want %d, %d\n", sizeof(t.array1), offsetof(CdefsTest, array1[0]), sizeof(o.array1), offsetof(CdefsOrig, array1[0]));
+ ret = 1;
+ }
+ if(sizeof(t.array2) != sizeof(o.array2) || offsetof(CdefsTest, array2[0][0]) != offsetof(CdefsOrig, array2[0][0])) {
+ runtime·printf("array2: size, offset = %d, %d, want %d, %d\n", sizeof(t.array2), offsetof(CdefsTest, array2[0][0]), sizeof(o.array2), offsetof(CdefsOrig, array2[0][0]));
+ ret = 1;
+ }
+ if(sizeof(t.array3) != sizeof(o.array3) || offsetof(CdefsTest, array3[0]) != offsetof(CdefsOrig, array3[0])) {
+ runtime·printf("array3: size, offset = %d, %d, want %d, %d\n", sizeof(t.array3), offsetof(CdefsTest, array3[0]), sizeof(o.array3), offsetof(CdefsOrig, array3[0]));
+ ret = 1;
+ }
+ if(sizeof(t.array4) != sizeof(o.array4) || offsetof(CdefsTest, array4[0][0]) != offsetof(CdefsOrig, array4[0][0])) {
+ runtime·printf("array4: size, offset = %d, %d, want %d, %d\n", sizeof(t.array4), offsetof(CdefsTest, array4[0][0]), sizeof(o.array4), offsetof(CdefsOrig, array4[0][0]));
+ ret = 1;
+ }
+ if(sizeof(t.array5) != sizeof(o.array5) || offsetof(CdefsTest, array5[0][0]) != offsetof(CdefsOrig, array5[0][0])) {
+ runtime·printf("array5: size, offset = %d, %d, want %d, %d\n", sizeof(t.array5), offsetof(CdefsTest, array5[0][0]), sizeof(o.array5), offsetof(CdefsOrig, array5[0][0]));
+ ret = 1;
+ }
+ FLUSH(&ret); // flush return value
+}
diff --git a/misc/cgo/testcdefs/main.go b/misc/cgo/testcdefs/main.go
new file mode 100644
index 000000000..9231741ad
--- /dev/null
+++ b/misc/cgo/testcdefs/main.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.
+
+package main
+
+import "os"
+
+func test() int32 // in main.c
+
+func main() {
+ os.Exit(int(test()))
+}
diff --git a/misc/cgo/testcdefs/test.bash b/misc/cgo/testcdefs/test.bash
new file mode 100755
index 000000000..1a14ad35c
--- /dev/null
+++ b/misc/cgo/testcdefs/test.bash
@@ -0,0 +1,16 @@
+# 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.
+
+# Just add issue file prefixes to this list if more issues come up
+FILE_PREFIXES="cdefstest"
+
+for FP in $FILE_PREFIXES
+do
+ go tool cgo -cdefs ${FP}.go > ${FP}.h
+done
+
+go build . && ./testcdefs
+EXIT=$?
+rm -rf _obj main *.h
+exit $EXIT
diff --git a/misc/cgo/testso/cgoso.go b/misc/cgo/testso/cgoso.go
index 216cb1f05..ba6218348 100644
--- a/misc/cgo/testso/cgoso.go
+++ b/misc/cgo/testso/cgoso.go
@@ -5,7 +5,16 @@
package cgosotest
/*
-#cgo LDFLAGS: -L. -lcgosotest
+// intentionally write the same LDFLAGS differently
+// to test correct handling of LDFLAGS.
+#cgo linux LDFLAGS: -L. -lcgosotest
+#cgo dragonfly LDFLAGS: -L. -l cgosotest
+#cgo freebsd LDFLAGS: -L. -l cgosotest
+#cgo openbsd LDFLAGS: -L. -l cgosotest
+#cgo netbsd LDFLAGS: -L. libcgosotest.so
+#cgo darwin LDFLAGS: -L. libcgosotest.dylib
+#cgo windows LDFLAGS: -L. libcgosotest.dll
+
void init(void);
void sofunc(void);
*/
diff --git a/misc/cgo/testso/test.bash b/misc/cgo/testso/test.bash
index 5f113d216..f4061c68e 100755
--- a/misc/cgo/testso/test.bash
+++ b/misc/cgo/testso/test.bash
@@ -1,10 +1,22 @@
-#!/bin/sh
+#!/usr/bin/env bash
# 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.
set -e
-$(go env CC) $(go env GOGCCFLAGS) -shared -o libcgosotest.so cgoso_c.c
+
+args=
+dyld_envvar=LD_LIBRARY_PATH
+ext=so
+if [ "$(uname)" == "Darwin" ]; then
+ args="-undefined suppress -flat_namespace"
+ dyld_envvar=DYLD_LIBRARY_PATH
+ ext=dylib
+fi
+
+dylib=libcgosotest.$ext
+$(go env CC) $(go env GOGCCFLAGS) -shared $args -o $dylib cgoso_c.c
go build main.go
-LD_LIBRARY_PATH=. ./main
-rm -f libcgosotest.so main
+
+eval "$dyld_envvar"=. ./main
+rm -rf $dylib main *.dSYM
diff --git a/misc/dashboard/README b/misc/dashboard/README
deleted file mode 100644
index d599f3d06..000000000
--- a/misc/dashboard/README
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright 2009 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-The files in this directory constitute the continuous builder:
-
-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
-
-To run a builder:
-
-* Write the key ~gobuild/.gobuildkey
- You need to get it from someone who knows the key.
- You may also use a filename of the form .gobuildkey-$BUILDER if you
- wish to run builders for multiple targets.
-
-* Append your username and password googlecode.com credentials from
- https://code.google.com/hosting/settings
- to the buildkey file in the format "Username\nPassword\n".
- (This is for uploading tarballs to the project downloads section,
- and is an optional step.)
-
-* Build and run gobuilder (see its documentation for command-line options).
-
diff --git a/misc/dashboard/app/app.yaml b/misc/dashboard/app/app.yaml
deleted file mode 100644
index c5a1f6cb8..000000000
--- a/misc/dashboard/app/app.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-# Update with
-# google_appengine/appcfg.py [-V test-build] update .
-#
-# Using -V test-build will run as test-build.golang.org.
-
-application: golang-org
-version: build
-runtime: go
-api_version: go1
-
-handlers:
-- url: /static
- static_dir: static
-- url: /log/.+
- script: _go_app
-- url: /(|commit|packages|result|tag|todo)
- script: _go_app
-- url: /(init|buildtest|key|_ah/queue/go/delay)
- script: _go_app
- login: admin
diff --git a/misc/dashboard/app/build/build.go b/misc/dashboard/app/build/build.go
deleted file mode 100644
index e0c0f0048..000000000
--- a/misc/dashboard/app/build/build.go
+++ /dev/null
@@ -1,330 +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.
-
-package build
-
-import (
- "bytes"
- "compress/gzip"
- "crypto/sha1"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "strings"
- "time"
-
- "appengine"
- "appengine/datastore"
-)
-
-const maxDatastoreStringLen = 500
-
-// A Package describes a package that is listed on the dashboard.
-type Package struct {
- Kind string // "subrepo", "external", or empty for the main Go tree
- Name string
- Path string // (empty for the main Go tree)
- NextNum int // Num of the next head Commit
-}
-
-func (p *Package) String() string {
- return fmt.Sprintf("%s: %q", p.Path, p.Name)
-}
-
-func (p *Package) Key(c appengine.Context) *datastore.Key {
- key := p.Path
- if key == "" {
- key = "go"
- }
- return datastore.NewKey(c, "Package", key, 0, nil)
-}
-
-// LastCommit returns the most recent Commit for this Package.
-func (p *Package) LastCommit(c appengine.Context) (*Commit, error) {
- var commits []*Commit
- _, err := datastore.NewQuery("Commit").
- Ancestor(p.Key(c)).
- Order("-Time").
- Limit(1).
- GetAll(c, &commits)
- if _, ok := err.(*datastore.ErrFieldMismatch); ok {
- // Some fields have been removed, so it's okay to ignore this error.
- err = nil
- }
- if err != nil {
- return nil, err
- }
- if len(commits) != 1 {
- return nil, datastore.ErrNoSuchEntity
- }
- return commits[0], nil
-}
-
-// GetPackage fetches a Package by path from the datastore.
-func GetPackage(c appengine.Context, path string) (*Package, error) {
- p := &Package{Path: path}
- err := datastore.Get(c, p.Key(c), p)
- if err == datastore.ErrNoSuchEntity {
- return nil, fmt.Errorf("package %q not found", path)
- }
- if _, ok := err.(*datastore.ErrFieldMismatch); ok {
- // Some fields have been removed, so it's okay to ignore this error.
- err = nil
- }
- return p, err
-}
-
-// A Commit describes an individual commit in a package.
-//
-// Each Commit entity is a descendant of its associated Package entity.
-// In other words, all Commits with the same PackagePath belong to the same
-// datastore entity group.
-type Commit struct {
- PackagePath string // (empty for Go commits)
- Hash string
- ParentHash string
- Num int // Internal monotonic counter unique to this package.
-
- User string
- Desc string `datastore:",noindex"`
- Time time.Time
-
- // ResultData is the Data string of each build Result for this Commit.
- // For non-Go commits, only the Results for the current Go tip, weekly,
- // and release Tags are stored here. This is purely de-normalized data.
- // The complete data set is stored in Result entities.
- ResultData []string `datastore:",noindex"`
-
- FailNotificationSent bool
-}
-
-func (com *Commit) Key(c appengine.Context) *datastore.Key {
- if com.Hash == "" {
- panic("tried Key on Commit with empty Hash")
- }
- p := Package{Path: com.PackagePath}
- key := com.PackagePath + "|" + com.Hash
- return datastore.NewKey(c, "Commit", key, 0, p.Key(c))
-}
-
-func (c *Commit) Valid() error {
- if !validHash(c.Hash) {
- return errors.New("invalid Hash")
- }
- if c.ParentHash != "" && !validHash(c.ParentHash) { // empty is OK
- return errors.New("invalid ParentHash")
- }
- return nil
-}
-
-// each result line is approx 105 bytes. This constant is a tradeoff between
-// build history and the AppEngine datastore limit of 1mb.
-const maxResults = 1000
-
-// AddResult adds the denormalized Reuslt data to the Commit's Result field.
-// It must be called from inside a datastore transaction.
-func (com *Commit) AddResult(c appengine.Context, r *Result) error {
- if err := datastore.Get(c, com.Key(c), com); err != nil {
- return fmt.Errorf("getting Commit: %v", err)
- }
- com.ResultData = trim(append(com.ResultData, r.Data()), maxResults)
- if _, err := datastore.Put(c, com.Key(c), com); err != nil {
- return fmt.Errorf("putting Commit: %v", err)
- }
- return nil
-}
-
-func trim(s []string, n int) []string {
- l := min(len(s), n)
- return s[len(s)-l:]
-}
-
-func min(a, b int) int {
- if a < b {
- return a
- }
- return b
-}
-
-// Result returns the build Result for this Commit for the given builder/goHash.
-func (c *Commit) Result(builder, goHash string) *Result {
- for _, r := range c.ResultData {
- p := strings.SplitN(r, "|", 4)
- if len(p) != 4 || p[0] != builder || p[3] != goHash {
- continue
- }
- return partsToHash(c, p)
- }
- return nil
-}
-
-// Results returns the build Results for this Commit for the given goHash.
-func (c *Commit) Results(goHash string) (results []*Result) {
- for _, r := range c.ResultData {
- p := strings.SplitN(r, "|", 4)
- if len(p) != 4 || p[3] != goHash {
- continue
- }
- results = append(results, partsToHash(c, p))
- }
- return
-}
-
-// partsToHash converts a Commit and ResultData substrings to a Result.
-func partsToHash(c *Commit, p []string) *Result {
- return &Result{
- Builder: p[0],
- Hash: c.Hash,
- PackagePath: c.PackagePath,
- GoHash: p[3],
- OK: p[1] == "true",
- LogHash: p[2],
- }
-}
-
-// A Result describes a build result for a Commit on an OS/architecture.
-//
-// Each Result entity is a descendant of its associated Commit entity.
-type Result struct {
- Builder string // "os-arch[-note]"
- Hash string
- PackagePath string // (empty for Go commits)
-
- // The Go Commit this was built against (empty for Go commits).
- GoHash string
-
- OK bool
- Log string `datastore:"-"` // for JSON unmarshaling only
- LogHash string `datastore:",noindex"` // Key to the Log record.
-
- RunTime int64 // time to build+test in nanoseconds
-}
-
-func (r *Result) Key(c appengine.Context) *datastore.Key {
- p := Package{Path: r.PackagePath}
- key := r.Builder + "|" + r.PackagePath + "|" + r.Hash + "|" + r.GoHash
- return datastore.NewKey(c, "Result", key, 0, p.Key(c))
-}
-
-func (r *Result) Valid() error {
- if !validHash(r.Hash) {
- return errors.New("invalid Hash")
- }
- if r.PackagePath != "" && !validHash(r.GoHash) {
- return errors.New("invalid GoHash")
- }
- return nil
-}
-
-// Data returns the Result in string format
-// to be stored in Commit's ResultData field.
-func (r *Result) Data() string {
- return fmt.Sprintf("%v|%v|%v|%v", r.Builder, r.OK, r.LogHash, r.GoHash)
-}
-
-// A Log is a gzip-compressed log file stored under the SHA1 hash of the
-// uncompressed log text.
-type Log struct {
- CompressedLog []byte
-}
-
-func (l *Log) Text() ([]byte, error) {
- d, err := gzip.NewReader(bytes.NewBuffer(l.CompressedLog))
- if err != nil {
- return nil, fmt.Errorf("reading log data: %v", err)
- }
- b, err := ioutil.ReadAll(d)
- if err != nil {
- return nil, fmt.Errorf("reading log data: %v", err)
- }
- return b, nil
-}
-
-func PutLog(c appengine.Context, text string) (hash string, err error) {
- h := sha1.New()
- io.WriteString(h, text)
- b := new(bytes.Buffer)
- z, _ := gzip.NewWriterLevel(b, gzip.BestCompression)
- io.WriteString(z, text)
- z.Close()
- hash = fmt.Sprintf("%x", h.Sum(nil))
- key := datastore.NewKey(c, "Log", hash, 0, nil)
- _, err = datastore.Put(c, key, &Log{b.Bytes()})
- return
-}
-
-// A Tag is used to keep track of the most recent Go weekly and release tags.
-// Typically there will be one Tag entity for each kind of hg tag.
-type Tag struct {
- Kind string // "weekly", "release", or "tip"
- Name string // the tag itself (for example: "release.r60")
- Hash string
-}
-
-func (t *Tag) Key(c appengine.Context) *datastore.Key {
- p := &Package{}
- return datastore.NewKey(c, "Tag", t.Kind, 0, p.Key(c))
-}
-
-func (t *Tag) Valid() error {
- if t.Kind != "weekly" && t.Kind != "release" && t.Kind != "tip" {
- return errors.New("invalid Kind")
- }
- if !validHash(t.Hash) {
- return errors.New("invalid Hash")
- }
- return nil
-}
-
-// Commit returns the Commit that corresponds with this Tag.
-func (t *Tag) Commit(c appengine.Context) (*Commit, error) {
- com := &Commit{Hash: t.Hash}
- err := datastore.Get(c, com.Key(c), com)
- return com, err
-}
-
-// GetTag fetches a Tag by name from the datastore.
-func GetTag(c appengine.Context, tag string) (*Tag, error) {
- t := &Tag{Kind: tag}
- if err := datastore.Get(c, t.Key(c), t); err != nil {
- if err == datastore.ErrNoSuchEntity {
- return nil, errors.New("tag not found: " + tag)
- }
- return nil, err
- }
- if err := t.Valid(); err != nil {
- return nil, err
- }
- return t, nil
-}
-
-// Packages returns packages of the specified kind.
-// Kind must be one of "external" or "subrepo".
-func Packages(c appengine.Context, kind string) ([]*Package, error) {
- switch kind {
- case "external", "subrepo":
- default:
- return nil, errors.New(`kind must be one of "external" or "subrepo"`)
- }
- var pkgs []*Package
- q := datastore.NewQuery("Package").Filter("Kind=", kind)
- for t := q.Run(c); ; {
- pkg := new(Package)
- _, err := t.Next(pkg)
- if _, ok := err.(*datastore.ErrFieldMismatch); ok {
- // Some fields have been removed, so it's okay to ignore this error.
- err = nil
- }
- if err == datastore.Done {
- break
- } else if err != nil {
- return nil, err
- }
- if pkg.Path != "" {
- pkgs = append(pkgs, pkg)
- }
- }
- return pkgs, nil
-}
diff --git a/misc/dashboard/app/build/handler.go b/misc/dashboard/app/build/handler.go
deleted file mode 100644
index 1a1118641..000000000
--- a/misc/dashboard/app/build/handler.go
+++ /dev/null
@@ -1,446 +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.
-
-package build
-
-import (
- "crypto/hmac"
- "crypto/md5"
- "encoding/json"
- "errors"
- "fmt"
- "net/http"
-
- "appengine"
- "appengine/datastore"
- "cache"
-)
-
-const commitsPerPage = 30
-
-// commitHandler retrieves commit data or records a new commit.
-//
-// For GET requests it returns a Commit value for the specified
-// packagePath and hash.
-//
-// For POST requests it reads a JSON-encoded Commit value from the request
-// body and creates a new Commit entity. It also updates the "tip" Tag for
-// each new commit at tip.
-//
-// This handler is used by a gobuilder process in -commit mode.
-func commitHandler(r *http.Request) (interface{}, error) {
- c := appengine.NewContext(r)
- com := new(Commit)
-
- if r.Method == "GET" {
- com.PackagePath = r.FormValue("packagePath")
- com.Hash = r.FormValue("hash")
- if err := datastore.Get(c, com.Key(c), com); err != nil {
- return nil, fmt.Errorf("getting Commit: %v", err)
- }
- return com, nil
- }
- if r.Method != "POST" {
- return nil, errBadMethod(r.Method)
- }
-
- // POST request
- defer r.Body.Close()
- if err := json.NewDecoder(r.Body).Decode(com); err != nil {
- return nil, fmt.Errorf("decoding Body: %v", err)
- }
- if len(com.Desc) > maxDatastoreStringLen {
- com.Desc = com.Desc[:maxDatastoreStringLen]
- }
- if err := com.Valid(); err != nil {
- return nil, fmt.Errorf("validating Commit: %v", err)
- }
- defer cache.Tick(c)
- tx := func(c appengine.Context) error {
- return addCommit(c, com)
- }
- return nil, datastore.RunInTransaction(c, tx, nil)
-}
-
-// addCommit adds the Commit entity to the datastore and updates the tip Tag.
-// It must be run inside a datastore transaction.
-func addCommit(c appengine.Context, com *Commit) error {
- var tc Commit // temp value so we don't clobber com
- err := datastore.Get(c, com.Key(c), &tc)
- if err != datastore.ErrNoSuchEntity {
- // if this commit is already in the datastore, do nothing
- if err == nil {
- return nil
- }
- return fmt.Errorf("getting Commit: %v", err)
- }
- // get the next commit number
- p, err := GetPackage(c, com.PackagePath)
- if err != nil {
- return fmt.Errorf("GetPackage: %v", err)
- }
- com.Num = p.NextNum
- p.NextNum++
- if _, err := datastore.Put(c, p.Key(c), p); err != nil {
- return fmt.Errorf("putting Package: %v", err)
- }
- // if this isn't the first Commit test the parent commit exists
- if com.Num > 0 {
- n, err := datastore.NewQuery("Commit").
- Filter("Hash =", com.ParentHash).
- Ancestor(p.Key(c)).
- Count(c)
- if err != nil {
- return fmt.Errorf("testing for parent Commit: %v", err)
- }
- if n == 0 {
- return errors.New("parent commit not found")
- }
- }
- // update the tip Tag if this is the Go repo
- if p.Path == "" {
- t := &Tag{Kind: "tip", Hash: com.Hash}
- if _, err = datastore.Put(c, t.Key(c), t); err != nil {
- return fmt.Errorf("putting Tag: %v", err)
- }
- }
- // put the Commit
- if _, err = datastore.Put(c, com.Key(c), com); err != nil {
- return fmt.Errorf("putting Commit: %v", err)
- }
- return nil
-}
-
-// tagHandler records a new tag. It reads a JSON-encoded Tag value from the
-// request body and updates the Tag entity for the Kind of tag provided.
-//
-// This handler is used by a gobuilder process in -commit mode.
-func tagHandler(r *http.Request) (interface{}, error) {
- if r.Method != "POST" {
- return nil, errBadMethod(r.Method)
- }
-
- t := new(Tag)
- defer r.Body.Close()
- if err := json.NewDecoder(r.Body).Decode(t); err != nil {
- return nil, err
- }
- if err := t.Valid(); err != nil {
- return nil, err
- }
- c := appengine.NewContext(r)
- defer cache.Tick(c)
- _, err := datastore.Put(c, t.Key(c), t)
- return nil, err
-}
-
-// Todo is a todoHandler response.
-type Todo struct {
- Kind string // "build-go-commit" or "build-package"
- Data interface{}
-}
-
-// todoHandler returns the next action to be performed by a builder.
-// It expects "builder" and "kind" query parameters and returns a *Todo value.
-// Multiple "kind" parameters may be specified.
-func todoHandler(r *http.Request) (interface{}, error) {
- c := appengine.NewContext(r)
- now := cache.Now(c)
- key := "build-todo-" + r.Form.Encode()
- var todo *Todo
- if cache.Get(r, now, key, &todo) {
- return todo, nil
- }
- var err error
- builder := r.FormValue("builder")
- for _, kind := range r.Form["kind"] {
- var data interface{}
- switch kind {
- case "build-go-commit":
- data, err = buildTodo(c, builder, "", "")
- case "build-package":
- packagePath := r.FormValue("packagePath")
- goHash := r.FormValue("goHash")
- data, err = buildTodo(c, builder, packagePath, goHash)
- }
- if data != nil || err != nil {
- todo = &Todo{Kind: kind, Data: data}
- break
- }
- }
- if err == nil {
- cache.Set(r, now, key, todo)
- }
- return todo, err
-}
-
-// buildTodo returns the next Commit to be built (or nil if none available).
-//
-// If packagePath and goHash are empty, it scans the first 20 Go Commits in
-// Num-descending order and returns the first one it finds that doesn't have a
-// Result for this builder.
-//
-// If provided with non-empty packagePath and goHash args, it scans the first
-// 20 Commits in Num-descending order for the specified packagePath and
-// returns the first that doesn't have a Result for this builder and goHash.
-func buildTodo(c appengine.Context, builder, packagePath, goHash string) (interface{}, error) {
- p, err := GetPackage(c, packagePath)
- if err != nil {
- return nil, err
- }
-
- t := datastore.NewQuery("Commit").
- Ancestor(p.Key(c)).
- Limit(commitsPerPage).
- Order("-Num").
- Run(c)
- for {
- com := new(Commit)
- if _, err := t.Next(com); err == datastore.Done {
- break
- } else if err != nil {
- return nil, err
- }
- if com.Result(builder, goHash) == nil {
- return com, nil
- }
- }
-
- // Nothing left to do if this is a package (not the Go tree).
- if packagePath != "" {
- return nil, nil
- }
-
- // If there are no Go tree commits left to build,
- // see if there are any subrepo commits that need to be built at tip.
- // If so, ask the builder to build a go tree at the tip commit.
- // TODO(adg): do the same for "weekly" and "release" tags.
-
- tag, err := GetTag(c, "tip")
- if err != nil {
- return nil, err
- }
-
- // Check that this Go commit builds OK for this builder.
- // If not, don't re-build as the subrepos will never get built anyway.
- com, err := tag.Commit(c)
- if err != nil {
- return nil, err
- }
- if r := com.Result(builder, ""); r != nil && !r.OK {
- return nil, nil
- }
-
- pkgs, err := Packages(c, "subrepo")
- if err != nil {
- return nil, err
- }
- for _, pkg := range pkgs {
- com, err := pkg.LastCommit(c)
- if err != nil {
- c.Warningf("%v: no Commit found: %v", pkg, err)
- continue
- }
- if com.Result(builder, tag.Hash) == nil {
- return tag.Commit(c)
- }
- }
-
- return nil, nil
-}
-
-// packagesHandler returns a list of the non-Go Packages monitored
-// by the dashboard.
-func packagesHandler(r *http.Request) (interface{}, error) {
- kind := r.FormValue("kind")
- c := appengine.NewContext(r)
- now := cache.Now(c)
- key := "build-packages-" + kind
- var p []*Package
- if cache.Get(r, now, key, &p) {
- return p, nil
- }
- p, err := Packages(c, kind)
- if err != nil {
- return nil, err
- }
- cache.Set(r, now, key, p)
- return p, nil
-}
-
-// resultHandler records a build result.
-// It reads a JSON-encoded Result value from the request body,
-// creates a new Result entity, and updates the relevant Commit entity.
-// If the Log field is not empty, resultHandler creates a new Log entity
-// and updates the LogHash field before putting the Commit entity.
-func resultHandler(r *http.Request) (interface{}, error) {
- if r.Method != "POST" {
- return nil, errBadMethod(r.Method)
- }
-
- c := appengine.NewContext(r)
- res := new(Result)
- defer r.Body.Close()
- if err := json.NewDecoder(r.Body).Decode(res); err != nil {
- return nil, fmt.Errorf("decoding Body: %v", err)
- }
- if err := res.Valid(); err != nil {
- return nil, fmt.Errorf("validating Result: %v", err)
- }
- defer cache.Tick(c)
- // store the Log text if supplied
- if len(res.Log) > 0 {
- hash, err := PutLog(c, res.Log)
- if err != nil {
- return nil, fmt.Errorf("putting Log: %v", err)
- }
- res.LogHash = hash
- }
- tx := func(c appengine.Context) error {
- // check Package exists
- if _, err := GetPackage(c, res.PackagePath); err != nil {
- return fmt.Errorf("GetPackage: %v", err)
- }
- // put Result
- if _, err := datastore.Put(c, res.Key(c), res); err != nil {
- return fmt.Errorf("putting Result: %v", err)
- }
- // add Result to Commit
- com := &Commit{PackagePath: res.PackagePath, Hash: res.Hash}
- if err := com.AddResult(c, res); err != nil {
- return fmt.Errorf("AddResult: %v", err)
- }
- // Send build failure notifications, if necessary.
- // Note this must run after the call AddResult, which
- // populates the Commit's ResultData field.
- return notifyOnFailure(c, com, res.Builder)
- }
- return nil, datastore.RunInTransaction(c, tx, nil)
-}
-
-// logHandler displays log text for a given hash.
-// It handles paths like "/log/hash".
-func logHandler(w http.ResponseWriter, r *http.Request) {
- w.Header().Set("Content-type", "text/plain; charset=utf-8")
- c := appengine.NewContext(r)
- hash := r.URL.Path[len("/log/"):]
- key := datastore.NewKey(c, "Log", hash, 0, nil)
- l := new(Log)
- if err := datastore.Get(c, key, l); err != nil {
- logErr(w, r, err)
- return
- }
- b, err := l.Text()
- if err != nil {
- logErr(w, r, err)
- return
- }
- w.Write(b)
-}
-
-type dashHandler func(*http.Request) (interface{}, error)
-
-type dashResponse struct {
- Response interface{}
- Error string
-}
-
-// errBadMethod is returned by a dashHandler when
-// the request has an unsuitable method.
-type errBadMethod string
-
-func (e errBadMethod) Error() string {
- return "bad method: " + string(e)
-}
-
-// AuthHandler wraps a http.HandlerFunc with a handler that validates the
-// supplied key and builder query parameters.
-func AuthHandler(h dashHandler) http.HandlerFunc {
- return func(w http.ResponseWriter, r *http.Request) {
- c := appengine.NewContext(r)
-
- // Put the URL Query values into r.Form to avoid parsing the
- // request body when calling r.FormValue.
- r.Form = r.URL.Query()
-
- var err error
- var resp interface{}
-
- // Validate key query parameter for POST requests only.
- key := r.FormValue("key")
- builder := r.FormValue("builder")
- if r.Method == "POST" && !validKey(c, key, builder) {
- err = errors.New("invalid key: " + key)
- }
-
- // Call the original HandlerFunc and return the response.
- if err == nil {
- resp, err = h(r)
- }
-
- // Write JSON response.
- dashResp := &dashResponse{Response: resp}
- if err != nil {
- c.Errorf("%v", err)
- dashResp.Error = err.Error()
- }
- w.Header().Set("Content-Type", "application/json")
- if err = json.NewEncoder(w).Encode(dashResp); err != nil {
- c.Criticalf("encoding response: %v", err)
- }
- }
-}
-
-func keyHandler(w http.ResponseWriter, r *http.Request) {
- builder := r.FormValue("builder")
- if builder == "" {
- logErr(w, r, errors.New("must supply builder in query string"))
- return
- }
- c := appengine.NewContext(r)
- fmt.Fprint(w, builderKey(c, builder))
-}
-
-func init() {
- // admin handlers
- http.HandleFunc("/init", initHandler)
- http.HandleFunc("/key", keyHandler)
-
- // authenticated handlers
- http.HandleFunc("/commit", AuthHandler(commitHandler))
- http.HandleFunc("/packages", AuthHandler(packagesHandler))
- http.HandleFunc("/result", AuthHandler(resultHandler))
- http.HandleFunc("/tag", AuthHandler(tagHandler))
- http.HandleFunc("/todo", AuthHandler(todoHandler))
-
- // public handlers
- http.HandleFunc("/log/", logHandler)
-}
-
-func validHash(hash string) bool {
- // TODO(adg): correctly validate a hash
- return hash != ""
-}
-
-func validKey(c appengine.Context, key, builder string) bool {
- if appengine.IsDevAppServer() {
- return true
- }
- if key == secretKey(c) {
- return true
- }
- return key == builderKey(c, builder)
-}
-
-func builderKey(c appengine.Context, builder string) string {
- h := hmac.New(md5.New, []byte(secretKey(c)))
- h.Write([]byte(builder))
- return fmt.Sprintf("%x", h.Sum(nil))
-}
-
-func logErr(w http.ResponseWriter, r *http.Request, err error) {
- appengine.NewContext(r).Errorf("Error: %v", err)
- w.WriteHeader(http.StatusInternalServerError)
- fmt.Fprint(w, "Error: ", err)
-}
diff --git a/misc/dashboard/app/build/init.go b/misc/dashboard/app/build/init.go
deleted file mode 100644
index 505f96fc4..000000000
--- a/misc/dashboard/app/build/init.go
+++ /dev/null
@@ -1,65 +0,0 @@
-// Copyright 2012 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 build
-
-import (
- "fmt"
- "net/http"
-
- "appengine"
- "appengine/datastore"
- "cache"
-)
-
-// defaultPackages specifies the Package records to be created by initHandler.
-var defaultPackages = []*Package{
- {Name: "Go", Kind: "go"},
-}
-
-// subRepos specifies the Go project sub-repositories.
-var subRepos = []string{
- "blog",
- "codereview",
- "crypto",
- "exp",
- "image",
- "net",
- "talks",
-}
-
-// Put subRepos into defaultPackages.
-func init() {
- for _, name := range subRepos {
- p := &Package{
- Kind: "subrepo",
- Name: "go." + name,
- Path: "code.google.com/p/go." + name,
- }
- defaultPackages = append(defaultPackages, p)
- }
-}
-
-func initHandler(w http.ResponseWriter, r *http.Request) {
- c := appengine.NewContext(r)
- defer cache.Tick(c)
- for _, p := range defaultPackages {
- err := datastore.Get(c, p.Key(c), new(Package))
- if _, ok := err.(*datastore.ErrFieldMismatch); ok {
- // Some fields have been removed, so it's okay to ignore this error.
- err = nil
- }
- if err == nil {
- continue
- } else if err != datastore.ErrNoSuchEntity {
- logErr(w, r, err)
- return
- }
- if _, err := datastore.Put(c, p.Key(c), p); err != nil {
- logErr(w, r, err)
- return
- }
- }
- fmt.Fprint(w, "OK")
-}
diff --git a/misc/dashboard/app/build/key.go b/misc/dashboard/app/build/key.go
deleted file mode 100644
index 49ab236d4..000000000
--- a/misc/dashboard/app/build/key.go
+++ /dev/null
@@ -1,62 +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.
-
-package build
-
-import (
- "sync"
-
- "appengine"
- "appengine/datastore"
-)
-
-var theKey struct {
- sync.RWMutex
- BuilderKey
-}
-
-type BuilderKey struct {
- Secret string
-}
-
-func (k *BuilderKey) Key(c appengine.Context) *datastore.Key {
- return datastore.NewKey(c, "BuilderKey", "root", 0, nil)
-}
-
-func secretKey(c appengine.Context) string {
- // check with rlock
- theKey.RLock()
- k := theKey.Secret
- theKey.RUnlock()
- if k != "" {
- return k
- }
-
- // prepare to fill; check with lock and keep lock
- theKey.Lock()
- defer theKey.Unlock()
- if theKey.Secret != "" {
- return theKey.Secret
- }
-
- // fill
- if err := datastore.Get(c, theKey.Key(c), &theKey.BuilderKey); err != nil {
- if err == datastore.ErrNoSuchEntity {
- // If the key is not stored in datastore, write it.
- // This only happens at the beginning of a new deployment.
- // The code is left here for SDK use and in case a fresh
- // deployment is ever needed. "gophers rule" is not the
- // real key.
- if !appengine.IsDevAppServer() {
- panic("lost key from datastore")
- }
- theKey.Secret = "gophers rule"
- datastore.Put(c, theKey.Key(c), &theKey.BuilderKey)
- return theKey.Secret
- }
- panic("cannot load builder key: " + err.Error())
- }
-
- return theKey.Secret
-}
diff --git a/misc/dashboard/app/build/notify.go b/misc/dashboard/app/build/notify.go
deleted file mode 100644
index 52b91f6c1..000000000
--- a/misc/dashboard/app/build/notify.go
+++ /dev/null
@@ -1,166 +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.
-
-package build
-
-import (
- "appengine"
- "appengine/datastore"
- "appengine/delay"
- "appengine/mail"
- "bytes"
- "encoding/gob"
- "fmt"
- "text/template"
-)
-
-const (
- mailFrom = "builder@golang.org" // use this for sending any mail
- failMailTo = "golang-dev@googlegroups.com"
- domain = "build.golang.org"
-)
-
-// failIgnore is a set of builders that we don't email about because
-// they're too flaky.
-var failIgnore = map[string]bool{
- "netbsd-386-bsiegert": true,
- "netbsd-amd64-bsiegert": true,
-}
-
-// notifyOnFailure checks whether the supplied Commit or the subsequent
-// Commit (if present) breaks the build for this builder.
-// If either of those commits break the build an email notification is sent
-// from a delayed task. (We use a task because this way the mail won't be
-// sent if the enclosing datastore transaction fails.)
-//
-// This must be run in a datastore transaction, and the provided *Commit must
-// have been retrieved from the datastore within that transaction.
-func notifyOnFailure(c appengine.Context, com *Commit, builder string) error {
- if failIgnore[builder] {
- return nil
- }
-
- // TODO(adg): implement notifications for packages
- if com.PackagePath != "" {
- return nil
- }
-
- p := &Package{Path: com.PackagePath}
- var broken *Commit
- cr := com.Result(builder, "")
- if cr == nil {
- return fmt.Errorf("no result for %s/%s", com.Hash, builder)
- }
- q := datastore.NewQuery("Commit").Ancestor(p.Key(c))
- if cr.OK {
- // This commit is OK. Notify if next Commit is broken.
- next := new(Commit)
- q = q.Filter("ParentHash=", com.Hash)
- if err := firstMatch(c, q, next); err != nil {
- if err == datastore.ErrNoSuchEntity {
- // OK at tip, no notification necessary.
- return nil
- }
- return err
- }
- if nr := next.Result(builder, ""); nr != nil && !nr.OK {
- c.Debugf("commit ok: %#v\nresult: %#v", com, cr)
- c.Debugf("next commit broken: %#v\nnext result:%#v", next, nr)
- broken = next
- }
- } else {
- // This commit is broken. Notify if the previous Commit is OK.
- prev := new(Commit)
- q = q.Filter("Hash=", com.ParentHash)
- if err := firstMatch(c, q, prev); err != nil {
- if err == datastore.ErrNoSuchEntity {
- // No previous result, let the backfill of
- // this result trigger the notification.
- return nil
- }
- return err
- }
- if pr := prev.Result(builder, ""); pr != nil && pr.OK {
- c.Debugf("commit broken: %#v\nresult: %#v", com, cr)
- c.Debugf("previous commit ok: %#v\nprevious result:%#v", prev, pr)
- broken = com
- }
- }
- var err error
- if broken != nil && !broken.FailNotificationSent {
- c.Infof("%s is broken commit; notifying", broken.Hash)
- sendFailMailLater.Call(c, broken, builder) // add task to queue
- broken.FailNotificationSent = true
- _, err = datastore.Put(c, broken.Key(c), broken)
- }
- return err
-}
-
-// firstMatch executes the query q and loads the first entity into v.
-func firstMatch(c appengine.Context, q *datastore.Query, v interface{}) error {
- t := q.Limit(1).Run(c)
- _, err := t.Next(v)
- if err == datastore.Done {
- err = datastore.ErrNoSuchEntity
- }
- return err
-}
-
-var (
- sendFailMailLater = delay.Func("sendFailMail", sendFailMail)
- sendFailMailTmpl = template.Must(
- template.New("notify.txt").
- Funcs(template.FuncMap(tmplFuncs)).
- ParseFiles("build/notify.txt"),
- )
-)
-
-func init() {
- gob.Register(&Commit{}) // for delay
-}
-
-// sendFailMail sends a mail notification that the build failed on the
-// provided commit and builder.
-func sendFailMail(c appengine.Context, com *Commit, builder string) {
- // TODO(adg): handle packages
-
- // get Result
- r := com.Result(builder, "")
- if r == nil {
- c.Errorf("finding result for %q: %+v", builder, com)
- return
- }
-
- // get Log
- k := datastore.NewKey(c, "Log", r.LogHash, 0, nil)
- l := new(Log)
- if err := datastore.Get(c, k, l); err != nil {
- c.Errorf("finding Log record %v: %v", r.LogHash, err)
- return
- }
-
- // prepare mail message
- var body bytes.Buffer
- err := sendFailMailTmpl.Execute(&body, map[string]interface{}{
- "Builder": builder, "Commit": com, "Result": r, "Log": l,
- "Hostname": domain,
- })
- if err != nil {
- c.Errorf("rendering mail template: %v", err)
- return
- }
- subject := fmt.Sprintf("%s broken by %s", builder, shortDesc(com.Desc))
- msg := &mail.Message{
- Sender: mailFrom,
- To: []string{failMailTo},
- ReplyTo: failMailTo,
- Subject: subject,
- Body: body.String(),
- }
-
- // send mail
- if err := mail.Send(c, msg); err != nil {
- c.Errorf("sending mail: %v", err)
- }
-}
diff --git a/misc/dashboard/app/build/notify.txt b/misc/dashboard/app/build/notify.txt
deleted file mode 100644
index 6c9006703..000000000
--- a/misc/dashboard/app/build/notify.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Change {{shortHash .Commit.Hash}} broke the {{.Builder}} build:
-http://{{.Hostname}}/log/{{.Result.LogHash}}
-
-{{.Commit.Desc}}
-
-http://code.google.com/p/go/source/detail?r={{shortHash .Commit.Hash}}
-
-$ tail -200 < log
-{{printf "%s" .Log.Text | tail 200}}
diff --git a/misc/dashboard/app/build/test.go b/misc/dashboard/app/build/test.go
deleted file mode 100644
index 7e5539236..000000000
--- a/misc/dashboard/app/build/test.go
+++ /dev/null
@@ -1,256 +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.
-
-package build
-
-// TODO(adg): test authentication
-
-import (
- "appengine"
- "appengine/datastore"
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "net/http"
- "net/http/httptest"
- "net/url"
- "strings"
- "time"
-)
-
-func init() {
- http.HandleFunc("/buildtest", testHandler)
-}
-
-var testEntityKinds = []string{
- "Package",
- "Commit",
- "Result",
- "Log",
-}
-
-const testPkg = "code.google.com/p/go.test"
-
-var testPackage = &Package{Name: "Test", Kind: "subrepo", Path: testPkg}
-
-var testPackages = []*Package{
- {Name: "Go", Path: ""},
- testPackage,
-}
-
-var tCommitTime = time.Now().Add(-time.Hour * 24 * 7)
-
-func tCommit(hash, parentHash, path string) *Commit {
- tCommitTime.Add(time.Hour) // each commit should have a different time
- return &Commit{
- PackagePath: path,
- Hash: hash,
- ParentHash: parentHash,
- Time: tCommitTime,
- User: "adg",
- Desc: "change description " + hash,
- }
-}
-
-var testRequests = []struct {
- path string
- vals url.Values
- req interface{}
- res interface{}
-}{
- // Packages
- {"/packages?kind=subrepo", nil, nil, []*Package{testPackage}},
-
- // Go repo
- {"/commit", nil, tCommit("0001", "0000", ""), nil},
- {"/commit", nil, tCommit("0002", "0001", ""), nil},
- {"/commit", nil, tCommit("0003", "0002", ""), nil},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
- {"/result", nil, &Result{Builder: "linux-386", Hash: "0001", OK: true}, nil},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
- {"/result", nil, &Result{Builder: "linux-386", Hash: "0002", OK: true}, nil},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
-
- // multiple builders
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
- {"/result", nil, &Result{Builder: "linux-amd64", Hash: "0003", OK: true}, nil},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-amd64"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0002"}}},
-
- // branches
- {"/commit", nil, tCommit("0004", "0003", ""), nil},
- {"/commit", nil, tCommit("0005", "0002", ""), nil},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
- {"/result", nil, &Result{Builder: "linux-386", Hash: "0005", OK: true}, nil},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0004"}}},
- {"/result", nil, &Result{Builder: "linux-386", Hash: "0004", OK: false}, nil},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0003"}}},
-
- // logs
- {"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},
- {"/log/a94a8fe5ccb19ba61c4c0873d391e987982fbbd3", nil, nil, "test"},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},
-
- // repeat failure (shouldn't re-send mail)
- {"/result", nil, &Result{Builder: "linux-386", Hash: "0003", OK: false, Log: "test"}, nil},
-
- // non-Go repos
- {"/commit", nil, tCommit("1001", "1000", testPkg), nil},
- {"/commit", nil, tCommit("1002", "1001", testPkg), nil},
- {"/commit", nil, tCommit("1003", "1002", testPkg), nil},
- {"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},
- {"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1003", GoHash: "0001", OK: true}, nil},
- {"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1002"}}},
- {"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1002", GoHash: "0001", OK: true}, nil},
- {"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1001"}}},
- {"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0001", OK: true}, nil},
- {"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0001"}}, nil, nil},
- {"/todo", url.Values{"kind": {"build-package"}, "builder": {"linux-386"}, "packagePath": {testPkg}, "goHash": {"0002"}}, nil, &Todo{Kind: "build-package", Data: &Commit{Hash: "1003"}}},
-
- // re-build Go revision for stale subrepos
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, &Todo{Kind: "build-go-commit", Data: &Commit{Hash: "0005"}}},
- {"/result", nil, &Result{PackagePath: testPkg, Builder: "linux-386", Hash: "1001", GoHash: "0005", OK: false, Log: "boo"}, nil},
- {"/todo", url.Values{"kind": {"build-go-commit"}, "builder": {"linux-386"}}, nil, nil},
-}
-
-func testHandler(w http.ResponseWriter, r *http.Request) {
- if !appengine.IsDevAppServer() {
- fmt.Fprint(w, "These tests must be run under the dev_appserver.")
- return
- }
- c := appengine.NewContext(r)
- if err := nukeEntities(c, testEntityKinds); err != nil {
- logErr(w, r, err)
- return
- }
- if r.FormValue("nukeonly") != "" {
- fmt.Fprint(w, "OK")
- return
- }
-
- for _, p := range testPackages {
- if _, err := datastore.Put(c, p.Key(c), p); err != nil {
- logErr(w, r, err)
- return
- }
- }
-
- for i, t := range testRequests {
- c.Infof("running test %d %s", i, t.path)
- errorf := func(format string, args ...interface{}) {
- fmt.Fprintf(w, "%d %s: ", i, t.path)
- fmt.Fprintf(w, format, args...)
- fmt.Fprintln(w)
- }
- var body io.ReadWriter
- if t.req != nil {
- body = new(bytes.Buffer)
- json.NewEncoder(body).Encode(t.req)
- }
- url := "http://" + domain + t.path
- if t.vals != nil {
- url += "?" + t.vals.Encode()
- }
- req, err := http.NewRequest("POST", url, body)
- if err != nil {
- logErr(w, r, err)
- return
- }
- if t.req != nil {
- req.Method = "POST"
- }
- req.Header = r.Header
- rec := httptest.NewRecorder()
-
- // Make the request
- http.DefaultServeMux.ServeHTTP(rec, req)
-
- if rec.Code != 0 && rec.Code != 200 {
- errorf(rec.Body.String())
- return
- }
- resp := new(dashResponse)
-
- // If we're expecting a *Todo value,
- // prime the Response field with a Todo and a Commit inside it.
- if _, ok := t.res.(*Todo); ok {
- resp.Response = &Todo{Data: &Commit{}}
- }
-
- if strings.HasPrefix(t.path, "/log/") {
- resp.Response = rec.Body.String()
- } else {
- err := json.NewDecoder(rec.Body).Decode(resp)
- if err != nil {
- errorf("decoding response: %v", err)
- return
- }
- }
- if e, ok := t.res.(string); ok {
- g, ok := resp.Response.(string)
- if !ok {
- errorf("Response not string: %T", resp.Response)
- return
- }
- if g != e {
- errorf("response mismatch: got %q want %q", g, e)
- return
- }
- }
- if e, ok := t.res.(*Todo); ok {
- g, ok := resp.Response.(*Todo)
- if !ok {
- errorf("Response not *Todo: %T", resp.Response)
- return
- }
- if e.Data == nil && g.Data != nil {
- errorf("Response.Data should be nil, got: %v", g.Data)
- return
- }
- if g.Data == nil {
- errorf("Response.Data is nil, want: %v", e.Data)
- return
- }
- gd, ok := g.Data.(*Commit)
- if !ok {
- errorf("Response.Data not *Commit: %T", g.Data)
- return
- }
- if eh := e.Data.(*Commit).Hash; eh != gd.Hash {
- errorf("hashes don't match: got %q, want %q", gd.Hash, eh)
- return
- }
- }
- if t.res == nil && resp.Response != nil {
- errorf("response mismatch: got %q expected <nil>",
- resp.Response)
- return
- }
- }
- fmt.Fprint(w, "PASS\nYou should see only one mail notification (for 0003/linux-386) in the dev_appserver logs.")
-}
-
-func nukeEntities(c appengine.Context, kinds []string) error {
- if !appengine.IsDevAppServer() {
- return errors.New("can't nuke production data")
- }
- var keys []*datastore.Key
- for _, kind := range kinds {
- q := datastore.NewQuery(kind).KeysOnly()
- for t := q.Run(c); ; {
- k, err := t.Next(nil)
- if err == datastore.Done {
- break
- }
- if err != nil {
- return err
- }
- keys = append(keys, k)
- }
- }
- return datastore.DeleteMulti(c, keys)
-}
diff --git a/misc/dashboard/app/build/ui.go b/misc/dashboard/app/build/ui.go
deleted file mode 100644
index cc3629a5a..000000000
--- a/misc/dashboard/app/build/ui.go
+++ /dev/null
@@ -1,319 +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.
-
-// TODO(adg): packages at weekly/release
-// TODO(adg): some means to register new packages
-
-package build
-
-import (
- "bytes"
- "errors"
- "html/template"
- "net/http"
- "regexp"
- "sort"
- "strconv"
- "strings"
-
- "appengine"
- "appengine/datastore"
- "cache"
-)
-
-func init() {
- http.HandleFunc("/", uiHandler)
-}
-
-// uiHandler draws the build status page.
-func uiHandler(w http.ResponseWriter, r *http.Request) {
- c := appengine.NewContext(r)
- now := cache.Now(c)
- const key = "build-ui"
-
- page, _ := strconv.Atoi(r.FormValue("page"))
- if page < 0 {
- page = 0
- }
-
- // Used cached version of front page, if available.
- if page == 0 {
- var b []byte
- if cache.Get(r, now, key, &b) {
- w.Write(b)
- return
- }
- }
-
- commits, err := goCommits(c, page)
- if err != nil {
- logErr(w, r, err)
- return
- }
- builders := commitBuilders(commits, "")
-
- var tipState *TagState
- if page == 0 {
- // only show sub-repo state on first page
- tipState, err = TagStateByName(c, "tip")
- if err != nil {
- logErr(w, r, err)
- return
- }
- }
-
- p := &Pagination{}
- if len(commits) == commitsPerPage {
- p.Next = page + 1
- }
- if page > 0 {
- p.Prev = page - 1
- p.HasPrev = true
- }
- data := &uiTemplateData{commits, builders, tipState, p}
-
- var buf bytes.Buffer
- if err := uiTemplate.Execute(&buf, data); err != nil {
- logErr(w, r, err)
- return
- }
-
- // Cache the front page.
- if page == 0 {
- cache.Set(r, now, key, buf.Bytes())
- }
-
- buf.WriteTo(w)
-}
-
-type Pagination struct {
- Next, Prev int
- HasPrev bool
-}
-
-// goCommits gets a slice of the latest Commits to the Go repository.
-// If page > 0 it paginates by commitsPerPage.
-func goCommits(c appengine.Context, page int) ([]*Commit, error) {
- q := datastore.NewQuery("Commit").
- Ancestor((&Package{}).Key(c)).
- Order("-Num").
- Limit(commitsPerPage).
- Offset(page * commitsPerPage)
- var commits []*Commit
- _, err := q.GetAll(c, &commits)
- return commits, err
-}
-
-// commitBuilders returns the names of the builders that provided
-// Results for the provided commits.
-func commitBuilders(commits []*Commit, goHash string) []string {
- builders := make(map[string]bool)
- for _, commit := range commits {
- for _, r := range commit.Results(goHash) {
- builders[r.Builder] = true
- }
- }
- return keys(builders)
-}
-
-func keys(m map[string]bool) (s []string) {
- for k := range m {
- s = append(s, k)
- }
- sort.Strings(s)
- return
-}
-
-// TagState represents the state of all Packages at a Tag.
-type TagState struct {
- Tag *Commit
- Packages []*PackageState
-}
-
-// PackageState represents the state of a Package at a Tag.
-type PackageState struct {
- Package *Package
- Commit *Commit
-}
-
-// TagStateByName fetches the results for all Go subrepos at the specified Tag.
-func TagStateByName(c appengine.Context, name string) (*TagState, error) {
- tag, err := GetTag(c, name)
- if err != nil {
- return nil, err
- }
- pkgs, err := Packages(c, "subrepo")
- if err != nil {
- return nil, err
- }
- var st TagState
- for _, pkg := range pkgs {
- com, err := pkg.LastCommit(c)
- if err != nil {
- c.Warningf("%v: no Commit found: %v", pkg, err)
- continue
- }
- st.Packages = append(st.Packages, &PackageState{pkg, com})
- }
- st.Tag, err = tag.Commit(c)
- if err != nil {
- return nil, err
- }
- return &st, nil
-}
-
-type uiTemplateData struct {
- Commits []*Commit
- Builders []string
- TipState *TagState
- Pagination *Pagination
-}
-
-var uiTemplate = template.Must(
- template.New("ui.html").Funcs(tmplFuncs).ParseFiles("build/ui.html"),
-)
-
-var tmplFuncs = template.FuncMap{
- "builderOS": builderOS,
- "builderArch": builderArch,
- "builderArchShort": builderArchShort,
- "builderArchChar": builderArchChar,
- "builderTitle": builderTitle,
- "builderSpans": builderSpans,
- "repoURL": repoURL,
- "shortDesc": shortDesc,
- "shortHash": shortHash,
- "shortUser": shortUser,
- "tail": tail,
-}
-
-func splitDash(s string) (string, string) {
- i := strings.Index(s, "-")
- if i >= 0 {
- return s[:i], s[i+1:]
- }
- return s, ""
-}
-
-// builderOS returns the os tag for a builder string
-func builderOS(s string) string {
- os, _ := splitDash(s)
- return os
-}
-
-// builderArch returns the arch tag for a builder string
-func builderArch(s string) string {
- _, arch := splitDash(s)
- arch, _ = splitDash(arch) // chop third part
- return arch
-}
-
-// builderArchShort returns a short arch tag for a builder string
-func builderArchShort(s string) string {
- if s == "linux-amd64-race" {
- return "race"
- }
- arch := builderArch(s)
- switch arch {
- case "amd64":
- return "x64"
- }
- return arch
-}
-
-// builderArchChar returns the architecture letter for a builder string
-func builderArchChar(s string) string {
- arch := builderArch(s)
- switch arch {
- case "386":
- return "8"
- case "amd64":
- return "6"
- case "arm":
- return "5"
- }
- return arch
-}
-
-type builderSpan struct {
- N int
- OS string
-}
-
-// builderSpans creates a list of tags showing
-// the builder's operating system names, spanning
-// the appropriate number of columns.
-func builderSpans(s []string) []builderSpan {
- var sp []builderSpan
- for len(s) > 0 {
- i := 1
- os := builderOS(s[0])
- for i < len(s) && builderOS(s[i]) == os {
- i++
- }
- sp = append(sp, builderSpan{i, os})
- s = s[i:]
- }
- return sp
-}
-
-// builderTitle formats "linux-amd64-foo" as "linux amd64 foo".
-func builderTitle(s string) string {
- return strings.Replace(s, "-", " ", -1)
-}
-
-// shortDesc returns the first line of a description.
-func shortDesc(desc string) string {
- if i := strings.Index(desc, "\n"); i != -1 {
- desc = desc[:i]
- }
- return desc
-}
-
-// shortHash returns a short version of a hash.
-func shortHash(hash string) string {
- if len(hash) > 12 {
- hash = hash[:12]
- }
- return hash
-}
-
-// shortUser returns a shortened version of a user string.
-func shortUser(user string) string {
- if i, j := strings.Index(user, "<"), strings.Index(user, ">"); 0 <= i && i < j {
- user = user[i+1 : j]
- }
- if i := strings.Index(user, "@"); i >= 0 {
- return user[:i]
- }
- return user
-}
-
-// repoRe matches Google Code repositories and subrepositories (without paths).
-var repoRe = regexp.MustCompile(`^code\.google\.com/p/([a-z0-9\-]+)(\.[a-z0-9\-]+)?$`)
-
-// repoURL returns the URL of a change at a Google Code repository or subrepo.
-func repoURL(hash, packagePath string) (string, error) {
- if packagePath == "" {
- return "https://code.google.com/p/go/source/detail?r=" + hash, nil
- }
- m := repoRe.FindStringSubmatch(packagePath)
- if m == nil {
- return "", errors.New("unrecognized package: " + packagePath)
- }
- url := "https://code.google.com/p/" + m[1] + "/source/detail?r=" + hash
- if len(m) > 2 {
- url += "&repo=" + m[2][1:]
- }
- return url, nil
-}
-
-// tail returns the trailing n lines of s.
-func tail(n int, s string) string {
- lines := strings.Split(s, "\n")
- if len(lines) < n {
- return s
- }
- return strings.Join(lines[len(lines)-n:], "\n")
-}
diff --git a/misc/dashboard/app/build/ui.html b/misc/dashboard/app/build/ui.html
deleted file mode 100644
index 5b5f4ebe3..000000000
--- a/misc/dashboard/app/build/ui.html
+++ /dev/null
@@ -1,209 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Go Build Dashboard</title>
- <style>
- body {
- font-family: sans-serif;
- padding: 0; margin: 0;
- }
- h1, h2 {
- margin: 0;
- padding: 5px;
- }
- h1 {
- background: #eee;
- }
- h2 {
- margin-top: 20px;
- }
- .build, .packages {
- margin: 5px;
- border-collapse: collapse;
- }
- .build td, .build th, .packages td, .packages th {
- vertical-align: top;
- padding: 2px 4px;
- font-size: 10pt;
- }
- .build tr.commit:nth-child(2n) {
- background-color: #f0f0f0;
- }
- .build .hash {
- font-family: monospace;
- font-size: 9pt;
- }
- .build .result {
- text-align: center;
- width: 2em;
- }
- .col-hash, .col-result {
- border-right: solid 1px #ccc;
- }
- .build .arch {
- font-size: 66%;
- font-weight: normal;
- }
- .build .time {
- color: #666;
- }
- .build .ok {
- font-size: 83%;
- }
- .build .desc, .build .time, .build .user {
- white-space: nowrap;
- }
- .paginate {
- padding: 0.5em;
- }
- .paginate a {
- padding: 0.5em;
- background: #eee;
- color: blue;
- }
- .paginate a.inactive {
- color: #999;
- }
- .fail {
- color: #C00;
- }
- </style>
- </head>
- <body>
-
- <h1>Go Build Status</h1>
-
- {{if $.Commits}}
-
- <table class="build">
- <colgroup class="col-hash"></colgroup>
- {{range $.Builders | builderSpans}}
- <colgroup class="col-result" span="{{.N}}"></colgroup>
- {{end}}
- <colgroup class="col-user"></colgroup>
- <colgroup class="col-time"></colgroup>
- <colgroup class="col-desc"></colgroup>
- <tr>
- <!-- extra row to make alternating colors use dark for first result -->
- </tr>
- <tr>
- <th>&nbsp;</th>
- {{range $.Builders | builderSpans}}
- <th colspan="{{.N}}">{{.OS}}</th>
- {{end}}
- <th></th>
- <th></th>
- <th></th>
- </tr>
- <tr>
- <th>&nbsp;</th>
- {{range $.Builders}}
- <th class="result arch" title="{{.}}">{{builderArchShort .}}</th>
- {{end}}
- </tr>
- {{range $c := $.Commits}}
- <tr class="commit">
- <td class="hash"><a href="{{repoURL .Hash ""}}">{{shortHash .Hash}}</a></td>
- {{range $.Builders}}
- <td class="result">
- {{with $c.Result . ""}}
- {{if .OK}}
- <span class="ok">ok</span>
- {{else}}
- <a href="/log/{{.LogHash}}" class="fail">fail</a>
- {{end}}
- {{else}}
- &nbsp;
- {{end}}
- </td>
- {{end}}
- <td class="user" title="{{.User}}">{{shortUser .User}}</td>
- <td class="time">{{.Time.Format "Mon 02 Jan 15:04"}}</td>
- <td class="desc" title="{{.Desc}}">{{shortDesc .Desc}}</td>
- </tr>
- {{end}}
- </table>
-
- {{with $.Pagination}}
- <div class="paginate">
- <a {{if .HasPrev}}href="?page={{.Prev}}"{{else}}class="inactive"{{end}}>newer</a>
- <a {{if .Next}}href="?page={{.Next}}"{{else}}class="inactive"{{end}}>older</a>
- <a {{if .HasPrev}}href="."{{else}}class="inactive"{{end}}>latest</a>
- </div>
- {{end}}
-
- {{else}}
- <p>No commits to display. Hm.</p>
- {{end}}
-
- {{with $.TipState}}
- {{$goHash := .Tag.Hash}}
- <h2>
- Sub-repositories at tip
- <small>(<a href="{{repoURL .Tag.Hash ""}}">{{shortHash .Tag.Hash}}</a>)</small>
- </h2>
-
- <table class="build">
- <colgroup class="col-package"></colgroup>
- <colgroup class="col-hash"></colgroup>
- {{range $.Builders | builderSpans}}
- <colgroup class="col-result" span="{{.N}}"></colgroup>
- {{end}}
- <colgroup class="col-user"></colgroup>
- <colgroup class="col-time"></colgroup>
- <colgroup class="col-desc"></colgroup>
- <tr>
- <!-- extra row to make alternating colors use dark for first result -->
- </tr>
- <tr>
- <th></th>
- <th></th>
- {{range $.Builders | builderSpans}}
- <th colspan="{{.N}}">{{.OS}}</th>
- {{end}}
- <th></th>
- <th></th>
- <th></th>
- </tr>
- <tr>
- <th></th>
- <th></th>
- {{range $.Builders}}
- <th class="result arch" title="{{.}}">{{builderArchShort .}}</th>
- {{end}}
- <th></th>
- <th></th>
- <th></th>
- </tr>
- {{range $pkg := .Packages}}
- <tr class="commit">
- <td><a title="{{.Package.Path}}">{{.Package.Name}}</a></td>
- <td class="hash">
- {{$h := $pkg.Commit.Hash}}
- <a href="{{repoURL $h $pkg.Commit.PackagePath}}">{{shortHash $h}}</a>
- </td>
- {{range $.Builders}}
- <td class="result">
- {{with $pkg.Commit.Result . $goHash}}
- {{if .OK}}
- <span class="ok">ok</span>
- {{else}}
- <a href="/log/{{.LogHash}}" class="fail">fail</a>
- {{end}}
- {{else}}
- &nbsp;
- {{end}}
- </td>
- {{end}}
- {{with $pkg.Commit}}
- <td class="user" title="{{.User}}">{{shortUser .User}}</td>
- <td class="time">{{.Time.Format "Mon 02 Jan 15:04"}}</td>
- <td class="desc" title="{{.Desc}}">{{shortDesc .Desc}}</td>
- {{end}}
- </tr>
- {{end}}
- </table>
- {{end}}
-
- </body>
-</html>
diff --git a/misc/dashboard/app/cache/cache.go b/misc/dashboard/app/cache/cache.go
deleted file mode 100644
index 8bd3020f3..000000000
--- a/misc/dashboard/app/cache/cache.go
+++ /dev/null
@@ -1,82 +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.
-
-package cache
-
-import (
- "fmt"
- "net/http"
- "time"
-
- "appengine"
- "appengine/memcache"
-)
-
-const (
- nocache = "nocache"
- timeKey = "cachetime"
- expiry = 600 // 10 minutes
-)
-
-func newTime() uint64 { return uint64(time.Now().Unix()) << 32 }
-
-// Now returns the current logical datastore time to use for cache lookups.
-func Now(c appengine.Context) uint64 {
- t, err := memcache.Increment(c, timeKey, 0, newTime())
- if err != nil {
- c.Errorf("cache.Now: %v", err)
- return 0
- }
- return t
-}
-
-// Tick sets the current logical datastore time to a never-before-used time
-// and returns that time. It should be called to invalidate the cache.
-func Tick(c appengine.Context) uint64 {
- t, err := memcache.Increment(c, timeKey, 1, newTime())
- if err != nil {
- c.Errorf("cache.Tick: %v", err)
- return 0
- }
- return t
-}
-
-// Get fetches data for name at time now from memcache and unmarshals it into
-// value. It reports whether it found the cache record and logs any errors to
-// the admin console.
-func Get(r *http.Request, now uint64, name string, value interface{}) bool {
- if now == 0 || r.FormValue(nocache) != "" {
- return false
- }
- c := appengine.NewContext(r)
- key := fmt.Sprintf("%s.%d", name, now)
- _, err := memcache.JSON.Get(c, key, value)
- if err == nil {
- c.Debugf("cache hit %q", key)
- return true
- }
- c.Debugf("cache miss %q", key)
- if err != memcache.ErrCacheMiss {
- c.Errorf("get cache %q: %v", key, err)
- }
- return false
-}
-
-// Set puts value into memcache under name at time now.
-// It logs any errors to the admin console.
-func Set(r *http.Request, now uint64, name string, value interface{}) {
- if now == 0 || r.FormValue(nocache) != "" {
- return
- }
- c := appengine.NewContext(r)
- key := fmt.Sprintf("%s.%d", name, now)
- err := memcache.JSON.Set(c, &memcache.Item{
- Key: key,
- Object: value,
- Expiration: expiry,
- })
- if err != nil {
- c.Errorf("set cache %q: %v", key, err)
- }
-}
diff --git a/misc/dashboard/app/static/status_alert.gif b/misc/dashboard/app/static/status_alert.gif
deleted file mode 100644
index 495d9d2e0..000000000
--- a/misc/dashboard/app/static/status_alert.gif
+++ /dev/null
Binary files differ
diff --git a/misc/dashboard/app/static/status_good.gif b/misc/dashboard/app/static/status_good.gif
deleted file mode 100644
index ef9c5a8f6..000000000
--- a/misc/dashboard/app/static/status_good.gif
+++ /dev/null
Binary files differ
diff --git a/misc/dashboard/builder/Makefile b/misc/dashboard/builder/Makefile
deleted file mode 100644
index 4e4d408bf..000000000
--- a/misc/dashboard/builder/Makefile
+++ /dev/null
@@ -1,9 +0,0 @@
-# Copyright 2009 The Go Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-builder: $(shell ls *.go)
- go build -o $@ $^
-
-clean:
- rm -f builder
diff --git a/misc/dashboard/builder/doc.go b/misc/dashboard/builder/doc.go
deleted file mode 100644
index 519286170..000000000
--- a/misc/dashboard/builder/doc.go
+++ /dev/null
@@ -1,58 +0,0 @@
-// Copyright 2010 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.
-
-/*
-
-Go Builder is a continuous build client for the Go project.
-It integrates with the Go Dashboard AppEngine application.
-
-Go Builder is intended to run continuously as a background process.
-
-It periodically pulls updates from the Go Mercurial repository.
-
-When a newer revision is found, Go Builder creates a clone of the repository,
-runs all.bash, and reports build success or failure to the Go Dashboard.
-
-For a release revision (a change description that matches "release.YYYY-MM-DD"),
-Go Builder will create a tar.gz archive of the GOROOT and deliver it to the
-Go Google Code project's downloads section.
-
-Usage:
-
- gobuilder goos-goarch...
-
- Several goos-goarch combinations can be provided, and the builder will
- build them in serial.
-
-Optional flags:
-
- -dashboard="godashboard.appspot.com": Go Dashboard Host
- The location of the Go Dashboard application to which Go Builder will
- report its results.
-
- -release: Build and deliver binary release archive
-
- -rev=N: Build revision N and exit
-
- -cmd="./all.bash": Build command (specify absolute or relative to go/src)
-
- -v: Verbose logging
-
- -external: External package builder mode (will not report Go build
- state to dashboard or issue releases)
-
-The key file should be located at $HOME/.gobuildkey or, for a builder-specific
-key, $HOME/.gobuildkey-$BUILDER (eg, $HOME/.gobuildkey-linux-amd64).
-
-The build key file is a text file of the format:
-
- godashboard-key
- googlecode-username
- googlecode-password
-
-If the Google Code credentials are not provided the archival step
-will be skipped.
-
-*/
-package main
diff --git a/misc/dashboard/builder/exec.go b/misc/dashboard/builder/exec.go
deleted file mode 100644
index a4aabd284..000000000
--- a/misc/dashboard/builder/exec.go
+++ /dev/null
@@ -1,79 +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.
-
-package main
-
-import (
- "bytes"
- "fmt"
- "io"
- "log"
- "os"
- "os/exec"
- "time"
-)
-
-// run is a simple wrapper for exec.Run/Close
-func run(timeout time.Duration, envv []string, dir string, argv ...string) error {
- if *verbose {
- log.Println("run", argv)
- }
- cmd := exec.Command(argv[0], argv[1:]...)
- cmd.Dir = dir
- cmd.Env = envv
- cmd.Stderr = os.Stderr
- if err := cmd.Start(); err != nil {
- return err
- }
- return waitWithTimeout(timeout, cmd)
-}
-
-// runLog runs a process and returns the combined stdout/stderr. It returns
-// process combined stdout and stderr output, exit status and error. The
-// error returned is nil, if process is started successfully, even if exit
-// status is not successful.
-func runLog(timeout time.Duration, envv []string, dir string, argv ...string) (string, bool, error) {
- var b bytes.Buffer
- ok, err := runOutput(timeout, envv, &b, dir, argv...)
- return b.String(), ok, err
-}
-
-// runOutput runs a process and directs any output to the supplied writer.
-// It returns exit status and error. The error returned is nil, if process
-// is started successfully, even if exit status is not successful.
-func runOutput(timeout time.Duration, envv []string, out io.Writer, dir string, argv ...string) (bool, error) {
- if *verbose {
- log.Println("runOutput", argv)
- }
-
- cmd := exec.Command(argv[0], argv[1:]...)
- cmd.Dir = dir
- cmd.Env = envv
- cmd.Stdout = out
- cmd.Stderr = out
-
- startErr := cmd.Start()
- if startErr != nil {
- return false, startErr
- }
- if err := waitWithTimeout(timeout, cmd); err != nil {
- return false, err
- }
- return true, nil
-}
-
-func waitWithTimeout(timeout time.Duration, cmd *exec.Cmd) error {
- errc := make(chan error, 1)
- go func() {
- errc <- cmd.Wait()
- }()
- var err error
- select {
- case <-time.After(timeout):
- cmd.Process.Kill()
- err = fmt.Errorf("timed out after %v", timeout)
- case err = <-errc:
- }
- return err
-}
diff --git a/misc/dashboard/builder/http.go b/misc/dashboard/builder/http.go
deleted file mode 100644
index b50e84551..000000000
--- a/misc/dashboard/builder/http.go
+++ /dev/null
@@ -1,167 +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.
-
-package main
-
-import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "io"
- "log"
- "net/http"
- "net/url"
- "time"
-)
-
-type obj map[string]interface{}
-
-// dash runs the given method and command on the dashboard.
-// If args is non-nil it is encoded as the URL query string.
-// If req is non-nil it is JSON-encoded and passed as the body of the HTTP POST.
-// If resp is non-nil the server's response is decoded into the value pointed
-// to by resp (resp must be a pointer).
-func dash(meth, cmd string, args url.Values, req, resp interface{}) error {
- var r *http.Response
- var err error
- if *verbose {
- log.Println("dash", meth, cmd, args, req)
- }
- cmd = "http://" + *dashboard + "/" + cmd
- if len(args) > 0 {
- cmd += "?" + args.Encode()
- }
- switch meth {
- case "GET":
- if req != nil {
- log.Panicf("%s to %s with req", meth, cmd)
- }
- r, err = http.Get(cmd)
- case "POST":
- var body io.Reader
- if req != nil {
- b, err := json.Marshal(req)
- if err != nil {
- return err
- }
- body = bytes.NewBuffer(b)
- }
- r, err = http.Post(cmd, "text/json", body)
- default:
- log.Panicf("%s: invalid method %q", cmd, meth)
- panic("invalid method: " + meth)
- }
- if err != nil {
- return err
- }
- defer r.Body.Close()
- if r.StatusCode != http.StatusOK {
- return fmt.Errorf("bad http response: %v", r.Status)
- }
- body := new(bytes.Buffer)
- if _, err := body.ReadFrom(r.Body); err != nil {
- return err
- }
-
- // Read JSON-encoded Response into provided resp
- // and return an error if present.
- var result = struct {
- Response interface{}
- Error string
- }{
- // Put the provided resp in here as it can be a pointer to
- // some value we should unmarshal into.
- Response: resp,
- }
- if err = json.Unmarshal(body.Bytes(), &result); err != nil {
- log.Printf("json unmarshal %#q: %s\n", body.Bytes(), err)
- return err
- }
- if result.Error != "" {
- return errors.New(result.Error)
- }
-
- return nil
-}
-
-// todo returns the next hash to build.
-func (b *Builder) todo(kind, pkg, goHash string) (rev string, err error) {
- args := url.Values{
- "kind": {kind},
- "builder": {b.name},
- "packagePath": {pkg},
- "goHash": {goHash},
- }
- var resp *struct {
- Kind string
- Data struct {
- Hash string
- }
- }
- if err = dash("GET", "todo", args, nil, &resp); err != nil {
- return "", err
- }
- if resp == nil {
- return "", nil
- }
- if kind != resp.Kind {
- return "", fmt.Errorf("expecting Kind %q, got %q", kind, resp.Kind)
- }
- return resp.Data.Hash, nil
-}
-
-// recordResult sends build results to the dashboard
-func (b *Builder) recordResult(ok bool, pkg, hash, goHash, buildLog string, runTime time.Duration) error {
- req := obj{
- "Builder": b.name,
- "PackagePath": pkg,
- "Hash": hash,
- "GoHash": goHash,
- "OK": ok,
- "Log": buildLog,
- "RunTime": runTime,
- }
- args := url.Values{"key": {b.key}, "builder": {b.name}}
- return dash("POST", "result", args, req, nil)
-}
-
-func postCommit(key, pkg string, l *HgLog) error {
- t, err := time.Parse(time.RFC3339, l.Date)
- if err != nil {
- return fmt.Errorf("parsing %q: %v", l.Date, t)
- }
- return dash("POST", "commit", url.Values{"key": {key}}, obj{
- "PackagePath": pkg,
- "Hash": l.Hash,
- "ParentHash": l.Parent,
- "Time": t.Format(time.RFC3339),
- "User": l.Author,
- "Desc": l.Desc,
- }, nil)
-}
-
-func dashboardCommit(pkg, hash string) bool {
- err := dash("GET", "commit", url.Values{
- "packagePath": {pkg},
- "hash": {hash},
- }, nil, nil)
- return err == nil
-}
-
-func dashboardPackages(kind string) []string {
- args := url.Values{"kind": []string{kind}}
- var resp []struct {
- Path string
- }
- if err := dash("GET", "packages", args, nil, &resp); err != nil {
- log.Println("dashboardPackages:", err)
- return nil
- }
- var pkgs []string
- for _, r := range resp {
- pkgs = append(pkgs, r.Path)
- }
- return pkgs
-}
diff --git a/misc/dashboard/builder/main.go b/misc/dashboard/builder/main.go
deleted file mode 100644
index 9a155bd0c..000000000
--- a/misc/dashboard/builder/main.go
+++ /dev/null
@@ -1,642 +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.
-
-package main
-
-import (
- "bytes"
- "flag"
- "fmt"
- "io"
- "io/ioutil"
- "log"
- "os"
- "path/filepath"
- "regexp"
- "runtime"
- "strings"
- "time"
-)
-
-const (
- codeProject = "go"
- codePyScript = "misc/dashboard/googlecode_upload.py"
- hgUrl = "https://code.google.com/p/go/"
- mkdirPerm = 0750
- waitInterval = 30 * time.Second // time to wait before checking for new revs
- pkgBuildInterval = 24 * time.Hour // rebuild packages every 24 hours
-)
-
-// These variables are copied from the gobuilder's environment
-// to the envv of its subprocesses.
-var extraEnv = []string{
- "CC",
- "GOARM",
- "PATH",
- "TMPDIR",
- "USER",
-}
-
-type Builder struct {
- goroot *Repo
- name string
- goos, goarch string
- key string
-}
-
-var (
- buildroot = flag.String("buildroot", defaultBuildRoot(), "Directory under which to build")
- dashboard = flag.String("dashboard", "build.golang.org", "Go Dashboard Host")
- buildRelease = flag.Bool("release", false, "Build and upload binary release archives")
- buildRevision = flag.String("rev", "", "Build specified revision and exit")
- buildCmd = flag.String("cmd", filepath.Join(".", allCmd), "Build command (specify relative to go/src/)")
- failAll = flag.Bool("fail", false, "fail all builds")
- parallel = flag.Bool("parallel", false, "Build multiple targets in parallel")
- buildTimeout = flag.Duration("buildTimeout", 60*time.Minute, "Maximum time to wait for builds and tests")
- cmdTimeout = flag.Duration("cmdTimeout", 5*time.Minute, "Maximum time to wait for an external command")
- commitInterval = flag.Duration("commitInterval", 1*time.Minute, "Time to wait between polling for new commits (0 disables commit poller)")
- verbose = flag.Bool("v", false, "verbose")
-)
-
-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()
-)
-
-func main() {
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, "usage: %s goos-goarch...\n", os.Args[0])
- flag.PrintDefaults()
- os.Exit(2)
- }
- flag.Parse()
- if len(flag.Args()) == 0 {
- flag.Usage()
- }
- goroot := &Repo{
- Path: filepath.Join(*buildroot, "goroot"),
- }
-
- // set up work environment, use existing enviroment if possible
- if goroot.Exists() || *failAll {
- log.Print("Found old workspace, will use it")
- } else {
- if err := os.RemoveAll(*buildroot); err != nil {
- log.Fatalf("Error removing build root (%s): %s", *buildroot, err)
- }
- if err := os.Mkdir(*buildroot, mkdirPerm); err != nil {
- log.Fatalf("Error making build root (%s): %s", *buildroot, err)
- }
- var err error
- goroot, err = RemoteRepo(hgUrl).Clone(goroot.Path, "tip")
- if err != nil {
- log.Fatal("Error cloning repository:", err)
- }
- }
-
- // set up builders
- builders := make([]*Builder, len(flag.Args()))
- for i, name := range flag.Args() {
- b, err := NewBuilder(goroot, name)
- if err != nil {
- log.Fatal(err)
- }
- builders[i] = b
- }
-
- if *failAll {
- failMode(builders)
- return
- }
-
- // if specified, build revision and return
- if *buildRevision != "" {
- hash, err := goroot.FullHash(*buildRevision)
- if err != nil {
- log.Fatal("Error finding revision: ", err)
- }
- for _, b := range builders {
- if err := b.buildHash(hash); err != nil {
- log.Println(err)
- }
- }
- return
- }
-
- // Start commit watcher
- go commitWatcher(goroot)
-
- // go continuous build mode
- // check for new commits and build them
- for {
- built := false
- t := time.Now()
- if *parallel {
- done := make(chan bool)
- for _, b := range builders {
- go func(b *Builder) {
- done <- b.build()
- }(b)
- }
- for _ = range builders {
- built = <-done || built
- }
- } else {
- for _, b := range builders {
- built = b.build() || built
- }
- }
- // sleep if there was nothing to build
- if !built {
- time.Sleep(waitInterval)
- }
- // sleep if we're looping too fast.
- dt := time.Now().Sub(t)
- if dt < waitInterval {
- time.Sleep(waitInterval - dt)
- }
- }
-}
-
-// go continuous fail mode
-// check for new commits and FAIL them
-func failMode(builders []*Builder) {
- for {
- built := false
- for _, b := range builders {
- built = b.failBuild() || built
- }
- // stop if there was nothing to fail
- if !built {
- break
- }
- }
-}
-
-func NewBuilder(goroot *Repo, name string) (*Builder, error) {
- b := &Builder{
- goroot: goroot,
- name: name,
- }
-
- // get goos/goarch from builder string
- s := strings.SplitN(b.name, "-", 3)
- if len(s) >= 2 {
- b.goos, b.goarch = s[0], s[1]
- } else {
- return nil, fmt.Errorf("unsupported builder form: %s", name)
- }
-
- // read keys from keyfile
- fn := ""
- if runtime.GOOS == "windows" {
- fn = os.Getenv("HOMEDRIVE") + os.Getenv("HOMEPATH")
- } else {
- fn = os.Getenv("HOME")
- }
- fn = filepath.Join(fn, ".gobuildkey")
- if s := fn + "-" + b.name; isFile(s) { // builder-specific file
- fn = s
- }
- c, err := ioutil.ReadFile(fn)
- if err != nil {
- return nil, fmt.Errorf("readKeys %s (%s): %s", b.name, fn, err)
- }
- b.key = string(bytes.TrimSpace(bytes.SplitN(c, []byte("\n"), 2)[0]))
- 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.
-func (b *Builder) build() bool {
- hash, err := b.todo("build-go-commit", "", "")
- if err != nil {
- log.Println(err)
- return false
- }
- if hash == "" {
- return false
- }
-
- if err := b.buildHash(hash); err != nil {
- log.Println(err)
- }
- return true
-}
-
-func (b *Builder) buildHash(hash string) error {
- log.Println(b.name, "building", hash)
-
- // create place in which to do work
- workpath := filepath.Join(*buildroot, b.name+"-"+hash[:12])
- if err := os.Mkdir(workpath, mkdirPerm); err != nil {
- return err
- }
- defer os.RemoveAll(workpath)
-
- // pull before cloning to ensure we have the revision
- if err := b.goroot.Pull(); err != nil {
- return err
- }
-
- // clone repo at specified revision
- if _, err := b.goroot.Clone(filepath.Join(workpath, "go"), hash); err != nil {
- return err
- }
-
- srcDir := filepath.Join(workpath, "go", "src")
-
- // build
- var buildlog bytes.Buffer
- logfile := filepath.Join(workpath, "build.log")
- f, err := os.Create(logfile)
- if err != nil {
- return err
- }
- defer f.Close()
- w := io.MultiWriter(f, &buildlog)
-
- cmd := b.buildCmd()
- if !filepath.IsAbs(cmd) {
- cmd = filepath.Join(srcDir, cmd)
- }
- startTime := time.Now()
- ok, err := runOutput(*buildTimeout, b.envv(), w, srcDir, cmd)
- runTime := time.Now().Sub(startTime)
- errf := func() string {
- if err != nil {
- return fmt.Sprintf("error: %v", err)
- }
- if !ok {
- return "failed"
- }
- return "success"
- }
- fmt.Fprintf(w, "Build complete, duration %v. Result: %v\n", runTime, errf())
-
- if err != nil || !ok {
- // record failure
- return b.recordResult(false, "", hash, "", buildlog.String(), runTime)
- }
-
- // record success
- if err = b.recordResult(true, "", hash, "", "", runTime); err != nil {
- return fmt.Errorf("recordResult: %s", err)
- }
-
- // build Go sub-repositories
- goRoot := filepath.Join(workpath, "go")
- goPath := workpath
- b.buildSubrepos(goRoot, goPath, hash)
-
- return nil
-}
-
-// failBuild checks for a new commit for this builder
-// and fails it if one is found.
-// It returns true if a build was "attempted".
-func (b *Builder) failBuild() bool {
- hash, err := b.todo("build-go-commit", "", "")
- if err != nil {
- log.Println(err)
- return false
- }
- if hash == "" {
- return false
- }
-
- log.Printf("fail %s %s\n", b.name, hash)
-
- if err := b.recordResult(false, "", hash, "", "auto-fail mode run by "+os.Getenv("USER"), 0); err != nil {
- log.Print(err)
- }
- return true
-}
-
-func (b *Builder) buildSubrepos(goRoot, goPath, goHash string) {
- for _, pkg := range dashboardPackages("subrepo") {
- // get the latest todo for this package
- hash, err := b.todo("build-package", pkg, goHash)
- if err != nil {
- log.Printf("buildSubrepos %s: %v", pkg, err)
- continue
- }
- if hash == "" {
- continue
- }
-
- // build the package
- if *verbose {
- log.Printf("buildSubrepos %s: building %q", pkg, hash)
- }
- buildLog, err := b.buildSubrepo(goRoot, goPath, pkg, hash)
- if err != nil {
- if buildLog == "" {
- buildLog = err.Error()
- }
- log.Printf("buildSubrepos %s: %v", pkg, err)
- }
-
- // record the result
- err = b.recordResult(err == nil, pkg, hash, goHash, buildLog, 0)
- if err != nil {
- log.Printf("buildSubrepos %s: %v", pkg, err)
- }
- }
-}
-
-// buildSubrepo fetches the given package, updates it to the specified hash,
-// and runs 'go test -short pkg/...'. It returns the build log and any error.
-func (b *Builder) buildSubrepo(goRoot, goPath, pkg, hash string) (string, error) {
- goTool := filepath.Join(goRoot, "bin", "go")
- env := append(b.envv(), "GOROOT="+goRoot, "GOPATH="+goPath)
-
- // add $GOROOT/bin and $GOPATH/bin to PATH
- for i, e := range env {
- const p = "PATH="
- if !strings.HasPrefix(e, p) {
- continue
- }
- sep := string(os.PathListSeparator)
- env[i] = p + filepath.Join(goRoot, "bin") + sep + filepath.Join(goPath, "bin") + sep + e[len(p):]
- }
-
- // fetch package and dependencies
- log, ok, err := runLog(*cmdTimeout, env, goPath, goTool, "get", "-d", pkg+"/...")
- if err == nil && !ok {
- err = fmt.Errorf("go exited with status 1")
- }
- if err != nil {
- return log, err
- }
-
- // hg update to the specified hash
- repo := Repo{Path: filepath.Join(goPath, "src", pkg)}
- if err := repo.UpdateTo(hash); err != nil {
- return "", err
- }
-
- // test the package
- log, ok, err = runLog(*buildTimeout, env, goPath, goTool, "test", "-short", pkg+"/...")
- if err == nil && !ok {
- err = fmt.Errorf("go exited with status 1")
- }
- return log, err
-}
-
-// envv returns an environment for build/bench execution
-func (b *Builder) envv() []string {
- if runtime.GOOS == "windows" {
- return b.envvWindows()
- }
- e := []string{
- "GOOS=" + b.goos,
- "GOHOSTOS=" + b.goos,
- "GOARCH=" + b.goarch,
- "GOHOSTARCH=" + b.goarch,
- "GOROOT_FINAL=/usr/local/go",
- }
- for _, k := range extraEnv {
- if s, ok := getenvOk(k); ok {
- e = append(e, k+"="+s)
- }
- }
- return e
-}
-
-// windows version of envv
-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.
- }
- for _, name := range extraEnv {
- if s, ok := getenvOk(name); ok {
- start[name] = s
- }
- }
- skip := map[string]bool{
- "GOBIN": true,
- "GOROOT": true,
- "INCLUDE": true,
- "LIB": true,
- }
- var e []string
- for name, v := range start {
- e = append(e, name+"="+v)
- skip[name] = true
- }
- for _, kv := range os.Environ() {
- s := strings.SplitN(kv, "=", 2)
- name := strings.ToUpper(s[0])
- switch {
- case name == "":
- // variables, like "=C:=C:\", just copy them
- e = append(e, kv)
- case !skip[name]:
- e = append(e, kv)
- skip[name] = true
- }
- }
- return e
-}
-
-func isDirectory(name string) bool {
- s, err := os.Stat(name)
- return err == nil && s.IsDir()
-}
-
-func isFile(name string) bool {
- s, err := os.Stat(name)
- return err == nil && !s.IsDir()
-}
-
-// commitWatcher polls hg for new commits and tells the dashboard about them.
-func commitWatcher(goroot *Repo) {
- if *commitInterval == 0 {
- log.Printf("commitInterval is %s, disabling commitWatcher", *commitInterval)
- return
- }
- // Create builder just to get master key.
- b, err := NewBuilder(goroot, "mercurial-commit")
- if err != nil {
- log.Fatal(err)
- }
- key := b.key
-
- for {
- if *verbose {
- log.Printf("poll...")
- }
- // Main Go repository.
- commitPoll(goroot, "", key)
- // Go sub-repositories.
- for _, pkg := range dashboardPackages("subrepo") {
- pkgroot := &Repo{
- Path: filepath.Join(*buildroot, pkg),
- }
- commitPoll(pkgroot, pkg, key)
- }
- if *verbose {
- log.Printf("sleep...")
- }
- time.Sleep(*commitInterval)
- }
-}
-
-// logByHash is a cache of all Mercurial revisions we know about,
-// indexed by full hash.
-var logByHash = map[string]*HgLog{}
-
-// commitPoll pulls any new revisions from the hg server
-// and tells the server about them.
-func commitPoll(repo *Repo, pkg, key string) {
- if !repo.Exists() {
- var err error
- repo, err = RemoteRepo(repoURL(pkg)).Clone(repo.Path, "tip")
- if err != nil {
- log.Printf("%s: hg clone failed: %v", pkg, err)
- if err := os.RemoveAll(repo.Path); err != nil {
- log.Printf("%s: %v", pkg, err)
- }
- }
- return
- }
-
- logs, err := repo.Log() // repo.Log calls repo.Pull internally
- if err != nil {
- log.Printf("hg log: %v", err)
- return
- }
-
- // Pass 1. Fill in parents and add new log entries to logsByHash.
- // Empty parent means take parent from next log entry.
- // Non-empty parent has form 1234:hashhashhash; we want full hash.
- for i := range logs {
- l := &logs[i]
- if l.Parent == "" && i+1 < len(logs) {
- l.Parent = logs[i+1].Hash
- } else if l.Parent != "" {
- l.Parent, _ = repo.FullHash(l.Parent)
- }
- if *verbose {
- log.Printf("hg log %s: %s < %s\n", pkg, l.Hash, l.Parent)
- }
- if logByHash[l.Hash] == nil {
- // Make copy to avoid pinning entire slice when only one entry is new.
- t := *l
- logByHash[t.Hash] = &t
- }
- }
-
- for _, l := range logs {
- addCommit(pkg, l.Hash, key)
- }
-}
-
-// addCommit adds the commit with the named hash to the dashboard.
-// key is the secret key for authentication to the dashboard.
-// It avoids duplicate effort.
-func addCommit(pkg, hash, key string) bool {
- l := logByHash[hash]
- if l == nil {
- return false
- }
- if l.added {
- return true
- }
-
- // Check for already added, perhaps in an earlier run.
- if dashboardCommit(pkg, hash) {
- log.Printf("%s already on dashboard\n", hash)
- // Record that this hash is on the dashboard,
- // as must be all its parents.
- for l != nil {
- l.added = true
- l = logByHash[l.Parent]
- }
- return true
- }
-
- // Create parent first, to maintain some semblance of order.
- if l.Parent != "" {
- if !addCommit(pkg, l.Parent, key) {
- return false
- }
- }
-
- // Create commit.
- if err := postCommit(key, pkg, l); err != nil {
- log.Printf("failed to add %s to dashboard: %v", key, err)
- return false
- }
- return true
-}
-
-var repoRe = regexp.MustCompile(`^code\.google\.com/p/([a-z0-9\-]+(\.[a-z0-9\-]+)?)(/[a-z0-9A-Z_.\-/]+)?$`)
-
-// repoURL returns the repository URL for the supplied import path.
-func repoURL(importPath string) string {
- m := repoRe.FindStringSubmatch(importPath)
- if len(m) < 2 {
- log.Printf("repoURL: couldn't decipher %q", importPath)
- return ""
- }
- return "https://code.google.com/p/" + m[1]
-}
-
-// defaultSuffix returns file extension used for command files in
-// current os environment.
-func defaultSuffix() string {
- if runtime.GOOS == "windows" {
- return ".bat"
- }
- return ".bash"
-}
-
-// defaultBuildRoot returns default buildroot directory.
-func defaultBuildRoot() string {
- var d string
- if runtime.GOOS == "windows" {
- // will use c:\, otherwise absolute paths become too long
- // during builder run, see http://golang.org/issue/3358.
- d = `c:\`
- } else {
- d = os.TempDir()
- }
- return filepath.Join(d, "gobuilder")
-}
-
-func getenvOk(k string) (v string, ok bool) {
- v = os.Getenv(k)
- if v != "" {
- return v, true
- }
- keq := k + "="
- for _, kv := range os.Environ() {
- if kv == keq {
- return "", true
- }
- }
- return "", false
-}
diff --git a/misc/dashboard/builder/vcs.go b/misc/dashboard/builder/vcs.go
deleted file mode 100644
index 63198a34b..000000000
--- a/misc/dashboard/builder/vcs.go
+++ /dev/null
@@ -1,148 +0,0 @@
-// 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 main
-
-import (
- "encoding/xml"
- "fmt"
- "log"
- "os"
- "path/filepath"
- "strconv"
- "strings"
- "sync"
-)
-
-// Repo represents a mercurial repository.
-type Repo struct {
- Path string
- sync.Mutex
-}
-
-// RemoteRepo constructs a *Repo representing a remote repository.
-func RemoteRepo(url string) *Repo {
- return &Repo{
- Path: url,
- }
-}
-
-// Clone clones the current Repo to a new destination
-// returning a new *Repo if successful.
-func (r *Repo) Clone(path, rev string) (*Repo, error) {
- r.Lock()
- defer r.Unlock()
- if err := run(*cmdTimeout, nil, *buildroot, r.hgCmd("clone", "-r", rev, r.Path, path)...); err != nil {
- return nil, err
- }
- return &Repo{
- Path: path,
- }, nil
-}
-
-// UpdateTo updates the working copy of this Repo to the
-// supplied revision.
-func (r *Repo) UpdateTo(hash string) error {
- r.Lock()
- defer r.Unlock()
- return run(*cmdTimeout, nil, r.Path, r.hgCmd("update", hash)...)
-}
-
-// Exists reports whether this Repo represents a valid Mecurial repository.
-func (r *Repo) Exists() bool {
- fi, err := os.Stat(filepath.Join(r.Path, ".hg"))
- if err != nil {
- return false
- }
- return fi.IsDir()
-}
-
-// Pull pulls changes from the default path, that is, the path
-// this Repo was cloned from.
-func (r *Repo) Pull() error {
- r.Lock()
- defer r.Unlock()
- return run(*cmdTimeout, nil, r.Path, r.hgCmd("pull")...)
-}
-
-// Log returns the changelog for this repository.
-func (r *Repo) Log() ([]HgLog, error) {
- if err := r.Pull(); err != nil {
- return nil, err
- }
- const N = 50 // how many revisions to grab
-
- r.Lock()
- defer r.Unlock()
- data, _, err := runLog(*cmdTimeout, nil, r.Path, r.hgCmd("log",
- "--encoding=utf-8",
- "--limit="+strconv.Itoa(N),
- "--template="+xmlLogTemplate)...,
- )
- if err != nil {
- return nil, err
- }
-
- var logStruct struct {
- Log []HgLog
- }
- err = xml.Unmarshal([]byte("<Top>"+data+"</Top>"), &logStruct)
- if err != nil {
- log.Printf("unmarshal hg log: %v", err)
- return nil, err
- }
- return logStruct.Log, nil
-}
-
-// FullHash returns the full hash for the given Mercurial revision.
-func (r *Repo) FullHash(rev string) (string, error) {
- r.Lock()
- defer r.Unlock()
- s, _, err := runLog(*cmdTimeout, nil, r.Path,
- r.hgCmd("log",
- "--encoding=utf-8",
- "--rev="+rev,
- "--limit=1",
- "--template={node}")...,
- )
- if err != nil {
- return "", nil
- }
- s = strings.TrimSpace(s)
- if s == "" {
- return "", fmt.Errorf("cannot find revision")
- }
- if len(s) != 40 {
- return "", fmt.Errorf("hg returned invalid hash " + s)
- }
- return s, nil
-}
-
-func (r *Repo) hgCmd(args ...string) []string {
- return append([]string{"hg", "--config", "extensions.codereview=!"}, args...)
-}
-
-// HgLog represents a single Mercurial revision.
-type HgLog struct {
- Hash string
- Author string
- Date string
- Desc string
- Parent string
-
- // Internal metadata
- added bool
-}
-
-// xmlLogTemplate is a template to pass to Mercurial to make
-// hg log print the log in valid XML for parsing with xml.Unmarshal.
-const xmlLogTemplate = `
- <Log>
- <Hash>{node|escape}</Hash>
- <Parent>{parent|escape}</Parent>
- <Author>{author|escape}</Author>
- <Date>{date|rfc3339date}</Date>
- <Desc>{desc|escape}</Desc>
- </Log>
-`
diff --git a/misc/dashboard/codereview/dashboard/front.go b/misc/dashboard/codereview/dashboard/front.go
index c7b0f0fbf..ea9fe0ddf 100644
--- a/misc/dashboard/codereview/dashboard/front.go
+++ b/misc/dashboard/codereview/dashboard/front.go
@@ -230,7 +230,7 @@ var frontPage = template.Must(template.New("front").Funcs(template.FuncMap{
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
- <head>
+ </head>
<body>
<img id="gopherstamp" src="/static/gopherstamp.jpg" />
diff --git a/misc/dashboard/codereview/dashboard/people.go b/misc/dashboard/codereview/dashboard/people.go
index 21bd8f89c..7bab2537b 100644
--- a/misc/dashboard/codereview/dashboard/people.go
+++ b/misc/dashboard/codereview/dashboard/people.go
@@ -24,9 +24,12 @@ func init() {
"agl",
"bradfitz",
"campoy",
+ "cshapiro",
"dsymonds",
"gri",
"iant",
+ "khr",
+ "mpvl",
"nigeltao",
"r",
"rsc",
diff --git a/misc/dist/bindist.go b/misc/dist/bindist.go
index 19b0baac2..223d2dc17 100644
--- a/misc/dist/bindist.go
+++ b/misc/dist/bindist.go
@@ -3,7 +3,7 @@
// license that can be found in the LICENSE file.
// This is a tool for packaging binary releases.
-// It supports FreeBSD, Linux, NetBSD, OS X, and Windows.
+// It supports FreeBSD, Linux, NetBSD, OpenBSD, OS X, and Windows.
package main
import (
@@ -22,6 +22,7 @@ import (
"net/http"
"os"
"os/exec"
+ "path"
"path/filepath"
"regexp"
"runtime"
@@ -30,22 +31,36 @@ import (
var (
tag = flag.String("tag", "release", "mercurial tag to check out")
+ toolTag = flag.String("tool", defaultToolTag, "go.tools 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")
+ staticToolchain = flag.Bool("static", true, "try to build statically linked toolchain (only supported on ELF targets)")
username, password string // for Google Code upload
)
const (
- uploadURL = "https://go.googlecode.com/files"
+ uploadURL = "https://go.googlecode.com/files"
+ blogPath = "code.google.com/p/go.blog"
+ toolPath = "code.google.com/p/go.tools"
+ tourPath = "code.google.com/p/go-tour"
+ defaultToolTag = "release-branch.go1.2"
)
+// Import paths for tool commands.
+// These must be the command that cmd/go knows to install to $GOROOT/bin
+// or $GOROOT/pkg/tool.
+var toolPaths = []string{
+ "code.google.com/p/go.tools/cmd/cover",
+ "code.google.com/p/go.tools/cmd/godoc",
+ "code.google.com/p/go.tools/cmd/vet",
+}
+
var preBuildCleanFiles = []string{
"lib/codereview",
"misc/dashboard/godashboard",
@@ -74,12 +89,16 @@ var tourPackages = []string{
}
var tourContent = []string{
+ "content",
"js",
- "prog",
"solutions",
"static",
"template",
- "tour.article",
+}
+
+var blogContent = []string{
+ "content",
+ "template",
}
// The os-arches that support the race toolchain.
@@ -89,7 +108,17 @@ var raceAvailable = []string{
"windows-amd64",
}
-var fileRe = regexp.MustCompile(`^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+))\.`)
+// The OSes that support building statically linked toolchain
+// Only ELF platforms are supported.
+var staticLinkAvailable = []string{
+ "linux",
+ "freebsd",
+ "openbsd",
+ "netbsd",
+}
+
+var fileRe = regexp.MustCompile(
+ `^(go[a-z0-9-.]+)\.(src|([a-z0-9]+)-([a-z0-9]+)(?:-([a-z0-9.]))?)\.`)
func main() {
flag.Usage = func() {
@@ -120,6 +149,7 @@ func main() {
} else {
b.OS = m[3]
b.Arch = m[4]
+ b.Label = m[5]
}
if !*upload {
log.Printf("%s: -upload=false, skipping", targ)
@@ -133,20 +163,30 @@ func main() {
if targ == "source" {
b.Source = true
} else {
- p := strings.SplitN(targ, "-", 2)
- if len(p) != 2 {
+ p := strings.SplitN(targ, "-", 3)
+ if len(p) < 2 {
log.Println("Ignoring unrecognized target:", targ)
continue
}
b.OS = p[0]
b.Arch = p[1]
+ if len(p) >= 3 {
+ b.Label = p[2]
+ }
if *includeRace {
for _, t := range raceAvailable {
- if t == targ {
+ if t == targ || strings.HasPrefix(targ, t+"-") {
b.Race = true
}
}
}
+ if *staticToolchain {
+ for _, os := range staticLinkAvailable {
+ if b.OS == os {
+ b.static = true
+ }
+ }
+ }
}
if err := b.Do(); err != nil {
log.Printf("%s: %v", targ, err)
@@ -159,8 +199,10 @@ type Build struct {
Race bool // build race toolchain
OS string
Arch string
+ Label string
root string
gopath string
+ static bool // if true, build statically linked toolchain
}
func (b *Build) Do() error {
@@ -173,11 +215,11 @@ func (b *Build) Do() error {
b.gopath = work
// Clone Go distribution and update to tag.
- _, err = b.run(work, "hg", "clone", "-q", *repo, b.root)
+ _, err = b.hgCmd(work, "clone", *repo, b.root)
if err != nil {
return err
}
- _, err = b.run(b.root, "hg", "update", *tag)
+ _, err = b.hgCmd(b.root, "update", *tag)
if err != nil {
return err
}
@@ -214,12 +256,26 @@ func (b *Build) Do() error {
return err
}
// Re-install std without -race, so that we're not left
- // with a slower, race-enabled cmd/go, cmd/godoc, etc.
+ // with a slower, race-enabled cmd/go, etc.
_, err = b.run(src, goCmd, "install", "-a", "std")
+ // Re-building go command leaves old versions of go.exe as go.exe~ on windows.
+ // See (*builder).copyFile in $GOROOT/src/cmd/go/build.go for details.
+ // Remove it manually.
+ if b.OS == "windows" {
+ os.Remove(goCmd + "~")
+ }
}
if err != nil {
return err
}
+ err = b.tools()
+ if err != nil {
+ return err
+ }
+ err = b.blog()
+ if err != nil {
+ return err
+ }
err = b.tour()
}
if err != nil {
@@ -268,6 +324,9 @@ func (b *Build) Do() error {
// Create packages.
base := fmt.Sprintf("%s.%s-%s", version, b.OS, b.Arch)
+ if b.Label != "" {
+ base += "-" + b.Label
+ }
if !strings.HasPrefix(base, "go") {
base = "go." + base
}
@@ -316,7 +375,7 @@ func (b *Build) Do() error {
dist := filepath.Join(runtime.GOROOT(), "misc/dist")
_, err = b.run("", "pkgbuild",
"--identifier", "com.googlecode.go",
- "--version", "1.0",
+ "--version", version,
"--scripts", filepath.Join(dist, "darwin/scripts"),
"--root", work,
filepath.Join(pkgdest, "com.googlecode.go.pkg"))
@@ -402,15 +461,79 @@ func (b *Build) Do() error {
return err
}
+func (b *Build) tools() error {
+ defer b.cleanGopath()
+
+ // Fetch the tool packages (without building/installing).
+ args := append([]string{"get", "-d"}, toolPaths...)
+ _, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), args...)
+ if err != nil {
+ return err
+ }
+
+ // Update the repo to the revision specified by -tool.
+ repoPath := filepath.Join(b.gopath, "src", filepath.FromSlash(toolPath))
+ _, err = b.run(repoPath, "hg", "update", *toolTag)
+ if err != nil {
+ return err
+ }
+
+ // Install tools.
+ args = append([]string{"install"}, toolPaths...)
+ _, err = b.run(b.gopath, filepath.Join(b.root, "bin", "go"), args...)
+ if err != nil {
+ return err
+ }
+
+ // Copy doc.go from go.tools/cmd/$CMD to $GOROOT/src/cmd/$CMD
+ // while rewriting "package main" to "package documentation".
+ for _, p := range toolPaths {
+ d, err := ioutil.ReadFile(filepath.Join(b.gopath, "src",
+ filepath.FromSlash(p), "doc.go"))
+ if err != nil {
+ return err
+ }
+ d = bytes.Replace(d, []byte("\npackage main\n"),
+ []byte("\npackage documentation\n"), 1)
+ cmdDir := filepath.Join(b.root, "src", "cmd", path.Base(p))
+ if err := os.MkdirAll(cmdDir, 0755); err != nil {
+ return err
+ }
+ docGo := filepath.Join(cmdDir, "doc.go")
+ if err := ioutil.WriteFile(docGo, d, 0644); err != nil {
+ return err
+ }
+ }
+
+ return nil
+}
+
+func (b *Build) blog() error {
+ defer b.cleanGopath()
+
+ // Fetch the blog repository.
+ _, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), "get", "-d", blogPath+"/blog")
+ if err != nil {
+ return err
+ }
+
+ // Copy blog content to $GOROOT/blog.
+ blogSrc := filepath.Join(b.gopath, "src", filepath.FromSlash(blogPath))
+ contentDir := filepath.Join(b.root, "blog")
+ return cpAllDir(contentDir, blogSrc, blogContent...)
+}
+
func (b *Build) tour() error {
+ defer b.cleanGopath()
+
// go get the gotour package.
- _, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), "get", *tourPath+"/gotour")
+ _, err := b.run(b.gopath, filepath.Join(b.root, "bin", "go"), "get", tourPath+"/gotour")
if err != nil {
return err
}
// Copy all the tour content to $GOROOT/misc/tour.
- importPath := filepath.FromSlash(*tourPath)
+ importPath := filepath.FromSlash(tourPath)
tourSrc := filepath.Join(b.gopath, "src", importPath)
contentDir := filepath.Join(b.root, "misc", "tour")
if err = cpAllDir(contentDir, tourSrc, tourContent...); err != nil {
@@ -423,16 +546,29 @@ 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"+ext),
- filepath.Join(b.gopath, "bin", "gotour"+ext),
+ filepath.Join(b.root, "pkg", "tool", b.OS+"_"+b.Arch, "tour"+ext()),
+ filepath.Join(b.gopath, "bin", "gotour"+ext()),
)
}
+func (b *Build) cleanGopath() {
+ for _, d := range []string{"bin", "pkg", "src"} {
+ os.RemoveAll(filepath.Join(b.gopath, d))
+ }
+}
+
+func ext() string {
+ if runtime.GOOS == "windows" {
+ return ".exe"
+ }
+ return ""
+}
+
+func (b *Build) hgCmd(dir string, args ...string) ([]byte, error) {
+ return b.run(dir, "hg", append([]string{"--config", "extensions.codereview=!"}, args...)...)
+}
+
func (b *Build) run(dir, name string, args ...string) ([]byte, error) {
buf := new(bytes.Buffer)
absName, err := lookPath(name)
@@ -489,6 +625,9 @@ func (b *Build) env() []string {
"GOROOT_FINAL="+final,
"GOPATH="+b.gopath,
)
+ if b.static {
+ env = append(env, "GO_DISTFLAGS=-s")
+ }
return env
}
@@ -548,6 +687,9 @@ func (b *Build) Upload(version string, filename string) error {
if ftype != "" {
labels = append(labels, "Type-"+ftype)
}
+ if b.Label != "" {
+ labels = append(labels, b.Label)
+ }
if *addLabel != "" {
labels = append(labels, *addLabel)
}
diff --git a/misc/dist/darwin/scripts/postinstall b/misc/dist/darwin/scripts/postinstall
index 4410a3004..13f5bff9b 100755
--- a/misc/dist/darwin/scripts/postinstall
+++ b/misc/dist/darwin/scripts/postinstall
@@ -8,11 +8,3 @@ find . -exec chmod ugo+r \{\} \;
find bin -exec chmod ugo+rx \{\} \;
find . -type d -exec chmod ugo+rx \{\} \;
chmod o-w .
-
-echo "Installing miscellaneous files:"
-XCODE_MISC_DIR="/Library/Application Support/Developer/Shared/Xcode/Specifications/"
-if [ -d "$XCODE_MISC_DIR" ]; then
- echo " XCode"
- cp $GOROOT/misc/xcode/* $XCODE_MISC_DIR
-fi
-
diff --git a/misc/emacs/go-mode.el b/misc/emacs/go-mode.el
index 6f0442aff..75b28ac73 100644
--- a/misc/emacs/go-mode.el
+++ b/misc/emacs/go-mode.el
@@ -5,7 +5,9 @@
;; license that can be found in the LICENSE file.
(require 'cl)
+(require 'etags)
(require 'ffap)
+(require 'ring)
(require 'url)
;; XEmacs compatibility guidelines
@@ -39,27 +41,44 @@
(defalias 'go--kill-whole-line
(if (fboundp 'kill-whole-line)
- 'kill-whole-line
- 'kill-entire-line))
-
+ #'kill-whole-line
+ #'kill-entire-line))
+
+;; Delete the current line without putting it in the kill-ring.
+(defun go--delete-whole-line (&optional arg)
+ ;; Emacs uses both kill-region and kill-new, Xemacs only uses
+ ;; kill-region. In both cases we turn them into operations that do
+ ;; not modify the kill ring. This solution does depend on the
+ ;; implementation of kill-line, but it's the only viable solution
+ ;; that does not require to write kill-line from scratch.
+ (flet ((kill-region (beg end)
+ (delete-region beg end))
+ (kill-new (s) ()))
+ (go--kill-whole-line arg)))
+
+;; declare-function is an empty macro that only byte-compile cares
+;; about. Wrap in always false if to satisfy Emacsen without that
+;; macro.
+(if nil
+ (declare-function go--position-bytes "go-mode" (point)))
;; 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)
+ (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.
+;; GNU Emacs 24 has prog-mode, older GNU Emacs and XEmacs do not, so
+;; copy its definition for those.
(if (not (fboundp 'prog-mode))
- (define-derived-mode prog-mode fundamental-mode "" ""))
+ (define-derived-mode prog-mode fundamental-mode "Prog"
+ "Major mode for editing source code."
+ (set (make-local-variable 'require-final-newline) mode-require-final-newline)
+ (set (make-local-variable 'parse-sexp-ignore-comments) t)
+ (setq bidi-paragraph-direction 'left-to-right)))
(defun go--regexp-enclose-in-symbol (s)
;; XEmacs does not support \_<, GNU Emacs does. In GNU Emacs we make
@@ -72,12 +91,29 @@
(concat "\\<" s "\\>")
(concat "\\_<" s "\\_>")))
+;; Move up one level of parentheses.
+(defun go-goto-opening-parenthesis (&optional legacy-unused)
+ ;; The old implementation of go-goto-opening-parenthesis had an
+ ;; optional argument to speed up the function. It didn't change the
+ ;; function's outcome.
+
+ ;; Silently fail if there's no matching opening parenthesis.
+ (condition-case nil
+ (backward-up-list)
+ (scan-error nil)))
+
+
(defconst go-dangling-operators-regexp "[^-]-\\|[^+]\\+\\|[/*&><.=|^]")
(defconst go-identifier-regexp "[[:word:][:multibyte:]]+")
(defconst go-label-regexp 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-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"
@@ -97,16 +133,95 @@
(defvar go-dangling-cache)
(defvar go-godoc-history nil)
+(defvar go--coverage-current-file-name)
(defgroup go nil
"Major mode for editing Go code"
:group 'languages)
+(defgroup go-cover nil
+ "Options specific to `cover`"
+ :group 'go)
+
(defcustom go-fontify-function-calls t
"Fontify function and method calls if this is non-nil."
:type 'boolean
:group 'go)
+(defcustom go-mode-hook nil
+ "Hook called by `go-mode'."
+ :type 'hook
+ :group 'go)
+
+(defcustom go-command "go"
+ "The 'go' command. Some users have multiple Go development
+trees and invoke the 'go' tool via a wrapper that sets GOROOT and
+GOPATH based on the current directory. Such users should
+customize this variable to point to the wrapper script."
+ :type 'string
+ :group 'go)
+
+(defcustom gofmt-command "gofmt"
+ "The 'gofmt' command. Some users may replace this with 'goimports'
+from https://github.com/bradfitz/goimports."
+ :type 'string
+ :group 'go)
+
+(defface go-coverage-untracked
+ '((t (:foreground "#505050")))
+ "Coverage color of untracked code."
+ :group 'go-cover)
+
+(defface go-coverage-0
+ '((t (:foreground "#c00000")))
+ "Coverage color for uncovered code."
+ :group 'go-cover)
+(defface go-coverage-1
+ '((t (:foreground "#808080")))
+ "Coverage color for covered code with weight 1."
+ :group 'go-cover)
+(defface go-coverage-2
+ '((t (:foreground "#748c83")))
+ "Coverage color for covered code with weight 2."
+ :group 'go-cover)
+(defface go-coverage-3
+ '((t (:foreground "#689886")))
+ "Coverage color for covered code with weight 3."
+ :group 'go-cover)
+(defface go-coverage-4
+ '((t (:foreground "#5ca489")))
+ "Coverage color for covered code with weight 4."
+ :group 'go-cover)
+(defface go-coverage-5
+ '((t (:foreground "#50b08c")))
+ "Coverage color for covered code with weight 5."
+ :group 'go-cover)
+(defface go-coverage-6
+ '((t (:foreground "#44bc8f")))
+ "Coverage color for covered code with weight 6."
+ :group 'go-cover)
+(defface go-coverage-7
+ '((t (:foreground "#38c892")))
+ "Coverage color for covered code with weight 7."
+ :group 'go-cover)
+(defface go-coverage-8
+ '((t (:foreground "#2cd495")))
+ "Coverage color for covered code with weight 8.
+For mode=set, all covered lines will have this weight."
+ :group 'go-cover)
+(defface go-coverage-9
+ '((t (:foreground "#20e098")))
+ "Coverage color for covered code with weight 9."
+ :group 'go-cover)
+(defface go-coverage-10
+ '((t (:foreground "#14ec9b")))
+ "Coverage color for covered code with weight 10."
+ :group 'go-cover)
+(defface go-coverage-covered
+ '((t (:foreground "#2cd495")))
+ "Coverage color of covered code."
+ :group 'go-cover)
+
(defvar go-mode-syntax-table
(let ((st (make-syntax-table)))
(modify-syntax-entry ?+ "." st)
@@ -144,7 +259,7 @@
(if go-fontify-function-calls
`((,(concat "\\(" go-identifier-regexp "\\)[[:space:]]*(") 1 font-lock-function-name-face) ;; function call/method name
- (,(concat "(\\(" go-identifier-regexp "\\))[[:space:]]*(") 1 font-lock-function-name-face)) ;; bracketed function call
+ (,(concat "[^[:word:][:multibyte:]](\\(" go-identifier-regexp "\\))[[:space:]]*(") 1 font-lock-function-name-face)) ;; bracketed function call
`((,go-func-meth-regexp 1 font-lock-function-name-face))) ;; method name
`(
@@ -159,6 +274,7 @@
;; 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 (go--regexp-enclose-in-symbol "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-type-name-regexp ")") 1 font-lock-type-face) ;; Method receiver without variable name
;; 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.
@@ -167,14 +283,15 @@
(defvar go-mode-map
(let ((m (make-sparse-keymap)))
- (define-key m "}" 'go-mode-insert-and-indent)
- (define-key m ")" 'go-mode-insert-and-indent)
- (define-key m "," 'go-mode-insert-and-indent)
- (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)
+ (define-key m "}" #'go-mode-insert-and-indent)
+ (define-key m ")" #'go-mode-insert-and-indent)
+ (define-key m "," #'go-mode-insert-and-indent)
+ (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-x 4 C-c C-j") #'godef-jump-other-window)
+ (define-key m (kbd "C-c C-d") #'godef-describe)
m)
"Keymap used by Go mode to implement electric keys.")
@@ -267,18 +384,6 @@ curly brace we are checking. If they match, we return non-nil."
(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))
- (>= (go-paren-level) start-nesting))
- (if (zerop (skip-chars-backward
- (if char
- (case char (?\] "^[") (?\} "^{") (?\) "^("))
- "^[{(")))
- (if (go-in-string-or-comment-p)
- (go-goto-beginning-of-string-or-comment)
- (backward-char))))))
-
(defun go--indentation-for-opening-parenthesis ()
"Return the semantic indentation for the current opening parenthesis.
@@ -295,7 +400,7 @@ current line will be returned."
(defun go-indentation-at-point ()
(save-excursion
- (let (start-nesting (outindent 0))
+ (let (start-nesting)
(back-to-indentation)
(setq start-nesting (go-paren-level))
@@ -303,7 +408,7 @@ current line will be returned."
((go-in-string-p)
(current-indentation))
((looking-at "[])}]")
- (go-goto-opening-parenthesis (char-after))
+ (go-goto-opening-parenthesis)
(if (go-previous-line-has-dangling-op-p)
(- (current-indentation) tab-width)
(go--indentation-for-opening-parenthesis)))
@@ -325,7 +430,6 @@ current line will be returned."
(interactive)
(let (indent
shift-amt
- end
(pos (- (point-max) (point)))
(point (point))
(beg (line-beginning-position)))
@@ -404,6 +508,7 @@ The following extra functions are defined:
- `go-play-buffer' and `go-play-region'
- `go-download-play'
- `godef-describe' and `godef-jump'
+- `go-coverage'
If you want to automatically run `gofmt' before saving a file,
add the following hook to your emacs configuration:
@@ -415,7 +520,7 @@ 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)))
+ (local-set-key (kbd \"M-.\") #'godef-jump)))
Please note that godef is an external dependency. You can install
it with
@@ -435,7 +540,7 @@ recommended that you look at goflymake
'(go--build-font-lock-keywords))
;; Indentation
- (set (make-local-variable 'indent-line-function) 'go-mode-indent-line)
+ (set (make-local-variable 'indent-line-function) #'go-mode-indent-line)
;; Comments
(set (make-local-variable 'comment-start) "// ")
@@ -443,12 +548,12 @@ recommended that you look at goflymake
(set (make-local-variable 'comment-use-syntax) t)
(set (make-local-variable 'comment-start-skip) "\\(//+\\|/\\*+\\)\\s *")
- (set (make-local-variable 'beginning-of-defun-function) 'go-beginning-of-defun)
- (set (make-local-variable 'end-of-defun-function) 'go-end-of-defun)
+ (set (make-local-variable 'beginning-of-defun-function) #'go-beginning-of-defun)
+ (set (make-local-variable 'end-of-defun-function) #'go-end-of-defun)
(set (make-local-variable 'parse-sexp-lookup-properties) t)
(if (boundp 'syntax-propertize-function)
- (set (make-local-variable 'syntax-propertize-function) 'go-propertize-syntax))
+ (set (make-local-variable 'syntax-propertize-function) #'go-propertize-syntax))
(set (make-local-variable 'go-dangling-cache) (make-hash-table :test 'eql))
(add-hook 'before-change-functions (lambda (x y) (setq go-dangling-cache (make-hash-table :test 'eql))) t t)
@@ -515,10 +620,9 @@ buffer."
(insert text)))))
((equal action "d")
(with-current-buffer target-buffer
- (goto-char (point-min))
- (forward-line (- from line-offset 1))
+ (go--goto-line (- from line-offset))
(incf line-offset len)
- (go--kill-whole-line len)))
+ (go--delete-whole-line len)))
(t
(error "invalid rcs patch or internal error in go--apply-rcs-patch")))))))))
@@ -543,7 +647,7 @@ buffer."
;; 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 gofmt-command nil errbuf nil "-w" tmpfile))
(if (zerop (call-process-region (point-min) (point-max) "diff" nil patchbuf nil "-n" "-" tmpfile))
(progn
(kill-buffer errbuf)
@@ -654,6 +758,9 @@ declaration."
(let ((old-point (point)))
(goto-char (point-min))
(cond
+ ((re-search-forward "^import ()" nil t)
+ (backward-char 1)
+ 'block-empty)
((re-search-forward "^import ([^)]+)" nil t)
(backward-char 2)
'block)
@@ -679,7 +786,10 @@ link in the kill ring."
(let* ((url-request-method "POST")
(url-request-extra-headers
'(("Content-Type" . "application/x-www-form-urlencoded")))
- (url-request-data (buffer-substring-no-properties start end))
+ (url-request-data
+ (encode-coding-string
+ (buffer-substring-no-properties start end)
+ 'utf-8))
(content-buf (url-retrieve
"http://play.golang.org/share"
(lambda (arg)
@@ -714,15 +824,6 @@ buffer. Tries to look for a URL at point."
(while (search-forward "\\" end t)
(put-text-property (1- (point)) (point) 'syntax-table (if (= (char-after) ?`) '(1) '(9))))))
-;; ;; Commented until we actually make use of this function
-;; (defun go--common-prefix (sequences)
-;; ;; mismatch and reduce are cl
-;; (assert sequences)
-;; (flet ((common-prefix (s1 s2)
-;; (let ((diff-pos (mismatch s1 s2)))
-;; (if diff-pos (subseq s1 0 diff-pos) s1))))
-;; (reduce #'common-prefix sequences)))
-
(defun go-import-add (arg import)
"Add a new import to the list of imports.
@@ -754,6 +855,8 @@ uncommented, otherwise a new import will be added."
(uncomment-region (line-beginning-position) (line-end-position))
(case (go-goto-imports)
('fail (message "Could not find a place to add import."))
+ ('block-empty
+ (insert "\n\t" line "\n"))
('block
(save-excursion
(re-search-backward "^import (")
@@ -765,7 +868,8 @@ uncommented, otherwise a new import will be added."
('none (insert "\nimport (\n\t" line "\n)\n")))))))
(defun go-root-and-paths ()
- (let* ((output (split-string (shell-command-to-string "go env GOROOT GOPATH") "\n"))
+ (let* ((output (split-string (shell-command-to-string (concat go-command " env GOROOT GOPATH"))
+ "\n"))
(root (car output))
(paths (split-string (cadr output) ":")))
(append (list root) paths)))
@@ -803,13 +907,13 @@ If IGNORE-CASE is non-nil, the comparison is case-insensitive."
(mapcar (lambda (file)
(let ((sub (substring file (length pkgdir) -2)))
(unless (or (go--string-prefix-p "obj/" sub) (go--string-prefix-p "tool/" sub))
- (mapconcat 'identity (cdr (split-string sub "/")) "/"))))
+ (mapconcat #'identity (cdr (split-string sub "/")) "/"))))
(if (file-directory-p dir)
(directory-files dir t "\\.a$"))))
(if (file-directory-p pkgdir)
(go--directory-dirs pkgdir)))))
(go-root-and-paths)))
- 'string<))
+ #'string<))
(defun go-unused-imports-lines ()
;; FIXME Technically, -o /dev/null fails in quite some cases (on
@@ -820,13 +924,14 @@ If IGNORE-CASE is non-nil, the comparison is case-insensitive."
(reverse (remove nil
(mapcar
(lambda (line)
- (if (string-match "^\\(.+\\):\\([[:digit:]]+\\): imported and not used: \".+\"$" line)
+ (if (string-match "^\\(.+\\):\\([[:digit:]]+\\): imported and not used: \".+\".*$" line)
(if (string= (file-truename (match-string 1 line)) (file-truename buffer-file-name))
(string-to-number (match-string 2 line)))))
(split-string (shell-command-to-string
- (if (string-match "_test\.go$" buffer-file-truename)
- "go test -c"
- "go build -o /dev/null")) "\n")))))
+ (concat go-command
+ (if (string-match "_test\.go$" buffer-file-truename)
+ " test -c"
+ " build -o /dev/null"))) "\n")))))
(defun go-remove-unused-imports (arg)
"Removes all unused imports. If ARG is non-nil, unused imports
@@ -842,40 +947,52 @@ will be commented, otherwise they will be removed completely."
(message "Cannot operate on unsaved buffer")
(setq lines (go-unused-imports-lines))
(dolist (import lines)
- (goto-char (point-min))
- (forward-line (1- import))
+ (go--goto-line import)
(beginning-of-line)
(if arg
(comment-region (line-beginning-position) (line-end-position))
- (go--kill-whole-line)))
+ (go--delete-whole-line)))
(message "Removed %d imports" (length lines)))
(if flymake-state (flymake-mode-on)))))
-(defun godef--find-file-line-column (specifier)
+(defun godef--find-file-line-column (specifier other-window)
"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")))))
+ (if (not (string-match "\\(.+\\):\\([0-9]+\\):\\([0-9]+\\)" specifier))
+ ;; We've only been given a directory name
+ (funcall (if other-window #'find-file-other-window #'find-file) specifier)
+ (let ((filename (match-string 1 specifier))
+ (line (string-to-number (match-string 2 specifier)))
+ (column (string-to-number (match-string 3 specifier))))
+ (with-current-buffer (funcall (if other-window #'find-file-other-window #'find-file) filename)
+ (go--goto-line 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")
+ (error "godef does not reliably work in XEmacs, expect bad results"))
+ (if (not (buffer-file-name (go--coverage-origin-buffer)))
+ (error "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))))
+ (call-process-region (point-min)
+ (point-max)
+ "godef"
+ nil
+ outbuf
+ nil
+ "-i"
+ "-t"
+ "-f"
+ (file-truename (buffer-file-name (go--coverage-origin-buffer)))
+ "-o"
+ (number-to-string (go--position-bytes (point))))
(with-current-buffer outbuf
(split-string (buffer-substring-no-properties (point-min) (point-max)) "\n")))))
@@ -883,13 +1000,13 @@ description at POINT."
"Describe the expression at POINT."
(interactive "d")
(condition-case nil
- (let ((description (nth 1 (godef--call point))))
- (if (string= "" description)
+ (let ((description (cdr (butlast (godef--call point) 1))))
+ (if (not description)
(message "No description found for expression at point")
- (message "%s" description)))
+ (message "%s" (mapconcat #'identity description "\n"))))
(file-error (message "Could not run godef binary"))))
-(defun godef-jump (point)
+(defun godef-jump (point &optional other-window)
"Jump to the definition of the expression at POINT."
(interactive "d")
(condition-case nil
@@ -901,9 +1018,142 @@ description at POINT."
(message "%s" file))
((go--string-prefix-p "godef: no declaration found for " file)
(message "%s" file))
+ ((go--string-prefix-p "error finding import path for " file)
+ (message "%s" file))
(t
(push-mark)
- (godef--find-file-line-column file))))
+ (ring-insert find-tag-marker-ring (point-marker))
+ (godef--find-file-line-column file other-window))))
(file-error (message "Could not run godef binary"))))
+(defun godef-jump-other-window (point)
+ (interactive "d")
+ (godef-jump point t))
+
+(defun go--goto-line (line)
+ (goto-char (point-min))
+ (forward-line (1- line)))
+
+(defun go--line-column-to-point (line column)
+ (save-excursion
+ (go--goto-line line)
+ (forward-char (1- column))
+ (point)))
+
+(defstruct go--covered
+ start-line start-column end-line end-column covered count)
+
+(defun go--coverage-file ()
+ "Return the coverage file to use, either by reading it from the
+current coverage buffer or by prompting for it."
+ (if (boundp 'go--coverage-current-file-name)
+ go--coverage-current-file-name
+ (read-file-name "Coverage file: " nil nil t)))
+
+(defun go--coverage-origin-buffer ()
+ "Return the buffer to base the coverage on."
+ (or (buffer-base-buffer) (current-buffer)))
+
+(defun go--coverage-face (count divisor)
+ "Return the intensity face for COUNT when using DIVISOR
+to scale it to a range [0,10].
+
+DIVISOR scales the absolute cover count to values from 0 to 10.
+For DIVISOR = 0 the count will always translate to 8."
+ (let* ((norm (cond
+ ((= count 0)
+ -0.1) ;; Uncovered code, set to -0.1 so n becomes 0.
+ ((= divisor 0)
+ 0.8) ;; covermode=set, set to 0.8 so n becomes 8.
+ (t
+ (/ (log count) divisor))))
+ (n (1+ (floor (* norm 9))))) ;; Convert normalized count [0,1] to intensity [0,10]
+ (concat "go-coverage-" (number-to-string n))))
+
+(defun go--coverage-make-overlay (range divisor)
+ "Create a coverage overlay for a RANGE of covered/uncovered
+code. Uses DIVISOR to scale absolute counts to a [0,10] scale."
+ (let* ((count (go--covered-count range))
+ (face (go--coverage-face count divisor))
+ (ov (make-overlay (go--line-column-to-point (go--covered-start-line range)
+ (go--covered-start-column range))
+ (go--line-column-to-point (go--covered-end-line range)
+ (go--covered-end-column range)))))
+
+ (overlay-put ov 'face face)
+ (overlay-put ov 'help-echo (format "Count: %d" count))))
+
+(defun go--coverage-clear-overlays ()
+ "Remove existing overlays and put a single untracked overlay
+over the entire buffer."
+ (remove-overlays)
+ (overlay-put (make-overlay (point-min) (point-max))
+ 'face
+ 'go-coverage-untracked))
+
+(defun go--coverage-parse-file (coverage-file file-name)
+ "Parse COVERAGE-FILE and extract coverage information and
+divisor for FILE-NAME."
+ (let (ranges
+ (max-count 0))
+ (with-temp-buffer
+ (insert-file-contents coverage-file)
+ (go--goto-line 2) ;; Skip over mode
+ (while (not (eobp))
+ (let* ((parts (split-string (buffer-substring (point-at-bol) (point-at-eol)) ":"))
+ (file (car parts))
+ (rest (split-string (nth 1 parts) "[., ]")))
+
+ (destructuring-bind
+ (start-line start-column end-line end-column num count)
+ (mapcar #'string-to-number rest)
+
+ (when (and (string= (file-name-nondirectory file) file-name))
+ (if (> count max-count)
+ (setq max-count count))
+ (push (make-go--covered :start-line start-line
+ :start-column start-column
+ :end-line end-line
+ :end-column end-column
+ :covered (/= count 0)
+ :count count)
+ ranges)))
+
+ (forward-line)))
+
+ (list ranges (if (> max-count 0) (log max-count) 0)))))
+
+(defun go-coverage (&optional coverage-file)
+ "Open a clone of the current buffer and overlay it with
+coverage information gathered via go test -coverprofile=COVERAGE-FILE.
+
+If COVERAGE-FILE is nil, it will either be inferred from the
+current buffer if it's already a coverage buffer, or be prompted
+for."
+ (interactive)
+ (let* ((cur-buffer (current-buffer))
+ (origin-buffer (go--coverage-origin-buffer))
+ (gocov-buffer-name (concat (buffer-name origin-buffer) "<gocov>"))
+ (coverage-file (or coverage-file (go--coverage-file)))
+ (ranges-and-divisor (go--coverage-parse-file
+ coverage-file
+ (file-name-nondirectory (buffer-file-name origin-buffer))))
+ (cov-mtime (nth 5 (file-attributes coverage-file)))
+ (cur-mtime (nth 5 (file-attributes (buffer-file-name origin-buffer)))))
+
+ (if (< (float-time cov-mtime) (float-time cur-mtime))
+ (message "Coverage file is older than the source file."))
+
+ (with-current-buffer (or (get-buffer gocov-buffer-name)
+ (make-indirect-buffer origin-buffer gocov-buffer-name t))
+ (set (make-local-variable 'go--coverage-current-file-name) coverage-file)
+
+ (save-excursion
+ (go--coverage-clear-overlays)
+ (dolist (range (car ranges-and-divisor))
+ (go--coverage-make-overlay range (cadr ranges-and-divisor))))
+
+ (if (not (eq cur-buffer (current-buffer)))
+ (display-buffer (current-buffer) #'display-buffer-reuse-window)))))
+
(provide 'go-mode)
diff --git a/misc/goplay/goplay.go b/misc/goplay/goplay.go
index 94d04139d..9cb7d7bfb 100644
--- a/misc/goplay/goplay.go
+++ b/misc/goplay/goplay.go
@@ -14,7 +14,6 @@ import (
"os/exec"
"path/filepath"
"regexp"
- "runtime"
"strconv"
"text/template"
)
@@ -92,10 +91,6 @@ func compile(req *http.Request) (out []byte, err error) {
// x is the base name for .go, .6, executable files
x := filepath.Join(tmpdir, "compile"+strconv.Itoa(<-uniq))
src := x + ".go"
- bin := x
- if runtime.GOOS == "windows" {
- bin += ".exe"
- }
// rewrite filename in error output
defer func() {
@@ -116,16 +111,13 @@ func compile(req *http.Request) (out []byte, err error) {
return
}
- // build x.go, creating x
+ // go run x.go
dir, file := filepath.Split(src)
- out, err = run(dir, "go", "build", "-o", bin, file)
- defer os.Remove(bin)
+ out, err = run(dir, "go", "run", file)
if err != nil {
return
}
-
- // run x
- return run("", bin)
+ return out, nil
}
// error writes compile, link, or runtime errors to the HTTP connection.
diff --git a/misc/kate/go.xml b/misc/kate/go.xml
index c187eda82..03f4f2a0c 100644
--- a/misc/kate/go.xml
+++ b/misc/kate/go.xml
@@ -70,6 +70,7 @@
<item> close </item>
<item> complex </item>
<item> copy </item>
+ <item> delete </item>
<item> imag </item>
<item> len </item>
<item> make </item>
diff --git a/misc/linkcheck/linkcheck.go b/misc/linkcheck/linkcheck.go
new file mode 100644
index 000000000..d9bfd2f76
--- /dev/null
+++ b/misc/linkcheck/linkcheck.go
@@ -0,0 +1,193 @@
+// 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.
+
+// The linkcheck command finds missing links in the godoc website.
+// It crawls a URL recursively and notes URLs and URL fragments
+// that it's seen and prints a report of missing links at the end.
+package main
+
+import (
+ "errors"
+ "flag"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "net/http"
+ "os"
+ "regexp"
+ "strings"
+ "sync"
+)
+
+var (
+ root = flag.String("root", "http://localhost:6060", "Root to crawl")
+ verbose = flag.Bool("verbose", false, "verbose")
+)
+
+var wg sync.WaitGroup // outstanding fetches
+var urlq = make(chan string) // URLs to crawl
+
+// urlFrag is a URL and its optional #fragment (without the #)
+type urlFrag struct {
+ url, frag string
+}
+
+var (
+ mu sync.Mutex
+ crawled = make(map[string]bool) // URL without fragment -> true
+ neededFrags = make(map[urlFrag][]string) // URL#frag -> who needs it
+)
+
+var aRx = regexp.MustCompile(`<a href=['"]?(/[^\s'">]+)`)
+
+// Owned by crawlLoop goroutine:
+var (
+ linkSources = make(map[string][]string) // url no fragment -> sources
+ fragExists = make(map[urlFrag]bool)
+ problems []string
+)
+
+func localLinks(body string) (links []string) {
+ seen := map[string]bool{}
+ mv := aRx.FindAllStringSubmatch(body, -1)
+ for _, m := range mv {
+ ref := m[1]
+ if strings.HasPrefix(ref, "/src/") {
+ continue
+ }
+ if !seen[ref] {
+ seen[ref] = true
+ links = append(links, m[1])
+ }
+ }
+ return
+}
+
+var idRx = regexp.MustCompile(`\bid=['"]?([^\s'">]+)`)
+
+func pageIDs(body string) (ids []string) {
+ mv := idRx.FindAllStringSubmatch(body, -1)
+ for _, m := range mv {
+ ids = append(ids, m[1])
+ }
+ return
+}
+
+// url may contain a #fragment, and the fragment is then noted as needing to exist.
+func crawl(url string, sourceURL string) {
+ if strings.Contains(url, "/devel/release") {
+ return
+ }
+ mu.Lock()
+ defer mu.Unlock()
+ var frag string
+ if i := strings.Index(url, "#"); i >= 0 {
+ frag = url[i+1:]
+ url = url[:i]
+ if frag != "" {
+ uf := urlFrag{url, frag}
+ neededFrags[uf] = append(neededFrags[uf], sourceURL)
+ }
+ }
+ if crawled[url] {
+ return
+ }
+ crawled[url] = true
+
+ wg.Add(1)
+ go func() {
+ urlq <- url
+ }()
+}
+
+func addProblem(url, errmsg string) {
+ msg := fmt.Sprintf("Error on %s: %s (from %s)", url, errmsg, linkSources[url])
+ if *verbose {
+ log.Print(msg)
+ }
+ problems = append(problems, msg)
+}
+
+func crawlLoop() {
+ for url := range urlq {
+ if err := doCrawl(url); err != nil {
+ addProblem(url, err.Error())
+ }
+ }
+}
+
+func doCrawl(url string) error {
+ defer wg.Done()
+
+ req, err := http.NewRequest("GET", url, nil)
+ if err != nil {
+ return err
+ }
+ res, err := http.DefaultTransport.RoundTrip(req)
+ if err != nil {
+ return err
+ }
+ // Handle redirects.
+ if res.StatusCode/100 == 3 {
+ newURL, err := res.Location()
+ if err != nil {
+ return fmt.Errorf("resolving redirect: %v", err)
+ }
+ if !strings.HasPrefix(newURL.String(), *root) {
+ // Skip off-site redirects.
+ return nil
+ }
+ crawl(newURL.String(), url)
+ return nil
+ }
+ if res.StatusCode != 200 {
+ return errors.New(res.Status)
+ }
+ slurp, err := ioutil.ReadAll(res.Body)
+ res.Body.Close()
+ if err != nil {
+ log.Fatalf("Error reading %s body: %v", url, err)
+ }
+ if *verbose {
+ log.Printf("Len of %s: %d", url, len(slurp))
+ }
+ body := string(slurp)
+ for _, ref := range localLinks(body) {
+ if *verbose {
+ log.Printf(" links to %s", ref)
+ }
+ dest := *root + ref
+ linkSources[dest] = append(linkSources[dest], url)
+ crawl(dest, url)
+ }
+ for _, id := range pageIDs(body) {
+ if *verbose {
+ log.Printf(" url %s has #%s", url, id)
+ }
+ fragExists[urlFrag{url, id}] = true
+ }
+ return nil
+}
+
+func main() {
+ flag.Parse()
+
+ go crawlLoop()
+ crawl(*root, "")
+
+ wg.Wait()
+ close(urlq)
+ for uf, needers := range neededFrags {
+ if !fragExists[uf] {
+ problems = append(problems, fmt.Sprintf("Missing fragment for %+v from %v", uf, needers))
+ }
+ }
+
+ for _, s := range problems {
+ fmt.Println(s)
+ }
+ if len(problems) > 0 {
+ os.Exit(1)
+ }
+}
diff --git a/misc/notepadplus/README b/misc/notepadplus/README
index 000d31746..fca4f5f09 100644
--- a/misc/notepadplus/README
+++ b/misc/notepadplus/README
@@ -1,8 +1,59 @@
-Given a Notepad++ installation at <DIR>:
+Notepad++ syntax highlighting
+-----------------------------
-1. Add the contents of userDefineLang.xml at <DIR>\userDefineLang.xml
- between <NotepadPlus> ... </NotepadPlus>
-
-2. Copy go.xml to <DIR>\plugins\APIs
+The userDefineLang.xml uses the new User Defined Language system (UDL2),
+which needs Notepad++ v6.2 or higher.
-3. Restart Notepad++
+Installing from Notepad++ Installer
+
+ 1. Add the contents of userDefineLang.xml at %APPDATA%\Notepad++\userDefineLang.xml
+ between <NotepadPlus> ... </NotepadPlus>
+ 2. Restart Notepad++
+
+Installing from Notepad++ zip/7z package
+
+ 1. Given a Notepad++ installation at <DIR>.
+ 2. Add the contents of userDefineLang.xml at <DIR>\userDefineLang.xml
+ between <NotepadPlus> ... </NotepadPlus>
+ 3. Restart Notepad++
+
+Reference
+
+ 1. http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=User_Defined_Languages
+ 2. http://notepad-plus-plus.org/news/notepad-6.2-release-udl2.html
+ 3. http://udl20.weebly.com/index.html
+
+
+Notepad++ keyword auto-completion
+---------------------------------
+
+ 1. Given a Notepad++ installation at <DIR>.
+ 2. Copy go.xml to <DIR>\plugins\APIs
+ 3. Restart Notepad++
+
+Reference
+
+ 1. http://sourceforge.net/apps/mediawiki/notepad-plus/index.php?title=Auto_Completion
+
+Notepad++ Function List
+-----------------------
+
+The functionList.xml uses the Function List Pane new feature,
+which needs Notepad++ v6.4 or higher.
+
+Installing from Notepad++ Installer
+
+ 1. Add the contents of userDefineLang.xml at %APPDATA%\Notepad++\functionList.xml
+ between <associationMap> ... </associationMap> and <parsers> ... </parsers>
+ 2. Restart Notepad++
+
+Installing from Notepad++ zip/7z package
+
+ 1. Given a Notepad++ installation at <DIR>.
+ 2. Add the contents of functionList.xml at <DIR>\functionList.xml
+ between <associationMap> ... </associationMap> and <parsers> ... </parsers>
+ 3. Restart Notepad++
+
+Reference
+
+ 1. http://notepad-plus-plus.org/features/function-list.html
diff --git a/misc/notepadplus/functionList.xml b/misc/notepadplus/functionList.xml
new file mode 100644
index 000000000..ca949f018
--- /dev/null
+++ b/misc/notepadplus/functionList.xml
@@ -0,0 +1,43 @@
+<!-- <NotepadPlus> -->
+ <!-- <functionList> -->
+ <!-- <associationMap> -->
+ <association ext=".go" id="go"/>
+
+ <!-- </associationMap> -->
+ <!-- <parsers> -->
+ <parser id="go" displayName="Go" commentExpr="((/\*.*?\*)/|(//.*?$))">
+ <classRange
+ mainExpr="^type\s+\w+\s+interface\s*\{"
+ openSymbole = "\{"
+ closeSymbole = "\}"
+ displayMode="node">
+ <className>
+ <nameExpr expr="type\s+\w+"/>
+ <nameExpr expr="\s+\w+"/>
+ <nameExpr expr="\w+"/>
+ </className>
+ <function
+ mainExpr="^\s+\w+\s*\(">
+ <functionName>
+ <funcNameExpr expr="\w+"/>
+ </functionName>
+ </function>
+ </classRange>
+ <function
+ mainExpr="(^func\s+\w+)|(^func\s*\(\s*\w*\s*\*?\s*\w+\s*\)\s*\w+)"
+ displayMode="$className->$functionName">
+ <functionName>
+ <nameExpr expr="((func\s+\w+)|(\)\s*\w+))"/>
+ <nameExpr expr="((\s+\w+)|(\)\s*\w+))"/>
+ <nameExpr expr="\w+"/>
+ </functionName>
+ <className>
+ <nameExpr expr="\w+\s*\)"/>
+ <nameExpr expr="\w+"/>
+ </className>
+ </function>
+ </parser>
+
+ <!-- </parsers> -->
+ <!-- </functionList> -->
+<!-- </NotepadPlus> -->
diff --git a/misc/notepadplus/go.xml b/misc/notepadplus/go.xml
index 237ef6b4b..59e4116d6 100644
--- a/misc/notepadplus/go.xml
+++ b/misc/notepadplus/go.xml
@@ -1,68 +1,133 @@
-<NotepadPlus>
+<NotepadPlus>
<!-- Go Programming Language builtins and keywords -->
<AutoComplete>
- <KeyWord name="append"/>
- <KeyWord name="bool" />
- <KeyWord name="break" />
+ <KeyWord name="append" func="yes">
+ <Overload retVal="[]Type">
+ <Param name="slice []Type" />
+ <Param name="elems ...Type" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="bool" />
+ <KeyWord name="break" />
<KeyWord name="byte" />
- <KeyWord name="cap" />
- <KeyWord name="case" />
- <KeyWord name="chan" />
- <KeyWord name="close" />
- <KeyWord name="complex" />
- <KeyWord name="complex128" />
- <KeyWord name="complex64" />
- <KeyWord name="const" />
+ <KeyWord name="cap" func="yes">
+ <Overload retVal="int">
+ <Param name="v Type" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="case" />
+ <KeyWord name="chan" />
+ <KeyWord name="close" func="yes">
+ <Overload retVal="">
+ <Param name="c chan<- Type" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="complex" func="yes">
+ <Overload retVal="ComplexType">
+ <Param name="r" />
+ <Param name="i FloatType" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="complex128" />
+ <KeyWord name="complex64" />
+ <KeyWord name="const" />
<KeyWord name="continue" />
- <KeyWord name="copy" />
- <KeyWord name="default" />
- <KeyWord name="defer" />
+ <KeyWord name="copy" func="yes">
+ <Overload retVal="int">
+ <Param name="dst" />
+ <Param name="src []Type" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="default" />
+ <KeyWord name="defer" />
+ <KeyWord name="delete" func="yes">
+ <Overload retVal="">
+ <Param name="m map[Type]Type1" />
+ <Param name="key Type" />
+ </Overload>
+ </KeyWord>
<KeyWord name="else" />
<KeyWord name="error" />
- <KeyWord name="fallthrough" />
- <KeyWord name="false" />
- <KeyWord name="float32" />
+ <KeyWord name="fallthrough" />
+ <KeyWord name="false" />
+ <KeyWord name="float32" />
<KeyWord name="float64" />
<KeyWord name="for" />
- <KeyWord name="func" />
- <KeyWord name="go" />
- <KeyWord name="goto" />
- <KeyWord name="if" />
+ <KeyWord name="func" />
+ <KeyWord name="go" />
+ <KeyWord name="goto" />
+ <KeyWord name="if" />
<KeyWord name="iota" />
- <KeyWord name="imag" />
- <KeyWord name="import" />
- <KeyWord name="int" />
- <KeyWord name="int16" />
- <KeyWord name="int32" />
- <KeyWord name="int64" />
- <KeyWord name="int8" />
- <KeyWord name="interface" />
- <KeyWord name="len" />
- <KeyWord name="make" />
- <KeyWord name="map" />
- <KeyWord name="new" />
- <KeyWord name="nil" />
- <KeyWord name="package" />
- <KeyWord name="panic" />
- <KeyWord name="print" />
- <KeyWord name="println" />
- <KeyWord name="range" />
- <KeyWord name="real" />
- <KeyWord name="recover" />
+ <KeyWord name="imag" func="yes">
+ <Overload retVal="FloatType">
+ <Param name="c ComplexType" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="import" />
+ <KeyWord name="int" />
+ <KeyWord name="int16" />
+ <KeyWord name="int32" />
+ <KeyWord name="int64" />
+ <KeyWord name="int8" />
+ <KeyWord name="interface" />
+ <KeyWord name="len" func="yes">
+ <Overload retVal="int">
+ <Param name="v Type" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="make" func="yes">
+ <Overload retVal="Type">
+ <Param name="Type" />
+ <Param name="size IntegerType" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="map" />
+ <KeyWord name="new" func="yes">
+ <Overload retVal="*Type">
+ <Param name="Type" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="nil" />
+ <KeyWord name="package" />
+ <KeyWord name="panic" func="yes">
+ <Overload retVal="">
+ <Param name="v interface{}" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="print" func="yes">
+ <Overload retVal="">
+ <Param name="args ...Type" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="println" func="yes">
+ <Overload retVal="" >
+ <Param name="args ...Type" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="range" />
+ <KeyWord name="real" func="yes">
+ <Overload retVal="FloatType">
+ <Param name="c ComplexType" />
+ </Overload>
+ </KeyWord>
+ <KeyWord name="recover" func="yes">
+ <Overload retVal="interface{}">
+ </Overload>
+ </KeyWord>
<KeyWord name="return" />
<KeyWord name="rune" />
- <KeyWord name="select" />
- <KeyWord name="string" />
- <KeyWord name="struct" />
- <KeyWord name="switch" />
- <KeyWord name="true" />
- <KeyWord name="type" />
- <KeyWord name="uint" />
- <KeyWord name="uint16" />
- <KeyWord name="uint32" />
- <KeyWord name="uint64" />
- <KeyWord name="uint8" />
- <KeyWord name="uintptr" />
- <KeyWord name="var" />
- </AutoComplete>
+ <KeyWord name="select" />
+ <KeyWord name="string" />
+ <KeyWord name="struct" />
+ <KeyWord name="switch" />
+ <KeyWord name="true" />
+ <KeyWord name="type" />
+ <KeyWord name="uint" />
+ <KeyWord name="uint16" />
+ <KeyWord name="uint32" />
+ <KeyWord name="uint64" />
+ <KeyWord name="uint8" />
+ <KeyWord name="uintptr" />
+ <KeyWord name="var" />
+ </AutoComplete>
</NotepadPlus>
diff --git a/misc/notepadplus/userDefineLang.xml b/misc/notepadplus/userDefineLang.xml
index 2954aad48..9751f7901 100644
--- a/misc/notepadplus/userDefineLang.xml
+++ b/misc/notepadplus/userDefineLang.xml
@@ -1,36 +1,64 @@
<!-- <NotepadPlus> -->
- <UserLang name="go" ext="go">
+ <UserLang name="go" ext="go" udlVersion="2.1">
<Settings>
- <Global caseIgnored="no" />
- <TreatAsSymbol comment="no" commentLine="no" />
- <Prefix words1="no" words2="no" words3="no" words4="no" />
+ <Global caseIgnored="no" allowFoldOfComments="yes" foldCompact="no" forcePureLC="0" decimalSeparator="0" />
+ <Prefix Keywords1="no" Keywords2="no" Keywords3="no" Keywords4="no" Keywords5="no" Keywords6="no" Keywords7="no" Keywords8="no" />
</Settings>
<KeywordLists>
- <Keywords name="Delimiters">&quot;`0&quot;`</Keywords>
- <Keywords name="Folder+"></Keywords>
- <Keywords name="Folder-"></Keywords>
- <Keywords name="Operators">( ) [ ] { } ... . , _ &amp; ^ % &gt; &lt; ! = + - * | :</Keywords>
- <Keywords name="Comment"> 1/* 2*/ 0//</Keywords>
- <Keywords name="Words1">append bool break byte cap case chan close complex complex128 complex64 const continue copy default defer else error fallthrough false float32 float64 for func go goto if iota imag import int int16 int32 int64 int8 interface len make map new nil package panic print println range real recover return rune select string struct switch true type uint uint16 uint32 uint64 uint8 uintptr var</Keywords>
- <Keywords name="Words2"></Keywords>
- <Keywords name="Words3"></Keywords>
- <Keywords name="Words4"></Keywords>
+ <Keywords name="Comments">00// 01 02 03/* 04*/</Keywords>
+ <Keywords name="Numbers, prefix1"></Keywords>
+ <Keywords name="Numbers, prefix2">0x 0X</Keywords>
+ <Keywords name="Numbers, extras1">a b c d e f A B C D E F</Keywords>
+ <Keywords name="Numbers, extras2"></Keywords>
+ <Keywords name="Numbers, suffix1"></Keywords>
+ <Keywords name="Numbers, suffix2">i</Keywords>
+ <Keywords name="Numbers, range"></Keywords>
+ <Keywords name="Operators1">( ) [ ] { } ... , ; &amp; ^ % &gt; &lt; ! = + - * / | :</Keywords>
+ <Keywords name="Operators2"></Keywords>
+ <Keywords name="Folders in code1, open"></Keywords>
+ <Keywords name="Folders in code1, middle"></Keywords>
+ <Keywords name="Folders in code1, close"></Keywords>
+ <Keywords name="Folders in code2, open"></Keywords>
+ <Keywords name="Folders in code2, middle"></Keywords>
+ <Keywords name="Folders in code2, close"></Keywords>
+ <Keywords name="Folders in comment, open"></Keywords>
+ <Keywords name="Folders in comment, middle"></Keywords>
+ <Keywords name="Folders in comment, close"></Keywords>
+ <Keywords name="Keywords1">break default func interface select case defer go map struct chan else goto package switch const fallthrough if range type continue for import return var</Keywords>
+ <Keywords name="Keywords2">bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr true false iota nil</Keywords>
+ <Keywords name="Keywords3">append cap close complex copy delete imag len make new panic print println real recover _</Keywords>
+ <Keywords name="Keywords4"></Keywords>
+ <Keywords name="Keywords5"></Keywords>
+ <Keywords name="Keywords6"></Keywords>
+ <Keywords name="Keywords7"></Keywords>
+ <Keywords name="Keywords8"></Keywords>
+ <Keywords name="Delimiters">00&quot; 01\ 02&quot; 03&apos; 04\ 05&apos; 06` 07 08` 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23</Keywords>
</KeywordLists>
<Styles>
- <WordsStyle name="DEFAULT" styleID="11" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="FOLDEROPEN" styleID="12" fgColor="FFFF00" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="FOLDERCLOSE" styleID="13" fgColor="0B243B" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="KEYWORD1" styleID="5" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="1" />
- <WordsStyle name="KEYWORD2" styleID="6" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="1" />
- <WordsStyle name="KEYWORD3" styleID="7" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="KEYWORD4" styleID="8" fgColor="A00000" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="COMMENT" styleID="1" fgColor="AAAAAA" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="COMMENT LINE" styleID="2" fgColor="AAAAAA" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="NUMBER" styleID="4" fgColor="A52A2A" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="OPERATOR" styleID="10" fgColor="8000FF" bgColor="FFFFFF" fontName="" fontStyle="1" />
- <WordsStyle name="DELIMINER1" styleID="14" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="DELIMINER2" styleID="15" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" />
- <WordsStyle name="DELIMINER3" styleID="16" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" />
+ <WordsStyle name="DEFAULT" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="COMMENTS" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="LINE COMMENTS" fgColor="008000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="NUMBERS" fgColor="A52A2A" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="KEYWORDS1" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
+ <WordsStyle name="KEYWORDS2" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
+ <WordsStyle name="KEYWORDS3" fgColor="AA0000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="KEYWORDS4" fgColor="A00000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="KEYWORDS5" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="KEYWORDS6" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="KEYWORDS7" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="KEYWORDS8" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="OPERATORS" fgColor="8000FF" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
+ <WordsStyle name="FOLDER IN CODE1" fgColor="8000FF" bgColor="FFFFFF" fontName="" fontStyle="1" nesting="0" />
+ <WordsStyle name="FOLDER IN CODE2" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="FOLDER IN COMMENT" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="DELIMITERS1" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="DELIMITERS2" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="DELIMITERS3" fgColor="0000FF" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="DELIMITERS4" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="DELIMITERS5" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="DELIMITERS6" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="DELIMITERS7" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
+ <WordsStyle name="DELIMITERS8" fgColor="000000" bgColor="FFFFFF" fontName="" fontStyle="0" nesting="0" />
</Styles>
</UserLang>
<!-- </NotepadPlus> -->
diff --git a/misc/pprof b/misc/pprof
index f471c7395..1fc8d3621 100755
--- a/misc/pprof
+++ b/misc/pprof
@@ -78,6 +78,8 @@
use strict;
use warnings;
use Getopt::Long;
+use File::Temp;
+use File::Copy;
my $PPROF_VERSION = "1.5";
@@ -103,12 +105,12 @@ my $GV = "gv";
my $KCACHEGRIND = "kcachegrind";
my $PS2PDF = "ps2pdf";
# These are used for dynamic profiles
-my $CURL = "curl";
# These are the web pages that servers need to support for dynamic profiles
my $HEAP_PAGE = "/pprof/heap";
my $THREAD_PAGE = "/pprof/thread";
my $PROFILE_PAGE = "/pprof/profile"; # must support cgi-param "?seconds=#"
+my $BLOCK_PAGE = "/pprof/block";
my $PMUPROFILE_PAGE = "/pprof/pmuprofile(?:\\?.*)?"; # must support cgi-param
# ?seconds=#&event=x&period=n
my $GROWTH_PAGE = "/pprof/growth";
@@ -134,6 +136,13 @@ my @prefix_list = ();
my $sep_symbol = '_fini';
my $sep_address = undef;
+my $OS = $^O;
+my $DEVNULL = "/dev/null";
+if ($^O =~ /MSWin32|cygwin|msys/) {
+ $OS = "windows";
+ $DEVNULL = "NUL";
+}
+
##### Argument parsing #####
sub usage_string {
@@ -154,7 +163,7 @@ pprof [options] <profile>
The /<service> can be $HEAP_PAGE, $PROFILE_PAGE, /pprof/pmuprofile,
$GROWTH_PAGE, $CONTENTION_PAGE, /pprof/wall,
- $THREAD_PAGE, or /pprof/filteredprofile.
+ $THREAD_PAGE, $BLOCK_PAGE or /pprof/filteredprofile.
For instance:
pprof http://myserver.com:80$HEAP_PAGE
If /<service> is omitted, the service defaults to $PROFILE_PAGE (cpu profiling).
@@ -286,8 +295,9 @@ sub Init() {
# Setup tmp-file name and handler to clean it up.
# We do this in the very beginning so that we can use
# error() and cleanup() function anytime here after.
- $main::tmpfile_sym = "/tmp/pprof$$.sym";
- $main::tmpfile_ps = "/tmp/pprof$$";
+ $main::tmpfile_sym = File::Temp->new()->filename;
+ $main::tmpfile_ps = File::Temp->new()->filename;
+
$main::next_tmpfile = 0;
$SIG{'INT'} = \&sighandler;
@@ -492,7 +502,7 @@ sub Init() {
# Remote profiling without a binary (using $SYMBOL_PAGE instead)
if (IsProfileURL($ARGV[0])) {
$main::use_symbol_page = 1;
- } elsif (IsSymbolizedProfileFile($ARGV[0])) {
+ } elsif ($ARGV[0] && IsSymbolizedProfileFile($ARGV[0])) {
$main::use_symbolized_profile = 1;
$main::prog = $UNKNOWN_BINARY; # will be set later from the profile file
}
@@ -696,7 +706,7 @@ sub ReadlineMightFail {
sub RunGV {
my $fname = shift;
my $bg = shift; # "" or " &" if we should run in background
- if (!system("$GV --version >/dev/null 2>&1")) {
+ if (!system("$GV --version >$DEVNULL 2>&1")) {
# Options using double dash are supported by this gv version.
# Also, turn on noantialias to better handle bug in gv for
# postscript files with large dimensions.
@@ -1246,7 +1256,7 @@ sub Disassemble {
"--start-address=0x$start_addr " .
"--stop-address=0x$end_addr $prog");
- if (system("$objdump --help >/dev/null 2>&1") != 0) {
+ if (system("$objdump --help >$DEVNULL 2>&1") != 0) {
# objdump must not exist. Fall back to go tool objdump.
$objdump = "go tool objdump";
$cmd = "$objdump $prog 0x$start_addr 0x$end_addr";
@@ -1381,7 +1391,7 @@ sub PrintListing {
sub HtmlListingHeader {
return <<'EOF';
-<DOCTYPE html>
+<!DOCTYPE html>
<html>
<head>
<title>Pprof listing</title>
@@ -2616,6 +2626,7 @@ sub RemoveUninterestingFrames {
'operator new[]',
# Go
'catstring',
+ 'cnew',
'copyin',
'gostring',
'gostringsize',
@@ -2640,6 +2651,8 @@ sub RemoveUninterestingFrames {
'unsafe.New',
'runtime.mallocgc',
'runtime.catstring',
+ 'runtime.cnew',
+ 'runtime.cnewarray',
'runtime.growslice',
'runtime.ifaceT2E',
'runtime.ifaceT2I',
@@ -2965,10 +2978,9 @@ sub IsSymbolizedProfileFile {
sub CheckSymbolPage {
my $url = SymbolPageURL();
print STDERR "Read $url\n";
- open(SYMBOL, "$CURL -s '$url' |");
- my $line = <SYMBOL>;
+
+ my $line = FetchHTTP($url);
$line =~ s/\r//g; # turn windows-looking lines into unix-looking lines
- close(SYMBOL);
unless (defined($line)) {
error("$url doesn't exist\n");
}
@@ -2991,7 +3003,7 @@ sub IsProfileURL {
sub ParseProfileURL {
my $profile_name = shift;
if (defined($profile_name) &&
- $profile_name =~ m,^(?:(https?)://|)([^/:]+):(\d+)(|\@\d+)(|/|(.*?)($PROFILE_PAGE|$PMUPROFILE_PAGE|$HEAP_PAGE|$GROWTH_PAGE|$THREAD_PAGE|$CONTENTION_PAGE|$WALL_PAGE|$FILTEREDPROFILE_PAGE))$,o) {
+ $profile_name =~ m,^(?:(https?)://|)([^/:]+):(\d+)(|\@\d+)(|/|(.*?)($PROFILE_PAGE|$PMUPROFILE_PAGE|$HEAP_PAGE|$GROWTH_PAGE|$THREAD_PAGE|$BLOCK_PAGE|$CONTENTION_PAGE|$WALL_PAGE|$FILTEREDPROFILE_PAGE))$,o) {
# $7 is $PROFILE_PAGE/$HEAP_PAGE/etc. $5 is *everything* after
# the hostname, as long as that everything is the empty string,
# a slash, or something ending in $PROFILE_PAGE/$HEAP_PAGE/etc.
@@ -3010,35 +3022,16 @@ sub SymbolPageURL {
sub FetchProgramName() {
my ($scheme, $host, $port, $prefix, $path) = ParseProfileURL($main::pfile_args[0]);
my $url = "$scheme://$host:$port$prefix$PROGRAM_NAME_PAGE";
- my $command_line = "$CURL -s '$url'";
- open(CMDLINE, "$command_line |") or error($command_line);
- my $cmdline = <CMDLINE>;
+
+ my $cmdline = FetchHTTP($url);
+ $cmdline =~ s/\n.*//s; # first line only
$cmdline =~ s/\r//g; # turn windows-looking lines into unix-looking lines
- close(CMDLINE);
error("Failed to get program name from $url\n") unless defined($cmdline);
$cmdline =~ s/\x00.+//; # Remove argv[1] and latters.
$cmdline =~ s!\n!!g; # Remove LFs.
return $cmdline;
}
-# Gee, curl's -L (--location) option isn't reliable at least
-# with its 7.12.3 version. Curl will forget to post data if
-# there is a redirection. This function is a workaround for
-# curl. Redirection happens on borg hosts.
-sub ResolveRedirectionForCurl {
- my $url = shift;
- my $command_line = "$CURL -s --head '$url'";
- open(CMDLINE, "$command_line |") or error($command_line);
- while (<CMDLINE>) {
- s/\r//g; # turn windows-looking lines into unix-looking lines
- if (/^Location: (.*)/) {
- $url = $1;
- }
- }
- close(CMDLINE);
- return $url;
-}
-
# Reads a symbol map from the file handle name given as $1, returning
# the resulting symbol map. Also processes variables relating to symbols.
# Currently, the only variable processed is 'binary=<value>' which updates
@@ -3090,14 +3083,15 @@ sub FetchSymbols {
$symbol_map = {};
my $post_data = join("+", sort((map {"0x" . "$_"} @pcs)));
- open(POSTFILE, ">$main::tmpfile_sym");
- print POSTFILE $post_data;
- close(POSTFILE);
-
my $url = SymbolPageURL();
- $url = ResolveRedirectionForCurl($url);
- my $command_line = "$CURL -sd '\@$main::tmpfile_sym' '$url'";
- open(SYMBOL, "$command_line |") or error($command_line);
+ my $content = PostHTTP($url, $post_data);
+
+ my $tmp_symbol = File::Temp->new()->filename;
+ open(SYMBOL, ">$tmp_symbol");
+ print SYMBOL $content;
+ close(SYMBOL);
+
+ open(SYMBOL, "<$tmp_symbol") || error("$tmp_symbol");
ReadSymbols(*SYMBOL{IO}, $symbol_map);
close(SYMBOL);
}
@@ -3163,7 +3157,7 @@ sub FetchDynamicProfile {
my $profile_file = MakeProfileBaseName($binary_name, $profile_name);
my $url;
- my $curl_timeout;
+ my $timeout;
if (($path =~ m/$PROFILE_PAGE/) || ($path =~ m/$PMUPROFILE_PAGE/)) {
if ($path =~ m/$PROFILE_PAGE/) {
$url = sprintf("$scheme://$host:$port$prefix$path?seconds=%d",
@@ -3177,8 +3171,7 @@ sub FetchDynamicProfile {
$url = sprintf("$scheme://$profile_name" . "seconds=%d",
$main::opt_seconds);
}
- $curl_timeout = sprintf("--max-time %d",
- int($main::opt_seconds * 1.01 + 60));
+ $timeout = int($main::opt_seconds * 1.01 + 60);
} else {
# For non-CPU profiles, we add a type-extension to
# the target profile file name.
@@ -3186,22 +3179,15 @@ sub FetchDynamicProfile {
$suffix =~ s,/,.,g;
$profile_file .= "$suffix";
$url = "$scheme://$host:$port$prefix$path";
- $curl_timeout = "";
}
- my $profile_dir = $ENV{"PPROF_TMPDIR"} || ($ENV{HOME} . "/pprof");
- if (!(-d $profile_dir)) {
- mkdir($profile_dir)
- || die("Unable to create profile directory $profile_dir: $!\n");
- }
- my $tmp_profile = "$profile_dir/.tmp.$profile_file";
- my $real_profile = "$profile_dir/$profile_file";
+ my $tmp_profile = File::Temp->new()->filename;
+ my $real_profile = File::Temp->new()->filename;
if ($fetch_name_only > 0) {
return $real_profile;
}
- my $cmd = "$CURL $curl_timeout -s -o $tmp_profile '$url'";
if (($path =~ m/$PROFILE_PAGE/) || ($path =~ m/$PMUPROFILE_PAGE/)){
print STDERR "Gathering CPU profile from $url for $main::opt_seconds seconds to\n ${real_profile}\n";
if ($encourage_patience) {
@@ -3211,12 +3197,17 @@ sub FetchDynamicProfile {
print STDERR "Fetching $path profile from $host:$port to\n ${real_profile}\n";
}
- (system($cmd) == 0) || error("Failed to get profile: $cmd: $!\n");
- open(TMPPROF, "$tmp_profile") || error("Cannot open $tmp_profile: $!\n");
- my $line = <TMPPROF>;
- close(TMPPROF);
+ my $content = FetchHTTP($url, $timeout);
+
+ open(OUTFILE, ">$tmp_profile");
+ binmode(OUTFILE);
+ print OUTFILE $content;
+ close(OUTFILE);
+
+ my $line = $content;
$line !~ /^Could not enable CPU profiling/ || error($line);
- (system("mv $tmp_profile $real_profile") == 0) || error("Unable to rename profile\n");
+
+ copy($tmp_profile, $real_profile) || error("Unable to copy profile\n");
print STDERR "Wrote profile to $real_profile\n";
$main::collected_profile = $real_profile;
return $main::collected_profile;
@@ -4423,7 +4414,7 @@ sub MapToSymbols {
# 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).
- if (system("$addr2line --help >/dev/null 2>&1") != 0) {
+ if (system("$addr2line --help >$DEVNULL 2>&1") != 0) {
MapSymbolsWithNM($image, $offset, $pclist, $symbols);
return;
}
@@ -4441,7 +4432,7 @@ sub MapToSymbols {
if (defined($sep_address)) {
# Only add " -i" to addr2line if the binary supports it.
# addr2line --help returns 0, but not if it sees an unknown flag first.
- if (system("$cmd -i --help >/dev/null 2>&1") == 0) {
+ if (system("$cmd -i --help >$DEVNULL 2>&1") == 0) {
$cmd .= " -i";
} else {
$sep_address = undef; # no need for sep_address if we don't support -i
@@ -4596,7 +4587,12 @@ sub ConfigureObjTools {
(-e $prog_file) || error("$prog_file does not exist.\n");
# Follow symlinks (at least for systems where "file" supports that)
- my $file_type = `/usr/bin/file -L $prog_file 2>/dev/null || /usr/bin/file $prog_file`;
+ my $file_cmd = "/usr/bin/file -L $prog_file 2>$DEVNULL || /usr/bin/file $prog_file 2>$DEVNULL";
+ if ($^O eq "MSWin32") {
+ $file_cmd = "file -L $prog_file 2>NUL || file $prog_file 2>NUL";
+ }
+ my $file_type = `$file_cmd`;
+
if ($file_type =~ /64-bit/) {
# Change $address_length to 16 if the program file is ELF 64-bit.
# We can't detect this from many (most?) heap or lock contention
@@ -4605,14 +4601,13 @@ sub ConfigureObjTools {
$address_length = 16;
}
- if ($file_type =~ /MS Windows/) {
+ if (($file_type =~ /MS Windows/) || ($OS eq "windows")) {
# For windows, we provide a version of nm and addr2line as part of
# the opensource release, which is capable of parsing
# Windows-style PDB executables. It should live in the path, or
# in the same directory as pprof.
$obj_tool_map{"nm_pdb"} = "nm-pdb";
$obj_tool_map{"addr2line_pdb"} = "addr2line-pdb";
- $obj_tool_map{"is_windows"} = "true";
}
if ($file_type =~ /Mach-O/) {
@@ -4664,9 +4659,59 @@ sub ConfigureTool {
return $path;
}
+# FetchHTTP retrieves a URL using either curl or LWP::UserAgent.
+# It returns the entire body of the page on success, or exits the program
+# with an error message on any failure.
+sub FetchHTTP {
+ my $url = shift;
+ my $timeout = shift; # optional, in seconds
+ eval "use LWP::UserAgent ();";
+ if ($@) {
+ my @max;
+ push @max, "--max-time", $timeout if $timeout;
+ open(my $fh, "-|", "curl", @max, "-s", $url) or error("Neither LWP::UserAgent nor curl is installed: $!\n");
+ my $slurp = do { local $/; <$fh> };
+ close($fh);
+ if ($? != 0) {
+ error("Error fetching $url with curl: exit $?")
+ }
+ return $slurp;
+ }
+ my $ua = LWP::UserAgent->new;
+ $ua->timeout($timeout) if $timeout;
+ my $res = $ua->get($url);
+ error("Failed to fetch $url\n") unless $res->is_success();
+ return $res->content();
+}
+
+sub PostHTTP {
+ my ($url, $post_data) = @_;
+ eval "use LWP::UserAgent ();";
+ if ($@) {
+ open(POSTFILE, ">$main::tmpfile_sym");
+ print POSTFILE $post_data;
+ close(POSTFILE);
+
+ open(my $fh, "-|", "curl", "-s", "-d", "\@$main::tmpfile_sym", $url) or error("Neither LWP::UserAgent nor curl is installed: $!\n");
+ my $slurp = do { local $/; <$fh> };
+ close($fh);
+ if ($? != 0) {
+ error("Error fetching $url with curl: exit $?")
+ }
+ return $slurp;
+ }
+ my $req = HTTP::Request->new(POST => $url);
+ $req->content($post_data);
+ my $ua = LWP::UserAgent->new;
+ my $res = $ua->request($req);
+ error("Failed to POST to $url\n") unless $res->is_success();
+ return $res->content();
+}
+
sub cleanup {
- unlink($main::tmpfile_sym);
- unlink(keys %main::tempnames);
+ unlink($main::tmpfile_sym) if defined $main::tmpfile_sym;
+ unlink(keys %main::tempnames) if %main::tempnames;
+ unlink($main::collected_profile) if defined $main::collected_profile;
# We leave any collected profiles in $HOME/pprof in case the user wants
# to look at them later. We print a message informing them of this.
@@ -4798,29 +4843,23 @@ sub GetProcedureBoundaries {
# in an incompatible way. So first we test whether our nm supports
# --demangle and -f.
my $demangle_flag = "";
- if (system("$nm --demangle $image >/dev/null 2>&1") == 0) {
+ if (system("$nm --demangle $image >$DEVNULL 2>&1") == 0) {
# In this mode, we do "nm --demangle <foo>"
$demangle_flag = "--demangle";
}
my $flatten_flag = "";
- if (system("$nm -f $image >/dev/null 2>&1") == 0) {
+ if (system("$nm -f $image >$DEVNULL 2>&1") == 0) {
$flatten_flag = "-f";
}
# 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",
+ " $image 2>$DEVNULL",
"$nm -D -n $flatten_flag $demangle_flag" .
- " $image 2>/dev/null",
+ " $image 2>$DEVNULL",
# go tool nm is for Go binaries
- "go tool nm $image 2>/dev/null | sort");
-
- # If the executable is an MS Windows Go executable, we'll
- # have set up obj_tool_map("is_windows").
- if (exists $obj_tool_map{"is_windows"}) {
- @nm_commands = ("go tool nm $image 2>/dev/null | sort");
- }
+ "go tool nm $image 2>$DEVNULL | sort");
foreach my $nm_command (@nm_commands) {
my $symbol_table = GetProcedureBoundariesViaNm($nm_command, $regexp);
diff --git a/misc/swig/callback/callback.cc b/misc/swig/callback/callback.cc
new file mode 100644
index 000000000..eac24fba0
--- /dev/null
+++ b/misc/swig/callback/callback.cc
@@ -0,0 +1,15 @@
+// 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.
+
+// This .cc file will be automatically compiled by the go tool and
+// included in the package.
+
+#include <string>
+#include "callback.h"
+
+std::string Caller::call() {
+ if (callback_ != 0)
+ return callback_->run();
+ return "";
+}
diff --git a/misc/swig/callback/callback.h b/misc/swig/callback/callback.h
index 80232a8b3..97bf73cc2 100644
--- a/misc/swig/callback/callback.h
+++ b/misc/swig/callback/callback.h
@@ -16,9 +16,5 @@ public:
~Caller() { delCallback(); }
void delCallback() { delete callback_; callback_ = 0; }
void setCallback(Callback *cb) { delCallback(); callback_ = cb; }
- std::string call() {
- if (callback_ != 0)
- return callback_->run();
- return "";
- }
+ std::string call();
};
diff --git a/misc/vim/autoload/go/complete.vim b/misc/vim/autoload/go/complete.vim
index cc1013b7d..8dd43de4a 100644
--- a/misc/vim/autoload/go/complete.vim
+++ b/misc/vim/autoload/go/complete.vim
@@ -28,43 +28,75 @@ if len(s:goarch) == 0
endif
endif
+function! go#complete#PackageMembers(package, member)
+ silent! let content = system('godoc ' . a:package)
+ if v:shell_error || !len(content)
+ return []
+ endif
+ let lines = filter(split(content, "\n"),"v:val !~ '^\\s\\+$'")
+ try
+ let mx1 = '^\s\+\(\S+\)\s\+=\s\+.*'
+ let mx2 = '^\%(const\|var\|type\|func\) \([A-Z][^ (]\+\).*'
+ let candidates =
+ \ map(filter(copy(lines), 'v:val =~ mx1'), 'substitute(v:val, mx1, "\\1", "")')
+ \ + map(filter(copy(lines), 'v:val =~ mx2'), 'substitute(v:val, mx2, "\\1", "")')
+ return filter(candidates, '!stridx(v:val, a:member)')
+ catch
+ return []
+ endtry
+endfunction
+
function! go#complete#Package(ArgLead, CmdLine, CursorPos)
let dirs = []
+ let words = split(a:CmdLine, '\s\+', 1)
+ if len(words) > 2
+ " Complete package members
+ return go#complete#PackageMembers(words[1], words[2])
+ endif
+
if executable('go')
- let goroot = substitute(system('go env GOROOT'), '\n', '', 'g')
- if v:shell_error
- echo '\'go env GOROOT\' failed'
- endif
+ let goroot = substitute(system('go env GOROOT'), '\n', '', 'g')
+ if v:shell_error
+ echomsg '\'go env GOROOT\' failed'
+ endif
else
- let goroot = $GOROOT
+ let goroot = $GOROOT
endif
if len(goroot) != 0 && isdirectory(goroot)
- let dirs += [ goroot ]
+ let dirs += [goroot]
endif
- let workspaces = split($GOPATH, ':')
+ let pathsep = ':'
+ if s:goos == 'windows'
+ let pathsep = ';'
+ endif
+ let workspaces = split($GOPATH, pathsep)
if workspaces != []
- let dirs += workspaces
+ let dirs += workspaces
endif
if len(dirs) == 0
- " should not happen
- return []
+ " should not happen
+ return []
endif
let ret = {}
for dir in dirs
- let root = expand(dir . '/pkg/' . s:goos . '_' . s:goarch)
- for i in split(globpath(root, a:ArgLead.'*'), "\n")
- if isdirectory(i)
- let i .= '/'
- elseif i !~ '\.a$'
- continue
- endif
- let i = substitute(substitute(i[len(root)+1:], '[\\]', '/', 'g'), '\.a$', '', 'g')
- let ret[i] = i
+ " this may expand to multiple lines
+ let root = split(expand(dir . '/pkg/' . s:goos . '_' . s:goarch), "\n")
+ call add(root, expand(dir . '/src'))
+ for r in root
+ for i in split(globpath(r, a:ArgLead.'*'), "\n")
+ if isdirectory(i)
+ let i .= '/'
+ elseif i !~ '\.a$'
+ continue
+ endif
+ let i = substitute(substitute(i[len(r)+1:], '[\\]', '/', 'g'), '\.a$', '', 'g')
+ let ret[i] = i
+ endfor
endfor
endfor
return sort(keys(ret))
diff --git a/misc/vim/compiler/go.vim b/misc/vim/compiler/go.vim
new file mode 100644
index 000000000..2c8cce497
--- /dev/null
+++ b/misc/vim/compiler/go.vim
@@ -0,0 +1,30 @@
+" 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.
+"
+" compiler/go.vim: Vim compiler file for Go.
+
+if exists("current_compiler")
+ finish
+endif
+let current_compiler = "go"
+
+if exists(":CompilerSet") != 2
+ command -nargs=* CompilerSet setlocal <args>
+endif
+
+let s:save_cpo = &cpo
+set cpo-=C
+
+CompilerSet makeprg=go\ build
+CompilerSet errorformat=
+ \%-G#\ %.%#,
+ \%A%f:%l:%c:\ %m,
+ \%A%f:%l:\ %m,
+ \%C%*\\s%m,
+ \%-G%.%#
+
+let &cpo = s:save_cpo
+unlet s:save_cpo
+
+" vim:ts=4:sw=4:et
diff --git a/misc/vim/ftplugin/go.vim b/misc/vim/ftplugin/go.vim
new file mode 100644
index 000000000..8066733cf
--- /dev/null
+++ b/misc/vim/ftplugin/go.vim
@@ -0,0 +1,17 @@
+" 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.
+"
+" go.vim: Vim filetype plugin for Go.
+
+if exists("b:did_ftplugin")
+ finish
+endif
+let b:did_ftplugin = 1
+
+setlocal comments=s1:/*,mb:*,ex:*/,://
+setlocal commentstring=//\ %s
+
+let b:undo_ftplugin = "setl com< cms<"
+
+" vim:ts=4:sw=4:et
diff --git a/misc/vim/ftplugin/go/fmt.vim b/misc/vim/ftplugin/go/fmt.vim
index 30814fdfd..5f7976f5f 100644
--- a/misc/vim/ftplugin/go/fmt.vim
+++ b/misc/vim/ftplugin/go/fmt.vim
@@ -12,15 +12,35 @@
" It tries to preserve cursor position and avoids
" replacing the buffer with stderr output.
"
+" Options:
+"
+" g:go_fmt_commands [default=1]
+"
+" Flag to indicate whether to enable the commands listed above.
+"
+" g:gofmt_command [default="gofmt"]
+"
+" Flag naming the gofmt executable to use.
+"
if exists("b:did_ftplugin_go_fmt")
finish
endif
-command! -buffer Fmt call s:GoFormat()
+if !exists("g:go_fmt_commands")
+ let g:go_fmt_commands = 1
+endif
+
+if !exists("g:gofmt_command")
+ let g:gofmt_command = "gofmt"
+endif
+
+if g:go_fmt_commands
+ command! -buffer Fmt call s:GoFormat()
+endif
function! s:GoFormat()
let view = winsaveview()
- silent %!gofmt
+ silent execute "%!" . g:gofmt_command
if v:shell_error
let errors = []
for line in getline(1, line('$'))
diff --git a/misc/vim/ftplugin/go/import.vim b/misc/vim/ftplugin/go/import.vim
index 1d969e460..91c8697a4 100644
--- a/misc/vim/ftplugin/go/import.vim
+++ b/misc/vim/ftplugin/go/import.vim
@@ -24,23 +24,40 @@
" imported, an error will be displayed and the buffer will be
" untouched.
"
-" In addition to these commands, there are also two shortcuts mapped:
+" If you would like to add shortcuts, you can do so by doing the following:
"
-" \f - Runs :Import fmt
-" \F - Runs :Drop fmt
+" Import fmt
+" au Filetype go nnoremap <buffer> <LocalLeader>f :Import fmt<CR>
"
-" The backslash is the default maplocalleader, so it is possible that
+" Drop fmt
+" au Filetype go nnoremap <buffer> <LocalLeader>F :Drop fmt<CR>
+"
+" Import the word under your cursor
+" au Filetype go nnoremap <buffer> <LocalLeader>k
+" \ :exe 'Import ' . expand('<cword>')<CR>
+"
+" The backslash '\' is the default maplocalleader, so it is possible that
" your vim is set to use a different character (:help maplocalleader).
"
+" Options:
+"
+" g:go_import_commands [default=1]
+"
+" Flag to indicate whether to enable the commands listed above.
+"
if exists("b:did_ftplugin_go_import")
finish
endif
-command! -buffer -nargs=? -complete=customlist,go#complete#Package Drop call s:SwitchImport(0, '', <f-args>)
-command! -buffer -nargs=1 -complete=customlist,go#complete#Package Import call s:SwitchImport(1, '', <f-args>)
-command! -buffer -nargs=* -complete=customlist,go#complete#Package ImportAs call s:SwitchImport(1, <f-args>)
-map <buffer> <LocalLeader>f :Import fmt<CR>
-map <buffer> <LocalLeader>F :Drop fmt<CR>
+if !exists("g:go_import_commands")
+ let g:go_import_commands = 1
+endif
+
+if g:go_import_commands
+ command! -buffer -nargs=? -complete=customlist,go#complete#Package Drop call s:SwitchImport(0, '', <f-args>)
+ command! -buffer -nargs=1 -complete=customlist,go#complete#Package Import call s:SwitchImport(1, '', <f-args>)
+ command! -buffer -nargs=* -complete=customlist,go#complete#Package ImportAs call s:SwitchImport(1, <f-args>)
+endif
function! s:SwitchImport(enabled, localname, path)
let view = winsaveview()
diff --git a/misc/vim/ftplugin/go/test.sh b/misc/vim/ftplugin/go/test.sh
index a6e31d8a3..d8a5b8951 100755
--- a/misc/vim/ftplugin/go/test.sh
+++ b/misc/vim/ftplugin/go/test.sh
@@ -29,13 +29,13 @@ test_one() {
vim -e -s -u /dev/null -U /dev/null --noplugin -c "source import.vim" \
-c "$1" -c 'wq! test.go' base.go
# ensure blank lines are treated correctly
- if ! gofmt test.go | cmp test.go; then
+ if ! gofmt test.go | cmp test.go -; then
echo 2>&1 "gofmt conflict"
gofmt test.go | diff -u test.go - | sed "s/^/ /" 2>&1
fail=1
return
fi
- if ! grep -P -q "(?s)$2" test.go; then
+ if ! [[ $(cat test.go) =~ $2 ]]; then
echo 2>&1 "$2 did not match"
cat test.go | sed "s/^/ /" 2>&1
fail=1
diff --git a/misc/vim/plugin/godoc.vim b/misc/vim/plugin/godoc.vim
index a7b84de74..a145d313f 100644
--- a/misc/vim/plugin/godoc.vim
+++ b/misc/vim/plugin/godoc.vim
@@ -3,6 +3,20 @@
" license that can be found in the LICENSE file.
"
" godoc.vim: Vim command to see godoc.
+"
+"
+" Commands:
+"
+" :Godoc
+"
+" Open the relevant Godoc for either the word[s] passed to the command or
+" the, by default, the word under the cursor.
+"
+" Options:
+"
+" g:go_godoc_commands [default=1]
+"
+" Flag to indicate whether to enable the commands listed above.
if exists("g:loaded_godoc")
finish
@@ -12,6 +26,16 @@ let g:loaded_godoc = 1
let s:buf_nr = -1
let s:last_word = ''
+if !exists('g:go_godoc_commands')
+ let g:go_godoc_commands = 1
+endif
+
+if g:go_godoc_commands
+ command! -nargs=* -range -complete=customlist,go#complete#Package Godoc :call s:Godoc(<f-args>)
+endif
+
+nnoremap <silent> <Plug>(godoc-keyword) :<C-u>call <SID>Godoc('')<CR>
+
function! s:GodocView()
if !bufexists(s:buf_nr)
leftabove new
@@ -42,6 +66,13 @@ function! s:GodocView()
endfunction
function! s:GodocWord(word)
+ if !executable('godoc')
+ echohl WarningMsg
+ echo "godoc command not found."
+ echo " install with: go get code.google.com/p/go.tools/cmd/godoc"
+ echohl None
+ return 0
+ endif
let word = a:word
silent! let content = system('godoc ' . word)
if v:shell_error || !len(content)
@@ -49,12 +80,12 @@ function! s:GodocWord(word)
silent! let content = system('godoc ' . s:last_word.'/'.word)
if v:shell_error || !len(content)
echo 'No documentation found for "' . word . '".'
- return
+ return 0
endif
let word = s:last_word.'/'.word
else
echo 'No documentation found for "' . word . '".'
- return
+ return 0
endif
endif
let s:last_word = word
@@ -65,34 +96,35 @@ function! s:GodocWord(word)
silent! normal gg
setlocal nomodifiable
setfiletype godoc
+ return 1
endfunction
function! s:Godoc(...)
- let word = join(a:000, ' ')
- if !len(word)
+ if !len(a:000)
let oldiskeyword = &iskeyword
setlocal iskeyword+=.
let word = expand('<cword>')
let &iskeyword = oldiskeyword
+ let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g')
+ let words = split(word, '\.\ze[^./]\+$')
+ else
+ let words = a:000
endif
- let word = substitute(word, '[^a-zA-Z0-9\\/._~-]', '', 'g')
- let words = split(word, '\.')
if !len(words)
return
endif
- 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
+ if 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] . '(')
+ silent! normal zt
+ return
+ endif
+ echo 'No documentation found for "' . words[1] . '".'
endif
- echo 'No documentation found for "' . word . '".'
endif
endfunction
-command! -nargs=* -range -complete=customlist,go#complete#Package Godoc :call s:Godoc(<q-args>)
-nnoremap <silent> <Plug>(godoc-keyword) :<C-u>call <SID>Godoc('')<CR>
-
" vim:ts=4:sw=4:et
diff --git a/misc/vim/readme.txt b/misc/vim/readme.txt
index cb3a52073..b8469f927 100644
--- a/misc/vim/readme.txt
+++ b/misc/vim/readme.txt
@@ -14,6 +14,12 @@ To use all the Vim plugins, add these lines to your $HOME/.vimrc.
If you want to select fewer plugins, use the instructions in the rest of
this file.
+A popular configuration is to gofmt Go source files when they are saved.
+To do that, add this line to the end of your $HOME/.vimrc.
+
+ autocmd FileType go autocmd BufWritePre <buffer> Fmt
+
+
Vim syntax highlighting
-----------------------
@@ -47,9 +53,10 @@ Vim filetype plugins
To install one of the available filetype plugins:
1. Same as 1 above.
- 2. Copy or link one or more plugins from ftplugin/go/*.vim to the
- Go-specific ftplugin directory underneath your vim runtime directory
- (normally $HOME/.vim/ftplugin/go/*.vim).
+ 2. Copy or link ftplugin/go.vim to the ftplugin directory underneath your vim
+ runtime directory (normally $HOME/.vim/ftplugin). Copy or link one or more
+ additional plugins from ftplugin/go/*.vim to the Go-specific subdirectory
+ in the same place ($HOME/.vim/ftplugin/go/*.vim).
3. Add the following line to your .vimrc file (normally $HOME/.vimrc):
filetype plugin on
@@ -68,6 +75,21 @@ To install automatic indentation:
filetype indent on
+Vim compiler plugin
+-------------------
+
+To install the compiler plugin:
+
+ 1. Same as 1 above.
+ 2. Copy or link compiler/go.vim to the compiler directory underneath your vim
+ runtime directory (normally $HOME/.vim/compiler).
+ 3. Activate the compiler plugin with ":compiler go". To always enable the
+ compiler plugin in Go source files add an autocommand to your .vimrc file
+ (normally $HOME/.vimrc):
+
+ autocmd FileType go compiler go
+
+
Godoc plugin
------------
diff --git a/misc/vim/syntax/godoc.vim b/misc/vim/syntax/godoc.vim
index 82f78aa3c..bd4443f7c 100644
--- a/misc/vim/syntax/godoc.vim
+++ b/misc/vim/syntax/godoc.vim
@@ -7,7 +7,7 @@ if exists("b:current_syntax")
endif
syn case match
-syn match godocTitle "^\([A-Z]*\)$"
+syn match godocTitle "^\([A-Z][A-Z ]*\)$"
command -nargs=+ HiLink hi def link <args>
diff --git a/misc/xcode/4/go4xcode.sh b/misc/xcode/4/go4xcode.sh
index fbdd0cfed..4b0125e46 100755
--- a/misc/xcode/4/go4xcode.sh
+++ b/misc/xcode/4/go4xcode.sh
@@ -3,7 +3,7 @@
# Use of this source code is governed by a BSD-style
# license that can be found in the LICENSE file.
-# Illustrates how a Go language specification can be installed for Xcode 4.x.,
+# Illustrates how a Go language specification can be installed for Xcode 4+,
# to enable syntax coloring, by adding an entry to a plugindata file.
#
# FIXME: Write a decent Xcode plugin to handle the file type association and
@@ -14,21 +14,33 @@ set -e
# Assumes Xcode 4+.
XCODE_MAJOR_VERSION=`xcodebuild -version | awk 'NR == 1 {print substr($2,1,1)}'`
if [ "$XCODE_MAJOR_VERSION" -lt "4" ]; then
- echo "Xcode 4.x not found."
+ echo "Xcode 4+ not found."
exit 1
fi
-# DVTFOUNDATION_DIR may vary depending on Xcode setup. Change it to reflect
-# your current Xcode setup. Find suitable path with e.g.:
+# DVTFOUNDATION_DIR may vary depending on Xcode setup. If Xcode has installed
+# the `xcode-select` command, it will be determined automatically. Otherwise,
+# change it to reflect your current Xcode setup. Find suitable path with e.g.:
#
# find / -type f -name 'DVTFoundation.xcplugindata' 2> /dev/null
#
-# Example of DVTFOUNDATION_DIR's from "default" Xcode 4.x setups;
+# Example of DVTFOUNDATION_DIR's from "default" Xcode 4+ setups;
#
# Xcode 4.1: /Developer/Library/PrivateFrameworks/DVTFoundation.framework/Versions/A/Resources/
# Xcode 4.3: /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/
-#
+
+# Defaults to Xcode 4.3's DVTFOUNDATION_DIR. Path is modified automatically if
+# `xcode-select` command is available, as mentioned above.
DVTFOUNDATION_DIR="/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/"
+
+if type "xcode-select" > /dev/null; then
+ DVTFOUNDATION_DIR=`xcode-select --print-path`
+ DVTFOUNDATION_DIR+="/.."
+ FRAMEWORK_NAME="DVTFoundation.framework"
+ DVTFOUNDATION_DIR=`find $DVTFOUNDATION_DIR -name $FRAMEWORK_NAME -print`
+ DVTFOUNDATION_DIR+="/Versions/A/Resources"
+fi
+
PLUGINDATA_FILE="DVTFoundation.xcplugindata"
PLISTBUDDY=/usr/libexec/PlistBuddy
@@ -84,7 +96,7 @@ GO_LANG_ENTRY="
</plist>
"
-echo "Backing up plugindata file."
+echo "Backing up plugindata file (copied to $PLUGINDATA_FILE.bak)."
cp $DVTFOUNDATION_DIR/$PLUGINDATA_FILE $DVTFOUNDATION_DIR/$PLUGINDATA_FILE.bak
echo "Adding Go language specification entry."