runtime: Remove now unnecessary pad field from ParFor.
It is not needed due to the removal of the ctx field. Reviewed-on: https://go-review.googlesource.com/16525 From-SVN: r229616
This commit is contained in:
parent
725e1be340
commit
af146490bb
1007 changed files with 86529 additions and 30520 deletions
|
@ -1,4 +1,4 @@
|
|||
16f69a4007a1903da4055a496882b514e05f45f3
|
||||
4b6b496579225cdd897130f6d6fd18ecb100bf99
|
||||
|
||||
The first line of this file holds the git revision number of the last
|
||||
merge done from the gofrontend repository.
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
883bc6ed0ea815293fe6309d66f967ea60630e87
|
||||
bb03defe933c89fee44be675d7aa0fbd893ced30
|
||||
|
||||
The first line of this file holds the git revision number of the
|
||||
last merge done from the master library sources.
|
||||
|
|
|
@ -233,12 +233,15 @@ toolexeclibgogodir = $(toolexeclibgodir)/go
|
|||
toolexeclibgogo_DATA = \
|
||||
go/ast.gox \
|
||||
go/build.gox \
|
||||
go/constant.gox \
|
||||
go/doc.gox \
|
||||
go/format.gox \
|
||||
go/importer.gox \
|
||||
go/parser.gox \
|
||||
go/printer.gox \
|
||||
go/scanner.gox \
|
||||
go/token.gox
|
||||
go/token.gox \
|
||||
go/types.gox
|
||||
|
||||
toolexeclibgohashdir = $(toolexeclibgodir)/hash
|
||||
|
||||
|
@ -292,7 +295,8 @@ toolexeclibgomath_DATA = \
|
|||
toolexeclibgomimedir = $(toolexeclibgodir)/mime
|
||||
|
||||
toolexeclibgomime_DATA = \
|
||||
mime/multipart.gox
|
||||
mime/multipart.gox \
|
||||
mime/quotedprintable.gox
|
||||
|
||||
toolexeclibgonetdir = $(toolexeclibgodir)/net
|
||||
|
||||
|
@ -676,46 +680,74 @@ go_math_files = \
|
|||
go/math/tanh.go \
|
||||
go/math/unsafe.go
|
||||
|
||||
if LIBGO_IS_OPENBSD
|
||||
go_mime_type_file = go/mime/type_openbsd.go
|
||||
else
|
||||
if LIBGO_IS_FREEBSD
|
||||
go_mime_type_file = go/mime/type_freebsd.go
|
||||
else
|
||||
if LIBGO_IS_DRAGONFLY
|
||||
go_mime_type_file = go/mime/type_dragonfly.go
|
||||
else
|
||||
go_mime_type_file =
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
go_mime_files = \
|
||||
go/mime/encodedword.go \
|
||||
go/mime/grammar.go \
|
||||
go/mime/mediatype.go \
|
||||
go/mime/type.go \
|
||||
go/mime/type_unix.go
|
||||
go/mime/type_unix.go \
|
||||
$(go_mime_type_file)
|
||||
|
||||
if LIBGO_IS_LINUX
|
||||
go_net_cgo_file = go/net/cgo_linux.go
|
||||
go_net_sock_file = go/net/sock_linux.go
|
||||
go_net_sockopt_file = go/net/sockopt_linux.go
|
||||
go_net_sockoptip_file = go/net/sockoptip_linux.go go/net/sockoptip_posix.go
|
||||
go_net_cgo_sock_file = go/net/cgo_socknew.go
|
||||
go_net_cgo_res_file = go/net/cgo_resnew.go
|
||||
else
|
||||
if LIBGO_IS_IRIX
|
||||
go_net_cgo_file = go/net/cgo_linux.go
|
||||
go_net_sock_file = go/net/sock_linux.go
|
||||
go_net_sockopt_file = go/net/sockopt_linux.go
|
||||
go_net_sockoptip_file = go/net/sockoptip_linux.go go/net/sockoptip_posix.go
|
||||
go_net_cgo_sock_file = go/net/cgo_socknew.go
|
||||
go_net_cgo_res_file = go/net/cgo_resnew.go
|
||||
else
|
||||
if LIBGO_IS_SOLARIS
|
||||
go_net_cgo_file = go/net/cgo_linux.go
|
||||
go_net_cgo_file = go/net/cgo_solaris.go
|
||||
go_net_sock_file = go/net/sock_stub.go
|
||||
go_net_sockopt_file = go/net/sockopt_solaris.go
|
||||
go_net_sockoptip_file = go/net/sockoptip_stub.go
|
||||
go_net_cgo_sock_file = go/net/cgo_socknew.go
|
||||
go_net_cgo_res_file = go/net/cgo_resnew.go
|
||||
else
|
||||
if LIBGO_IS_FREEBSD
|
||||
go_net_cgo_file = go/net/cgo_bsd.go
|
||||
go_net_sock_file = go/net/sock_bsd.go
|
||||
go_net_sockopt_file = go/net/sockopt_bsd.go
|
||||
go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_posix.go
|
||||
go_net_cgo_sock_file = go/net/cgo_sockold.go
|
||||
go_net_cgo_res_file = go/net/cgo_resold.go
|
||||
else
|
||||
if LIBGO_IS_NETBSD
|
||||
go_net_cgo_file = go/net/cgo_netbsd.go
|
||||
go_net_sock_file = go/net/sock_bsd.go
|
||||
go_net_sockopt_file = go/net/sockopt_bsd.go
|
||||
go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_posix.go
|
||||
go_net_cgo_sock_file = go/net/cgo_sockold.go
|
||||
go_net_cgo_res_file = go/net/cgo_resnew.go
|
||||
else
|
||||
go_net_cgo_file = go/net/cgo_bsd.go
|
||||
go_net_sock_file = go/net/sock_bsd.go
|
||||
go_net_sockopt_file = go/net/sockopt_bsd.go
|
||||
go_net_sockoptip_file = go/net/sockoptip_bsd.go go/net/sockoptip_posix.go
|
||||
go_net_cgo_sock_file = go/net/cgo_sockold.go
|
||||
go_net_cgo_res_file = go/net/cgo_resold.go
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -731,10 +763,14 @@ else
|
|||
if LIBGO_IS_DRAGONFLY
|
||||
go_net_sendfile_file = go/net/sendfile_dragonfly.go
|
||||
else
|
||||
if LIBGO_IS_SOLARIS
|
||||
go_net_sendfile_file = go/net/sendfile_solaris.go
|
||||
else
|
||||
go_net_sendfile_file = go/net/sendfile_stub.go
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
if LIBGO_IS_LINUX
|
||||
go_net_interface_file = go/net/interface_linux.go
|
||||
|
@ -775,15 +811,22 @@ endif
|
|||
endif
|
||||
|
||||
go_net_common_files = \
|
||||
go/net/addrselect.go \
|
||||
$(go_net_cloexec_file) \
|
||||
go/net/conf.go \
|
||||
go/net/dial.go \
|
||||
go/net/dnsclient.go \
|
||||
go/net/dnsclient_unix.go \
|
||||
go/net/dnsconfig_unix.go \
|
||||
go/net/dnsmsg.go \
|
||||
go/net/fd_mutex.go \
|
||||
go/net/fd_posix.go \
|
||||
go/net/fd_unix.go \
|
||||
go/net/file.go \
|
||||
go/net/file_unix.go \
|
||||
go/net/hook.go \
|
||||
go/net/hook_cloexec.go \
|
||||
go/net/hook_unix.go \
|
||||
go/net/hosts.go \
|
||||
go/net/interface.go \
|
||||
$(go_net_interface_file) \
|
||||
|
@ -796,6 +839,7 @@ go_net_common_files = \
|
|||
go/net/lookup_unix.go \
|
||||
go/net/mac.go \
|
||||
go/net/net.go \
|
||||
go/net/nss.go \
|
||||
go/net/parse.go \
|
||||
go/net/pipe.go \
|
||||
go/net/fd_poll_runtime.go \
|
||||
|
@ -803,7 +847,6 @@ go_net_common_files = \
|
|||
go/net/port_unix.go \
|
||||
go/net/race0.go \
|
||||
$(go_net_sendfile_file) \
|
||||
go/net/singleflight.go \
|
||||
go/net/sock_posix.go \
|
||||
$(go_net_sock_file) \
|
||||
go/net/sockopt_posix.go \
|
||||
|
@ -821,6 +864,8 @@ go_net_common_files = \
|
|||
go_net_files = \
|
||||
go/net/cgo_unix.go \
|
||||
$(go_net_cgo_file) \
|
||||
$(go_net_cgo_res_file) \
|
||||
$(go_net_cgo_sock_file) \
|
||||
$(go_net_common_files)
|
||||
|
||||
go_netgo_files = \
|
||||
|
@ -919,6 +964,32 @@ else
|
|||
go_os_pipe_file = go/os/pipe_bsd.go
|
||||
endif
|
||||
|
||||
if LIBGO_IS_DARWIN
|
||||
go_os_sticky_file = go/os/sticky_bsd.go
|
||||
else
|
||||
if LIBGO_IS_DRAGONFLY
|
||||
go_os_sticky_file = go/os/sticky_bsd.go
|
||||
else
|
||||
if LIBGO_IS_FREEBSD
|
||||
go_os_sticky_file = go/os/sticky_bsd.go
|
||||
else
|
||||
if LIBGO_IS_NETBSD
|
||||
go_os_sticky_file = go/os/sticky_bsd.go
|
||||
else
|
||||
if LIBGO_IS_OPENBSD
|
||||
go_os_sticky_file = go/os/sticky_bsd.go
|
||||
else
|
||||
if LIBGO_IS_SOLARIS
|
||||
go_os_sticky_file = go/os/sticky_bsd.go
|
||||
else
|
||||
go_os_sticky_file = go/os/sticky_notbsd.go
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
go_os_files = \
|
||||
$(go_os_dir_file) \
|
||||
go/os/dir.go \
|
||||
|
@ -939,6 +1010,7 @@ go_os_files = \
|
|||
$(go_os_pipe_file) \
|
||||
go/os/proc.go \
|
||||
$(go_os_stat_file) \
|
||||
$(go_os_sticky_file) \
|
||||
go/os/str.go \
|
||||
$(go_os_sys_file) \
|
||||
$(go_os_cloexec_file) \
|
||||
|
@ -959,6 +1031,7 @@ go_reflect_makefunc_c_file = \
|
|||
go/reflect/makefunc_ffi_c.c
|
||||
|
||||
go_regexp_files = \
|
||||
go/regexp/backtrack.go \
|
||||
go/regexp/exec.go \
|
||||
go/regexp/onepass.go \
|
||||
go/regexp/regexp.go
|
||||
|
@ -974,7 +1047,6 @@ go_runtime_files = \
|
|||
go/runtime/error.go \
|
||||
go/runtime/extern.go \
|
||||
go/runtime/mem.go \
|
||||
go/runtime/softfloat64.go \
|
||||
version.go
|
||||
|
||||
version.go: s-version; @true
|
||||
|
@ -1012,6 +1084,7 @@ go_strconv_files = \
|
|||
go/strconv/atof.go \
|
||||
go/strconv/atoi.go \
|
||||
go/strconv/decimal.go \
|
||||
go/strconv/doc.go \
|
||||
go/strconv/extfloat.go \
|
||||
go/strconv/ftoa.go \
|
||||
go/strconv/isprint.go \
|
||||
|
@ -1019,6 +1092,7 @@ go_strconv_files = \
|
|||
go/strconv/quote.go
|
||||
|
||||
go_strings_files = \
|
||||
go/strings/compare.go \
|
||||
go/strings/reader.go \
|
||||
go/strings/replace.go \
|
||||
go/strings/search.go \
|
||||
|
@ -1048,6 +1122,7 @@ endif
|
|||
endif
|
||||
|
||||
go_log_syslog_files = \
|
||||
go/log/syslog/doc.go \
|
||||
go/log/syslog/syslog.go \
|
||||
$(go_syslog_file)
|
||||
go_syslog_c_files = \
|
||||
|
@ -1186,6 +1261,7 @@ crypto_rand_file =
|
|||
endif
|
||||
|
||||
go_crypto_rand_files = \
|
||||
go/crypto/rand/eagain.go \
|
||||
go/crypto/rand/rand.go \
|
||||
go/crypto/rand/rand_unix.go \
|
||||
$(crypto_rand_file) \
|
||||
|
@ -1222,6 +1298,37 @@ go_crypto_tls_files = \
|
|||
go/crypto/tls/prf.go \
|
||||
go/crypto/tls/ticket.go \
|
||||
go/crypto/tls/tls.go
|
||||
|
||||
if LIBGO_IS_LINUX
|
||||
go_crypto_x509_root_file = go/crypto/x509/root_linux.go
|
||||
else
|
||||
if LIBGO_IS_SOLARIS
|
||||
go_crypto_x509_root_file = go/crypto/x509/root_solaris.go
|
||||
else
|
||||
if LIBGO_IS_DRAGONFLY
|
||||
go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
|
||||
else
|
||||
if LIBGO_IS_FREEBSD
|
||||
go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
|
||||
else
|
||||
if LIBGO_IS_NETBSD
|
||||
go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
|
||||
else
|
||||
if LIBGO_IS_OPENBSD
|
||||
go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
|
||||
else
|
||||
if LIBGO_IS_DARWIN
|
||||
go_crypto_x509_root_file = go/crypto/x509/root_darwin.go
|
||||
else
|
||||
go_crypto_x509_root_file =
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
go_crypto_x509_files = \
|
||||
go/crypto/x509/cert_pool.go \
|
||||
go/crypto/x509/pem_decrypt.go \
|
||||
|
@ -1229,6 +1336,7 @@ go_crypto_x509_files = \
|
|||
go/crypto/x509/pkcs8.go \
|
||||
go/crypto/x509/root.go \
|
||||
go/crypto/x509/root_unix.go \
|
||||
$(go_crypto_x509_root_file) \
|
||||
go/crypto/x509/sec1.go \
|
||||
go/crypto/x509/verify.go \
|
||||
go/crypto/x509/x509.go
|
||||
|
@ -1246,6 +1354,7 @@ go_database_sql_driver_files = \
|
|||
|
||||
go_debug_dwarf_files = \
|
||||
go/debug/dwarf/buf.go \
|
||||
go/debug/dwarf/class_string.go \
|
||||
go/debug/dwarf/const.go \
|
||||
go/debug/dwarf/entry.go \
|
||||
go/debug/dwarf/line.go \
|
||||
|
@ -1337,6 +1446,9 @@ go_go_build_files = \
|
|||
go/go/build/doc.go \
|
||||
go/go/build/read.go \
|
||||
go/go/build/syslist.go
|
||||
go_go_constant_files = \
|
||||
go/go/constant/go14.go \
|
||||
go/go/constant/value.go
|
||||
go_go_doc_files = \
|
||||
go/go/doc/comment.go \
|
||||
go/go/doc/doc.go \
|
||||
|
@ -1347,6 +1459,8 @@ go_go_doc_files = \
|
|||
go/go/doc/synopsis.go
|
||||
go_go_format_files = \
|
||||
go/go/format/format.go
|
||||
go_go_importer_files = \
|
||||
go/go/importer/importer.go
|
||||
go_go_parser_files = \
|
||||
go/go/parser/interface.go \
|
||||
go/go/parser/parser.go
|
||||
|
@ -1360,6 +1474,47 @@ go_go_token_files = \
|
|||
go/go/token/position.go \
|
||||
go/go/token/serialize.go \
|
||||
go/go/token/token.go
|
||||
go_go_types_files = \
|
||||
go/go/types/api.go \
|
||||
go/go/types/assignments.go \
|
||||
go/go/types/builtins.go \
|
||||
go/go/types/call.go \
|
||||
go/go/types/check.go \
|
||||
go/go/types/conversions.go \
|
||||
go/go/types/decl.go \
|
||||
go/go/types/errors.go \
|
||||
go/go/types/eval.go \
|
||||
go/go/types/expr.go \
|
||||
go/go/types/exprstring.go \
|
||||
go/go/types/go12.go \
|
||||
go/go/types/initorder.go \
|
||||
go/go/types/labels.go \
|
||||
go/go/types/lookup.go \
|
||||
go/go/types/methodset.go \
|
||||
go/go/types/object.go \
|
||||
go/go/types/objset.go \
|
||||
go/go/types/operand.go \
|
||||
go/go/types/ordering.go \
|
||||
go/go/types/package.go \
|
||||
go/go/types/predicates.go \
|
||||
go/go/types/resolver.go \
|
||||
go/go/types/return.go \
|
||||
go/go/types/scope.go \
|
||||
go/go/types/selection.go \
|
||||
go/go/types/stmt.go \
|
||||
go/go/types/sizes.go \
|
||||
go/go/types/type.go \
|
||||
go/go/types/typestring.go \
|
||||
go/go/types/typexpr.go \
|
||||
go/go/types/universe.go
|
||||
|
||||
go_go_internal_gcimporter_files = \
|
||||
go/go/internal/gcimporter/exportdata.go \
|
||||
go/go/internal/gcimporter/gcimporter.go
|
||||
go_go_internal_gccgoimporter_files = \
|
||||
go/go/internal/gccgoimporter/gccgoinstallation.go \
|
||||
go/go/internal/gccgoimporter/importer.go \
|
||||
go/go/internal/gccgoimporter/parser.go
|
||||
|
||||
go_hash_adler32_files = \
|
||||
go/hash/adler32/adler32.go
|
||||
|
@ -1399,6 +1554,10 @@ go_image_gif_files = \
|
|||
go/image/gif/reader.go \
|
||||
go/image/gif/writer.go
|
||||
|
||||
go_image_internal_imageutil_files = \
|
||||
go/image/internal/imageutil/imageutil.go \
|
||||
go/image/internal/imageutil/impl.go
|
||||
|
||||
go_image_jpeg_files = \
|
||||
go/image/jpeg/fdct.go \
|
||||
go/image/jpeg/huffman.go \
|
||||
|
@ -1416,15 +1575,46 @@ go_index_suffixarray_files = \
|
|||
go/index/suffixarray/qsufsort.go \
|
||||
go/index/suffixarray/suffixarray.go
|
||||
|
||||
go_internal_format_files = \
|
||||
go/internal/format/format.go
|
||||
go_internal_singleflight_files = \
|
||||
go/internal/singleflight/singleflight.go
|
||||
|
||||
if LIBGO_IS_LINUX
|
||||
internal_syscall_unix_getrandom_file = go/internal/syscall/unix/getrandom_linux.go
|
||||
else
|
||||
internal_syscall_unix_getrandom_file =
|
||||
endif
|
||||
|
||||
go_internal_syscall_unix_files = \
|
||||
go/internal/syscall/unix/dummy.go \
|
||||
$(internal_syscall_unix_getrandom_file)
|
||||
|
||||
go_internal_testenv_files = \
|
||||
go/internal/testenv/testenv.go
|
||||
go_internal_trace_files = \
|
||||
go/internal/trace/goroutines.go \
|
||||
go/internal/trace/parser.go
|
||||
|
||||
go_io_ioutil_files = \
|
||||
go/io/ioutil/ioutil.go \
|
||||
go/io/ioutil/tempfile.go
|
||||
|
||||
go_math_big_files = \
|
||||
go/math/big/accuracy_string.go \
|
||||
go/math/big/arith.go \
|
||||
go/math/big/arith_decl_pure.go \
|
||||
go/math/big/decimal.go \
|
||||
go/math/big/float.go \
|
||||
go/math/big/floatconv.go \
|
||||
go/math/big/ftoa.go \
|
||||
go/math/big/int.go \
|
||||
go/math/big/intconv.go \
|
||||
go/math/big/nat.go \
|
||||
go/math/big/rat.go
|
||||
go/math/big/natconv.go \
|
||||
go/math/big/rat.go \
|
||||
go/math/big/ratconv.go \
|
||||
go/math/big/roundingmode_string.go
|
||||
go_math_cmplx_files = \
|
||||
go/math/cmplx/abs.go \
|
||||
go/math/cmplx/asin.go \
|
||||
|
@ -1450,9 +1640,12 @@ go_math_rand_files = \
|
|||
go_mime_multipart_files = \
|
||||
go/mime/multipart/formdata.go \
|
||||
go/mime/multipart/multipart.go \
|
||||
go/mime/multipart/quotedprintable.go \
|
||||
go/mime/multipart/writer.go
|
||||
|
||||
go_mime_quotedprintable_files = \
|
||||
go/mime/quotedprintable/reader.go \
|
||||
go/mime/quotedprintable/writer.go
|
||||
|
||||
go_net_http_files = \
|
||||
go/net/http/client.go \
|
||||
go/net/http/cookie.go \
|
||||
|
@ -1504,6 +1697,23 @@ go_net_http_httputil_files = \
|
|||
go_net_http_internal_files = \
|
||||
go/net/http/internal/chunked.go
|
||||
|
||||
if LIBGO_IS_LINUX
|
||||
go_net_internal_socktest_sys = go/net/internal/socktest/sys_cloexec.go
|
||||
else
|
||||
if LIBGO_IS_FREEBSD
|
||||
go_net_internal_socktest_sys = go/net/internal/socktest/sys_cloexec.go
|
||||
else
|
||||
go_net_internal_socktest_sys =
|
||||
endif
|
||||
endif
|
||||
|
||||
go_net_internal_socktest_files = \
|
||||
go/net/internal/socktest/switch.go \
|
||||
go/net/internal/socktest/switch_posix.go \
|
||||
go/net/internal/socktest/switch_unix.go \
|
||||
go/net/internal/socktest/sys_unix.go \
|
||||
$(go_net_internal_socktest_sys)
|
||||
|
||||
go_old_regexp_files = \
|
||||
go/old/regexp/regexp.go
|
||||
go_old_template_files = \
|
||||
|
@ -1514,6 +1724,7 @@ go_old_template_files = \
|
|||
|
||||
go_os_exec_files = \
|
||||
go/os/exec/exec.go \
|
||||
go/os/exec/exec_posix.go \
|
||||
go/os/exec/lp_unix.go
|
||||
|
||||
go_os_signal_files = \
|
||||
|
@ -1565,6 +1776,7 @@ go_text_template_files = \
|
|||
go/text/template/exec.go \
|
||||
go/text/template/funcs.go \
|
||||
go/text/template/helper.go \
|
||||
go/text/template/option.go \
|
||||
go/text/template/template.go
|
||||
go_text_template_parse_files = \
|
||||
go/text/template/parse/lex.go \
|
||||
|
@ -1767,6 +1979,12 @@ else
|
|||
syscall_creds_test_file =
|
||||
endif
|
||||
|
||||
if LIBGO_IS_LINUX
|
||||
syscall_exec_test_file = go/syscall/exec_linux_test.go go/syscall/syscall_linux_test.go
|
||||
else
|
||||
syscall_exec_test_file =
|
||||
endif
|
||||
|
||||
go_base_syscall_files = \
|
||||
go/syscall/env_unix.go \
|
||||
go/syscall/syscall_errno.go \
|
||||
|
@ -1810,21 +2028,14 @@ go_syscall_c_files = \
|
|||
|
||||
go_syscall_test_files = \
|
||||
$(syscall_creds_test_file) \
|
||||
$(syscall_exec_test_file) \
|
||||
go/syscall/exec_unix_test.go \
|
||||
go/syscall/export_test.go \
|
||||
go/syscall/export_unix_test.go \
|
||||
go/syscall/mmap_unix_test.go \
|
||||
go/syscall/syscall_test.go \
|
||||
go/syscall/syscall_unix_test.go
|
||||
|
||||
if LIBGO_IS_LINUX
|
||||
internal_syscall_getrandom_file = go/internal/syscall/getrandom_linux.go
|
||||
else
|
||||
internal_syscall_getrandom_file =
|
||||
endif
|
||||
|
||||
go_internal_syscall_files = \
|
||||
go/internal/syscall/dummy.go \
|
||||
$(internal_syscall_getrandom_file)
|
||||
|
||||
libcalls.go: s-libcalls; @true
|
||||
s-libcalls: libcalls-list go/syscall/mksyscall.awk $(go_base_syscall_files)
|
||||
rm -f libcalls.go.tmp
|
||||
|
@ -1978,12 +2189,17 @@ libgo_go_objs = \
|
|||
html/template.lo \
|
||||
go/ast.lo \
|
||||
go/build.lo \
|
||||
go/constant.lo \
|
||||
go/doc.lo \
|
||||
go/format.lo \
|
||||
go/importer.lo \
|
||||
go/internal/gcimporter.lo \
|
||||
go/internal/gccgoimporter.lo \
|
||||
go/parser.lo \
|
||||
go/printer.lo \
|
||||
go/scanner.lo \
|
||||
go/token.lo \
|
||||
go/types.lo \
|
||||
hash/adler32.lo \
|
||||
hash/crc32.lo \
|
||||
hash/crc64.lo \
|
||||
|
@ -1999,10 +2215,15 @@ libgo_go_objs = \
|
|||
image/color/palette.lo \
|
||||
image/draw.lo \
|
||||
image/gif.lo \
|
||||
image/internal/imageutil.lo \
|
||||
image/jpeg.lo \
|
||||
image/png.lo \
|
||||
index/suffixarray.lo \
|
||||
internal/syscall.lo \
|
||||
internal/format.lo \
|
||||
internal/singleflight.lo \
|
||||
internal/syscall/unix.lo \
|
||||
internal/testenv.lo \
|
||||
internal/trace.lo \
|
||||
io/ioutil.lo \
|
||||
log/syslog.lo \
|
||||
log/syslog/syslog_c.lo \
|
||||
|
@ -2010,7 +2231,9 @@ libgo_go_objs = \
|
|||
math/cmplx.lo \
|
||||
math/rand.lo \
|
||||
mime/multipart.lo \
|
||||
mime/quotedprintable.lo \
|
||||
net/http.lo \
|
||||
net/internal/socktest.lo \
|
||||
net/mail.lo \
|
||||
net/rpc.lo \
|
||||
net/smtp.lo \
|
||||
|
@ -2121,11 +2344,11 @@ CHECK = \
|
|||
$(MKDIR_P) $(@D); \
|
||||
rm -f $@-testsum $@-testlog; \
|
||||
if test "$(USE_DEJAGNU)" = "yes"; then \
|
||||
$(SHELL) $(srcdir)/testsuite/gotest --dejagnu=yes --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --testname="$(@D)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
|
||||
$(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --dejagnu=yes --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --testname="$(@D)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
|
||||
elif test "$(GOBENCH)" != ""; then \
|
||||
$(SHELL) $(srcdir)/testsuite/gotest --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" --bench="$(GOBENCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
|
||||
$(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" --bench="$(GOBENCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
|
||||
else \
|
||||
if $(SHELL) $(srcdir)/testsuite/gotest --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files) >>$@-testlog 2>&1; then \
|
||||
if $(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files) >>$@-testlog 2>&1; then \
|
||||
echo "PASS: $(@D)" >> $@-testlog; \
|
||||
echo "PASS: $(@D)"; \
|
||||
echo "PASS: $(@D)" > $@-testsum; \
|
||||
|
@ -2910,6 +3133,15 @@ go/build/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: go/build/check
|
||||
|
||||
@go_include@ go/constant.lo.dep
|
||||
go/constant.lo.dep: $(go_go_constant_files)
|
||||
$(BUILDDEPS)
|
||||
go/constant.lo: $(go_go_constant_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/constant/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/constant/check
|
||||
|
||||
@go_include@ go/doc.lo.dep
|
||||
go/doc.lo.dep: $(go_go_doc_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -2928,6 +3160,15 @@ go/format/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: go/format/check
|
||||
|
||||
@go_include@ go/importer.lo.dep
|
||||
go/importer.lo.dep: $(go_go_importer_files)
|
||||
$(BUILDDEPS)
|
||||
go/importer.lo: $(go_go_importer_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/importer/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/importer/check
|
||||
|
||||
@go_include@ go/parser.lo.dep
|
||||
go/parser.lo.dep: $(go_go_parser_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -2964,6 +3205,33 @@ go/token/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: go/token/check
|
||||
|
||||
@go_include@ go/types.lo.dep
|
||||
go/types.lo.dep: $(go_go_types_files)
|
||||
$(BUILDDEPS)
|
||||
go/types.lo: $(go_go_types_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/types/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/types/check
|
||||
|
||||
@go_include@ go/internal/gcimporter.lo.dep
|
||||
go/internal/gcimporter.lo.dep: $(go_go_internal_gcimporter_files)
|
||||
$(BUILDDEPS)
|
||||
go/internal/gcimporter.lo: $(go_go_internal_gcimporter_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/internal/gcimporter/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/internal/gcimporter/check
|
||||
|
||||
@go_include@ go/internal/gccgoimporter.lo.dep
|
||||
go/internal/gccgoimporter.lo.dep: $(go_go_internal_gccgoimporter_files)
|
||||
$(BUILDDEPS)
|
||||
go/internal/gccgoimporter.lo: $(go_go_internal_gccgoimporter_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/internal/gccgoimporter/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/internal/gccgoimporter/check
|
||||
|
||||
@go_include@ hash/adler32.lo.dep
|
||||
hash/adler32.lo.dep: $(go_hash_adler32_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -3036,6 +3304,15 @@ image/gif/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: image/gif/check
|
||||
|
||||
@go_include@ image/internal/imageutil.lo.dep
|
||||
image/internal/imageutil.lo.dep: $(go_image_internal_imageutil_files)
|
||||
$(BUILDDEPS)
|
||||
image/internal/imageutil.lo: $(go_image_internal_imageutil_files)
|
||||
$(BUILDPACKAGE)
|
||||
image/internal/imageutil/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: image/internal/imageutil/check
|
||||
|
||||
@go_include@ image/jpeg.lo.dep
|
||||
image/jpeg.lo.dep: $(go_image_jpeg_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -3063,6 +3340,51 @@ index/suffixarray/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: index/suffixarray/check
|
||||
|
||||
@go_include@ internal/format.lo.dep
|
||||
internal/format.lo.dep: $(go_internal_format_files)
|
||||
$(BUILDDEPS)
|
||||
internal/format.lo: $(go_internal_format_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/format/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/format/check
|
||||
|
||||
@go_include@ internal/singleflight.lo.dep
|
||||
internal/singleflight.lo.dep: $(go_internal_singleflight_files)
|
||||
$(BUILDDEPS)
|
||||
internal/singleflight.lo: $(go_internal_singleflight_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/singleflight/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/singleflight/check
|
||||
|
||||
@go_include@ internal/syscall/unix.lo.dep
|
||||
internal/syscall/unix.lo.dep: $(go_internal_syscall_unix_files)
|
||||
$(BUILDDEPS)
|
||||
internal/syscall/unix.lo: $(go_internal_syscall_unix_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/syscall/unix/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/syscall/unix/check
|
||||
|
||||
@go_include@ internal/testenv.lo.dep
|
||||
internal/testenv.lo.dep: $(go_internal_testenv_files)
|
||||
$(BUILDDEPS)
|
||||
internal/testenv.lo: $(go_internal_testenv_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/testenv/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/testenv/check
|
||||
|
||||
@go_include@ internal/trace.lo.dep
|
||||
internal/trace.lo.dep: $(go_internal_trace_files)
|
||||
$(BUILDDEPS)
|
||||
internal/trace.lo: $(go_internal_trace_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/trace/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/trace/check
|
||||
|
||||
@go_include@ io/ioutil.lo.dep
|
||||
io/ioutil.lo.dep: $(go_io_ioutil_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -3120,6 +3442,15 @@ mime/multipart/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: mime/multipart/check
|
||||
|
||||
@go_include@ mime/quotedprintable.lo.dep
|
||||
mime/quotedprintable.lo.dep: $(go_mime_quotedprintable_files)
|
||||
$(BUILDDEPS)
|
||||
mime/quotedprintable.lo: $(go_mime_quotedprintable_files)
|
||||
$(BUILDPACKAGE)
|
||||
mime/quotedprintable/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: mime/quotedprintable/check
|
||||
|
||||
@go_include@ net/http.lo.dep
|
||||
net/http.lo.dep: $(go_net_http_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -3237,6 +3568,15 @@ net/http/pprof/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: net/http/pprof/check
|
||||
|
||||
@go_include@ net/internal/socktest.lo.dep
|
||||
net/internal/socktest.lo.dep: $(go_net_internal_socktest_files)
|
||||
$(BUILDDEPS)
|
||||
net/internal/socktest.lo: $(go_net_internal_socktest_files)
|
||||
$(BUILDPACKAGE)
|
||||
net/internal/socktest/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: net/internal/socktest/check
|
||||
|
||||
@go_include@ net/rpc/jsonrpc.lo.dep
|
||||
net/rpc/jsonrpc.lo.dep: $(go_net_rpc_jsonrpc_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -3432,15 +3772,6 @@ syscall/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: syscall/check
|
||||
|
||||
@go_include@ internal/syscall.lo.dep
|
||||
internal/syscall.lo.dep: $(go_internal_syscall_files)
|
||||
$(BUILDDEPS)
|
||||
internal/syscall.lo: $(go_internal_syscall_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/syscall/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/syscall/check
|
||||
|
||||
# How to build a .gox file from a .lo file.
|
||||
BUILDGOX = \
|
||||
f=`echo $< | sed -e 's/.lo$$/.o/'`; \
|
||||
|
@ -3620,10 +3951,14 @@ go/ast.gox: go/ast.lo
|
|||
$(BUILDGOX)
|
||||
go/build.gox: go/build.lo
|
||||
$(BUILDGOX)
|
||||
go/constant.gox: go/constant.lo
|
||||
$(BUILDGOX)
|
||||
go/doc.gox: go/doc.lo
|
||||
$(BUILDGOX)
|
||||
go/format.gox: go/format.lo
|
||||
$(BUILDGOX)
|
||||
go/importer.gox: go/importer.lo
|
||||
$(BUILDGOX)
|
||||
go/parser.gox: go/parser.lo
|
||||
$(BUILDGOX)
|
||||
go/printer.gox: go/printer.lo
|
||||
|
@ -3632,6 +3967,13 @@ go/scanner.gox: go/scanner.lo
|
|||
$(BUILDGOX)
|
||||
go/token.gox: go/token.lo
|
||||
$(BUILDGOX)
|
||||
go/types.gox: go/types.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
go/internal/gcimporter.gox: go/internal/gcimporter.lo
|
||||
$(BUILDGOX)
|
||||
go/internal/gccgoimporter.gox: go/internal/gccgoimporter.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
hash/adler32.gox: hash/adler32.lo
|
||||
$(BUILDGOX)
|
||||
|
@ -3648,6 +3990,8 @@ image/draw.gox: image/draw.lo
|
|||
$(BUILDGOX)
|
||||
image/gif.gox: image/gif.lo
|
||||
$(BUILDGOX)
|
||||
image/internal/imageutil.gox: image/internal/imageutil.lo
|
||||
$(BUILDGOX)
|
||||
image/jpeg.gox: image/jpeg.lo
|
||||
$(BUILDGOX)
|
||||
image/png.gox: image/png.lo
|
||||
|
@ -3659,6 +4003,17 @@ image/color/palette.gox: image/color/palette.lo
|
|||
index/suffixarray.gox: index/suffixarray.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
internal/format.gox: internal/format.lo
|
||||
$(BUILDGOX)
|
||||
internal/singleflight.gox: internal/singleflight.lo
|
||||
$(BUILDGOX)
|
||||
internal/syscall/unix.gox: internal/syscall/unix.lo
|
||||
$(BUILDGOX)
|
||||
internal/testenv.gox: internal/testenv.lo
|
||||
$(BUILDGOX)
|
||||
internal/trace.gox: internal/trace.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
io/ioutil.gox: io/ioutil.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
|
@ -3674,6 +4029,8 @@ math/rand.gox: math/rand.lo
|
|||
|
||||
mime/multipart.gox: mime/multipart.lo
|
||||
$(BUILDGOX)
|
||||
mime/quotedprintable.gox: mime/quotedprintable.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
net/http.gox: net/http.lo
|
||||
$(BUILDGOX)
|
||||
|
@ -3704,6 +4061,9 @@ net/http/pprof.gox: net/http/pprof.lo
|
|||
net/http/internal.gox: net/http/internal.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
net/internal/socktest.gox: net/internal/socktest.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
net/rpc/jsonrpc.gox: net/rpc/jsonrpc.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
|
@ -3733,9 +4093,6 @@ runtime/pprof.gox: runtime/pprof.lo
|
|||
sync/atomic.gox: sync/atomic.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
internal/syscall.gox: internal/syscall.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
text/scanner.gox: text/scanner.lo
|
||||
$(BUILDGOX)
|
||||
text/tabwriter.gox: text/tabwriter.lo
|
||||
|
@ -3830,13 +4187,17 @@ TEST_PACKAGES = \
|
|||
exp/terminal/check \
|
||||
html/template/check \
|
||||
go/ast/check \
|
||||
$(go_build_check_omitted_since_it_calls_6g) \
|
||||
go/build/check \
|
||||
go/constant/check \
|
||||
go/doc/check \
|
||||
go/format/check \
|
||||
go/internal/gcimporter/check \
|
||||
go/internal/gccgoimporter/check \
|
||||
go/parser/check \
|
||||
go/printer/check \
|
||||
go/scanner/check \
|
||||
go/token/check \
|
||||
go/types/check \
|
||||
hash/adler32/check \
|
||||
hash/crc32/check \
|
||||
hash/crc64/check \
|
||||
|
@ -3846,12 +4207,15 @@ TEST_PACKAGES = \
|
|||
image/jpeg/check \
|
||||
image/png/check \
|
||||
index/suffixarray/check \
|
||||
internal/singleflight/check \
|
||||
internal/trace/check \
|
||||
io/ioutil/check \
|
||||
log/syslog/check \
|
||||
math/big/check \
|
||||
math/cmplx/check \
|
||||
math/rand/check \
|
||||
mime/multipart/check \
|
||||
mime/quotedprintable/check \
|
||||
net/http/check \
|
||||
net/http/cgi/check \
|
||||
net/http/cookiejar/check \
|
||||
|
@ -3859,6 +4223,7 @@ TEST_PACKAGES = \
|
|||
net/http/httptest/check \
|
||||
net/http/httputil/check \
|
||||
net/http/internal/check \
|
||||
net/internal/socktest/check \
|
||||
net/mail/check \
|
||||
net/rpc/check \
|
||||
net/smtp/check \
|
||||
|
|
|
@ -196,16 +196,21 @@ am__DEPENDENCIES_2 = bufio.lo bytes.lo bytes/index.lo crypto.lo \
|
|||
encoding/binary.lo encoding/csv.lo encoding/gob.lo \
|
||||
encoding/hex.lo encoding/json.lo encoding/pem.lo \
|
||||
encoding/xml.lo exp/proxy.lo exp/terminal.lo html/template.lo \
|
||||
go/ast.lo go/build.lo go/doc.lo go/format.lo go/parser.lo \
|
||||
go/printer.lo go/scanner.lo go/token.lo hash/adler32.lo \
|
||||
go/ast.lo go/build.lo go/constant.lo go/doc.lo go/format.lo \
|
||||
go/importer.lo go/internal/gcimporter.lo \
|
||||
go/internal/gccgoimporter.lo go/parser.lo go/printer.lo \
|
||||
go/scanner.lo go/token.lo go/types.lo hash/adler32.lo \
|
||||
hash/crc32.lo hash/crc64.lo hash/fnv.lo net/http/cgi.lo \
|
||||
net/http/cookiejar.lo net/http/fcgi.lo net/http/httptest.lo \
|
||||
net/http/httputil.lo net/http/internal.lo net/http/pprof.lo \
|
||||
image/color.lo image/color/palette.lo image/draw.lo \
|
||||
image/gif.lo image/jpeg.lo image/png.lo index/suffixarray.lo \
|
||||
internal/syscall.lo io/ioutil.lo log/syslog.lo \
|
||||
log/syslog/syslog_c.lo math/big.lo math/cmplx.lo math/rand.lo \
|
||||
mime/multipart.lo net/http.lo net/mail.lo net/rpc.lo \
|
||||
image/gif.lo image/internal/imageutil.lo image/jpeg.lo \
|
||||
image/png.lo index/suffixarray.lo internal/format.lo \
|
||||
internal/singleflight.lo internal/syscall/unix.lo \
|
||||
internal/testenv.lo internal/trace.lo io/ioutil.lo \
|
||||
log/syslog.lo log/syslog/syslog_c.lo math/big.lo math/cmplx.lo \
|
||||
math/rand.lo mime/multipart.lo mime/quotedprintable.lo \
|
||||
net/http.lo net/internal/socktest.lo net/mail.lo net/rpc.lo \
|
||||
net/smtp.lo net/textproto.lo net/url.lo old/regexp.lo \
|
||||
old/template.lo os/exec.lo $(am__DEPENDENCIES_1) os/signal.lo \
|
||||
os/user.lo path/filepath.lo regexp/syntax.lo \
|
||||
|
@ -681,12 +686,15 @@ toolexeclibgogodir = $(toolexeclibgodir)/go
|
|||
toolexeclibgogo_DATA = \
|
||||
go/ast.gox \
|
||||
go/build.gox \
|
||||
go/constant.gox \
|
||||
go/doc.gox \
|
||||
go/format.gox \
|
||||
go/importer.gox \
|
||||
go/parser.gox \
|
||||
go/printer.gox \
|
||||
go/scanner.gox \
|
||||
go/token.gox
|
||||
go/token.gox \
|
||||
go/types.gox
|
||||
|
||||
toolexeclibgohashdir = $(toolexeclibgodir)/hash
|
||||
toolexeclibgohash_DATA = \
|
||||
|
@ -731,7 +739,8 @@ toolexeclibgomath_DATA = \
|
|||
|
||||
toolexeclibgomimedir = $(toolexeclibgodir)/mime
|
||||
toolexeclibgomime_DATA = \
|
||||
mime/multipart.gox
|
||||
mime/multipart.gox \
|
||||
mime/quotedprintable.gox
|
||||
|
||||
toolexeclibgonetdir = $(toolexeclibgodir)/net
|
||||
toolexeclibgonet_DATA = \
|
||||
|
@ -1023,16 +1032,22 @@ go_math_files = \
|
|||
go/math/tanh.go \
|
||||
go/math/unsafe.go
|
||||
|
||||
@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@go_mime_type_file =
|
||||
@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@go_mime_type_file = go/mime/type_dragonfly.go
|
||||
@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_OPENBSD_FALSE@go_mime_type_file = go/mime/type_freebsd.go
|
||||
@LIBGO_IS_OPENBSD_TRUE@go_mime_type_file = go/mime/type_openbsd.go
|
||||
go_mime_files = \
|
||||
go/mime/encodedword.go \
|
||||
go/mime/grammar.go \
|
||||
go/mime/mediatype.go \
|
||||
go/mime/type.go \
|
||||
go/mime/type_unix.go
|
||||
go/mime/type_unix.go \
|
||||
$(go_mime_type_file)
|
||||
|
||||
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go
|
||||
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_netbsd.go
|
||||
@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_file = go/net/cgo_bsd.go
|
||||
@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_file = go/net/cgo_linux.go
|
||||
@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_file = go/net/cgo_solaris.go
|
||||
@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_cgo_file = go/net/cgo_linux.go
|
||||
@LIBGO_IS_LINUX_TRUE@go_net_cgo_file = go/net/cgo_linux.go
|
||||
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sock_file = go/net/sock_bsd.go
|
||||
|
@ -1053,7 +1068,20 @@ go_mime_files = \
|
|||
@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_sockoptip_file = go/net/sockoptip_stub.go
|
||||
@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_sockoptip_file = go/net/sockoptip_linux.go go/net/sockoptip_posix.go
|
||||
@LIBGO_IS_LINUX_TRUE@go_net_sockoptip_file = go/net/sockoptip_linux.go go/net/sockoptip_posix.go
|
||||
@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@go_net_sendfile_file = go/net/sendfile_stub.go
|
||||
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_sock_file = go/net/cgo_sockold.go
|
||||
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_sock_file = go/net/cgo_sockold.go
|
||||
@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_sock_file = go/net/cgo_sockold.go
|
||||
@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_sock_file = go/net/cgo_socknew.go
|
||||
@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_cgo_sock_file = go/net/cgo_socknew.go
|
||||
@LIBGO_IS_LINUX_TRUE@go_net_cgo_sock_file = go/net/cgo_socknew.go
|
||||
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_res_file = go/net/cgo_resold.go
|
||||
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_res_file = go/net/cgo_resnew.go
|
||||
@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_cgo_res_file = go/net/cgo_resold.go
|
||||
@LIBGO_IS_IRIX_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_cgo_res_file = go/net/cgo_resnew.go
|
||||
@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_cgo_res_file = go/net/cgo_resnew.go
|
||||
@LIBGO_IS_LINUX_TRUE@go_net_cgo_res_file = go/net/cgo_resnew.go
|
||||
@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_net_sendfile_file = go/net/sendfile_stub.go
|
||||
@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_net_sendfile_file = go/net/sendfile_solaris.go
|
||||
@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@go_net_sendfile_file = go/net/sendfile_dragonfly.go
|
||||
@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_sendfile_file = go/net/sendfile_freebsd.go
|
||||
@LIBGO_IS_LINUX_TRUE@go_net_sendfile_file = go/net/sendfile_linux.go
|
||||
|
@ -1069,15 +1097,22 @@ go_mime_files = \
|
|||
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_OPENBSD_FALSE@go_net_tcpsockopt_file = go/net/tcpsockopt_darwin.go
|
||||
@LIBGO_IS_OPENBSD_TRUE@go_net_tcpsockopt_file = go/net/tcpsockopt_openbsd.go
|
||||
go_net_common_files = \
|
||||
go/net/addrselect.go \
|
||||
$(go_net_cloexec_file) \
|
||||
go/net/conf.go \
|
||||
go/net/dial.go \
|
||||
go/net/dnsclient.go \
|
||||
go/net/dnsclient_unix.go \
|
||||
go/net/dnsconfig_unix.go \
|
||||
go/net/dnsmsg.go \
|
||||
go/net/fd_mutex.go \
|
||||
go/net/fd_posix.go \
|
||||
go/net/fd_unix.go \
|
||||
go/net/file.go \
|
||||
go/net/file_unix.go \
|
||||
go/net/hook.go \
|
||||
go/net/hook_cloexec.go \
|
||||
go/net/hook_unix.go \
|
||||
go/net/hosts.go \
|
||||
go/net/interface.go \
|
||||
$(go_net_interface_file) \
|
||||
|
@ -1090,6 +1125,7 @@ go_net_common_files = \
|
|||
go/net/lookup_unix.go \
|
||||
go/net/mac.go \
|
||||
go/net/net.go \
|
||||
go/net/nss.go \
|
||||
go/net/parse.go \
|
||||
go/net/pipe.go \
|
||||
go/net/fd_poll_runtime.go \
|
||||
|
@ -1097,7 +1133,6 @@ go_net_common_files = \
|
|||
go/net/port_unix.go \
|
||||
go/net/race0.go \
|
||||
$(go_net_sendfile_file) \
|
||||
go/net/singleflight.go \
|
||||
go/net/sock_posix.go \
|
||||
$(go_net_sock_file) \
|
||||
go/net/sockopt_posix.go \
|
||||
|
@ -1115,6 +1150,8 @@ go_net_common_files = \
|
|||
go_net_files = \
|
||||
go/net/cgo_unix.go \
|
||||
$(go_net_cgo_file) \
|
||||
$(go_net_cgo_res_file) \
|
||||
$(go_net_cgo_sock_file) \
|
||||
$(go_net_common_files)
|
||||
|
||||
go_netgo_files = \
|
||||
|
@ -1147,6 +1184,13 @@ go_netgo_files = \
|
|||
@LIBGO_IS_LINUX_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_os_stat_file = go/os/stat_atim.go
|
||||
@LIBGO_IS_LINUX_FALSE@go_os_pipe_file = go/os/pipe_bsd.go
|
||||
@LIBGO_IS_LINUX_TRUE@go_os_pipe_file = go/os/pipe_linux.go
|
||||
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_os_sticky_file = go/os/sticky_notbsd.go
|
||||
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
|
||||
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
|
||||
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_NETBSD_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
|
||||
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
|
||||
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
|
||||
@LIBGO_IS_DARWIN_TRUE@go_os_sticky_file = go/os/sticky_bsd.go
|
||||
go_os_files = \
|
||||
$(go_os_dir_file) \
|
||||
go/os/dir.go \
|
||||
|
@ -1167,6 +1211,7 @@ go_os_files = \
|
|||
$(go_os_pipe_file) \
|
||||
go/os/proc.go \
|
||||
$(go_os_stat_file) \
|
||||
$(go_os_sticky_file) \
|
||||
go/os/str.go \
|
||||
$(go_os_sys_file) \
|
||||
$(go_os_cloexec_file) \
|
||||
|
@ -1188,6 +1233,7 @@ go_reflect_makefunc_c_file = \
|
|||
go/reflect/makefunc_ffi_c.c
|
||||
|
||||
go_regexp_files = \
|
||||
go/regexp/backtrack.go \
|
||||
go/regexp/exec.go \
|
||||
go/regexp/onepass.go \
|
||||
go/regexp/regexp.go
|
||||
|
@ -1203,7 +1249,6 @@ go_runtime_files = \
|
|||
go/runtime/error.go \
|
||||
go/runtime/extern.go \
|
||||
go/runtime/mem.go \
|
||||
go/runtime/softfloat64.go \
|
||||
version.go
|
||||
|
||||
noinst_DATA = zstdpkglist.go
|
||||
|
@ -1216,6 +1261,7 @@ go_strconv_files = \
|
|||
go/strconv/atof.go \
|
||||
go/strconv/atoi.go \
|
||||
go/strconv/decimal.go \
|
||||
go/strconv/doc.go \
|
||||
go/strconv/extfloat.go \
|
||||
go/strconv/ftoa.go \
|
||||
go/strconv/isprint.go \
|
||||
|
@ -1223,6 +1269,7 @@ go_strconv_files = \
|
|||
go/strconv/quote.go
|
||||
|
||||
go_strings_files = \
|
||||
go/strings/compare.go \
|
||||
go/strings/reader.go \
|
||||
go/strings/replace.go \
|
||||
go/strings/search.go \
|
||||
|
@ -1246,6 +1293,7 @@ go_sync_files = \
|
|||
@LIBGO_IS_IRIX_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_syslog_file = go/log/syslog/syslog_libc.go
|
||||
@LIBGO_IS_SOLARIS_TRUE@go_syslog_file = go/log/syslog/syslog_libc.go
|
||||
go_log_syslog_files = \
|
||||
go/log/syslog/doc.go \
|
||||
go/log/syslog/syslog.go \
|
||||
$(go_syslog_file)
|
||||
|
||||
|
@ -1375,6 +1423,7 @@ go_crypto_md5_files = \
|
|||
@LIBGO_IS_LINUX_FALSE@crypto_rand_file =
|
||||
@LIBGO_IS_LINUX_TRUE@crypto_rand_file = go/crypto/rand/rand_linux.go
|
||||
go_crypto_rand_files = \
|
||||
go/crypto/rand/eagain.go \
|
||||
go/crypto/rand/rand.go \
|
||||
go/crypto/rand/rand_unix.go \
|
||||
$(crypto_rand_file) \
|
||||
|
@ -1418,6 +1467,14 @@ go_crypto_tls_files = \
|
|||
go/crypto/tls/ticket.go \
|
||||
go/crypto/tls/tls.go
|
||||
|
||||
@LIBGO_IS_DARWIN_FALSE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file =
|
||||
@LIBGO_IS_DARWIN_TRUE@@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_darwin.go
|
||||
@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_FALSE@@LIBGO_IS_OPENBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
|
||||
@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_NETBSD_TRUE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
|
||||
@LIBGO_IS_DRAGONFLY_FALSE@@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
|
||||
@LIBGO_IS_DRAGONFLY_TRUE@@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_FALSE@go_crypto_x509_root_file = go/crypto/x509/root_bsd.go
|
||||
@LIBGO_IS_LINUX_FALSE@@LIBGO_IS_SOLARIS_TRUE@go_crypto_x509_root_file = go/crypto/x509/root_solaris.go
|
||||
@LIBGO_IS_LINUX_TRUE@go_crypto_x509_root_file = go/crypto/x509/root_linux.go
|
||||
go_crypto_x509_files = \
|
||||
go/crypto/x509/cert_pool.go \
|
||||
go/crypto/x509/pem_decrypt.go \
|
||||
|
@ -1425,6 +1482,7 @@ go_crypto_x509_files = \
|
|||
go/crypto/x509/pkcs8.go \
|
||||
go/crypto/x509/root.go \
|
||||
go/crypto/x509/root_unix.go \
|
||||
$(go_crypto_x509_root_file) \
|
||||
go/crypto/x509/sec1.go \
|
||||
go/crypto/x509/verify.go \
|
||||
go/crypto/x509/x509.go
|
||||
|
@ -1442,6 +1500,7 @@ go_database_sql_driver_files = \
|
|||
|
||||
go_debug_dwarf_files = \
|
||||
go/debug/dwarf/buf.go \
|
||||
go/debug/dwarf/class_string.go \
|
||||
go/debug/dwarf/const.go \
|
||||
go/debug/dwarf/entry.go \
|
||||
go/debug/dwarf/line.go \
|
||||
|
@ -1551,6 +1610,10 @@ go_go_build_files = \
|
|||
go/go/build/read.go \
|
||||
go/go/build/syslist.go
|
||||
|
||||
go_go_constant_files = \
|
||||
go/go/constant/go14.go \
|
||||
go/go/constant/value.go
|
||||
|
||||
go_go_doc_files = \
|
||||
go/go/doc/comment.go \
|
||||
go/go/doc/doc.go \
|
||||
|
@ -1563,6 +1626,9 @@ go_go_doc_files = \
|
|||
go_go_format_files = \
|
||||
go/go/format/format.go
|
||||
|
||||
go_go_importer_files = \
|
||||
go/go/importer/importer.go
|
||||
|
||||
go_go_parser_files = \
|
||||
go/go/parser/interface.go \
|
||||
go/go/parser/parser.go
|
||||
|
@ -1580,6 +1646,49 @@ go_go_token_files = \
|
|||
go/go/token/serialize.go \
|
||||
go/go/token/token.go
|
||||
|
||||
go_go_types_files = \
|
||||
go/go/types/api.go \
|
||||
go/go/types/assignments.go \
|
||||
go/go/types/builtins.go \
|
||||
go/go/types/call.go \
|
||||
go/go/types/check.go \
|
||||
go/go/types/conversions.go \
|
||||
go/go/types/decl.go \
|
||||
go/go/types/errors.go \
|
||||
go/go/types/eval.go \
|
||||
go/go/types/expr.go \
|
||||
go/go/types/exprstring.go \
|
||||
go/go/types/go12.go \
|
||||
go/go/types/initorder.go \
|
||||
go/go/types/labels.go \
|
||||
go/go/types/lookup.go \
|
||||
go/go/types/methodset.go \
|
||||
go/go/types/object.go \
|
||||
go/go/types/objset.go \
|
||||
go/go/types/operand.go \
|
||||
go/go/types/ordering.go \
|
||||
go/go/types/package.go \
|
||||
go/go/types/predicates.go \
|
||||
go/go/types/resolver.go \
|
||||
go/go/types/return.go \
|
||||
go/go/types/scope.go \
|
||||
go/go/types/selection.go \
|
||||
go/go/types/stmt.go \
|
||||
go/go/types/sizes.go \
|
||||
go/go/types/type.go \
|
||||
go/go/types/typestring.go \
|
||||
go/go/types/typexpr.go \
|
||||
go/go/types/universe.go
|
||||
|
||||
go_go_internal_gcimporter_files = \
|
||||
go/go/internal/gcimporter/exportdata.go \
|
||||
go/go/internal/gcimporter/gcimporter.go
|
||||
|
||||
go_go_internal_gccgoimporter_files = \
|
||||
go/go/internal/gccgoimporter/gccgoinstallation.go \
|
||||
go/go/internal/gccgoimporter/importer.go \
|
||||
go/go/internal/gccgoimporter/parser.go
|
||||
|
||||
go_hash_adler32_files = \
|
||||
go/hash/adler32/adler32.go
|
||||
|
||||
|
@ -1621,6 +1730,10 @@ go_image_gif_files = \
|
|||
go/image/gif/reader.go \
|
||||
go/image/gif/writer.go
|
||||
|
||||
go_image_internal_imageutil_files = \
|
||||
go/image/internal/imageutil/imageutil.go \
|
||||
go/image/internal/imageutil/impl.go
|
||||
|
||||
go_image_jpeg_files = \
|
||||
go/image/jpeg/fdct.go \
|
||||
go/image/jpeg/huffman.go \
|
||||
|
@ -1638,15 +1751,44 @@ go_index_suffixarray_files = \
|
|||
go/index/suffixarray/qsufsort.go \
|
||||
go/index/suffixarray/suffixarray.go
|
||||
|
||||
go_internal_format_files = \
|
||||
go/internal/format/format.go
|
||||
|
||||
go_internal_singleflight_files = \
|
||||
go/internal/singleflight/singleflight.go
|
||||
|
||||
@LIBGO_IS_LINUX_FALSE@internal_syscall_unix_getrandom_file =
|
||||
@LIBGO_IS_LINUX_TRUE@internal_syscall_unix_getrandom_file = go/internal/syscall/unix/getrandom_linux.go
|
||||
go_internal_syscall_unix_files = \
|
||||
go/internal/syscall/unix/dummy.go \
|
||||
$(internal_syscall_unix_getrandom_file)
|
||||
|
||||
go_internal_testenv_files = \
|
||||
go/internal/testenv/testenv.go
|
||||
|
||||
go_internal_trace_files = \
|
||||
go/internal/trace/goroutines.go \
|
||||
go/internal/trace/parser.go
|
||||
|
||||
go_io_ioutil_files = \
|
||||
go/io/ioutil/ioutil.go \
|
||||
go/io/ioutil/tempfile.go
|
||||
|
||||
go_math_big_files = \
|
||||
go/math/big/accuracy_string.go \
|
||||
go/math/big/arith.go \
|
||||
go/math/big/arith_decl_pure.go \
|
||||
go/math/big/decimal.go \
|
||||
go/math/big/float.go \
|
||||
go/math/big/floatconv.go \
|
||||
go/math/big/ftoa.go \
|
||||
go/math/big/int.go \
|
||||
go/math/big/intconv.go \
|
||||
go/math/big/nat.go \
|
||||
go/math/big/rat.go
|
||||
go/math/big/natconv.go \
|
||||
go/math/big/rat.go \
|
||||
go/math/big/ratconv.go \
|
||||
go/math/big/roundingmode_string.go
|
||||
|
||||
go_math_cmplx_files = \
|
||||
go/math/cmplx/abs.go \
|
||||
|
@ -1674,9 +1816,12 @@ go_math_rand_files = \
|
|||
go_mime_multipart_files = \
|
||||
go/mime/multipart/formdata.go \
|
||||
go/mime/multipart/multipart.go \
|
||||
go/mime/multipart/quotedprintable.go \
|
||||
go/mime/multipart/writer.go
|
||||
|
||||
go_mime_quotedprintable_files = \
|
||||
go/mime/quotedprintable/reader.go \
|
||||
go/mime/quotedprintable/writer.go
|
||||
|
||||
go_net_http_files = \
|
||||
go/net/http/client.go \
|
||||
go/net/http/cookie.go \
|
||||
|
@ -1738,6 +1883,16 @@ go_net_http_httputil_files = \
|
|||
go_net_http_internal_files = \
|
||||
go/net/http/internal/chunked.go
|
||||
|
||||
@LIBGO_IS_FREEBSD_FALSE@@LIBGO_IS_LINUX_FALSE@go_net_internal_socktest_sys =
|
||||
@LIBGO_IS_FREEBSD_TRUE@@LIBGO_IS_LINUX_FALSE@go_net_internal_socktest_sys = go/net/internal/socktest/sys_cloexec.go
|
||||
@LIBGO_IS_LINUX_TRUE@go_net_internal_socktest_sys = go/net/internal/socktest/sys_cloexec.go
|
||||
go_net_internal_socktest_files = \
|
||||
go/net/internal/socktest/switch.go \
|
||||
go/net/internal/socktest/switch_posix.go \
|
||||
go/net/internal/socktest/switch_unix.go \
|
||||
go/net/internal/socktest/sys_unix.go \
|
||||
$(go_net_internal_socktest_sys)
|
||||
|
||||
go_old_regexp_files = \
|
||||
go/old/regexp/regexp.go
|
||||
|
||||
|
@ -1749,6 +1904,7 @@ go_old_template_files = \
|
|||
|
||||
go_os_exec_files = \
|
||||
go/os/exec/exec.go \
|
||||
go/os/exec/exec_posix.go \
|
||||
go/os/exec/lp_unix.go
|
||||
|
||||
go_os_signal_files = \
|
||||
|
@ -1798,6 +1954,7 @@ go_text_template_files = \
|
|||
go/text/template/exec.go \
|
||||
go/text/template/funcs.go \
|
||||
go/text/template/helper.go \
|
||||
go/text/template/option.go \
|
||||
go/text/template/template.go
|
||||
|
||||
go_text_template_parse_files = \
|
||||
|
@ -1917,6 +2074,8 @@ go_unicode_utf8_files = \
|
|||
|
||||
# Test files.
|
||||
@LIBGO_IS_LINUX_TRUE@syscall_creds_test_file = go/syscall/creds_test.go
|
||||
@LIBGO_IS_LINUX_FALSE@syscall_exec_test_file =
|
||||
@LIBGO_IS_LINUX_TRUE@syscall_exec_test_file = go/syscall/exec_linux_test.go go/syscall/syscall_linux_test.go
|
||||
go_base_syscall_files = \
|
||||
go/syscall/env_unix.go \
|
||||
go/syscall/syscall_errno.go \
|
||||
|
@ -1961,17 +2120,14 @@ go_syscall_c_files = \
|
|||
|
||||
go_syscall_test_files = \
|
||||
$(syscall_creds_test_file) \
|
||||
$(syscall_exec_test_file) \
|
||||
go/syscall/exec_unix_test.go \
|
||||
go/syscall/export_test.go \
|
||||
go/syscall/export_unix_test.go \
|
||||
go/syscall/mmap_unix_test.go \
|
||||
go/syscall/syscall_test.go \
|
||||
go/syscall/syscall_unix_test.go
|
||||
|
||||
@LIBGO_IS_LINUX_FALSE@internal_syscall_getrandom_file =
|
||||
@LIBGO_IS_LINUX_TRUE@internal_syscall_getrandom_file = go/internal/syscall/getrandom_linux.go
|
||||
go_internal_syscall_files = \
|
||||
go/internal/syscall/dummy.go \
|
||||
$(internal_syscall_getrandom_file)
|
||||
|
||||
@LIBGO_IS_LINUX_FALSE@os_lib_inotify_lo =
|
||||
|
||||
# os_lib_inotify_lo = os/inotify.lo
|
||||
|
@ -2064,12 +2220,17 @@ libgo_go_objs = \
|
|||
html/template.lo \
|
||||
go/ast.lo \
|
||||
go/build.lo \
|
||||
go/constant.lo \
|
||||
go/doc.lo \
|
||||
go/format.lo \
|
||||
go/importer.lo \
|
||||
go/internal/gcimporter.lo \
|
||||
go/internal/gccgoimporter.lo \
|
||||
go/parser.lo \
|
||||
go/printer.lo \
|
||||
go/scanner.lo \
|
||||
go/token.lo \
|
||||
go/types.lo \
|
||||
hash/adler32.lo \
|
||||
hash/crc32.lo \
|
||||
hash/crc64.lo \
|
||||
|
@ -2085,10 +2246,15 @@ libgo_go_objs = \
|
|||
image/color/palette.lo \
|
||||
image/draw.lo \
|
||||
image/gif.lo \
|
||||
image/internal/imageutil.lo \
|
||||
image/jpeg.lo \
|
||||
image/png.lo \
|
||||
index/suffixarray.lo \
|
||||
internal/syscall.lo \
|
||||
internal/format.lo \
|
||||
internal/singleflight.lo \
|
||||
internal/syscall/unix.lo \
|
||||
internal/testenv.lo \
|
||||
internal/trace.lo \
|
||||
io/ioutil.lo \
|
||||
log/syslog.lo \
|
||||
log/syslog/syslog_c.lo \
|
||||
|
@ -2096,7 +2262,9 @@ libgo_go_objs = \
|
|||
math/cmplx.lo \
|
||||
math/rand.lo \
|
||||
mime/multipart.lo \
|
||||
mime/quotedprintable.lo \
|
||||
net/http.lo \
|
||||
net/internal/socktest.lo \
|
||||
net/mail.lo \
|
||||
net/rpc.lo \
|
||||
net/smtp.lo \
|
||||
|
@ -2203,11 +2371,11 @@ CHECK = \
|
|||
$(MKDIR_P) $(@D); \
|
||||
rm -f $@-testsum $@-testlog; \
|
||||
if test "$(USE_DEJAGNU)" = "yes"; then \
|
||||
$(SHELL) $(srcdir)/testsuite/gotest --dejagnu=yes --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --testname="$(@D)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
|
||||
$(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --dejagnu=yes --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --testname="$(@D)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
|
||||
elif test "$(GOBENCH)" != ""; then \
|
||||
$(SHELL) $(srcdir)/testsuite/gotest --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" --bench="$(GOBENCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
|
||||
$(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" --bench="$(GOBENCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files); \
|
||||
else \
|
||||
if $(SHELL) $(srcdir)/testsuite/gotest --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files) >>$@-testlog 2>&1; then \
|
||||
if $(SHELL) $(srcdir)/testsuite/gotest --goarch=$(GOARCH) --goos=$(GOOS) --basedir=$(srcdir) --srcdir=$(srcdir)/go/$(@D) --pkgpath="$(@D)" --pkgfiles="$(go_$(subst /,_,$(@D))_files)" --goarch="$(GOARCH)" $(GOTESTFLAGS) $(go_$(subst /,_,$(@D))_test_files) >>$@-testlog 2>&1; then \
|
||||
echo "PASS: $(@D)" >> $@-testlog; \
|
||||
echo "PASS: $(@D)"; \
|
||||
echo "PASS: $(@D)" > $@-testsum; \
|
||||
|
@ -2320,13 +2488,17 @@ TEST_PACKAGES = \
|
|||
exp/terminal/check \
|
||||
html/template/check \
|
||||
go/ast/check \
|
||||
$(go_build_check_omitted_since_it_calls_6g) \
|
||||
go/build/check \
|
||||
go/constant/check \
|
||||
go/doc/check \
|
||||
go/format/check \
|
||||
go/internal/gcimporter/check \
|
||||
go/internal/gccgoimporter/check \
|
||||
go/parser/check \
|
||||
go/printer/check \
|
||||
go/scanner/check \
|
||||
go/token/check \
|
||||
go/types/check \
|
||||
hash/adler32/check \
|
||||
hash/crc32/check \
|
||||
hash/crc64/check \
|
||||
|
@ -2336,12 +2508,15 @@ TEST_PACKAGES = \
|
|||
image/jpeg/check \
|
||||
image/png/check \
|
||||
index/suffixarray/check \
|
||||
internal/singleflight/check \
|
||||
internal/trace/check \
|
||||
io/ioutil/check \
|
||||
log/syslog/check \
|
||||
math/big/check \
|
||||
math/cmplx/check \
|
||||
math/rand/check \
|
||||
mime/multipart/check \
|
||||
mime/quotedprintable/check \
|
||||
net/http/check \
|
||||
net/http/cgi/check \
|
||||
net/http/cookiejar/check \
|
||||
|
@ -2349,6 +2524,7 @@ TEST_PACKAGES = \
|
|||
net/http/httptest/check \
|
||||
net/http/httputil/check \
|
||||
net/http/internal/check \
|
||||
net/internal/socktest/check \
|
||||
net/mail/check \
|
||||
net/rpc/check \
|
||||
net/smtp/check \
|
||||
|
@ -5357,6 +5533,15 @@ go/build/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: go/build/check
|
||||
|
||||
@go_include@ go/constant.lo.dep
|
||||
go/constant.lo.dep: $(go_go_constant_files)
|
||||
$(BUILDDEPS)
|
||||
go/constant.lo: $(go_go_constant_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/constant/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/constant/check
|
||||
|
||||
@go_include@ go/doc.lo.dep
|
||||
go/doc.lo.dep: $(go_go_doc_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -5375,6 +5560,15 @@ go/format/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: go/format/check
|
||||
|
||||
@go_include@ go/importer.lo.dep
|
||||
go/importer.lo.dep: $(go_go_importer_files)
|
||||
$(BUILDDEPS)
|
||||
go/importer.lo: $(go_go_importer_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/importer/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/importer/check
|
||||
|
||||
@go_include@ go/parser.lo.dep
|
||||
go/parser.lo.dep: $(go_go_parser_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -5411,6 +5605,33 @@ go/token/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: go/token/check
|
||||
|
||||
@go_include@ go/types.lo.dep
|
||||
go/types.lo.dep: $(go_go_types_files)
|
||||
$(BUILDDEPS)
|
||||
go/types.lo: $(go_go_types_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/types/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/types/check
|
||||
|
||||
@go_include@ go/internal/gcimporter.lo.dep
|
||||
go/internal/gcimporter.lo.dep: $(go_go_internal_gcimporter_files)
|
||||
$(BUILDDEPS)
|
||||
go/internal/gcimporter.lo: $(go_go_internal_gcimporter_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/internal/gcimporter/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/internal/gcimporter/check
|
||||
|
||||
@go_include@ go/internal/gccgoimporter.lo.dep
|
||||
go/internal/gccgoimporter.lo.dep: $(go_go_internal_gccgoimporter_files)
|
||||
$(BUILDDEPS)
|
||||
go/internal/gccgoimporter.lo: $(go_go_internal_gccgoimporter_files)
|
||||
$(BUILDPACKAGE)
|
||||
go/internal/gccgoimporter/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: go/internal/gccgoimporter/check
|
||||
|
||||
@go_include@ hash/adler32.lo.dep
|
||||
hash/adler32.lo.dep: $(go_hash_adler32_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -5483,6 +5704,15 @@ image/gif/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: image/gif/check
|
||||
|
||||
@go_include@ image/internal/imageutil.lo.dep
|
||||
image/internal/imageutil.lo.dep: $(go_image_internal_imageutil_files)
|
||||
$(BUILDDEPS)
|
||||
image/internal/imageutil.lo: $(go_image_internal_imageutil_files)
|
||||
$(BUILDPACKAGE)
|
||||
image/internal/imageutil/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: image/internal/imageutil/check
|
||||
|
||||
@go_include@ image/jpeg.lo.dep
|
||||
image/jpeg.lo.dep: $(go_image_jpeg_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -5510,6 +5740,51 @@ index/suffixarray/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: index/suffixarray/check
|
||||
|
||||
@go_include@ internal/format.lo.dep
|
||||
internal/format.lo.dep: $(go_internal_format_files)
|
||||
$(BUILDDEPS)
|
||||
internal/format.lo: $(go_internal_format_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/format/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/format/check
|
||||
|
||||
@go_include@ internal/singleflight.lo.dep
|
||||
internal/singleflight.lo.dep: $(go_internal_singleflight_files)
|
||||
$(BUILDDEPS)
|
||||
internal/singleflight.lo: $(go_internal_singleflight_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/singleflight/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/singleflight/check
|
||||
|
||||
@go_include@ internal/syscall/unix.lo.dep
|
||||
internal/syscall/unix.lo.dep: $(go_internal_syscall_unix_files)
|
||||
$(BUILDDEPS)
|
||||
internal/syscall/unix.lo: $(go_internal_syscall_unix_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/syscall/unix/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/syscall/unix/check
|
||||
|
||||
@go_include@ internal/testenv.lo.dep
|
||||
internal/testenv.lo.dep: $(go_internal_testenv_files)
|
||||
$(BUILDDEPS)
|
||||
internal/testenv.lo: $(go_internal_testenv_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/testenv/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/testenv/check
|
||||
|
||||
@go_include@ internal/trace.lo.dep
|
||||
internal/trace.lo.dep: $(go_internal_trace_files)
|
||||
$(BUILDDEPS)
|
||||
internal/trace.lo: $(go_internal_trace_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/trace/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/trace/check
|
||||
|
||||
@go_include@ io/ioutil.lo.dep
|
||||
io/ioutil.lo.dep: $(go_io_ioutil_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -5567,6 +5842,15 @@ mime/multipart/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: mime/multipart/check
|
||||
|
||||
@go_include@ mime/quotedprintable.lo.dep
|
||||
mime/quotedprintable.lo.dep: $(go_mime_quotedprintable_files)
|
||||
$(BUILDDEPS)
|
||||
mime/quotedprintable.lo: $(go_mime_quotedprintable_files)
|
||||
$(BUILDPACKAGE)
|
||||
mime/quotedprintable/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: mime/quotedprintable/check
|
||||
|
||||
@go_include@ net/http.lo.dep
|
||||
net/http.lo.dep: $(go_net_http_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -5684,6 +5968,15 @@ net/http/pprof/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: net/http/pprof/check
|
||||
|
||||
@go_include@ net/internal/socktest.lo.dep
|
||||
net/internal/socktest.lo.dep: $(go_net_internal_socktest_files)
|
||||
$(BUILDDEPS)
|
||||
net/internal/socktest.lo: $(go_net_internal_socktest_files)
|
||||
$(BUILDPACKAGE)
|
||||
net/internal/socktest/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: net/internal/socktest/check
|
||||
|
||||
@go_include@ net/rpc/jsonrpc.lo.dep
|
||||
net/rpc/jsonrpc.lo.dep: $(go_net_rpc_jsonrpc_files)
|
||||
$(BUILDDEPS)
|
||||
|
@ -5875,15 +6168,6 @@ syscall/check: $(CHECK_DEPS)
|
|||
@$(CHECK)
|
||||
.PHONY: syscall/check
|
||||
|
||||
@go_include@ internal/syscall.lo.dep
|
||||
internal/syscall.lo.dep: $(go_internal_syscall_files)
|
||||
$(BUILDDEPS)
|
||||
internal/syscall.lo: $(go_internal_syscall_files)
|
||||
$(BUILDPACKAGE)
|
||||
internal/syscall/check: $(CHECK_DEPS)
|
||||
@$(CHECK)
|
||||
.PHONY: internal/syscall/check
|
||||
|
||||
bufio.gox: bufio.lo
|
||||
$(BUILDGOX)
|
||||
bytes.gox: bytes.lo
|
||||
|
@ -6058,10 +6342,14 @@ go/ast.gox: go/ast.lo
|
|||
$(BUILDGOX)
|
||||
go/build.gox: go/build.lo
|
||||
$(BUILDGOX)
|
||||
go/constant.gox: go/constant.lo
|
||||
$(BUILDGOX)
|
||||
go/doc.gox: go/doc.lo
|
||||
$(BUILDGOX)
|
||||
go/format.gox: go/format.lo
|
||||
$(BUILDGOX)
|
||||
go/importer.gox: go/importer.lo
|
||||
$(BUILDGOX)
|
||||
go/parser.gox: go/parser.lo
|
||||
$(BUILDGOX)
|
||||
go/printer.gox: go/printer.lo
|
||||
|
@ -6070,6 +6358,13 @@ go/scanner.gox: go/scanner.lo
|
|||
$(BUILDGOX)
|
||||
go/token.gox: go/token.lo
|
||||
$(BUILDGOX)
|
||||
go/types.gox: go/types.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
go/internal/gcimporter.gox: go/internal/gcimporter.lo
|
||||
$(BUILDGOX)
|
||||
go/internal/gccgoimporter.gox: go/internal/gccgoimporter.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
hash/adler32.gox: hash/adler32.lo
|
||||
$(BUILDGOX)
|
||||
|
@ -6086,6 +6381,8 @@ image/draw.gox: image/draw.lo
|
|||
$(BUILDGOX)
|
||||
image/gif.gox: image/gif.lo
|
||||
$(BUILDGOX)
|
||||
image/internal/imageutil.gox: image/internal/imageutil.lo
|
||||
$(BUILDGOX)
|
||||
image/jpeg.gox: image/jpeg.lo
|
||||
$(BUILDGOX)
|
||||
image/png.gox: image/png.lo
|
||||
|
@ -6097,6 +6394,17 @@ image/color/palette.gox: image/color/palette.lo
|
|||
index/suffixarray.gox: index/suffixarray.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
internal/format.gox: internal/format.lo
|
||||
$(BUILDGOX)
|
||||
internal/singleflight.gox: internal/singleflight.lo
|
||||
$(BUILDGOX)
|
||||
internal/syscall/unix.gox: internal/syscall/unix.lo
|
||||
$(BUILDGOX)
|
||||
internal/testenv.gox: internal/testenv.lo
|
||||
$(BUILDGOX)
|
||||
internal/trace.gox: internal/trace.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
io/ioutil.gox: io/ioutil.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
|
@ -6112,6 +6420,8 @@ math/rand.gox: math/rand.lo
|
|||
|
||||
mime/multipart.gox: mime/multipart.lo
|
||||
$(BUILDGOX)
|
||||
mime/quotedprintable.gox: mime/quotedprintable.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
net/http.gox: net/http.lo
|
||||
$(BUILDGOX)
|
||||
|
@ -6142,6 +6452,9 @@ net/http/pprof.gox: net/http/pprof.lo
|
|||
net/http/internal.gox: net/http/internal.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
net/internal/socktest.gox: net/internal/socktest.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
net/rpc/jsonrpc.gox: net/rpc/jsonrpc.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
|
@ -6171,9 +6484,6 @@ runtime/pprof.gox: runtime/pprof.lo
|
|||
sync/atomic.gox: sync/atomic.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
internal/syscall.gox: internal/syscall.lo
|
||||
$(BUILDGOX)
|
||||
|
||||
text/scanner.gox: text/scanner.lo
|
||||
$(BUILDGOX)
|
||||
text/tabwriter.gox: text/tabwriter.lo
|
||||
|
|
|
@ -1 +1 @@
|
|||
go1.4.2
|
||||
go1.5
|
|
@ -139,8 +139,8 @@ func (fi headerFileInfo) Mode() (mode os.FileMode) {
|
|||
}
|
||||
|
||||
switch fi.h.Typeflag {
|
||||
case TypeLink, TypeSymlink:
|
||||
// hard link, symbolic link
|
||||
case TypeSymlink:
|
||||
// symbolic link
|
||||
mode |= os.ModeSymlink
|
||||
case TypeChar:
|
||||
// character device node
|
||||
|
@ -249,6 +249,30 @@ func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) {
|
|||
if fm&os.ModeSticky != 0 {
|
||||
h.Mode |= c_ISVTX
|
||||
}
|
||||
// If possible, populate additional fields from OS-specific
|
||||
// FileInfo fields.
|
||||
if sys, ok := fi.Sys().(*Header); ok {
|
||||
// This FileInfo came from a Header (not the OS). Use the
|
||||
// original Header to populate all remaining fields.
|
||||
h.Uid = sys.Uid
|
||||
h.Gid = sys.Gid
|
||||
h.Uname = sys.Uname
|
||||
h.Gname = sys.Gname
|
||||
h.AccessTime = sys.AccessTime
|
||||
h.ChangeTime = sys.ChangeTime
|
||||
if sys.Xattrs != nil {
|
||||
h.Xattrs = make(map[string]string)
|
||||
for k, v := range sys.Xattrs {
|
||||
h.Xattrs[k] = v
|
||||
}
|
||||
}
|
||||
if sys.Typeflag == TypeLink {
|
||||
// hard link
|
||||
h.Typeflag = TypeLink
|
||||
h.Size = 0
|
||||
h.Linkname = sys.Linkname
|
||||
}
|
||||
}
|
||||
if sysStat != nil {
|
||||
return h, sysStat(fi, h)
|
||||
}
|
||||
|
|
|
@ -85,6 +85,8 @@ const (
|
|||
func NewReader(r io.Reader) *Reader { return &Reader{r: r} }
|
||||
|
||||
// Next advances to the next entry in the tar archive.
|
||||
//
|
||||
// io.EOF is returned at the end of the input.
|
||||
func (tr *Reader) Next() (*Header, error) {
|
||||
var hdr *Header
|
||||
if tr.err == nil {
|
||||
|
@ -108,7 +110,13 @@ func (tr *Reader) Next() (*Header, error) {
|
|||
// We actually read the whole file,
|
||||
// but this skips alignment padding
|
||||
tr.skipUnread()
|
||||
if tr.err != nil {
|
||||
return nil, tr.err
|
||||
}
|
||||
hdr = tr.readHeader()
|
||||
if hdr == nil {
|
||||
return nil, tr.err
|
||||
}
|
||||
mergePAX(hdr, headers)
|
||||
|
||||
// Check for a PAX format sparse file
|
||||
|
@ -331,7 +339,7 @@ func parsePAX(r io.Reader) (map[string]string, error) {
|
|||
}
|
||||
// Parse the first token as a decimal integer.
|
||||
n, err := strconv.ParseInt(string(buf[:sp]), 10, 0)
|
||||
if err != nil {
|
||||
if err != nil || n < 5 || int64(len(buf)) < n {
|
||||
return nil, ErrHeader
|
||||
}
|
||||
// Extract everything between the decimal and the n -1 on the
|
||||
|
@ -461,6 +469,10 @@ func (tr *Reader) readHeader() *Header {
|
|||
hdr.Uid = int(tr.octal(s.next(8)))
|
||||
hdr.Gid = int(tr.octal(s.next(8)))
|
||||
hdr.Size = tr.octal(s.next(12))
|
||||
if hdr.Size < 0 {
|
||||
tr.err = ErrHeader
|
||||
return nil
|
||||
}
|
||||
hdr.ModTime = time.Unix(tr.octal(s.next(12)), 0)
|
||||
s.next(8) // chksum
|
||||
hdr.Typeflag = s.next(1)[0]
|
||||
|
@ -785,6 +797,9 @@ func (sfr *sparseFileReader) Read(b []byte) (n int, err error) {
|
|||
// Otherwise, we're at the end of the file
|
||||
return 0, io.EOF
|
||||
}
|
||||
if sfr.tot < sfr.sp[0].offset {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
if sfr.pos < sfr.sp[0].offset {
|
||||
// We're in a hole
|
||||
n = sfr.readHole(b, sfr.sp[0].offset)
|
||||
|
|
|
@ -462,9 +462,14 @@ func TestParsePAXHeader(t *testing.T) {
|
|||
t.Error("Buffer wasn't consumed")
|
||||
}
|
||||
}
|
||||
badHeader := bytes.NewReader([]byte("3 somelongkey="))
|
||||
if _, err := parsePAX(badHeader); err != ErrHeader {
|
||||
t.Fatal("Unexpected success when parsing bad header")
|
||||
badHeaderTests := [][]byte{
|
||||
[]byte("3 somelongkey=\n"),
|
||||
[]byte("50 tooshort=\n"),
|
||||
}
|
||||
for _, test := range badHeaderTests {
|
||||
if _, err := parsePAX(bytes.NewReader(test)); err != ErrHeader {
|
||||
t.Fatal("Unexpected success when parsing bad header")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -741,3 +746,53 @@ func TestUninitializedRead(t *testing.T) {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
// Negative header size should not cause panic.
|
||||
// Issues 10959 and 10960.
|
||||
func TestNegativeHdrSize(t *testing.T) {
|
||||
f, err := os.Open("testdata/neg-size.tar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
r := NewReader(f)
|
||||
_, err = r.Next()
|
||||
if err != ErrHeader {
|
||||
t.Error("want ErrHeader, got", err)
|
||||
}
|
||||
io.Copy(ioutil.Discard, r)
|
||||
}
|
||||
|
||||
// This used to hang in (*sparseFileReader).readHole due to missing
|
||||
// verification of sparse offsets against file size.
|
||||
func TestIssue10968(t *testing.T) {
|
||||
f, err := os.Open("testdata/issue10968.tar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
r := NewReader(f)
|
||||
_, err = r.Next()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = io.Copy(ioutil.Discard, r)
|
||||
if err != io.ErrUnexpectedEOF {
|
||||
t.Fatalf("expected %q, got %q", io.ErrUnexpectedEOF, err)
|
||||
}
|
||||
}
|
||||
|
||||
// Do not panic if there are errors in header blocks after the pax header.
|
||||
// Issue 11169
|
||||
func TestIssue11169(t *testing.T) {
|
||||
f, err := os.Open("testdata/issue11169.tar")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer f.Close()
|
||||
r := NewReader(f)
|
||||
_, err = r.Next()
|
||||
if err == nil {
|
||||
t.Fatal("Unexpected success")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -147,17 +147,6 @@ func TestHeaderRoundTrip(t *testing.T) {
|
|||
},
|
||||
fm: 0644,
|
||||
},
|
||||
// hard link.
|
||||
{
|
||||
h: &Header{
|
||||
Name: "hard.txt",
|
||||
Mode: 0644 | c_ISLNK,
|
||||
Size: 0,
|
||||
ModTime: time.Unix(1360600916, 0),
|
||||
Typeflag: TypeLink,
|
||||
},
|
||||
fm: 0644 | os.ModeSymlink,
|
||||
},
|
||||
// symbolic link.
|
||||
{
|
||||
h: &Header{
|
||||
|
@ -246,6 +235,33 @@ func TestHeaderRoundTrip(t *testing.T) {
|
|||
},
|
||||
fm: 0600 | os.ModeSticky,
|
||||
},
|
||||
// hard link.
|
||||
{
|
||||
h: &Header{
|
||||
Name: "hard.txt",
|
||||
Mode: 0644 | c_ISREG,
|
||||
Size: 0,
|
||||
Linkname: "file.txt",
|
||||
ModTime: time.Unix(1360600916, 0),
|
||||
Typeflag: TypeLink,
|
||||
},
|
||||
fm: 0644,
|
||||
},
|
||||
// More information.
|
||||
{
|
||||
h: &Header{
|
||||
Name: "info.txt",
|
||||
Mode: 0600 | c_ISREG,
|
||||
Size: 0,
|
||||
Uid: 1000,
|
||||
Gid: 1000,
|
||||
ModTime: time.Unix(1360602540, 0),
|
||||
Uname: "slartibartfast",
|
||||
Gname: "users",
|
||||
Typeflag: TypeReg,
|
||||
},
|
||||
fm: 0600,
|
||||
},
|
||||
}
|
||||
|
||||
for i, g := range golden {
|
||||
|
@ -268,12 +284,37 @@ func TestHeaderRoundTrip(t *testing.T) {
|
|||
if got, want := h2.Size, g.h.Size; got != want {
|
||||
t.Errorf("i=%d: Size: got %v, want %v", i, got, want)
|
||||
}
|
||||
if got, want := h2.Uid, g.h.Uid; got != want {
|
||||
t.Errorf("i=%d: Uid: got %d, want %d", i, got, want)
|
||||
}
|
||||
if got, want := h2.Gid, g.h.Gid; got != want {
|
||||
t.Errorf("i=%d: Gid: got %d, want %d", i, got, want)
|
||||
}
|
||||
if got, want := h2.Uname, g.h.Uname; got != want {
|
||||
t.Errorf("i=%d: Uname: got %q, want %q", i, got, want)
|
||||
}
|
||||
if got, want := h2.Gname, g.h.Gname; got != want {
|
||||
t.Errorf("i=%d: Gname: got %q, want %q", i, got, want)
|
||||
}
|
||||
if got, want := h2.Linkname, g.h.Linkname; got != want {
|
||||
t.Errorf("i=%d: Linkname: got %v, want %v", i, got, want)
|
||||
}
|
||||
if got, want := h2.Typeflag, g.h.Typeflag; got != want {
|
||||
t.Logf("%#v %#v", g.h, fi.Sys())
|
||||
t.Errorf("i=%d: Typeflag: got %q, want %q", i, got, want)
|
||||
}
|
||||
if got, want := h2.Mode, g.h.Mode; got != want {
|
||||
t.Errorf("i=%d: Mode: got %o, want %o", i, got, want)
|
||||
}
|
||||
if got, want := fi.Mode(), g.fm; got != want {
|
||||
t.Errorf("i=%d: fi.Mode: got %o, want %o", i, got, want)
|
||||
}
|
||||
if got, want := h2.AccessTime, g.h.AccessTime; got != want {
|
||||
t.Errorf("i=%d: AccessTime: got %v, want %v", i, got, want)
|
||||
}
|
||||
if got, want := h2.ChangeTime, g.h.ChangeTime; got != want {
|
||||
t.Errorf("i=%d: ChangeTime: got %v, want %v", i, got, want)
|
||||
}
|
||||
if got, want := h2.ModTime, g.h.ModTime; got != want {
|
||||
t.Errorf("i=%d: ModTime: got %v, want %v", i, got, want)
|
||||
}
|
||||
|
|
BIN
libgo/go/archive/tar/testdata/hardlink.tar
vendored
Normal file
BIN
libgo/go/archive/tar/testdata/hardlink.tar
vendored
Normal file
Binary file not shown.
BIN
libgo/go/archive/tar/testdata/issue10968.tar
vendored
Normal file
BIN
libgo/go/archive/tar/testdata/issue10968.tar
vendored
Normal file
Binary file not shown.
BIN
libgo/go/archive/tar/testdata/issue11169.tar
vendored
Normal file
BIN
libgo/go/archive/tar/testdata/issue11169.tar
vendored
Normal file
Binary file not shown.
BIN
libgo/go/archive/tar/testdata/neg-size.tar
vendored
Normal file
BIN
libgo/go/archive/tar/testdata/neg-size.tar
vendored
Normal file
Binary file not shown.
|
@ -355,7 +355,7 @@ func paxHeader(msg string) string {
|
|||
// hdr.Size bytes are written after WriteHeader.
|
||||
func (tw *Writer) Write(b []byte) (n int, err error) {
|
||||
if tw.closed {
|
||||
err = ErrWriteTooLong
|
||||
err = ErrWriteAfterClose
|
||||
return
|
||||
}
|
||||
overwrite := false
|
||||
|
|
|
@ -147,6 +147,44 @@ var writerTests = []*writerTest{
|
|||
},
|
||||
},
|
||||
},
|
||||
// This file was produced using gnu tar 1.26
|
||||
// echo "Slartibartfast" > file.txt
|
||||
// ln file.txt hard.txt
|
||||
// tar -b 1 --format=ustar -c -f hardlink.tar file.txt hard.txt
|
||||
{
|
||||
file: "testdata/hardlink.tar",
|
||||
entries: []*writerTestEntry{
|
||||
{
|
||||
header: &Header{
|
||||
Name: "file.txt",
|
||||
Mode: 0644,
|
||||
Uid: 1000,
|
||||
Gid: 100,
|
||||
Size: 15,
|
||||
ModTime: time.Unix(1425484303, 0),
|
||||
Typeflag: '0',
|
||||
Uname: "vbatts",
|
||||
Gname: "users",
|
||||
},
|
||||
contents: "Slartibartfast\n",
|
||||
},
|
||||
{
|
||||
header: &Header{
|
||||
Name: "hard.txt",
|
||||
Mode: 0644,
|
||||
Uid: 1000,
|
||||
Gid: 100,
|
||||
Size: 0,
|
||||
ModTime: time.Unix(1425484303, 0),
|
||||
Typeflag: '1',
|
||||
Linkname: "file.txt",
|
||||
Uname: "vbatts",
|
||||
Gname: "users",
|
||||
},
|
||||
// no contents
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
// Render byte array in a two-character hexadecimal string, spaced for easy visual inspection.
|
||||
|
@ -489,3 +527,20 @@ func TestValidTypeflagWithPAXHeader(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriteAfterClose(t *testing.T) {
|
||||
var buffer bytes.Buffer
|
||||
tw := NewWriter(&buffer)
|
||||
|
||||
hdr := &Header{
|
||||
Name: "small.txt",
|
||||
Size: 5,
|
||||
}
|
||||
if err := tw.WriteHeader(hdr); err != nil {
|
||||
t.Fatalf("Failed to write header: %s", err)
|
||||
}
|
||||
tw.Close()
|
||||
if _, err := tw.Write([]byte("Kilts")); err != ErrWriteAfterClose {
|
||||
t.Fatalf("Write: got %v; want ErrWriteAfterClose", err)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
"bufio"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"io"
|
||||
|
@ -77,6 +78,9 @@ func (z *Reader) init(r io.ReaderAt, size int64) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if end.directoryRecords > uint64(size)/fileHeaderLen {
|
||||
return fmt.Errorf("archive/zip: TOC declares impossible %d files in %d byte zip", end.directoryRecords, size)
|
||||
}
|
||||
z.r = r
|
||||
z.File = make([]*File, 0, end.directoryRecords)
|
||||
z.Comment = end.comment
|
||||
|
@ -146,16 +150,22 @@ func (f *File) Open() (rc io.ReadCloser, err error) {
|
|||
if f.hasDataDescriptor() {
|
||||
desr = io.NewSectionReader(f.zipr, f.headerOffset+bodyOffset+size, dataDescriptorLen)
|
||||
}
|
||||
rc = &checksumReader{rc, crc32.NewIEEE(), f, desr, nil}
|
||||
rc = &checksumReader{
|
||||
rc: rc,
|
||||
hash: crc32.NewIEEE(),
|
||||
f: f,
|
||||
desr: desr,
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
type checksumReader struct {
|
||||
rc io.ReadCloser
|
||||
hash hash.Hash32
|
||||
f *File
|
||||
desr io.Reader // if non-nil, where to read the data descriptor
|
||||
err error // sticky error
|
||||
rc io.ReadCloser
|
||||
hash hash.Hash32
|
||||
nread uint64 // number of bytes read so far
|
||||
f *File
|
||||
desr io.Reader // if non-nil, where to read the data descriptor
|
||||
err error // sticky error
|
||||
}
|
||||
|
||||
func (r *checksumReader) Read(b []byte) (n int, err error) {
|
||||
|
@ -164,13 +174,21 @@ func (r *checksumReader) Read(b []byte) (n int, err error) {
|
|||
}
|
||||
n, err = r.rc.Read(b)
|
||||
r.hash.Write(b[:n])
|
||||
r.nread += uint64(n)
|
||||
if err == nil {
|
||||
return
|
||||
}
|
||||
if err == io.EOF {
|
||||
if r.nread != r.f.UncompressedSize64 {
|
||||
return 0, io.ErrUnexpectedEOF
|
||||
}
|
||||
if r.desr != nil {
|
||||
if err1 := readDataDescriptor(r.desr, r.f); err1 != nil {
|
||||
err = err1
|
||||
if err1 == io.EOF {
|
||||
err = io.ErrUnexpectedEOF
|
||||
} else {
|
||||
err = err1
|
||||
}
|
||||
} else if r.hash.Sum32() != r.f.CRC32 {
|
||||
err = ErrChecksum
|
||||
}
|
||||
|
|
|
@ -531,3 +531,77 @@ func TestIssue8186(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Verify we return ErrUnexpectedEOF when length is short.
|
||||
func TestIssue10957(t *testing.T) {
|
||||
data := []byte("PK\x03\x040000000PK\x01\x0200000" +
|
||||
"0000000000000000000\x00" +
|
||||
"\x00\x00\x00\x00\x00000000000000PK\x01" +
|
||||
"\x020000000000000000000" +
|
||||
"00000\v\x00\x00\x00\x00\x00000000000" +
|
||||
"00000000000000PK\x01\x0200" +
|
||||
"00000000000000000000" +
|
||||
"00\v\x00\x00\x00\x00\x00000000000000" +
|
||||
"00000000000PK\x01\x020000<" +
|
||||
"0\x00\x0000000000000000\v\x00\v" +
|
||||
"\x00\x00\x00\x00\x0000000000\x00\x00\x00\x00000" +
|
||||
"00000000PK\x01\x0200000000" +
|
||||
"0000000000000000\v\x00\x00\x00" +
|
||||
"\x00\x0000PK\x05\x06000000\x05\x000000" +
|
||||
"\v\x00\x00\x00\x00\x00")
|
||||
z, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, f := range z.File {
|
||||
r, err := f.Open()
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if f.UncompressedSize64 < 1e6 {
|
||||
n, err := io.Copy(ioutil.Discard, r)
|
||||
if i == 3 && err != io.ErrUnexpectedEOF {
|
||||
t.Errorf("File[3] error = %v; want io.ErrUnexpectedEOF", err)
|
||||
}
|
||||
if err == nil && uint64(n) != f.UncompressedSize64 {
|
||||
t.Errorf("file %d: bad size: copied=%d; want=%d", i, n, f.UncompressedSize64)
|
||||
}
|
||||
}
|
||||
r.Close()
|
||||
}
|
||||
}
|
||||
|
||||
// Verify the number of files is sane.
|
||||
func TestIssue10956(t *testing.T) {
|
||||
data := []byte("PK\x06\x06PK\x06\a0000\x00\x00\x00\x00\x00\x00\x00\x00" +
|
||||
"0000PK\x05\x06000000000000" +
|
||||
"0000\v\x00000\x00\x00\x00\x00\x00\x00\x000")
|
||||
_, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
const want = "TOC declares impossible 3472328296227680304 files in 57 byte"
|
||||
if err == nil && !strings.Contains(err.Error(), want) {
|
||||
t.Errorf("error = %v; want %q", err, want)
|
||||
}
|
||||
}
|
||||
|
||||
// Verify we return ErrUnexpectedEOF when reading truncated data descriptor.
|
||||
func TestIssue11146(t *testing.T) {
|
||||
data := []byte("PK\x03\x040000000000000000" +
|
||||
"000000\x01\x00\x00\x000\x01\x00\x00\xff\xff0000" +
|
||||
"0000000000000000PK\x01\x02" +
|
||||
"0000\b0\b\x00000000000000" +
|
||||
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x000000PK\x05\x06\x00\x00" +
|
||||
"\x00\x0000\x01\x0000008\x00\x00\x00\x00\x00")
|
||||
z, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
r, err := z.File[0].Open()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = ioutil.ReadAll(r)
|
||||
if err != io.ErrUnexpectedEOF {
|
||||
t.Errorf("File[0] error = %v; want io.ErrUnexpectedEOF", err)
|
||||
}
|
||||
r.Close()
|
||||
}
|
||||
|
|
|
@ -81,8 +81,8 @@ type FileHeader struct {
|
|||
ModifiedTime uint16 // MS-DOS time
|
||||
ModifiedDate uint16 // MS-DOS date
|
||||
CRC32 uint32
|
||||
CompressedSize uint32 // deprecated; use CompressedSize64
|
||||
UncompressedSize uint32 // deprecated; use UncompressedSize64
|
||||
CompressedSize uint32 // Deprecated: Use CompressedSize64 instead.
|
||||
UncompressedSize uint32 // Deprecated: Use UncompressedSize64 instead.
|
||||
CompressedSize64 uint64
|
||||
UncompressedSize64 uint64
|
||||
Extra []byte
|
||||
|
@ -233,7 +233,7 @@ func (h *FileHeader) SetMode(mode os.FileMode) {
|
|||
}
|
||||
}
|
||||
|
||||
// isZip64 returns true if the file size exceeds the 32 bit limit
|
||||
// isZip64 reports whether the file size exceeds the 32 bit limit
|
||||
func (fh *FileHeader) isZip64() bool {
|
||||
return fh.CompressedSize64 > uint32max || fh.UncompressedSize64 > uint32max
|
||||
}
|
||||
|
|
|
@ -34,6 +34,17 @@ func NewWriter(w io.Writer) *Writer {
|
|||
return &Writer{cw: &countWriter{w: bufio.NewWriter(w)}}
|
||||
}
|
||||
|
||||
// SetOffset sets the offset of the beginning of the zip data within the
|
||||
// underlying writer. It should be used when the zip data is appended to an
|
||||
// existing file, such as a binary executable.
|
||||
// It must be called before any data is written.
|
||||
func (w *Writer) SetOffset(n int64) {
|
||||
if w.cw.count != 0 {
|
||||
panic("zip: SetOffset called after data was written")
|
||||
}
|
||||
w.cw.count = n
|
||||
}
|
||||
|
||||
// Flush flushes any buffered data to the underlying writer.
|
||||
// Calling Flush is not normally necessary; calling Close is sufficient.
|
||||
func (w *Writer) Flush() error {
|
||||
|
@ -122,15 +133,15 @@ func (w *Writer) Close() error {
|
|||
|
||||
// zip64 end of central directory record
|
||||
b.uint32(directory64EndSignature)
|
||||
b.uint64(directory64EndLen)
|
||||
b.uint16(zipVersion45) // version made by
|
||||
b.uint16(zipVersion45) // version needed to extract
|
||||
b.uint32(0) // number of this disk
|
||||
b.uint32(0) // number of the disk with the start of the central directory
|
||||
b.uint64(records) // total number of entries in the central directory on this disk
|
||||
b.uint64(records) // total number of entries in the central directory
|
||||
b.uint64(size) // size of the central directory
|
||||
b.uint64(offset) // offset of start of central directory with respect to the starting disk number
|
||||
b.uint64(directory64EndLen - 12) // length minus signature (uint32) and length fields (uint64)
|
||||
b.uint16(zipVersion45) // version made by
|
||||
b.uint16(zipVersion45) // version needed to extract
|
||||
b.uint32(0) // number of this disk
|
||||
b.uint32(0) // number of the disk with the start of the central directory
|
||||
b.uint64(records) // total number of entries in the central directory on this disk
|
||||
b.uint64(records) // total number of entries in the central directory
|
||||
b.uint64(size) // size of the central directory
|
||||
b.uint64(offset) // offset of start of central directory with respect to the starting disk number
|
||||
|
||||
// zip64 end of central directory locator
|
||||
b.uint32(directory64LocSignature)
|
||||
|
@ -184,14 +195,20 @@ func (w *Writer) Create(name string) (io.Writer, error) {
|
|||
// CreateHeader adds a file to the zip file using the provided FileHeader
|
||||
// for the file metadata.
|
||||
// It returns a Writer to which the file contents should be written.
|
||||
//
|
||||
// The file's contents must be written to the io.Writer before the next
|
||||
// call to Create, CreateHeader, or Close.
|
||||
// call to Create, CreateHeader, or Close. The provided FileHeader fh
|
||||
// must not be modified after a call to CreateHeader.
|
||||
func (w *Writer) CreateHeader(fh *FileHeader) (io.Writer, error) {
|
||||
if w.last != nil && !w.last.closed {
|
||||
if err := w.last.close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
if len(w.dir) > 0 && w.dir[len(w.dir)-1].FileHeader == fh {
|
||||
// See https://golang.org/issue/11144 confusion.
|
||||
return nil, errors.New("archive/zip: invalid duplicate FileHeader")
|
||||
}
|
||||
|
||||
fh.Flags |= 0x8 // we will write a data descriptor
|
||||
|
||||
|
|
|
@ -87,6 +87,41 @@ func TestWriter(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestWriterOffset(t *testing.T) {
|
||||
largeData := make([]byte, 1<<17)
|
||||
for i := range largeData {
|
||||
largeData[i] = byte(rand.Int())
|
||||
}
|
||||
writeTests[1].Data = largeData
|
||||
defer func() {
|
||||
writeTests[1].Data = nil
|
||||
}()
|
||||
|
||||
// write a zip file
|
||||
buf := new(bytes.Buffer)
|
||||
existingData := []byte{1, 2, 3, 1, 2, 3, 1, 2, 3}
|
||||
n, _ := buf.Write(existingData)
|
||||
w := NewWriter(buf)
|
||||
w.SetOffset(int64(n))
|
||||
|
||||
for _, wt := range writeTests {
|
||||
testCreate(t, w, &wt)
|
||||
}
|
||||
|
||||
if err := w.Close(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
// read it back
|
||||
r, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for i, wt := range writeTests {
|
||||
testReadFile(t, r.File[i], &wt)
|
||||
}
|
||||
}
|
||||
|
||||
func TestWriterFlush(t *testing.T) {
|
||||
var buf bytes.Buffer
|
||||
w := NewWriter(struct{ io.Writer }{&buf})
|
||||
|
|
|
@ -229,10 +229,11 @@ func TestZip64(t *testing.T) {
|
|||
t.Skip("slow test; skipping")
|
||||
}
|
||||
const size = 1 << 32 // before the "END\n" part
|
||||
testZip64(t, size)
|
||||
buf := testZip64(t, size)
|
||||
testZip64DirectoryRecordLength(buf, t)
|
||||
}
|
||||
|
||||
func testZip64(t testing.TB, size int64) {
|
||||
func testZip64(t testing.TB, size int64) *rleBuffer {
|
||||
const chunkSize = 1024
|
||||
chunks := int(size / chunkSize)
|
||||
// write 2^32 bytes plus "END\n" to a zip file
|
||||
|
@ -302,6 +303,37 @@ func testZip64(t testing.TB, size int64) {
|
|||
if got, want := f0.UncompressedSize64, uint64(size)+uint64(len(end)); got != want {
|
||||
t.Errorf("UncompressedSize64 %d, want %d", got, want)
|
||||
}
|
||||
|
||||
return buf
|
||||
}
|
||||
|
||||
// Issue 9857
|
||||
func testZip64DirectoryRecordLength(buf *rleBuffer, t *testing.T) {
|
||||
d := make([]byte, 1024)
|
||||
if _, err := buf.ReadAt(d, buf.Size()-int64(len(d))); err != nil {
|
||||
t.Fatal("read:", err)
|
||||
}
|
||||
|
||||
sigOff := findSignatureInBlock(d)
|
||||
dirOff, err := findDirectory64End(buf, buf.Size()-int64(len(d))+int64(sigOff))
|
||||
if err != nil {
|
||||
t.Fatal("findDirectory64End:", err)
|
||||
}
|
||||
|
||||
d = make([]byte, directory64EndLen)
|
||||
if _, err := buf.ReadAt(d, dirOff); err != nil {
|
||||
t.Fatal("read:", err)
|
||||
}
|
||||
|
||||
b := readBuf(d)
|
||||
if sig := b.uint32(); sig != directory64EndSignature {
|
||||
t.Fatalf("Expected directory64EndSignature (%d), got %d", directory64EndSignature, sig)
|
||||
}
|
||||
|
||||
size := b.uint64()
|
||||
if size != directory64EndLen-12 {
|
||||
t.Fatalf("Expected length of %d, got %d", directory64EndLen-12, size)
|
||||
}
|
||||
}
|
||||
|
||||
func testInvalidHeader(h *FileHeader, t *testing.T) {
|
||||
|
|
|
@ -144,6 +144,39 @@ func (b *Reader) Peek(n int) ([]byte, error) {
|
|||
return b.buf[b.r : b.r+n], err
|
||||
}
|
||||
|
||||
// Discard skips the next n bytes, returning the number of bytes discarded.
|
||||
//
|
||||
// If Discard skips fewer than n bytes, it also returns an error.
|
||||
// If 0 <= n <= b.Buffered(), Discard is guaranteed to succeed without
|
||||
// reading from the underlying io.Reader.
|
||||
func (b *Reader) Discard(n int) (discarded int, err error) {
|
||||
if n < 0 {
|
||||
return 0, ErrNegativeCount
|
||||
}
|
||||
if n == 0 {
|
||||
return
|
||||
}
|
||||
remain := n
|
||||
for {
|
||||
skip := b.Buffered()
|
||||
if skip == 0 {
|
||||
b.fill()
|
||||
skip = b.Buffered()
|
||||
}
|
||||
if skip > remain {
|
||||
skip = remain
|
||||
}
|
||||
b.r += skip
|
||||
remain -= skip
|
||||
if remain == 0 {
|
||||
return n, nil
|
||||
}
|
||||
if b.err != nil {
|
||||
return n - remain, b.readErr()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read reads data into p.
|
||||
// It returns the number of bytes read into p.
|
||||
// It calls Read at most once on the underlying Reader,
|
||||
|
@ -367,7 +400,6 @@ func (b *Reader) ReadBytes(delim byte) (line []byte, err error) {
|
|||
// accumulating full buffers.
|
||||
var frag []byte
|
||||
var full [][]byte
|
||||
err = nil
|
||||
|
||||
for {
|
||||
var e error
|
||||
|
|
|
@ -1268,6 +1268,135 @@ func TestWriterReset(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestReaderDiscard(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
r io.Reader
|
||||
bufSize int // 0 means 16
|
||||
peekSize int
|
||||
|
||||
n int // input to Discard
|
||||
|
||||
want int // from Discard
|
||||
wantErr error // from Discard
|
||||
|
||||
wantBuffered int
|
||||
}{
|
||||
{
|
||||
name: "normal case",
|
||||
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
|
||||
peekSize: 16,
|
||||
n: 6,
|
||||
want: 6,
|
||||
wantBuffered: 10,
|
||||
},
|
||||
{
|
||||
name: "discard causing read",
|
||||
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
|
||||
n: 6,
|
||||
want: 6,
|
||||
wantBuffered: 10,
|
||||
},
|
||||
{
|
||||
name: "discard all without peek",
|
||||
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
|
||||
n: 26,
|
||||
want: 26,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
{
|
||||
name: "discard more than end",
|
||||
r: strings.NewReader("abcdefghijklmnopqrstuvwxyz"),
|
||||
n: 27,
|
||||
want: 26,
|
||||
wantErr: io.EOF,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
// Any error from filling shouldn't show up until we
|
||||
// get past the valid bytes. Here we return we return 5 valid bytes at the same time
|
||||
// as an error, but test that we don't see the error from Discard.
|
||||
{
|
||||
name: "fill error, discard less",
|
||||
r: newScriptedReader(func(p []byte) (n int, err error) {
|
||||
if len(p) < 5 {
|
||||
panic("unexpected small read")
|
||||
}
|
||||
return 5, errors.New("5-then-error")
|
||||
}),
|
||||
n: 4,
|
||||
want: 4,
|
||||
wantErr: nil,
|
||||
wantBuffered: 1,
|
||||
},
|
||||
{
|
||||
name: "fill error, discard equal",
|
||||
r: newScriptedReader(func(p []byte) (n int, err error) {
|
||||
if len(p) < 5 {
|
||||
panic("unexpected small read")
|
||||
}
|
||||
return 5, errors.New("5-then-error")
|
||||
}),
|
||||
n: 5,
|
||||
want: 5,
|
||||
wantErr: nil,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
{
|
||||
name: "fill error, discard more",
|
||||
r: newScriptedReader(func(p []byte) (n int, err error) {
|
||||
if len(p) < 5 {
|
||||
panic("unexpected small read")
|
||||
}
|
||||
return 5, errors.New("5-then-error")
|
||||
}),
|
||||
n: 6,
|
||||
want: 5,
|
||||
wantErr: errors.New("5-then-error"),
|
||||
wantBuffered: 0,
|
||||
},
|
||||
// Discard of 0 shouldn't cause a read:
|
||||
{
|
||||
name: "discard zero",
|
||||
r: newScriptedReader(), // will panic on Read
|
||||
n: 0,
|
||||
want: 0,
|
||||
wantErr: nil,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
{
|
||||
name: "discard negative",
|
||||
r: newScriptedReader(), // will panic on Read
|
||||
n: -1,
|
||||
want: 0,
|
||||
wantErr: ErrNegativeCount,
|
||||
wantBuffered: 0,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
br := NewReaderSize(tt.r, tt.bufSize)
|
||||
if tt.peekSize > 0 {
|
||||
peekBuf, err := br.Peek(tt.peekSize)
|
||||
if err != nil {
|
||||
t.Errorf("%s: Peek(%d): %v", tt.name, tt.peekSize, err)
|
||||
continue
|
||||
}
|
||||
if len(peekBuf) != tt.peekSize {
|
||||
t.Errorf("%s: len(Peek(%d)) = %v; want %v", tt.name, tt.peekSize, len(peekBuf), tt.peekSize)
|
||||
continue
|
||||
}
|
||||
}
|
||||
discarded, err := br.Discard(tt.n)
|
||||
if ge, we := fmt.Sprint(err), fmt.Sprint(tt.wantErr); discarded != tt.want || ge != we {
|
||||
t.Errorf("%s: Discard(%d) = (%v, %v); want (%v, %v)", tt.name, tt.n, discarded, ge, tt.want, we)
|
||||
continue
|
||||
}
|
||||
if bn := br.Buffered(); bn != tt.wantBuffered {
|
||||
t.Errorf("%s: after Discard, Buffered = %d; want %d", tt.name, bn, tt.wantBuffered)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// An onlyReader only implements io.Reader, no matter what other methods the underlying implementation may have.
|
||||
type onlyReader struct {
|
||||
io.Reader
|
||||
|
@ -1278,6 +1407,23 @@ type onlyWriter struct {
|
|||
io.Writer
|
||||
}
|
||||
|
||||
// A scriptedReader is an io.Reader that executes its steps sequentially.
|
||||
type scriptedReader []func(p []byte) (n int, err error)
|
||||
|
||||
func (sr *scriptedReader) Read(p []byte) (n int, err error) {
|
||||
if len(*sr) == 0 {
|
||||
panic("too many Read calls on scripted Reader. No steps remain.")
|
||||
}
|
||||
step := (*sr)[0]
|
||||
*sr = (*sr)[1:]
|
||||
return step(p)
|
||||
}
|
||||
|
||||
func newScriptedReader(steps ...func(p []byte) (n int, err error)) io.Reader {
|
||||
sr := scriptedReader(steps)
|
||||
return &sr
|
||||
}
|
||||
|
||||
func BenchmarkReaderCopyOptimal(b *testing.B) {
|
||||
// Optimal case is where the underlying reader implements io.WriterTo
|
||||
srcBuf := bytes.NewBuffer(make([]byte, 8192))
|
||||
|
|
|
@ -109,7 +109,7 @@ func (s *Scanner) Text() string {
|
|||
// After Scan returns false, the Err method will return any error that
|
||||
// occurred during scanning, except that if it was io.EOF, Err
|
||||
// will return nil.
|
||||
// Split panics if the split function returns 100 empty tokens without
|
||||
// Scan panics if the split function returns 100 empty tokens without
|
||||
// advancing the input. This is a common error mode for scanners.
|
||||
func (s *Scanner) Scan() bool {
|
||||
// Loop until we have a token.
|
||||
|
|
|
@ -236,14 +236,14 @@ func panic(v interface{})
|
|||
// panicking.
|
||||
func recover() interface{}
|
||||
|
||||
// The print built-in function formats its arguments in an implementation-
|
||||
// specific way and writes the result to standard error.
|
||||
// The print built-in function formats its arguments in an
|
||||
// implementation-specific way and writes the result to standard error.
|
||||
// Print is useful for bootstrapping and debugging; it is not guaranteed
|
||||
// to stay in the language.
|
||||
func print(args ...Type)
|
||||
|
||||
// The println built-in function formats its arguments in an implementation-
|
||||
// specific way and writes the result to standard error.
|
||||
// The println built-in function formats its arguments in an
|
||||
// implementation-specific way and writes the result to standard error.
|
||||
// Spaces are always added between arguments and a newline is appended.
|
||||
// Println is useful for bootstrapping and debugging; it is not guaranteed
|
||||
// to stay in the language.
|
||||
|
|
|
@ -56,6 +56,10 @@ func (b *Buffer) String() string {
|
|||
// b.Len() == len(b.Bytes()).
|
||||
func (b *Buffer) Len() int { return len(b.buf) - b.off }
|
||||
|
||||
// Cap returns the capacity of the buffer's underlying byte slice, that is, the
|
||||
// total space allocated for the buffer's data.
|
||||
func (b *Buffer) Cap() int { return cap(b.buf) }
|
||||
|
||||
// Truncate discards all but the first n unread bytes from the buffer.
|
||||
// It panics if n is negative or greater than the length of the buffer.
|
||||
func (b *Buffer) Truncate(n int) {
|
||||
|
|
|
@ -231,6 +231,23 @@ func TestMixedReadsAndWrites(t *testing.T) {
|
|||
empty(t, "TestMixedReadsAndWrites (2)", &buf, s, make([]byte, buf.Len()))
|
||||
}
|
||||
|
||||
func TestCapWithPreallocatedSlice(t *testing.T) {
|
||||
buf := NewBuffer(make([]byte, 10))
|
||||
n := buf.Cap()
|
||||
if n != 10 {
|
||||
t.Errorf("expected 10, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCapWithSliceAndWrittenData(t *testing.T) {
|
||||
buf := NewBuffer(make([]byte, 0, 10))
|
||||
buf.Write([]byte("test"))
|
||||
n := buf.Cap()
|
||||
if n != 10 {
|
||||
t.Errorf("expected 10, got %d", n)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNil(t *testing.T) {
|
||||
var b *Buffer
|
||||
if b.String() != "<nil>" {
|
||||
|
|
|
@ -23,7 +23,7 @@ func equalPortable(a, b []byte) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
// explode splits s into a slice of UTF-8 sequences, one per Unicode character (still slices of bytes),
|
||||
// explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes),
|
||||
// up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes.
|
||||
func explode(s []byte, n int) [][]byte {
|
||||
if n <= 0 {
|
||||
|
@ -47,6 +47,7 @@ func explode(s []byte, n int) [][]byte {
|
|||
}
|
||||
|
||||
// Count counts the number of non-overlapping instances of sep in s.
|
||||
// If sep is an empty slice, Count returns 1 + the number of Unicode code points in s.
|
||||
func Count(s, sep []byte) int {
|
||||
n := len(sep)
|
||||
if n == 0 {
|
||||
|
@ -137,6 +138,16 @@ func LastIndex(s, sep []byte) int {
|
|||
return -1
|
||||
}
|
||||
|
||||
// LastIndexByte returns the index of the last instance of c in s, or -1 if c is not present in s.
|
||||
func LastIndexByte(s []byte, c byte) int {
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
if s[i] == c {
|
||||
return i
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
// IndexRune interprets s as a sequence of UTF-8-encoded Unicode code points.
|
||||
// It returns the byte index of the first occurrence in s of the given rune.
|
||||
// It returns -1 if rune is not present in s.
|
||||
|
@ -442,7 +453,7 @@ func isSeparator(r rune) bool {
|
|||
// Title returns a copy of s with all Unicode letters that begin words
|
||||
// mapped to their title case.
|
||||
//
|
||||
// BUG: The rule Title uses for word boundaries does not handle Unicode punctuation properly.
|
||||
// BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
|
||||
func Title(s []byte) []byte {
|
||||
// Use a closure here to remember state.
|
||||
// Hackish but effective. Depends on Map scanning in order and calling
|
||||
|
|
|
@ -21,4 +21,4 @@ func Equal(a, b []byte) bool // ../runtime/asm_$GOARCH.s
|
|||
// Compare returns an integer comparing two byte slices lexicographically.
|
||||
// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
|
||||
// A nil argument is equivalent to an empty slice.
|
||||
func Compare(a, b []byte) int // ../runtime/noasm_arm.goc or ../runtime/asm_{386,amd64}.s
|
||||
func Compare(a, b []byte) int // ../runtime/noasm.go or ../runtime/asm_{386,amd64}.s
|
||||
|
|
|
@ -265,6 +265,23 @@ func TestIndexByte(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestLastIndexByte(t *testing.T) {
|
||||
testCases := []BinOpTest{
|
||||
{"", "q", -1},
|
||||
{"abcdef", "q", -1},
|
||||
{"abcdefabcdef", "a", len("abcdef")}, // something in the middle
|
||||
{"abcdefabcdef", "f", len("abcdefabcde")}, // last byte
|
||||
{"zabcdefabcdef", "z", 0}, // first byte
|
||||
{"a☺b☻c☹d", "b", len("a☺")}, // non-ascii
|
||||
}
|
||||
for _, test := range testCases {
|
||||
actual := LastIndexByte([]byte(test.a), test.b[0])
|
||||
if actual != test.i {
|
||||
t.Errorf("LastIndexByte(%q,%c) = %v; want %v", test.a, test.b[0], actual, test.i)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// test a larger buffer with different sizes and alignments
|
||||
func TestIndexByteBig(t *testing.T) {
|
||||
var n = 1024
|
||||
|
|
|
@ -17,6 +17,8 @@ var compareTests = []struct {
|
|||
{[]byte("a"), []byte(""), 1},
|
||||
{[]byte(""), []byte("a"), -1},
|
||||
{[]byte("abc"), []byte("abc"), 0},
|
||||
{[]byte("abd"), []byte("abc"), 1},
|
||||
{[]byte("abc"), []byte("abd"), -1},
|
||||
{[]byte("ab"), []byte("abc"), -1},
|
||||
{[]byte("abc"), []byte("ab"), 1},
|
||||
{[]byte("x"), []byte("ab"), 1},
|
||||
|
@ -27,6 +29,7 @@ var compareTests = []struct {
|
|||
{[]byte("abcdefgh"), []byte("abcdefgh"), 0},
|
||||
{[]byte("abcdefghi"), []byte("abcdefghi"), 0},
|
||||
{[]byte("abcdefghi"), []byte("abcdefghj"), -1},
|
||||
{[]byte("abcdefghj"), []byte("abcdefghi"), 1},
|
||||
// nil tests
|
||||
{nil, nil, 0},
|
||||
{[]byte(""), nil, 0},
|
||||
|
|
|
@ -7,7 +7,3 @@ package bytes
|
|||
// Export func for testing
|
||||
var IndexBytePortable = indexBytePortable
|
||||
var EqualPortable = equalPortable
|
||||
|
||||
func (b *Buffer) Cap() int {
|
||||
return cap(b.buf)
|
||||
}
|
||||
|
|
|
@ -29,6 +29,12 @@ func (r *Reader) Len() int {
|
|||
return int(int64(len(r.s)) - r.i)
|
||||
}
|
||||
|
||||
// Size returns the original length of the underlying byte slice.
|
||||
// Size is the number of bytes available for reading via ReadAt.
|
||||
// The returned value is always the same and is not affected by calls
|
||||
// to any other method.
|
||||
func (r *Reader) Size() int64 { return int64(len(r.s)) }
|
||||
|
||||
func (r *Reader) Read(b []byte) (n int, err error) {
|
||||
if len(b) == 0 {
|
||||
return 0, nil
|
||||
|
|
|
@ -244,3 +244,15 @@ func TestReaderCopyNothing(t *testing.T) {
|
|||
t.Errorf("behavior differs: with = %#v; without: %#v", with, withOut)
|
||||
}
|
||||
}
|
||||
|
||||
// tests that Len is affected by reads, but Size is not.
|
||||
func TestReaderLenSize(t *testing.T) {
|
||||
r := NewReader([]byte("abc"))
|
||||
io.CopyN(ioutil.Discard, r, 1)
|
||||
if r.Len() != 2 {
|
||||
t.Errorf("Len = %d; want 2", r.Len())
|
||||
}
|
||||
if r.Size() != 3 {
|
||||
t.Errorf("Size = %d; want 3", r.Size())
|
||||
}
|
||||
}
|
||||
|
|
|
@ -235,9 +235,17 @@ func (f *File) saveExport(x interface{}, context string) {
|
|||
error_(c.Pos(), "export comment has wrong name %q, want %q", name, n.Name.Name)
|
||||
}
|
||||
|
||||
doc := ""
|
||||
for _, c1 := range n.Doc.List {
|
||||
if c1 != c {
|
||||
doc += c1.Text + "\n"
|
||||
}
|
||||
}
|
||||
|
||||
f.ExpFunc = append(f.ExpFunc, &ExpFunc{
|
||||
Func: n,
|
||||
ExpName: name,
|
||||
Doc: doc,
|
||||
})
|
||||
break
|
||||
}
|
||||
|
|
|
@ -20,16 +20,23 @@ the C parts of the package. For example:
|
|||
// #include <errno.h>
|
||||
import "C"
|
||||
|
||||
The preamble may contain any C code, including function and variable
|
||||
declarations and definitions. These may then be referred to from Go
|
||||
code as though they were defined in the package "C". All names
|
||||
declared in the preamble may be used, even if they start with a
|
||||
lower-case letter. Exception: static variables in the preamble may
|
||||
not be referenced from Go code; static functions are permitted.
|
||||
|
||||
See $GOROOT/misc/cgo/stdio and $GOROOT/misc/cgo/gmp for examples. See
|
||||
"C? Go? Cgo!" for an introduction to using cgo:
|
||||
http://golang.org/doc/articles/c_go_cgo.html.
|
||||
https://golang.org/doc/articles/c_go_cgo.html.
|
||||
|
||||
CFLAGS, CPPFLAGS, CXXFLAGS and LDFLAGS may be defined with pseudo #cgo
|
||||
directives within these comments to tweak the behavior of the C or C++
|
||||
compiler. Values defined in multiple directives are concatenated
|
||||
together. The directive can include a list of build constraints limiting its
|
||||
effect to systems satisfying one of the constraints
|
||||
(see http://golang.org/pkg/go/build/#hdr-Build_Constraints for details about the constraint syntax).
|
||||
(see https://golang.org/pkg/go/build/#hdr-Build_Constraints for details about the constraint syntax).
|
||||
For example:
|
||||
|
||||
// #cgo CFLAGS: -DPNG_DEBUG=1
|
||||
|
@ -60,6 +67,18 @@ concatenated and used at link time. All the pkg-config directives are
|
|||
concatenated and sent to pkg-config simultaneously to add to each appropriate
|
||||
set of command-line flags.
|
||||
|
||||
When the cgo directives are parsed, any occurrence of the string ${SRCDIR}
|
||||
will be replaced by the absolute path to the directory containing the source
|
||||
file. This allows pre-compiled static libraries to be included in the package
|
||||
directory and linked properly.
|
||||
For example if package foo is in the directory /go/src/foo:
|
||||
|
||||
// #cgo LDFLAGS: -L${SRCDIR}/libs -lfoo
|
||||
|
||||
Will be expanded to:
|
||||
|
||||
// #cgo LDFLAGS: -L/go/src/foo/libs -lfoo
|
||||
|
||||
When the Go tool sees that one or more Go files use the special import
|
||||
"C", it will look for other non-Go files in the directory and compile
|
||||
them as part of the Go package. Any .c, .s, or .S files will be
|
||||
|
@ -71,17 +90,19 @@ compilers may be changed by the CC and CXX environment variables,
|
|||
respectively; those environment variables may include command line
|
||||
options.
|
||||
|
||||
To enable cgo during cross compiling builds, set the CGO_ENABLED
|
||||
environment variable to 1 when building the Go tools with make.bash.
|
||||
Also, set CC_FOR_TARGET to the C cross compiler for the target. CC will
|
||||
be used for compiling for the host.
|
||||
The cgo tool is enabled by default for native builds on systems where
|
||||
it is expected to work. It is disabled by default when
|
||||
cross-compiling. You can control this by setting the CGO_ENABLED
|
||||
environment variable when running the go tool: set it to 1 to enable
|
||||
the use of cgo, and to 0 to disable it. The go tool will set the
|
||||
build constraint "cgo" if cgo is enabled.
|
||||
|
||||
After the Go tools are built, when running the go command, CC_FOR_TARGET is
|
||||
ignored. The value of CC_FOR_TARGET when running make.bash is the default
|
||||
compiler. However, you can set the environment variable CC, not CC_FOR_TARGET,
|
||||
to control the compiler when running the go tool.
|
||||
|
||||
CXX_FOR_TARGET works in a similar way for C++ code.
|
||||
When cross-compiling, you must specify a C cross-compiler for cgo to
|
||||
use. You can do this by setting the CC_FOR_TARGET environment
|
||||
variable when building the toolchain using make.bash, or by setting
|
||||
the CC environment variable any time you run the go tool. The
|
||||
CXX_FOR_TARGET and CXX environment variables work in a similar way for
|
||||
C++ code.
|
||||
|
||||
Go references to C
|
||||
|
||||
|
@ -195,16 +216,18 @@ Not all Go types can be mapped to C types in a useful way.
|
|||
|
||||
Using //export in a file places a restriction on the preamble:
|
||||
since it is copied into two different C output files, it must not
|
||||
contain any definitions, only declarations. Definitions must be
|
||||
placed in preambles in other files, or in C source files.
|
||||
contain any definitions, only declarations. If a file contains both
|
||||
definitions and declarations, then the two output files will produce
|
||||
duplicate symbols and the linker will fail. To avoid this, definitions
|
||||
must be placed in preambles in other files, or in C source files.
|
||||
|
||||
Using cgo directly
|
||||
|
||||
Usage:
|
||||
go tool cgo [cgo options] [-- compiler options] file.go
|
||||
go tool cgo [cgo options] [-- compiler options] gofiles...
|
||||
|
||||
Cgo transforms the input file.go into four output files: two Go source
|
||||
files, a C file for 6c (or 8c or 5c), and a C file for gcc.
|
||||
Cgo transforms the specified input Go source files into several output
|
||||
Go and C source files.
|
||||
|
||||
The compiler options are passed through uninterpreted when
|
||||
invoking the C compiler to compile the C parts of the package.
|
||||
|
@ -217,18 +240,23 @@ The following options are available when running cgo directly:
|
|||
build when building a cgo package.
|
||||
-dynout file
|
||||
Write -dynimport output to file.
|
||||
-dynpackage package
|
||||
Set Go package for -dynimport output.
|
||||
-dynlinker
|
||||
Write dynamic linker as part of -dynimport output.
|
||||
-godefs
|
||||
Write out input file in Go syntax replacing C package
|
||||
names with real values. Used to generate files in the
|
||||
syscall package when bootstrapping a new target.
|
||||
-cdefs
|
||||
Like -godefs, but write file in C syntax.
|
||||
Used to generate files in the runtime package when
|
||||
bootstrapping a new target.
|
||||
-objdir directory
|
||||
Put all generated files in directory.
|
||||
-importpath string
|
||||
The import path for the Go package. Optional; used for
|
||||
nicer comments in the generated files.
|
||||
-exportheader file
|
||||
If there are any exported functions, write the
|
||||
generated export declarations to file.
|
||||
C code can #include this to see the declarations.
|
||||
-gccgo
|
||||
Generate output for the gccgo compiler rather than the
|
||||
gc compiler.
|
||||
|
@ -363,9 +391,9 @@ the translation process.
|
|||
|
||||
Translating Go
|
||||
|
||||
[The rest of this comment refers to 6g and 6c, the Go and C compilers
|
||||
that are part of the amd64 port of the gc Go toolchain. Everything here
|
||||
applies to another architecture's compilers as well.]
|
||||
[The rest of this comment refers to 6g, the Go compiler that is part
|
||||
of the amd64 port of the gc Go toolchain. Everything here applies to
|
||||
another architecture's compilers as well.]
|
||||
|
||||
Given the input Go files x.go and y.go, cgo generates these source
|
||||
files:
|
||||
|
@ -373,44 +401,41 @@ files:
|
|||
x.cgo1.go # for 6g
|
||||
y.cgo1.go # for 6g
|
||||
_cgo_gotypes.go # for 6g
|
||||
_cgo_defun.c # for 6c
|
||||
_cgo_import.go # for 6g (if -dynout _cgo_import.go)
|
||||
x.cgo2.c # for gcc
|
||||
y.cgo2.c # for gcc
|
||||
_cgo_defun.c # for gcc (if -gccgo)
|
||||
_cgo_export.c # for gcc
|
||||
_cgo_export.h # for gcc
|
||||
_cgo_main.c # for gcc
|
||||
_cgo_flags # for alternative build tools
|
||||
|
||||
The file x.cgo1.go is a copy of x.go with the import "C" removed and
|
||||
references to C.xxx replaced with names like _Cfunc_xxx or _Ctype_xxx.
|
||||
The definitions of those identifiers, written as Go functions, types,
|
||||
or variables, are provided in _cgo_gotypes.go.
|
||||
|
||||
Here is a _cgo_gotypes.go containing definitions for C.flush (provided
|
||||
in the preamble) and C.puts (from stdio):
|
||||
Here is a _cgo_gotypes.go containing definitions for needed C types:
|
||||
|
||||
type _Ctype_char int8
|
||||
type _Ctype_int int32
|
||||
type _Ctype_void [0]byte
|
||||
|
||||
func _Cfunc_CString(string) *_Ctype_char
|
||||
func _Cfunc_flush() _Ctype_void
|
||||
func _Cfunc_puts(*_Ctype_char) _Ctype_int
|
||||
|
||||
For functions, cgo only writes an external declaration in the Go
|
||||
output. The implementation is in a combination of C for 6c (meaning
|
||||
any gc-toolchain compiler) and C for gcc.
|
||||
|
||||
The 6c file contains the definitions of the functions. They all have
|
||||
similar bodies that invoke runtime·cgocall to make a switch from the
|
||||
Go runtime world to the system C (GCC-based) world.
|
||||
The _cgo_gotypes.go file also contains the definitions of the
|
||||
functions. They all have similar bodies that invoke runtime·cgocall
|
||||
to make a switch from the Go runtime world to the system C (GCC-based)
|
||||
world.
|
||||
|
||||
For example, here is the definition of _Cfunc_puts:
|
||||
|
||||
void _cgo_be59f0f25121_Cfunc_puts(void*);
|
||||
//go:cgo_import_static _cgo_be59f0f25121_Cfunc_puts
|
||||
//go:linkname __cgofn__cgo_be59f0f25121_Cfunc_puts _cgo_be59f0f25121_Cfunc_puts
|
||||
var __cgofn__cgo_be59f0f25121_Cfunc_puts byte
|
||||
var _cgo_be59f0f25121_Cfunc_puts = unsafe.Pointer(&__cgofn__cgo_be59f0f25121_Cfunc_puts)
|
||||
|
||||
void
|
||||
·_Cfunc_puts(struct{uint8 x[1];}p)
|
||||
{
|
||||
runtime·cgocall(_cgo_be59f0f25121_Cfunc_puts, &p);
|
||||
func _Cfunc_puts(p0 *_Ctype_char) (r1 _Ctype_int) {
|
||||
_cgo_runtime_cgocall(_cgo_be59f0f25121_Cfunc_puts, uintptr(unsafe.Pointer(&p0)))
|
||||
return
|
||||
}
|
||||
|
||||
The hexadecimal number is a hash of cgo's input, chosen to be
|
||||
|
@ -421,6 +446,7 @@ file compiled by gcc, the file x.cgo2.c:
|
|||
void
|
||||
_cgo_be59f0f25121_Cfunc_puts(void *v)
|
||||
{
|
||||
_cgo_wait_runtime_init_done();
|
||||
struct {
|
||||
char* p0;
|
||||
int r;
|
||||
|
@ -429,7 +455,8 @@ file compiled by gcc, the file x.cgo2.c:
|
|||
a->r = puts((void*)a->p0);
|
||||
}
|
||||
|
||||
It extracts the arguments from the pointer to _Cfunc_puts's argument
|
||||
It waits for Go runtime to be initialized (required for shared libraries),
|
||||
extracts the arguments from the pointer to _Cfunc_puts's argument
|
||||
frame, invokes the system C function (in this case, puts), stores the
|
||||
result in the frame, and returns.
|
||||
|
||||
|
@ -448,6 +475,7 @@ _cgo_main.c:
|
|||
|
||||
int main() { return 0; }
|
||||
void crosscall2(void(*fn)(void*, int), void *a, int c) { }
|
||||
void _cgo_wait_runtime_init_done() { }
|
||||
void _cgo_allocate(void *a, int c) { }
|
||||
void _cgo_panic(void *a, int c) { }
|
||||
|
||||
|
@ -456,23 +484,21 @@ code generated for gcc. The build process links this stub, along with
|
|||
_cgo_export.c and *.cgo2.c, into a dynamic executable and then lets
|
||||
cgo examine the executable. Cgo records the list of shared library
|
||||
references and resolved names and writes them into a new file
|
||||
_cgo_import.c, which looks like:
|
||||
_cgo_import.go, which looks like:
|
||||
|
||||
#pragma cgo_dynamic_linker "/lib64/ld-linux-x86-64.so.2"
|
||||
#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
|
||||
#pragma cgo_import_dynamic __libc_start_main __libc_start_main#GLIBC_2.2.5 "libc.so.6"
|
||||
#pragma cgo_import_dynamic stdout stdout#GLIBC_2.2.5 "libc.so.6"
|
||||
#pragma cgo_import_dynamic fflush fflush#GLIBC_2.2.5 "libc.so.6"
|
||||
#pragma cgo_import_dynamic _ _ "libpthread.so.0"
|
||||
#pragma cgo_import_dynamic _ _ "libc.so.6"
|
||||
//go:cgo_dynamic_linker "/lib64/ld-linux-x86-64.so.2"
|
||||
//go:cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
|
||||
//go:cgo_import_dynamic __libc_start_main __libc_start_main#GLIBC_2.2.5 "libc.so.6"
|
||||
//go:cgo_import_dynamic stdout stdout#GLIBC_2.2.5 "libc.so.6"
|
||||
//go:cgo_import_dynamic fflush fflush#GLIBC_2.2.5 "libc.so.6"
|
||||
//go:cgo_import_dynamic _ _ "libpthread.so.0"
|
||||
//go:cgo_import_dynamic _ _ "libc.so.6"
|
||||
|
||||
In the end, the compiled Go package, which will eventually be
|
||||
presented to 6l as part of a larger program, contains:
|
||||
|
||||
_go_.6 # 6g-compiled object for _cgo_gotypes.go *.cgo1.go
|
||||
_cgo_defun.6 # 6c-compiled object for _cgo_defun.c
|
||||
_go_.6 # 6g-compiled object for _cgo_gotypes.go, _cgo_import.go, *.cgo1.go
|
||||
_all.o # gcc-compiled object for _cgo_export.c, *.cgo2.c
|
||||
_cgo_import.6 # 6c-compiled object for _cgo_import.c
|
||||
|
||||
The final program will be a dynamic executable, so that 6l can avoid
|
||||
needing to process arbitrary .o files. It only needs to process the .o
|
||||
|
@ -496,20 +522,21 @@ Runtime
|
|||
|
||||
When using cgo, Go must not assume that it owns all details of the
|
||||
process. In particular it needs to coordinate with C in the use of
|
||||
threads and thread-local storage. The runtime package, in its own
|
||||
(6c-compiled) C code, declares a few uninitialized (default bss)
|
||||
threads and thread-local storage. The runtime package declares a few
|
||||
variables:
|
||||
|
||||
bool runtime·iscgo;
|
||||
void (*libcgo_thread_start)(void*);
|
||||
void (*initcgo)(G*);
|
||||
var (
|
||||
iscgo bool
|
||||
_cgo_init unsafe.Pointer
|
||||
_cgo_thread_start unsafe.Pointer
|
||||
)
|
||||
|
||||
Any package using cgo imports "runtime/cgo", which provides
|
||||
initializations for these variables. It sets iscgo to 1, initcgo to a
|
||||
gcc-compiled function that can be called early during program startup,
|
||||
and libcgo_thread_start to a gcc-compiled function that can be used to
|
||||
create a new thread, in place of the runtime's usual direct system
|
||||
calls.
|
||||
initializations for these variables. It sets iscgo to true, _cgo_init
|
||||
to a gcc-compiled function that can be called early during program
|
||||
startup, and _cgo_thread_start to a gcc-compiled function that can be
|
||||
used to create a new thread, in place of the runtime's usual direct
|
||||
system calls.
|
||||
|
||||
Internal and External Linking
|
||||
|
||||
|
@ -522,12 +549,12 @@ code can only be used as a dynamic library). On the other hand, when
|
|||
using internal linking, 6l can generate Go binaries by itself.
|
||||
|
||||
In order to allow linking arbitrary object files without requiring
|
||||
dynamic libraries, cgo will soon support an "external" linking mode
|
||||
too. In external linking mode, 6l does not process any host object
|
||||
files. Instead, it collects all the Go code and writes a single go.o
|
||||
object file containing it. Then it invokes the host linker (usually
|
||||
gcc) to combine the go.o object file and any supporting non-Go code
|
||||
into a final executable. External linking avoids the dynamic library
|
||||
dynamic libraries, cgo supports an "external" linking mode too. In
|
||||
external linking mode, 6l does not process any host object files.
|
||||
Instead, it collects all the Go code and writes a single go.o object
|
||||
file containing it. Then it invokes the host linker (usually gcc) to
|
||||
combine the go.o object file and any supporting non-Go code into a
|
||||
final executable. External linking avoids the dynamic library
|
||||
requirement but introduces a requirement that the host linker be
|
||||
present to create such a binary.
|
||||
|
||||
|
@ -555,13 +582,13 @@ to be made when linking the final binary.
|
|||
Linking Directives
|
||||
|
||||
In either linking mode, package-specific directives must be passed
|
||||
through to 6l. These are communicated by writing #pragma directives
|
||||
in a C source file compiled by 6c. The directives are copied into the .6 object file
|
||||
and then processed by the linker.
|
||||
through to 6l. These are communicated by writing //go: directives in a
|
||||
Go source file compiled by 6g. The directives are copied into the .6
|
||||
object file and then processed by the linker.
|
||||
|
||||
The directives are:
|
||||
|
||||
#pragma cgo_import_dynamic <local> [<remote> ["<library>"]]
|
||||
//go:cgo_import_dynamic <local> [<remote> ["<library>"]]
|
||||
|
||||
In internal linking mode, allow an unresolved reference to
|
||||
<local>, assuming it will be resolved by a dynamic library
|
||||
|
@ -572,9 +599,9 @@ The directives are:
|
|||
In the <remote>, # or @ can be used to introduce a symbol version.
|
||||
|
||||
Examples:
|
||||
#pragma cgo_import_dynamic puts
|
||||
#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5
|
||||
#pragma cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
|
||||
//go:cgo_import_dynamic puts
|
||||
//go:cgo_import_dynamic puts puts#GLIBC_2.2.5
|
||||
//go:cgo_import_dynamic puts puts#GLIBC_2.2.5 "libc.so.6"
|
||||
|
||||
A side effect of the cgo_import_dynamic directive with a
|
||||
library is to make the final binary depend on that dynamic
|
||||
|
@ -582,12 +609,12 @@ The directives are:
|
|||
symbols, use _ for local and remote.
|
||||
|
||||
Example:
|
||||
#pragma cgo_import_dynamic _ _ "libc.so.6"
|
||||
//go:cgo_import_dynamic _ _ "libc.so.6"
|
||||
|
||||
For compatibility with current versions of SWIG,
|
||||
#pragma dynimport is an alias for #pragma cgo_import_dynamic.
|
||||
#pragma dynimport is an alias for //go:cgo_import_dynamic.
|
||||
|
||||
#pragma cgo_dynamic_linker "<path>"
|
||||
//go:cgo_dynamic_linker "<path>"
|
||||
|
||||
In internal linking mode, use "<path>" as the dynamic linker
|
||||
in the final binary. This directive is only needed from one
|
||||
|
@ -595,9 +622,9 @@ The directives are:
|
|||
supplied by runtime/cgo.
|
||||
|
||||
Example:
|
||||
#pragma cgo_dynamic_linker "/lib/ld-linux.so.2"
|
||||
//go:cgo_dynamic_linker "/lib/ld-linux.so.2"
|
||||
|
||||
#pragma cgo_export_dynamic <local> <remote>
|
||||
//go:cgo_export_dynamic <local> <remote>
|
||||
|
||||
In internal linking mode, put the Go symbol
|
||||
named <local> into the program's exported symbol table as
|
||||
|
@ -606,9 +633,9 @@ The directives are:
|
|||
to share Go's data.
|
||||
|
||||
For compatibility with current versions of SWIG,
|
||||
#pragma dynexport is an alias for #pragma cgo_export_dynamic.
|
||||
#pragma dynexport is an alias for //go:cgo_export_dynamic.
|
||||
|
||||
#pragma cgo_import_static <local>
|
||||
//go:cgo_import_static <local>
|
||||
|
||||
In external linking mode, allow unresolved references to
|
||||
<local> in the go.o object file prepared for the host linker,
|
||||
|
@ -616,9 +643,9 @@ The directives are:
|
|||
other object files that will be linked with go.o.
|
||||
|
||||
Example:
|
||||
#pragma cgo_import_static puts_wrapper
|
||||
//go:cgo_import_static puts_wrapper
|
||||
|
||||
#pragma cgo_export_static <local> <remote>
|
||||
//go:cgo_export_static <local> <remote>
|
||||
|
||||
In external linking mode, put the Go symbol
|
||||
named <local> into the program's exported symbol table as
|
||||
|
@ -626,15 +653,15 @@ The directives are:
|
|||
mechanism makes it possible for C code to call back into Go or
|
||||
to share Go's data.
|
||||
|
||||
#pragma cgo_ldflag "<arg>"
|
||||
//go:cgo_ldflag "<arg>"
|
||||
|
||||
In external linking mode, invoke the host linker (usually gcc)
|
||||
with "<arg>" as a command-line argument following the .o files.
|
||||
Note that the arguments are for "gcc", not "ld".
|
||||
|
||||
Example:
|
||||
#pragma cgo_ldflag "-lpthread"
|
||||
#pragma cgo_ldflag "-L/usr/local/sqlite3/lib"
|
||||
//go:cgo_ldflag "-lpthread"
|
||||
//go:cgo_ldflag "-L/usr/local/sqlite3/lib"
|
||||
|
||||
A package compiled with cgo will include directives for both
|
||||
internal and external linking; the linker will select the appropriate
|
||||
|
@ -647,22 +674,18 @@ The following code will be generated by cgo:
|
|||
|
||||
// compiled by 6g
|
||||
|
||||
//go:cgo_ldflag "-lm"
|
||||
|
||||
type _Ctype_double float64
|
||||
func _Cfunc_sin(_Ctype_double) _Ctype_double
|
||||
|
||||
// compiled by 6c
|
||||
//go:cgo_import_static _cgo_gcc_Cfunc_sin
|
||||
//go:linkname __cgo_gcc_Cfunc_sin _cgo_gcc_Cfunc_sin
|
||||
var __cgo_gcc_Cfunc_sin byte
|
||||
var _cgo_gcc_Cfunc_sin = unsafe.Pointer(&__cgo_gcc_Cfunc_sin)
|
||||
|
||||
#pragma cgo_import_dynamic sin sin#GLIBC_2.2.5 "libm.so.6"
|
||||
|
||||
#pragma cgo_import_static _cgo_gcc_Cfunc_sin
|
||||
#pragma cgo_ldflag "-lm"
|
||||
|
||||
void _cgo_gcc_Cfunc_sin(void*);
|
||||
|
||||
void
|
||||
·_Cfunc_sin(struct{uint8 x[16];}p)
|
||||
{
|
||||
runtime·cgocall(_cgo_gcc_Cfunc_sin, &p);
|
||||
func _Cfunc_sin(p0 _Ctype_double) (r1 _Ctype_double) {
|
||||
_cgo_runtime_cgocall(_cgo_gcc_Cfunc_sin, uintptr(unsafe.Pointer(&p0)))
|
||||
return
|
||||
}
|
||||
|
||||
// compiled by gcc, into foo.cgo2.o
|
||||
|
@ -682,8 +705,8 @@ using the internal or external mode. If other packages are compiled in
|
|||
"external only" mode, then the final link will be an external one.
|
||||
Otherwise the link will be an internal one.
|
||||
|
||||
The directives in the 6c-compiled file are used according to the kind
|
||||
of final link used.
|
||||
The linking directives are used according to the kind of final link
|
||||
used.
|
||||
|
||||
In internal mode, 6l itself processes all the host object files, in
|
||||
particular foo.cgo2.o. To do so, it uses the cgo_import_dynamic and
|
||||
|
@ -694,10 +717,10 @@ symbol sin with version GLIBC_2.2.5 from the dynamic library
|
|||
runtime dynamic linker.
|
||||
|
||||
In external mode, 6l does not process any host object files, in
|
||||
particular foo.cgo2.o. It links together the 6g- and 6c-generated
|
||||
object files, along with any other Go code, into a go.o file. While
|
||||
doing that, 6l will discover that there is no definition for
|
||||
_cgo_gcc_Cfunc_sin, referred to by the 6c-compiled source file. This
|
||||
particular foo.cgo2.o. It links together the 6g-generated object
|
||||
files, along with any other Go code, into a go.o file. While doing
|
||||
that, 6l will discover that there is no definition for
|
||||
_cgo_gcc_Cfunc_sin, referred to by the 6g-compiled source file. This
|
||||
is okay, because 6l also processes the cgo_import_static directive and
|
||||
knows that _cgo_gcc_Cfunc_sin is expected to be supplied by a host
|
||||
object file, so 6l does not treat the missing symbol as an error when
|
||||
|
|
|
@ -154,20 +154,6 @@ func splitQuoted(s string) (r []string, err error) {
|
|||
return args, err
|
||||
}
|
||||
|
||||
var safeBytes = []byte(`+-.,/0123456789:=ABCDEFGHIJKLMNOPQRSTUVWXYZ\_abcdefghijklmnopqrstuvwxyz`)
|
||||
|
||||
func safeName(s string) bool {
|
||||
if s == "" {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(s); i++ {
|
||||
if c := s[i]; c < 0x80 && bytes.IndexByte(safeBytes, c) < 0 {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Translate rewrites f.AST, the original Go input, to remove
|
||||
// references to the imported package C, replacing them with
|
||||
// references to the equivalent Go types, functions, and variables.
|
||||
|
@ -213,6 +199,10 @@ func (p *Package) loadDefines(f *File) {
|
|||
val = strings.TrimSpace(line[tabIndex:])
|
||||
}
|
||||
|
||||
if key == "__clang__" {
|
||||
p.GccIsClang = true
|
||||
}
|
||||
|
||||
if n := f.Name[key]; n != nil {
|
||||
if *debugDefine {
|
||||
fmt.Fprintf(os.Stderr, "#define %s %s\n", key, val)
|
||||
|
@ -582,7 +572,7 @@ func (p *Package) mangleName(n *Name) {
|
|||
|
||||
// rewriteRef rewrites all the C.xxx references in f.AST to refer to the
|
||||
// Go equivalents, now that we have figured out the meaning of all
|
||||
// the xxx. In *godefs or *cdefs mode, rewriteRef replaces the names
|
||||
// the xxx. In *godefs mode, rewriteRef replaces the names
|
||||
// with full definitions instead of mangled names.
|
||||
func (p *Package) rewriteRef(f *File) {
|
||||
// Keep a list of all the functions, to remove the ones
|
||||
|
@ -673,6 +663,13 @@ func (p *Package) rewriteRef(f *File) {
|
|||
expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
|
||||
}
|
||||
|
||||
case "selector":
|
||||
if r.Name.Kind == "var" {
|
||||
expr = &ast.StarExpr{Star: (*r.Expr).Pos(), X: expr}
|
||||
} else {
|
||||
error_(r.Pos(), "only C variables allowed in selector expression", fixGo(r.Name.Go))
|
||||
}
|
||||
|
||||
case "type":
|
||||
if r.Name.Kind != "type" {
|
||||
error_(r.Pos(), "expression C.%s used as type", fixGo(r.Name.Go))
|
||||
|
@ -688,7 +685,7 @@ func (p *Package) rewriteRef(f *File) {
|
|||
error_(r.Pos(), "must call C.%s", fixGo(r.Name.Go))
|
||||
}
|
||||
}
|
||||
if *godefs || *cdefs {
|
||||
if *godefs {
|
||||
// Substitute definition for mangled type name.
|
||||
if id, ok := expr.(*ast.Ident); ok {
|
||||
if t := typedef[id.Name]; t != nil {
|
||||
|
@ -746,6 +743,10 @@ func (p *Package) gccMachine() []string {
|
|||
return []string{"-m32"}
|
||||
case "arm":
|
||||
return []string{"-marm"} // not thumb
|
||||
case "s390":
|
||||
return []string{"-m31"}
|
||||
case "s390x":
|
||||
return []string{"-m64"}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -765,7 +766,7 @@ func (p *Package) gccCmd() []string {
|
|||
"-c", // do not link
|
||||
"-xc", // input language is C
|
||||
)
|
||||
if strings.Contains(c[0], "clang") {
|
||||
if p.GccIsClang {
|
||||
c = append(c,
|
||||
"-ferror-limit=0",
|
||||
// Apple clang version 1.7 (tags/Apple/clang-77) (based on LLVM 2.9svn)
|
||||
|
@ -780,7 +781,7 @@ func (p *Package) gccCmd() []string {
|
|||
// incorrectly typed unsigned long. We work around that
|
||||
// by disabling the builtin functions (this is safe as
|
||||
// it won't affect the actual compilation of the C code).
|
||||
// See: http://golang.org/issue/6506.
|
||||
// See: https://golang.org/issue/6506.
|
||||
"-fno-builtin",
|
||||
)
|
||||
}
|
||||
|
@ -992,8 +993,8 @@ func (c *typeConv) Init(ptrSize, intSize int64) {
|
|||
c.goVoid = c.Ident("_Ctype_void")
|
||||
|
||||
// Normally cgo translates void* to unsafe.Pointer,
|
||||
// but for historical reasons -cdefs and -godefs use *byte instead.
|
||||
if *cdefs || *godefs {
|
||||
// but for historical reasons -godefs uses *byte instead.
|
||||
if *godefs {
|
||||
c.goVoidPtr = &ast.StarExpr{X: c.byte}
|
||||
} else {
|
||||
c.goVoidPtr = c.Ident("unsafe.Pointer")
|
||||
|
@ -1045,7 +1046,7 @@ func (tr *TypeRepr) String() string {
|
|||
return fmt.Sprintf(tr.Repr, tr.FormatArgs...)
|
||||
}
|
||||
|
||||
// Empty returns true if the result of String would be "".
|
||||
// Empty reports whether the result of String would be "".
|
||||
func (tr *TypeRepr) Empty() bool {
|
||||
return len(tr.Repr) == 0
|
||||
}
|
||||
|
@ -1334,8 +1335,8 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
|||
// If sub.Go.Name is "_Ctype_struct_foo" or "_Ctype_union_foo" or "_Ctype_class_foo",
|
||||
// use that as the Go form for this typedef too, so that the typedef will be interchangeable
|
||||
// with the base type.
|
||||
// In -godefs and -cdefs mode, do this for all typedefs.
|
||||
if isStructUnionClass(sub.Go) || *godefs || *cdefs {
|
||||
// In -godefs mode, do this for all typedefs.
|
||||
if isStructUnionClass(sub.Go) || *godefs {
|
||||
t.Go = sub.Go
|
||||
|
||||
if isStructUnionClass(sub.Go) {
|
||||
|
@ -1397,7 +1398,7 @@ func (c *typeConv) Type(dtype dwarf.Type, pos token.Pos) *Type {
|
|||
name := c.Ident("_Ctype_" + s)
|
||||
tt := *t
|
||||
typedef[name.Name] = &tt
|
||||
if !*godefs && !*cdefs {
|
||||
if !*godefs {
|
||||
t.Go = name
|
||||
}
|
||||
}
|
||||
|
@ -1543,14 +1544,16 @@ func (c *typeConv) intExpr(n int64) ast.Expr {
|
|||
}
|
||||
|
||||
// Add padding of given size to fld.
|
||||
func (c *typeConv) pad(fld []*ast.Field, size int64) []*ast.Field {
|
||||
func (c *typeConv) pad(fld []*ast.Field, sizes []int64, size int64) ([]*ast.Field, []int64) {
|
||||
n := len(fld)
|
||||
fld = fld[0 : n+1]
|
||||
fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident("_")}, Type: c.Opaque(size)}
|
||||
return fld
|
||||
sizes = sizes[0 : n+1]
|
||||
sizes[n] = size
|
||||
return fld, sizes
|
||||
}
|
||||
|
||||
// Struct conversion: return Go and (6g) C syntax for type.
|
||||
// Struct conversion: return Go and (gc) C syntax for type.
|
||||
func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.StructType, csyntax string, align int64) {
|
||||
// Minimum alignment for a struct is 1 byte.
|
||||
align = 1
|
||||
|
@ -1558,6 +1561,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
|||
var buf bytes.Buffer
|
||||
buf.WriteString("struct {")
|
||||
fld := make([]*ast.Field, 0, 2*len(dt.Field)+1) // enough for padding around every field
|
||||
sizes := make([]int64, 0, 2*len(dt.Field)+1)
|
||||
off := int64(0)
|
||||
|
||||
// Rename struct fields that happen to be named Go keywords into
|
||||
|
@ -1573,7 +1577,7 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
|||
used[f.Name] = true
|
||||
}
|
||||
|
||||
if !*godefs && !*cdefs {
|
||||
if !*godefs {
|
||||
for cid, goid := range ident {
|
||||
if token.Lookup(goid).IsKeyword() {
|
||||
// Avoid keyword
|
||||
|
@ -1593,19 +1597,19 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
|||
anon := 0
|
||||
for _, f := range dt.Field {
|
||||
if f.ByteOffset > off {
|
||||
fld = c.pad(fld, f.ByteOffset-off)
|
||||
fld, sizes = c.pad(fld, sizes, f.ByteOffset-off)
|
||||
off = f.ByteOffset
|
||||
}
|
||||
|
||||
name := f.Name
|
||||
ft := f.Type
|
||||
|
||||
// In godefs or cdefs mode, if this field is a C11
|
||||
// In godefs mode, if this field is a C11
|
||||
// anonymous union then treat the first field in the
|
||||
// union as the field in the struct. This handles
|
||||
// cases like the glibc <sys/resource.h> file; see
|
||||
// issue 6677.
|
||||
if *godefs || *cdefs {
|
||||
if *godefs {
|
||||
if st, ok := f.Type.(*dwarf.StructType); ok && name == "" && st.Kind == "union" && len(st.Field) > 0 && !used[st.Field[0].Name] {
|
||||
name = st.Field[0].Name
|
||||
ident[name] = name
|
||||
|
@ -1635,14 +1639,12 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
|||
talign = size
|
||||
}
|
||||
|
||||
if talign > 0 && f.ByteOffset%talign != 0 && !*cdefs {
|
||||
if talign > 0 && f.ByteOffset%talign != 0 {
|
||||
// Drop misaligned fields, the same way we drop integer bit fields.
|
||||
// The goal is to make available what can be made available.
|
||||
// Otherwise one bad and unneeded field in an otherwise okay struct
|
||||
// makes the whole program not compile. Much of the time these
|
||||
// structs are in system headers that cannot be corrected.
|
||||
// Exception: In -cdefs mode, we use #pragma pack, so misaligned
|
||||
// fields should still work.
|
||||
continue
|
||||
}
|
||||
n := len(fld)
|
||||
|
@ -1653,6 +1655,8 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
|||
ident[name] = name
|
||||
}
|
||||
fld[n] = &ast.Field{Names: []*ast.Ident{c.Ident(ident[name])}, Type: tgo}
|
||||
sizes = sizes[0 : n+1]
|
||||
sizes[n] = size
|
||||
off += size
|
||||
buf.WriteString(t.C.String())
|
||||
buf.WriteString(" ")
|
||||
|
@ -1663,16 +1667,29 @@ func (c *typeConv) Struct(dt *dwarf.StructType, pos token.Pos) (expr *ast.Struct
|
|||
}
|
||||
}
|
||||
if off < dt.ByteSize {
|
||||
fld = c.pad(fld, dt.ByteSize-off)
|
||||
fld, sizes = c.pad(fld, sizes, dt.ByteSize-off)
|
||||
off = dt.ByteSize
|
||||
}
|
||||
|
||||
// If the last field in a non-zero-sized struct is zero-sized
|
||||
// the compiler is going to pad it by one (see issue 9401).
|
||||
// We can't permit that, because then the size of the Go
|
||||
// struct will not be the same as the size of the C struct.
|
||||
// Our only option in such a case is to remove the field,
|
||||
// which means that it can not be referenced from Go.
|
||||
for off > 0 && sizes[len(sizes)-1] == 0 {
|
||||
n := len(sizes)
|
||||
fld = fld[0 : n-1]
|
||||
sizes = sizes[0 : n-1]
|
||||
}
|
||||
|
||||
if off != dt.ByteSize {
|
||||
fatalf("%s: struct size calculation error off=%d bytesize=%d", lineno(pos), off, dt.ByteSize)
|
||||
}
|
||||
buf.WriteString("}")
|
||||
csyntax = buf.String()
|
||||
|
||||
if *godefs || *cdefs {
|
||||
if *godefs {
|
||||
godefsFields(fld)
|
||||
}
|
||||
expr = &ast.StructType{Fields: &ast.FieldList{List: fld}}
|
||||
|
@ -1707,9 +1724,7 @@ func godefsFields(fld []*ast.Field) {
|
|||
n.Name = "Pad_cgo_" + strconv.Itoa(npad)
|
||||
npad++
|
||||
}
|
||||
if !*cdefs {
|
||||
n.Name = upper(n.Name)
|
||||
}
|
||||
n.Name = upper(n.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1721,9 +1736,6 @@ func godefsFields(fld []*ast.Field) {
|
|||
// package syscall's data structures, we drop a common prefix
|
||||
// (so sec, usec, which will get turned into Sec, Usec for exporting).
|
||||
func fieldPrefix(fld []*ast.Field) string {
|
||||
if *cdefs {
|
||||
return ""
|
||||
}
|
||||
prefix := ""
|
||||
for _, f := range fld {
|
||||
for _, n := range f.Names {
|
||||
|
|
|
@ -114,173 +114,6 @@ func (p *Package) godefs(f *File, srcfile string) string {
|
|||
return buf.String()
|
||||
}
|
||||
|
||||
// cdefs returns the output for -cdefs mode.
|
||||
// The easiest way to do this is to translate the godefs Go to C.
|
||||
func (p *Package) cdefs(f *File, srcfile string) string {
|
||||
godefsOutput := p.godefs(f, srcfile)
|
||||
|
||||
lines := strings.Split(godefsOutput, "\n")
|
||||
lines[0] = "// Created by cgo -cdefs - DO NOT EDIT"
|
||||
|
||||
for i, line := range lines {
|
||||
lines[i] = strings.TrimSpace(line)
|
||||
}
|
||||
|
||||
var out bytes.Buffer
|
||||
printf := func(format string, args ...interface{}) { fmt.Fprintf(&out, format, args...) }
|
||||
|
||||
didTypedef := false
|
||||
for i := 0; i < len(lines); i++ {
|
||||
line := lines[i]
|
||||
|
||||
// Delete
|
||||
// package x
|
||||
if strings.HasPrefix(line, "package ") {
|
||||
continue
|
||||
}
|
||||
|
||||
// Convert
|
||||
// const (
|
||||
// A = 1
|
||||
// B = 2
|
||||
// )
|
||||
//
|
||||
// to
|
||||
//
|
||||
// enum {
|
||||
// A = 1,
|
||||
// B = 2,
|
||||
// };
|
||||
if line == "const (" {
|
||||
printf("enum {\n")
|
||||
for i++; i < len(lines) && lines[i] != ")"; i++ {
|
||||
line = lines[i]
|
||||
if line != "" {
|
||||
printf("\t%s,", line)
|
||||
}
|
||||
printf("\n")
|
||||
}
|
||||
printf("};\n")
|
||||
continue
|
||||
}
|
||||
|
||||
// Convert
|
||||
// const A = 1
|
||||
// to
|
||||
// enum { A = 1 };
|
||||
if strings.HasPrefix(line, "const ") {
|
||||
printf("enum { %s };\n", line[len("const "):])
|
||||
continue
|
||||
}
|
||||
|
||||
// On first type definition, typedef all the structs
|
||||
// in case there are dependencies between them.
|
||||
if !didTypedef && strings.HasPrefix(line, "type ") {
|
||||
didTypedef = true
|
||||
for _, line := range lines {
|
||||
line = strings.TrimSpace(line)
|
||||
if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") {
|
||||
s := strings.TrimSuffix(strings.TrimPrefix(line, "type "), " struct {")
|
||||
printf("typedef struct %s %s;\n", s, s)
|
||||
}
|
||||
}
|
||||
printf("\n")
|
||||
printf("#pragma pack on\n")
|
||||
printf("\n")
|
||||
}
|
||||
|
||||
// Convert
|
||||
// type T struct {
|
||||
// X int64
|
||||
// Y *int32
|
||||
// Z [4]byte
|
||||
// }
|
||||
//
|
||||
// to
|
||||
//
|
||||
// struct T {
|
||||
// int64 X;
|
||||
// int32 *Y;
|
||||
// byte Z[4];
|
||||
// }
|
||||
if strings.HasPrefix(line, "type ") && strings.HasSuffix(line, " struct {") {
|
||||
if len(lines) > i+1 && lines[i+1] == "}" {
|
||||
// do not output empty struct
|
||||
i++
|
||||
continue
|
||||
}
|
||||
s := line[len("type ") : len(line)-len(" struct {")]
|
||||
printf("struct %s {\n", s)
|
||||
for i++; i < len(lines) && lines[i] != "}"; i++ {
|
||||
line := lines[i]
|
||||
if line != "" {
|
||||
f := strings.Fields(line)
|
||||
if len(f) != 2 {
|
||||
fmt.Fprintf(os.Stderr, "cgo: cannot parse struct field: %s\n", line)
|
||||
nerrors++
|
||||
continue
|
||||
}
|
||||
printf("\t%s;", cdecl(f[0], f[1]))
|
||||
}
|
||||
printf("\n")
|
||||
}
|
||||
printf("};\n")
|
||||
continue
|
||||
}
|
||||
|
||||
// Convert
|
||||
// type T int
|
||||
// to
|
||||
// typedef int T;
|
||||
if strings.HasPrefix(line, "type ") {
|
||||
f := strings.Fields(line[len("type "):])
|
||||
if len(f) != 2 {
|
||||
fmt.Fprintf(os.Stderr, "cgo: cannot parse type definition: %s\n", line)
|
||||
nerrors++
|
||||
continue
|
||||
}
|
||||
printf("typedef\t%s;\n", cdecl(f[0], f[1]))
|
||||
continue
|
||||
}
|
||||
|
||||
printf("%s\n", line)
|
||||
}
|
||||
|
||||
if didTypedef {
|
||||
printf("\n")
|
||||
printf("#pragma pack off\n")
|
||||
}
|
||||
|
||||
return out.String()
|
||||
}
|
||||
|
||||
// cdecl returns the C declaration for the given Go name and type.
|
||||
// It only handles the specific cases necessary for converting godefs output.
|
||||
func cdecl(name, typ string) string {
|
||||
// X *[0]byte -> X *void
|
||||
if strings.HasPrefix(typ, "*[0]") {
|
||||
typ = "*void"
|
||||
}
|
||||
// X [4]byte -> X[4] byte
|
||||
for strings.HasPrefix(typ, "[") {
|
||||
i := strings.Index(typ, "]") + 1
|
||||
name = name + typ[:i]
|
||||
typ = typ[i:]
|
||||
}
|
||||
// X *byte -> *X byte
|
||||
for strings.HasPrefix(typ, "*") {
|
||||
name = "*" + name
|
||||
typ = typ[1:]
|
||||
}
|
||||
// X T -> T X
|
||||
// Handle the special case: 'unsafe.Pointer' is 'void *'
|
||||
if typ == "unsafe.Pointer" {
|
||||
typ = "void"
|
||||
name = "*" + name
|
||||
}
|
||||
return typ + "\t" + name
|
||||
}
|
||||
|
||||
var gofmtBuf bytes.Buffer
|
||||
|
||||
// gofmt returns the gofmt-formatted string for an AST node.
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// TODO(rsc):
|
||||
// Emit correct line number annotations.
|
||||
// Make 6g understand the annotations.
|
||||
// Make gc understand the annotations.
|
||||
|
||||
package main
|
||||
|
||||
|
@ -33,6 +33,7 @@ type Package struct {
|
|||
PtrSize int64
|
||||
IntSize int64
|
||||
GccOptions []string
|
||||
GccIsClang bool
|
||||
CgoFlags map[string][]string // #cgo flags (CFLAGS, LDFLAGS)
|
||||
Written map[string]bool
|
||||
Name map[string]*Name // accumulated Name from Files
|
||||
|
@ -87,7 +88,7 @@ type Name struct {
|
|||
Const string // constant definition
|
||||
}
|
||||
|
||||
// IsVar returns true if Kind is either "var" or "fpvar"
|
||||
// IsVar reports whether Kind is either "var" or "fpvar"
|
||||
func (n *Name) IsVar() bool {
|
||||
return n.Kind == "var" || n.Kind == "fpvar"
|
||||
}
|
||||
|
@ -98,6 +99,7 @@ func (n *Name) IsVar() bool {
|
|||
type ExpFunc struct {
|
||||
Func *ast.FuncDecl
|
||||
ExpName string // name to use from C
|
||||
Doc string
|
||||
}
|
||||
|
||||
// A TypeRepr contains the string representation of a type.
|
||||
|
@ -174,15 +176,18 @@ var cPrefix string
|
|||
var fset = token.NewFileSet()
|
||||
|
||||
var dynobj = flag.String("dynimport", "", "if non-empty, print dynamic import data for that file")
|
||||
var dynout = flag.String("dynout", "", "write -dynobj output to this file")
|
||||
var dynlinker = flag.Bool("dynlinker", false, "record dynamic linker information in dynimport mode")
|
||||
var dynout = flag.String("dynout", "", "write -dynimport output to this file")
|
||||
var dynpackage = flag.String("dynpackage", "main", "set Go package for -dynimport output")
|
||||
var dynlinker = flag.Bool("dynlinker", false, "record dynamic linker information in -dynimport mode")
|
||||
|
||||
// These flags are for bootstrapping a new Go implementation,
|
||||
// to generate Go and C headers that match the data layout and
|
||||
// This flag is for bootstrapping a new Go implementation,
|
||||
// to generate Go types that match the data layout and
|
||||
// constant values used in the host's C libraries and system calls.
|
||||
var godefs = flag.Bool("godefs", false, "for bootstrap: write Go definitions for C file to standard output")
|
||||
var cdefs = flag.Bool("cdefs", false, "for bootstrap: write C definitions for C file to standard output")
|
||||
|
||||
var objDir = flag.String("objdir", "", "object directory")
|
||||
var importPath = flag.String("importpath", "", "import path of package being built (for comments in generated files)")
|
||||
var exportHeader = flag.String("exportheader", "", "where to write export header if any exported functions")
|
||||
|
||||
var gccgo = flag.Bool("gccgo", false, "generate files for use with gccgo")
|
||||
var gccgoprefix = flag.String("gccgoprefix", "", "-fgo-prefix option used with gccgo")
|
||||
|
@ -208,12 +213,7 @@ func main() {
|
|||
return
|
||||
}
|
||||
|
||||
if *godefs && *cdefs {
|
||||
fmt.Fprintf(os.Stderr, "cgo: cannot use -cdefs and -godefs together\n")
|
||||
os.Exit(2)
|
||||
}
|
||||
|
||||
if *godefs || *cdefs {
|
||||
if *godefs {
|
||||
// Generating definitions pulled from header files,
|
||||
// to be checked into Go repositories.
|
||||
// Line numbers are just noise.
|
||||
|
@ -305,14 +305,12 @@ func main() {
|
|||
p.Record(f)
|
||||
if *godefs {
|
||||
os.Stdout.WriteString(p.godefs(f, input))
|
||||
} else if *cdefs {
|
||||
os.Stdout.WriteString(p.cdefs(f, input))
|
||||
} else {
|
||||
p.writeOutput(f, input)
|
||||
}
|
||||
}
|
||||
|
||||
if !*godefs && !*cdefs {
|
||||
if !*godefs {
|
||||
p.writeDefs()
|
||||
}
|
||||
if nerrors > 0 {
|
||||
|
|
|
@ -13,6 +13,7 @@ import (
|
|||
"go/ast"
|
||||
"go/printer"
|
||||
"go/token"
|
||||
"io"
|
||||
"os"
|
||||
"sort"
|
||||
"strings"
|
||||
|
@ -20,11 +21,17 @@ import (
|
|||
|
||||
var conf = printer.Config{Mode: printer.SourcePos, Tabwidth: 8}
|
||||
|
||||
// writeDefs creates output files to be compiled by 6g, 6c, and gcc.
|
||||
// (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.)
|
||||
// writeDefs creates output files to be compiled by gc and gcc.
|
||||
func (p *Package) writeDefs() {
|
||||
fgo2 := creat(*objDir + "_cgo_gotypes.go")
|
||||
fc := creat(*objDir + "_cgo_defun.c")
|
||||
var fgo2, fc io.Writer
|
||||
f := creat(*objDir + "_cgo_gotypes.go")
|
||||
defer f.Close()
|
||||
fgo2 = f
|
||||
if *gccgo {
|
||||
f := creat(*objDir + "_cgo_defun.c")
|
||||
defer f.Close()
|
||||
fc = f
|
||||
}
|
||||
fm := creat(*objDir + "_cgo_main.c")
|
||||
|
||||
var gccgoInit bytes.Buffer
|
||||
|
@ -34,7 +41,7 @@ func (p *Package) writeDefs() {
|
|||
fmt.Fprintf(fflg, "_CGO_%s=%s\n", k, strings.Join(v, " "))
|
||||
if k == "LDFLAGS" && !*gccgo {
|
||||
for _, arg := range v {
|
||||
fmt.Fprintf(fc, "#pragma cgo_ldflag %q\n", arg)
|
||||
fmt.Fprintf(fgo2, "//go:cgo_ldflag %q\n", arg)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -44,14 +51,17 @@ func (p *Package) writeDefs() {
|
|||
fmt.Fprintf(fm, "int main() { return 0; }\n")
|
||||
if *importRuntimeCgo {
|
||||
fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a, int c) { }\n")
|
||||
fmt.Fprintf(fm, "void _cgo_wait_runtime_init_done() { }\n")
|
||||
fmt.Fprintf(fm, "char* _cgo_topofstack(void) { return (char*)0; }\n")
|
||||
} else {
|
||||
// If we're not importing runtime/cgo, we *are* runtime/cgo,
|
||||
// which provides crosscall2. We just need a prototype.
|
||||
// which provides these functions. We just need a prototype.
|
||||
fmt.Fprintf(fm, "void crosscall2(void(*fn)(void*, int), void *a, int c);\n")
|
||||
fmt.Fprintf(fm, "void _cgo_wait_runtime_init_done();\n")
|
||||
}
|
||||
fmt.Fprintf(fm, "void _cgo_allocate(void *a, int c) { }\n")
|
||||
fmt.Fprintf(fm, "void _cgo_panic(void *a, int c) { }\n")
|
||||
fmt.Fprintf(fm, "void _cgo_reginit(void) { }\n")
|
||||
|
||||
// Write second Go output: definitions of _C_xxx.
|
||||
// In a separate file so that the import of "unsafe" does not
|
||||
|
@ -68,6 +78,13 @@ func (p *Package) writeDefs() {
|
|||
}
|
||||
fmt.Fprintf(fgo2, "func _Cgo_ptr(ptr unsafe.Pointer) unsafe.Pointer { return ptr }\n\n")
|
||||
|
||||
if !*gccgo {
|
||||
fmt.Fprintf(fgo2, "//go:linkname _Cgo_always_false runtime.cgoAlwaysFalse\n")
|
||||
fmt.Fprintf(fgo2, "var _Cgo_always_false bool\n")
|
||||
fmt.Fprintf(fgo2, "//go:linkname _Cgo_use runtime.cgoUse\n")
|
||||
fmt.Fprintf(fgo2, "func _Cgo_use(interface{})\n")
|
||||
}
|
||||
|
||||
typedefNames := make([]string, 0, len(typedef))
|
||||
for name := range typedef {
|
||||
typedefNames = append(typedefNames, name)
|
||||
|
@ -88,7 +105,6 @@ func (p *Package) writeDefs() {
|
|||
if *gccgo {
|
||||
fmt.Fprint(fc, p.cPrologGccgo())
|
||||
} else {
|
||||
fmt.Fprint(fc, cProlog)
|
||||
fmt.Fprint(fgo2, goProlog)
|
||||
}
|
||||
|
||||
|
@ -102,44 +118,44 @@ func (p *Package) writeDefs() {
|
|||
}
|
||||
|
||||
if !cVars[n.C] {
|
||||
fmt.Fprintf(fm, "extern char %s[];\n", n.C)
|
||||
fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C)
|
||||
|
||||
if !*gccgo {
|
||||
fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", n.C)
|
||||
if *gccgo {
|
||||
fmt.Fprintf(fc, "extern byte *%s;\n", n.C)
|
||||
} else {
|
||||
fmt.Fprintf(fm, "extern char %s[];\n", n.C)
|
||||
fmt.Fprintf(fm, "void *_cgohack_%s = %s;\n\n", n.C, n.C)
|
||||
fmt.Fprintf(fgo2, "//go:linkname __cgo_%s %s\n", n.C, n.C)
|
||||
fmt.Fprintf(fgo2, "//go:cgo_import_static %s\n", n.C)
|
||||
fmt.Fprintf(fgo2, "var __cgo_%s byte\n", n.C)
|
||||
}
|
||||
|
||||
fmt.Fprintf(fc, "extern byte *%s;\n", n.C)
|
||||
|
||||
cVars[n.C] = true
|
||||
}
|
||||
var amp string
|
||||
|
||||
var node ast.Node
|
||||
if n.Kind == "var" {
|
||||
amp = "&"
|
||||
node = &ast.StarExpr{X: n.Type.Go}
|
||||
} else if n.Kind == "fpvar" {
|
||||
node = n.Type.Go
|
||||
if *gccgo {
|
||||
amp = "&"
|
||||
}
|
||||
} else {
|
||||
panic(fmt.Errorf("invalid var kind %q", n.Kind))
|
||||
}
|
||||
if *gccgo {
|
||||
fmt.Fprintf(fc, `extern void *%s __asm__("%s.%s");`, n.Mangle, gccgoSymbolPrefix, n.Mangle)
|
||||
fmt.Fprintf(&gccgoInit, "\t%s = %s%s;\n", n.Mangle, amp, n.C)
|
||||
} else {
|
||||
fmt.Fprintf(fc, "#pragma dataflag NOPTR /* C pointer, not heap pointer */ \n")
|
||||
fmt.Fprintf(fc, "void *·%s = %s%s;\n", n.Mangle, amp, n.C)
|
||||
fmt.Fprintf(&gccgoInit, "\t%s = &%s;\n", n.Mangle, n.C)
|
||||
fmt.Fprintf(fc, "\n")
|
||||
}
|
||||
fmt.Fprintf(fc, "\n")
|
||||
|
||||
fmt.Fprintf(fgo2, "var %s ", n.Mangle)
|
||||
conf.Fprint(fgo2, fset, node)
|
||||
if !*gccgo {
|
||||
fmt.Fprintf(fgo2, " = (")
|
||||
conf.Fprint(fgo2, fset, node)
|
||||
fmt.Fprintf(fgo2, ")(unsafe.Pointer(&__cgo_%s))", n.C)
|
||||
}
|
||||
fmt.Fprintf(fgo2, "\n")
|
||||
}
|
||||
fmt.Fprintf(fc, "\n")
|
||||
if *gccgo {
|
||||
fmt.Fprintf(fc, "\n")
|
||||
}
|
||||
|
||||
for _, key := range nameKeys(p.Name) {
|
||||
n := p.Name[key]
|
||||
|
@ -152,14 +168,37 @@ func (p *Package) writeDefs() {
|
|||
for _, key := range nameKeys(p.Name) {
|
||||
n := p.Name[key]
|
||||
if n.FuncType != nil {
|
||||
p.writeDefsFunc(fc, fgo2, n)
|
||||
p.writeDefsFunc(fgo2, n)
|
||||
}
|
||||
}
|
||||
|
||||
fgcc := creat(*objDir + "_cgo_export.c")
|
||||
fgcch := creat(*objDir + "_cgo_export.h")
|
||||
if *gccgo {
|
||||
p.writeGccgoExports(fgo2, fc, fm)
|
||||
p.writeGccgoExports(fgo2, fm, fgcc, fgcch)
|
||||
} else {
|
||||
p.writeExports(fgo2, fc, fm)
|
||||
p.writeExports(fgo2, fm, fgcc, fgcch)
|
||||
}
|
||||
if err := fgcc.Close(); err != nil {
|
||||
fatalf("%s", err)
|
||||
}
|
||||
if err := fgcch.Close(); err != nil {
|
||||
fatalf("%s", err)
|
||||
}
|
||||
|
||||
if *exportHeader != "" && len(p.ExpFunc) > 0 {
|
||||
fexp := creat(*exportHeader)
|
||||
fgcch, err := os.Open(*objDir + "_cgo_export.h")
|
||||
if err != nil {
|
||||
fatalf("%s", err)
|
||||
}
|
||||
_, err = io.Copy(fexp, fgcch)
|
||||
if err != nil {
|
||||
fatalf("%s", err)
|
||||
}
|
||||
if err = fexp.Close(); err != nil {
|
||||
fatalf("%s", err)
|
||||
}
|
||||
}
|
||||
|
||||
init := gccgoInit.String()
|
||||
|
@ -169,9 +208,6 @@ func (p *Package) writeDefs() {
|
|||
fmt.Fprint(fc, init)
|
||||
fmt.Fprintln(fc, "}")
|
||||
}
|
||||
|
||||
fgo2.Close()
|
||||
fc.Close()
|
||||
}
|
||||
|
||||
func dynimport(obj string) {
|
||||
|
@ -184,13 +220,15 @@ func dynimport(obj string) {
|
|||
stdout = f
|
||||
}
|
||||
|
||||
fmt.Fprintf(stdout, "package %s\n", *dynpackage)
|
||||
|
||||
if f, err := elf.Open(obj); err == nil {
|
||||
if *dynlinker {
|
||||
// Emit the cgo_dynamic_linker line.
|
||||
if sec := f.Section(".interp"); sec != nil {
|
||||
if data, err := sec.Data(); err == nil && len(data) > 1 {
|
||||
// skip trailing \0 in data
|
||||
fmt.Fprintf(stdout, "#pragma cgo_dynamic_linker %q\n", string(data[:len(data)-1]))
|
||||
fmt.Fprintf(stdout, "//go:cgo_dynamic_linker %q\n", string(data[:len(data)-1]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -203,14 +241,14 @@ func dynimport(obj string) {
|
|||
if s.Version != "" {
|
||||
targ += "#" + s.Version
|
||||
}
|
||||
fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library)
|
||||
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s.Name, targ, s.Library)
|
||||
}
|
||||
lib, err := f.ImportedLibraries()
|
||||
if err != nil {
|
||||
fatalf("cannot load imported libraries from ELF file %s: %v", obj, err)
|
||||
}
|
||||
for _, l := range lib {
|
||||
fmt.Fprintf(stdout, "#pragma cgo_import_dynamic _ _ %q\n", l)
|
||||
fmt.Fprintf(stdout, "//go:cgo_import_dynamic _ _ %q\n", l)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -224,14 +262,14 @@ func dynimport(obj string) {
|
|||
if len(s) > 0 && s[0] == '_' {
|
||||
s = s[1:]
|
||||
}
|
||||
fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", s, s, "")
|
||||
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", s, s, "")
|
||||
}
|
||||
lib, err := f.ImportedLibraries()
|
||||
if err != nil {
|
||||
fatalf("cannot load imported libraries from Mach-O file %s: %v", obj, err)
|
||||
}
|
||||
for _, l := range lib {
|
||||
fmt.Fprintf(stdout, "#pragma cgo_import_dynamic _ _ %q\n", l)
|
||||
fmt.Fprintf(stdout, "//go:cgo_import_dynamic _ _ %q\n", l)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -244,7 +282,7 @@ func dynimport(obj string) {
|
|||
for _, s := range sym {
|
||||
ss := strings.Split(s, ":")
|
||||
name := strings.Split(ss[0], "@")[0]
|
||||
fmt.Fprintf(stdout, "#pragma cgo_import_dynamic %s %s %q\n", name, ss[0], strings.ToLower(ss[1]))
|
||||
fmt.Fprintf(stdout, "//go:cgo_import_dynamic %s %s %q\n", name, ss[0], strings.ToLower(ss[1]))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -252,10 +290,10 @@ func dynimport(obj string) {
|
|||
fatalf("cannot parse %s as ELF, Mach-O or PE", obj)
|
||||
}
|
||||
|
||||
// Construct a gcc struct matching the 6c argument frame.
|
||||
// Construct a gcc struct matching the gc argument frame.
|
||||
// Assumes that in gcc, char is 1 byte, short 2 bytes, int 4 bytes, long long 8 bytes.
|
||||
// These assumptions are checked by the gccProlog.
|
||||
// Also assumes that 6c convention is to word-align the
|
||||
// Also assumes that gc convention is to word-align the
|
||||
// input and output parameters.
|
||||
func (p *Package) structType(n *Name) (string, int64) {
|
||||
var buf bytes.Buffer
|
||||
|
@ -304,7 +342,7 @@ func (p *Package) structType(n *Name) (string, int64) {
|
|||
return buf.String(), off
|
||||
}
|
||||
|
||||
func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
||||
func (p *Package) writeDefsFunc(fgo2 io.Writer, n *Name) {
|
||||
name := n.Go
|
||||
gtype := n.FuncType.Go
|
||||
void := gtype.Results == nil || len(gtype.Results.List) == 0
|
||||
|
@ -396,11 +434,11 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
|||
return
|
||||
}
|
||||
|
||||
// C wrapper calls into gcc, passing a pointer to the argument frame.
|
||||
fmt.Fprintf(fc, "#pragma cgo_import_static %s\n", cname)
|
||||
fmt.Fprintf(fc, "void %s(void*);\n", cname)
|
||||
fmt.Fprintf(fc, "#pragma dataflag NOPTR\n")
|
||||
fmt.Fprintf(fc, "void *·%s = %s;\n", cname, cname)
|
||||
// Wrapper calls into gcc, passing a pointer to the argument frame.
|
||||
fmt.Fprintf(fgo2, "//go:cgo_import_static %s\n", cname)
|
||||
fmt.Fprintf(fgo2, "//go:linkname __cgofn_%s %s\n", cname, cname)
|
||||
fmt.Fprintf(fgo2, "var __cgofn_%s byte\n", cname)
|
||||
fmt.Fprintf(fgo2, "var %s = unsafe.Pointer(&__cgofn_%s)\n", cname, cname)
|
||||
|
||||
nret := 0
|
||||
if !void {
|
||||
|
@ -412,7 +450,6 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
|||
}
|
||||
|
||||
fmt.Fprint(fgo2, "\n")
|
||||
fmt.Fprintf(fgo2, "var %s unsafe.Pointer\n", cname)
|
||||
conf.Fprint(fgo2, fset, d)
|
||||
fmt.Fprint(fgo2, " {\n")
|
||||
|
||||
|
@ -428,16 +465,20 @@ func (p *Package) writeDefsFunc(fc, fgo2 *os.File, n *Name) {
|
|||
if n.AddError {
|
||||
prefix = "errno := "
|
||||
}
|
||||
fmt.Fprintf(fgo2, "\t%s_cgo_runtime_cgocall_errno(%s, %s)\n", prefix, cname, arg)
|
||||
fmt.Fprintf(fgo2, "\t%s_cgo_runtime_cgocall(%s, %s)\n", prefix, cname, arg)
|
||||
if n.AddError {
|
||||
fmt.Fprintf(fgo2, "\tif errno != 0 { r2 = syscall.Errno(errno) }\n")
|
||||
}
|
||||
fmt.Fprintf(fgo2, "\tif _Cgo_always_false {\n")
|
||||
for i := range d.Type.Params.List {
|
||||
fmt.Fprintf(fgo2, "\t\t_Cgo_use(p%d)\n", i)
|
||||
}
|
||||
fmt.Fprintf(fgo2, "\t}\n")
|
||||
fmt.Fprintf(fgo2, "\treturn\n")
|
||||
fmt.Fprintf(fgo2, "}\n")
|
||||
}
|
||||
|
||||
// writeOutput creates stubs for a specific source file to be compiled by 6g
|
||||
// (The comments here say 6g and 6c but the code applies to the 8 and 5 tools too.)
|
||||
// writeOutput creates stubs for a specific source file to be compiled by gc
|
||||
func (p *Package) writeOutput(f *File, srcfile string) {
|
||||
base := srcfile
|
||||
if strings.HasSuffix(base, ".go") {
|
||||
|
@ -454,7 +495,7 @@ func (p *Package) writeOutput(f *File, srcfile string) {
|
|||
fmt.Fprintf(fgo1, "// Created by cgo - DO NOT EDIT\n\n")
|
||||
conf.Fprint(fgo1, fset, f.AST)
|
||||
|
||||
// While we process the vars and funcs, also write 6c and gcc output.
|
||||
// While we process the vars and funcs, also write gcc output.
|
||||
// Gcc output starts with the preamble.
|
||||
fmt.Fprintf(fgcc, "%s\n", f.Preamble)
|
||||
fmt.Fprintf(fgcc, "%s\n", gccProlog)
|
||||
|
@ -516,7 +557,7 @@ func (p *Package) writeOutputFunc(fgcc *os.File, n *Name) {
|
|||
if n.AddError {
|
||||
fmt.Fprintf(fgcc, "\terrno = 0;\n")
|
||||
}
|
||||
// We're trying to write a gcc struct that matches 6c/8c/5c's layout.
|
||||
// We're trying to write a gcc struct that matches gc's layout.
|
||||
// Use packed attribute to force no padding in this struct in case
|
||||
// gcc has different packing requirements.
|
||||
fmt.Fprintf(fgcc, "\t%s %v *a = v;\n", ctype, p.packedAttribute())
|
||||
|
@ -612,13 +653,13 @@ func (p *Package) writeGccgoOutputFunc(fgcc *os.File, n *Name) {
|
|||
}
|
||||
|
||||
// packedAttribute returns host compiler struct attribute that will be
|
||||
// used to match 6c/8c/5c's struct layout. For example, on 386 Windows,
|
||||
// gcc wants to 8-align int64s, but 8c does not.
|
||||
// used to match gc's struct layout. For example, on 386 Windows,
|
||||
// gcc wants to 8-align int64s, but gc does not.
|
||||
// Use __gcc_struct__ to work around http://gcc.gnu.org/PR52991 on x86,
|
||||
// and http://golang.org/issue/5603.
|
||||
// and https://golang.org/issue/5603.
|
||||
func (p *Package) packedAttribute() string {
|
||||
s := "__attribute__((__packed__"
|
||||
if !strings.Contains(p.gccBaseCmd()[0], "clang") && (goarch == "amd64" || goarch == "386") {
|
||||
if !p.GccIsClang && (goarch == "amd64" || goarch == "386") {
|
||||
s += ", __gcc_struct__"
|
||||
}
|
||||
return s + "))"
|
||||
|
@ -626,23 +667,19 @@ func (p *Package) packedAttribute() string {
|
|||
|
||||
// Write out the various stubs we need to support functions exported
|
||||
// from Go so that they are callable from C.
|
||||
func (p *Package) writeExports(fgo2, fc, fm *os.File) {
|
||||
fgcc := creat(*objDir + "_cgo_export.c")
|
||||
fgcch := creat(*objDir + "_cgo_export.h")
|
||||
|
||||
fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n")
|
||||
fmt.Fprintf(fgcch, "%s\n", p.Preamble)
|
||||
fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
|
||||
func (p *Package) writeExports(fgo2, fm, fgcc, fgcch io.Writer) {
|
||||
p.writeExportHeader(fgcch)
|
||||
|
||||
fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n")
|
||||
fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n")
|
||||
fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n\n")
|
||||
|
||||
fmt.Fprintf(fgcc, "\nextern void crosscall2(void (*fn)(void *, int), void *, int);\n\n")
|
||||
fmt.Fprintf(fgcc, "extern void crosscall2(void (*fn)(void *, int), void *, int);\n")
|
||||
fmt.Fprintf(fgcc, "extern void _cgo_wait_runtime_init_done();\n\n")
|
||||
|
||||
for _, exp := range p.ExpFunc {
|
||||
fn := exp.Func
|
||||
|
||||
// Construct a gcc struct matching the 6c argument and
|
||||
// Construct a gcc struct matching the gc argument and
|
||||
// result frame. The gcc struct will be compiled with
|
||||
// __attribute__((packed)) so all padding must be accounted
|
||||
// for explicitly.
|
||||
|
@ -728,11 +765,16 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
|
|||
s += fmt.Sprintf("%s p%d", p.cgoType(atype).C, i)
|
||||
})
|
||||
s += ")"
|
||||
|
||||
if len(exp.Doc) > 0 {
|
||||
fmt.Fprintf(fgcch, "\n%s", exp.Doc)
|
||||
}
|
||||
fmt.Fprintf(fgcch, "\nextern %s;\n", s)
|
||||
|
||||
fmt.Fprintf(fgcc, "extern void _cgoexp%s_%s(void *, int);\n", cPrefix, exp.ExpName)
|
||||
fmt.Fprintf(fgcc, "\n%s\n", s)
|
||||
fmt.Fprintf(fgcc, "{\n")
|
||||
fmt.Fprintf(fgcc, "\t_cgo_wait_runtime_init_done();\n")
|
||||
fmt.Fprintf(fgcc, "\t%s %v a;\n", ctype, p.packedAttribute())
|
||||
if gccResult != "void" && (len(fntype.Results.List) > 1 || len(fntype.Results.List[0].Names) > 1) {
|
||||
fmt.Fprintf(fgcc, "\t%s r;\n", gccResult)
|
||||
|
@ -758,20 +800,21 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
|
|||
}
|
||||
fmt.Fprintf(fgcc, "}\n")
|
||||
|
||||
// Build the wrapper function compiled by 6c/8c
|
||||
// Build the wrapper function compiled by gc.
|
||||
goname := exp.Func.Name.Name
|
||||
if fn.Recv != nil {
|
||||
goname = "_cgoexpwrap" + cPrefix + "_" + fn.Recv.List[0].Names[0].Name + "_" + goname
|
||||
}
|
||||
fmt.Fprintf(fc, "#pragma cgo_export_dynamic %s\n", goname)
|
||||
fmt.Fprintf(fc, "extern void ·%s();\n\n", goname)
|
||||
fmt.Fprintf(fc, "#pragma cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
|
||||
fmt.Fprintf(fc, "#pragma textflag 7\n") // no split stack, so no use of m or g
|
||||
fmt.Fprintf(fc, "void\n")
|
||||
fmt.Fprintf(fc, "_cgoexp%s_%s(void *a, int32 n)\n", cPrefix, exp.ExpName)
|
||||
fmt.Fprintf(fc, "{\n")
|
||||
fmt.Fprintf(fc, "\truntime·cgocallback(·%s, a, n);\n", goname)
|
||||
fmt.Fprintf(fc, "}\n")
|
||||
fmt.Fprintf(fgo2, "//go:cgo_export_dynamic %s\n", goname)
|
||||
fmt.Fprintf(fgo2, "//go:linkname _cgoexp%s_%s _cgoexp%s_%s\n", cPrefix, exp.ExpName, cPrefix, exp.ExpName)
|
||||
fmt.Fprintf(fgo2, "//go:cgo_export_static _cgoexp%s_%s\n", cPrefix, exp.ExpName)
|
||||
fmt.Fprintf(fgo2, "//go:nosplit\n") // no split stack, so no use of m or g
|
||||
fmt.Fprintf(fgo2, "//go:norace\n") // must not have race detector calls inserted
|
||||
fmt.Fprintf(fgo2, "func _cgoexp%s_%s(a unsafe.Pointer, n int32) {", cPrefix, exp.ExpName)
|
||||
fmt.Fprintf(fgo2, "\tfn := %s\n", goname)
|
||||
// The indirect here is converting from a Go function pointer to a C function pointer.
|
||||
fmt.Fprintf(fgo2, "\t_cgo_runtime_cgocallback(**(**unsafe.Pointer)(unsafe.Pointer(&fn)), a, uintptr(n));\n")
|
||||
fmt.Fprintf(fgo2, "}\n")
|
||||
|
||||
fmt.Fprintf(fm, "int _cgoexp%s_%s;\n", cPrefix, exp.ExpName)
|
||||
|
||||
|
@ -814,23 +857,20 @@ func (p *Package) writeExports(fgo2, fc, fm *os.File) {
|
|||
fmt.Fprint(fgo2, "}\n")
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Fprintf(fgcch, "%s", gccExportHeaderEpilog)
|
||||
}
|
||||
|
||||
// Write out the C header allowing C code to call exported gccgo functions.
|
||||
func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
|
||||
fgcc := creat(*objDir + "_cgo_export.c")
|
||||
fgcch := creat(*objDir + "_cgo_export.h")
|
||||
|
||||
func (p *Package) writeGccgoExports(fgo2, fm, fgcc, fgcch io.Writer) {
|
||||
gccgoSymbolPrefix := p.gccgoSymbolPrefix()
|
||||
|
||||
fmt.Fprintf(fgcch, "/* Created by cgo - DO NOT EDIT. */\n")
|
||||
fmt.Fprintf(fgcch, "%s\n", p.Preamble)
|
||||
fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
|
||||
p.writeExportHeader(fgcch)
|
||||
|
||||
fmt.Fprintf(fgcc, "/* Created by cgo - DO NOT EDIT. */\n")
|
||||
fmt.Fprintf(fgcc, "#include \"_cgo_export.h\"\n")
|
||||
|
||||
fmt.Fprintf(fm, "#include \"_cgo_export.h\"\n")
|
||||
fmt.Fprintf(fgcc, "%s\n", gccgoExportFileProlog)
|
||||
|
||||
for _, exp := range p.ExpFunc {
|
||||
fn := exp.Func
|
||||
|
@ -851,6 +891,7 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
|
|||
})
|
||||
default:
|
||||
// Declare a result struct.
|
||||
fmt.Fprintf(fgcch, "\n/* Return type for %s */\n", exp.ExpName)
|
||||
fmt.Fprintf(fgcch, "struct %s_result {\n", exp.ExpName)
|
||||
forFieldList(fntype.Results,
|
||||
func(i int, atype ast.Expr) {
|
||||
|
@ -880,6 +921,10 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
|
|||
fmt.Fprintf(cdeclBuf, ")")
|
||||
cParams := cdeclBuf.String()
|
||||
|
||||
if len(exp.Doc) > 0 {
|
||||
fmt.Fprintf(fgcch, "\n%s", exp.Doc)
|
||||
}
|
||||
|
||||
// We need to use a name that will be exported by the
|
||||
// Go code; otherwise gccgo will make it static and we
|
||||
// will not be able to link against it from the C
|
||||
|
@ -900,6 +945,8 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
|
|||
|
||||
fmt.Fprint(fgcc, "\n")
|
||||
fmt.Fprintf(fgcc, "%s %s %s {\n", cRet, exp.ExpName, cParams)
|
||||
fmt.Fprintf(fgcc, "\tif(_cgo_wait_runtime_init_done)\n")
|
||||
fmt.Fprintf(fgcc, "\t\t_cgo_wait_runtime_init_done();\n")
|
||||
fmt.Fprint(fgcc, "\t")
|
||||
if resultCount > 0 {
|
||||
fmt.Fprint(fgcc, "return ")
|
||||
|
@ -919,7 +966,8 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
|
|||
fmt.Fprint(fgcc, "}\n")
|
||||
|
||||
// Dummy declaration for _cgo_main.c
|
||||
fmt.Fprintf(fm, "%s %s %s {}\n", cRet, goName, cParams)
|
||||
fmt.Fprintf(fm, `char %s[1] __asm__("%s.%s");`, goName, gccgoSymbolPrefix, goName)
|
||||
fmt.Fprint(fm, "\n")
|
||||
|
||||
// For gccgo we use a wrapper function in Go, in order
|
||||
// to call CgocallBack and CgocallBackDone.
|
||||
|
@ -974,6 +1022,24 @@ func (p *Package) writeGccgoExports(fgo2, fc, fm *os.File) {
|
|||
fmt.Fprint(fgo2, ")\n")
|
||||
fmt.Fprint(fgo2, "}\n")
|
||||
}
|
||||
|
||||
fmt.Fprintf(fgcch, "%s", gccExportHeaderEpilog)
|
||||
}
|
||||
|
||||
// writeExportHeader writes out the start of the _cgo_export.h file.
|
||||
func (p *Package) writeExportHeader(fgcch io.Writer) {
|
||||
fmt.Fprintf(fgcch, "/* Created by \"go tool cgo\" - DO NOT EDIT. */\n\n")
|
||||
pkg := *importPath
|
||||
if pkg == "" {
|
||||
pkg = p.PackagePath
|
||||
}
|
||||
fmt.Fprintf(fgcch, "/* package %s */\n\n", pkg)
|
||||
|
||||
fmt.Fprintf(fgcch, "/* Start of preamble from import \"C\" comments. */\n\n")
|
||||
fmt.Fprintf(fgcch, "%s\n", p.Preamble)
|
||||
fmt.Fprintf(fgcch, "\n/* End of preamble from import \"C\" comments. */\n\n")
|
||||
|
||||
fmt.Fprintf(fgcch, "%s\n", p.gccExportHeaderProlog())
|
||||
}
|
||||
|
||||
// Return the package prefix when using gccgo.
|
||||
|
@ -1164,60 +1230,39 @@ char *CString(_GoString_);
|
|||
void *_CMalloc(size_t);
|
||||
`
|
||||
|
||||
const cProlog = `
|
||||
#include "runtime.h"
|
||||
#include "cgocall.h"
|
||||
#include "textflag.h"
|
||||
|
||||
#pragma dataflag NOPTR
|
||||
static void *cgocall_errno = runtime·cgocall_errno;
|
||||
#pragma dataflag NOPTR
|
||||
void *·_cgo_runtime_cgocall_errno = &cgocall_errno;
|
||||
|
||||
#pragma dataflag NOPTR
|
||||
static void *runtime_gostring = runtime·gostring;
|
||||
#pragma dataflag NOPTR
|
||||
void *·_cgo_runtime_gostring = &runtime_gostring;
|
||||
|
||||
#pragma dataflag NOPTR
|
||||
static void *runtime_gostringn = runtime·gostringn;
|
||||
#pragma dataflag NOPTR
|
||||
void *·_cgo_runtime_gostringn = &runtime_gostringn;
|
||||
|
||||
#pragma dataflag NOPTR
|
||||
static void *runtime_gobytes = runtime·gobytes;
|
||||
#pragma dataflag NOPTR
|
||||
void *·_cgo_runtime_gobytes = &runtime_gobytes;
|
||||
|
||||
#pragma dataflag NOPTR
|
||||
static void *runtime_cmalloc = runtime·cmalloc;
|
||||
#pragma dataflag NOPTR
|
||||
void *·_cgo_runtime_cmalloc = &runtime_cmalloc;
|
||||
|
||||
void ·_Cerrno(void*, int32);
|
||||
`
|
||||
|
||||
const goProlog = `
|
||||
var _cgo_runtime_cgocall_errno func(unsafe.Pointer, uintptr) int32
|
||||
var _cgo_runtime_cmalloc func(uintptr) unsafe.Pointer
|
||||
//go:linkname _cgo_runtime_cgocall runtime.cgocall
|
||||
func _cgo_runtime_cgocall(unsafe.Pointer, uintptr) int32
|
||||
|
||||
//go:linkname _cgo_runtime_cmalloc runtime.cmalloc
|
||||
func _cgo_runtime_cmalloc(uintptr) unsafe.Pointer
|
||||
|
||||
//go:linkname _cgo_runtime_cgocallback runtime.cgocallback
|
||||
func _cgo_runtime_cgocallback(unsafe.Pointer, unsafe.Pointer, uintptr)
|
||||
`
|
||||
|
||||
const goStringDef = `
|
||||
var _cgo_runtime_gostring func(*_Ctype_char) string
|
||||
//go:linkname _cgo_runtime_gostring runtime.gostring
|
||||
func _cgo_runtime_gostring(*_Ctype_char) string
|
||||
|
||||
func _Cfunc_GoString(p *_Ctype_char) string {
|
||||
return _cgo_runtime_gostring(p)
|
||||
}
|
||||
`
|
||||
|
||||
const goStringNDef = `
|
||||
var _cgo_runtime_gostringn func(*_Ctype_char, int) string
|
||||
//go:linkname _cgo_runtime_gostringn runtime.gostringn
|
||||
func _cgo_runtime_gostringn(*_Ctype_char, int) string
|
||||
|
||||
func _Cfunc_GoStringN(p *_Ctype_char, l _Ctype_int) string {
|
||||
return _cgo_runtime_gostringn(p, int(l))
|
||||
}
|
||||
`
|
||||
|
||||
const goBytesDef = `
|
||||
var _cgo_runtime_gobytes func(unsafe.Pointer, int) []byte
|
||||
//go:linkname _cgo_runtime_gobytes runtime.gobytes
|
||||
func _cgo_runtime_gobytes(unsafe.Pointer, int) []byte
|
||||
|
||||
func _Cfunc_GoBytes(p unsafe.Pointer, l _Ctype_int) []byte {
|
||||
return _cgo_runtime_gobytes(p, int(l))
|
||||
}
|
||||
|
@ -1310,6 +1355,11 @@ func (p *Package) gccExportHeaderProlog() string {
|
|||
}
|
||||
|
||||
const gccExportHeaderProlog = `
|
||||
/* Start of boilerplate cgo prologue. */
|
||||
|
||||
#ifndef GO_CGO_PROLOGUE_H
|
||||
#define GO_CGO_PROLOGUE_H
|
||||
|
||||
typedef signed char GoInt8;
|
||||
typedef unsigned char GoUint8;
|
||||
typedef short GoInt16;
|
||||
|
@ -1326,9 +1376,44 @@ typedef double GoFloat64;
|
|||
typedef __complex float GoComplex64;
|
||||
typedef __complex double GoComplex128;
|
||||
|
||||
// static assertion to make sure the file is being used on architecture
|
||||
// at least with matching size of GoInt.
|
||||
typedef char _check_for_GOINTBITS_bit_pointer_matching_GoInt[sizeof(void*)==GOINTBITS/8 ? 1:-1];
|
||||
|
||||
typedef struct { char *p; GoInt n; } GoString;
|
||||
typedef void *GoMap;
|
||||
typedef void *GoChan;
|
||||
typedef struct { void *t; void *v; } GoInterface;
|
||||
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
|
||||
|
||||
#endif
|
||||
|
||||
/* End of boilerplate cgo prologue. */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
`
|
||||
|
||||
// gccExportHeaderEpilog goes at the end of the generated header file.
|
||||
const gccExportHeaderEpilog = `
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
`
|
||||
|
||||
// gccgoExportFileProlog is written to the _cgo_export.c file when
|
||||
// using gccgo.
|
||||
// We use weak declarations, and test the addresses, so that this code
|
||||
// works with older versions of gccgo.
|
||||
const gccgoExportFileProlog = `
|
||||
extern _Bool runtime_iscgo __attribute__ ((weak));
|
||||
|
||||
static void GoInit(void) __attribute__ ((constructor));
|
||||
static void GoInit(void) {
|
||||
if(&runtime_iscgo)
|
||||
runtime_iscgo = 1;
|
||||
}
|
||||
|
||||
extern void _cgo_wait_runtime_init_done() __attribute__ ((weak));
|
||||
`
|
||||
|
|
|
@ -55,7 +55,7 @@ func error_(pos token.Pos, msg string, args ...interface{}) {
|
|||
fmt.Fprintf(os.Stderr, "\n")
|
||||
}
|
||||
|
||||
// isName returns true if s is a valid C identifier
|
||||
// isName reports whether s is a valid C identifier
|
||||
func isName(s string) bool {
|
||||
for i, v := range s {
|
||||
if v != '_' && (v < 'A' || v > 'Z') && (v < 'a' || v > 'z') && (v < '0' || v > '9') {
|
||||
|
|
1482
libgo/go/cmd/go/alldocs.go
Normal file
1482
libgo/go/cmd/go/alldocs.go
Normal file
File diff suppressed because it is too large
Load diff
|
@ -17,11 +17,19 @@ import (
|
|||
|
||||
var errHTTP = errors.New("no http in bootstrap go command")
|
||||
|
||||
type httpError struct {
|
||||
statusCode int
|
||||
}
|
||||
|
||||
func (e *httpError) Error() string {
|
||||
panic("unreachable")
|
||||
}
|
||||
|
||||
func httpGET(url string) ([]byte, error) {
|
||||
return nil, errHTTP
|
||||
}
|
||||
|
||||
func httpsOrHTTP(importPath string) (string, io.ReadCloser, error) {
|
||||
func httpsOrHTTP(importPath string, security securityMode) (string, io.ReadCloser, error) {
|
||||
return "", nil, errHTTP
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -36,7 +36,6 @@ func mkEnv() []envVar {
|
|||
env := []envVar{
|
||||
{"GOARCH", goarch},
|
||||
{"GOBIN", gobin},
|
||||
{"GOCHAR", archChar},
|
||||
{"GOEXE", exeSuffix},
|
||||
{"GOHOSTARCH", runtime.GOARCH},
|
||||
{"GOHOSTOS", runtime.GOOS},
|
||||
|
@ -45,6 +44,7 @@ func mkEnv() []envVar {
|
|||
{"GORACE", os.Getenv("GORACE")},
|
||||
{"GOROOT", goroot},
|
||||
{"GOTOOLDIR", toolDir},
|
||||
{"GO15VENDOREXPERIMENT", os.Getenv("GO15VENDOREXPERIMENT")},
|
||||
|
||||
// disable escape codes in clang errors
|
||||
{"TERM", "dumb"},
|
||||
|
|
|
@ -11,7 +11,7 @@ var cmdFix = &Command{
|
|||
Long: `
|
||||
Fix runs the Go fix command on the packages named by the import paths.
|
||||
|
||||
For more about fix, see 'godoc fix'.
|
||||
For more about fix, see 'go doc cmd/fix'.
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
To run fix with specific options, run 'go tool fix'.
|
||||
|
@ -25,6 +25,6 @@ func runFix(cmd *Command, args []string) {
|
|||
// Use pkg.gofiles instead of pkg.Dir so that
|
||||
// the command only applies to this package,
|
||||
// not to packages in subdirectories.
|
||||
run(stringList(tool("fix"), relPaths(pkg.allgofiles)))
|
||||
run(stringList(buildToolExec, tool("fix"), relPaths(pkg.allgofiles)))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@
|
|||
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func init() {
|
||||
addBuildFlagsNX(cmdFmt)
|
||||
}
|
||||
|
@ -16,7 +21,7 @@ var cmdFmt = &Command{
|
|||
Fmt runs the command 'gofmt -l -w' on the packages named
|
||||
by the import paths. It prints the names of the files that are modified.
|
||||
|
||||
For more about gofmt, see 'godoc gofmt'.
|
||||
For more about gofmt, see 'go doc cmd/gofmt'.
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
The -n flag prints commands that would be executed.
|
||||
|
@ -29,10 +34,31 @@ See also: go fix, go vet.
|
|||
}
|
||||
|
||||
func runFmt(cmd *Command, args []string) {
|
||||
gofmt := gofmtPath()
|
||||
for _, pkg := range packages(args) {
|
||||
// Use pkg.gofiles instead of pkg.Dir so that
|
||||
// the command only applies to this package,
|
||||
// not to packages in subdirectories.
|
||||
run(stringList("gofmt", "-l", "-w", relPaths(pkg.allgofiles)))
|
||||
run(stringList(gofmt, "-l", "-w", relPaths(pkg.allgofiles)))
|
||||
}
|
||||
}
|
||||
|
||||
func gofmtPath() string {
|
||||
gofmt := "gofmt"
|
||||
if toolIsWindows {
|
||||
gofmt += toolWindowsExtension
|
||||
}
|
||||
|
||||
gofmtPath := filepath.Join(gobin, gofmt)
|
||||
if _, err := os.Stat(gofmtPath); err == nil {
|
||||
return gofmtPath
|
||||
}
|
||||
|
||||
gofmtPath = filepath.Join(goroot, "bin", gofmt)
|
||||
if _, err := os.Stat(gofmtPath); err == nil {
|
||||
return gofmtPath
|
||||
}
|
||||
|
||||
// fallback to looking for gofmt in $PATH
|
||||
return "gofmt"
|
||||
}
|
||||
|
|
|
@ -13,11 +13,11 @@ import (
|
|||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unicode"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
var cmdGenerate = &Command{
|
||||
|
@ -62,8 +62,12 @@ Go generate sets several variables when it runs the generator:
|
|||
The execution operating system (linux, windows, etc.)
|
||||
$GOFILE
|
||||
The base name of the file.
|
||||
$GOLINE
|
||||
The line number of the directive in the source file.
|
||||
$GOPACKAGE
|
||||
The name of the package of the file containing the directive.
|
||||
$DOLLAR
|
||||
A dollar sign.
|
||||
|
||||
Other than variable substitution and quoted-string evaluation, no
|
||||
special processing such as "globbing" is performed on the command
|
||||
|
@ -106,9 +110,10 @@ The generator is run in the package's source directory.
|
|||
Go generate accepts one specific flag:
|
||||
|
||||
-run=""
|
||||
TODO: This flag is unimplemented.
|
||||
if non-empty, specifies a regular expression to
|
||||
select directives whose command matches the expression.
|
||||
if non-empty, specifies a regular expression to select
|
||||
directives whose full original source text (excluding
|
||||
any trailing spaces and final newline) matches the
|
||||
expression.
|
||||
|
||||
It also accepts the standard build flags -v, -n, and -x.
|
||||
The -v flag prints the names of packages and files as they are
|
||||
|
@ -120,7 +125,10 @@ For more about specifying packages, see 'go help packages'.
|
|||
`,
|
||||
}
|
||||
|
||||
var generateRunFlag string // generate -run flag
|
||||
var (
|
||||
generateRunFlag string // generate -run flag
|
||||
generateRunRE *regexp.Regexp // compiled expression for -run
|
||||
)
|
||||
|
||||
func init() {
|
||||
addBuildFlags(cmdGenerate)
|
||||
|
@ -128,6 +136,13 @@ func init() {
|
|||
}
|
||||
|
||||
func runGenerate(cmd *Command, args []string) {
|
||||
if generateRunFlag != "" {
|
||||
var err error
|
||||
generateRunRE, err = regexp.Compile(generateRunFlag)
|
||||
if err != nil {
|
||||
log.Fatalf("generate: %s", err)
|
||||
}
|
||||
}
|
||||
// Even if the arguments are .go files, this loop suffices.
|
||||
for _, pkg := range packages(args) {
|
||||
for _, file := range pkg.gofiles {
|
||||
|
@ -163,7 +178,7 @@ type Generator struct {
|
|||
file string // base name of file.
|
||||
pkg string
|
||||
commands map[string][]string
|
||||
lineNum int
|
||||
lineNum int // current line number.
|
||||
}
|
||||
|
||||
// run runs the generators in the current file.
|
||||
|
@ -221,6 +236,11 @@ func (g *Generator) run() (ok bool) {
|
|||
if !isGoGenerate(buf) {
|
||||
continue
|
||||
}
|
||||
if generateRunFlag != "" {
|
||||
if !generateRunRE.Match(bytes.TrimSpace(buf)) {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
words := g.split(string(buf))
|
||||
if len(words) == 0 {
|
||||
|
@ -306,7 +326,7 @@ Words:
|
|||
}
|
||||
// Substitute environment variables.
|
||||
for i, word := range words {
|
||||
words[i] = g.expandEnv(word)
|
||||
words[i] = os.Expand(word, g.expandVar)
|
||||
}
|
||||
return words
|
||||
}
|
||||
|
@ -322,38 +342,25 @@ func (g *Generator) errorf(format string, args ...interface{}) {
|
|||
panic(stop)
|
||||
}
|
||||
|
||||
// expandEnv expands any $XXX invocations in word.
|
||||
func (g *Generator) expandEnv(word string) string {
|
||||
if !strings.ContainsRune(word, '$') {
|
||||
return word
|
||||
// expandVar expands the $XXX invocation in word. It is called
|
||||
// by os.Expand.
|
||||
func (g *Generator) expandVar(word string) string {
|
||||
switch word {
|
||||
case "GOARCH":
|
||||
return buildContext.GOARCH
|
||||
case "GOOS":
|
||||
return buildContext.GOOS
|
||||
case "GOFILE":
|
||||
return g.file
|
||||
case "GOLINE":
|
||||
return fmt.Sprint(g.lineNum)
|
||||
case "GOPACKAGE":
|
||||
return g.pkg
|
||||
case "DOLLAR":
|
||||
return "$"
|
||||
default:
|
||||
return os.Getenv(word)
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
var w int
|
||||
var r rune
|
||||
for i := 0; i < len(word); i += w {
|
||||
r, w = utf8.DecodeRuneInString(word[i:])
|
||||
if r != '$' {
|
||||
buf.WriteRune(r)
|
||||
continue
|
||||
}
|
||||
w += g.identLength(word[i+w:])
|
||||
envVar := word[i+1 : i+w]
|
||||
var sub string
|
||||
switch envVar {
|
||||
case "GOARCH":
|
||||
sub = runtime.GOARCH
|
||||
case "GOOS":
|
||||
sub = runtime.GOOS
|
||||
case "GOFILE":
|
||||
sub = g.file
|
||||
case "GOPACKAGE":
|
||||
sub = g.pkg
|
||||
default:
|
||||
sub = os.Getenv(envVar)
|
||||
}
|
||||
buf.WriteString(sub)
|
||||
}
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// identLength returns the length of the identifier beginning the string.
|
||||
|
@ -395,7 +402,7 @@ func (g *Generator) exec(words []string) {
|
|||
"GOFILE=" + g.file,
|
||||
"GOPACKAGE=" + g.pkg,
|
||||
}
|
||||
cmd.Env = mergeEnvLists(env, os.Environ())
|
||||
cmd.Env = mergeEnvLists(env, origEnv)
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
g.errorf("running %q: %s", words[0], err)
|
||||
|
|
|
@ -26,6 +26,7 @@ var splitTests = []splitTest{
|
|||
{"$GOPACKAGE", []string{"sys"}},
|
||||
{"a $XXNOTDEFINEDXX b", []string{"a", "", "b"}},
|
||||
{"/$XXNOTDEFINED/", []string{"//"}},
|
||||
{"/$DOLLAR/", []string{"/$/"}},
|
||||
{"yacc -o $GOARCH/yacc_$GOFILE", []string{"go", "tool", "yacc", "-o", runtime.GOARCH + "/yacc_proc.go"}},
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ import (
|
|||
)
|
||||
|
||||
var cmdGet = &Command{
|
||||
UsageLine: "get [-d] [-f] [-fix] [-t] [-u] [build flags] [packages]",
|
||||
UsageLine: "get [-d] [-f] [-fix] [-insecure] [-t] [-u] [build flags] [packages]",
|
||||
Short: "download and install packages and dependencies",
|
||||
Long: `
|
||||
Get downloads and installs the packages named by the import paths,
|
||||
|
@ -33,6 +33,9 @@ of the original.
|
|||
The -fix flag instructs get to run the fix tool on the downloaded packages
|
||||
before resolving dependencies or building the code.
|
||||
|
||||
The -insecure flag permits fetching from repositories and resolving
|
||||
custom domains using insecure schemes such as HTTP. Use with caution.
|
||||
|
||||
The -t flag instructs get to also download the packages required to build
|
||||
the tests for the specified packages.
|
||||
|
||||
|
@ -48,6 +51,10 @@ rule is that if the local installation is running version "go1", get
|
|||
searches for a branch or tag named "go1". If no such version exists it
|
||||
retrieves the most recent version of the package.
|
||||
|
||||
If the vendoring experiment is enabled (see 'go help gopath'),
|
||||
then when go get checks out or updates a Git repository,
|
||||
it also updates any git submodules referenced by the repository.
|
||||
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
For more about how 'go get' finds source code to
|
||||
|
@ -62,6 +69,7 @@ var getF = cmdGet.Flag.Bool("f", false, "")
|
|||
var getT = cmdGet.Flag.Bool("t", false, "")
|
||||
var getU = cmdGet.Flag.Bool("u", false, "")
|
||||
var getFix = cmdGet.Flag.Bool("fix", false, "")
|
||||
var getInsecure = cmdGet.Flag.Bool("insecure", false, "")
|
||||
|
||||
func init() {
|
||||
addBuildFlags(cmdGet)
|
||||
|
@ -73,10 +81,20 @@ func runGet(cmd *Command, args []string) {
|
|||
fatalf("go get: cannot use -f flag without -u")
|
||||
}
|
||||
|
||||
// Disable any prompting for passwords by Git.
|
||||
// Only has an effect for 2.3.0 or later, but avoiding
|
||||
// the prompt in earlier versions is just too hard.
|
||||
// See golang.org/issue/9341.
|
||||
os.Setenv("GIT_TERMINAL_PROMPT", "0")
|
||||
|
||||
// Phase 1. Download/update.
|
||||
var stk importStack
|
||||
mode := 0
|
||||
if *getT {
|
||||
mode |= getTestDeps
|
||||
}
|
||||
for _, arg := range downloadPaths(args) {
|
||||
download(arg, &stk, *getT)
|
||||
download(arg, nil, &stk, mode)
|
||||
}
|
||||
exitIfErrors()
|
||||
|
||||
|
@ -92,12 +110,13 @@ func runGet(cmd *Command, args []string) {
|
|||
}
|
||||
|
||||
args = importPaths(args)
|
||||
packagesForBuild(args)
|
||||
|
||||
// Phase 3. Install.
|
||||
if *getD {
|
||||
// Download only.
|
||||
// Check delayed until now so that importPaths
|
||||
// has a chance to print errors.
|
||||
// and packagesForBuild have a chance to print errors.
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -148,13 +167,30 @@ var downloadRootCache = map[string]bool{}
|
|||
|
||||
// download runs the download half of the get command
|
||||
// for the package named by the argument.
|
||||
func download(arg string, stk *importStack, getTestDeps bool) {
|
||||
p := loadPackage(arg, stk)
|
||||
func download(arg string, parent *Package, stk *importStack, mode int) {
|
||||
load := func(path string, mode int) *Package {
|
||||
if parent == nil {
|
||||
return loadPackage(path, stk)
|
||||
}
|
||||
return loadImport(path, parent.Dir, parent, stk, nil, mode)
|
||||
}
|
||||
|
||||
p := load(arg, mode)
|
||||
if p.Error != nil && p.Error.hard {
|
||||
errorf("%s", p.Error)
|
||||
return
|
||||
}
|
||||
|
||||
// loadPackage inferred the canonical ImportPath from arg.
|
||||
// Use that in the following to prevent hysteresis effects
|
||||
// in e.g. downloadCache and packageCache.
|
||||
// This allows invocations such as:
|
||||
// mkdir -p $GOPATH/src/github.com/user
|
||||
// cd $GOPATH/src/github.com/user
|
||||
// go get ./foo
|
||||
// see: golang.org/issue/9767
|
||||
arg = p.ImportPath
|
||||
|
||||
// There's nothing to do if this is a package in the standard library.
|
||||
if p.Standard {
|
||||
return
|
||||
|
@ -163,7 +199,7 @@ func download(arg string, stk *importStack, getTestDeps bool) {
|
|||
// Only process each package once.
|
||||
// (Unless we're fetching test dependencies for this package,
|
||||
// in which case we want to process it again.)
|
||||
if downloadCache[arg] && !getTestDeps {
|
||||
if downloadCache[arg] && mode&getTestDeps == 0 {
|
||||
return
|
||||
}
|
||||
downloadCache[arg] = true
|
||||
|
@ -175,7 +211,7 @@ func download(arg string, stk *importStack, getTestDeps bool) {
|
|||
// Download if the package is missing, or update if we're using -u.
|
||||
if p.Dir == "" || *getU {
|
||||
// The actual download.
|
||||
stk.push(p.ImportPath)
|
||||
stk.push(arg)
|
||||
err := downloadPackage(p)
|
||||
if err != nil {
|
||||
errorf("%s", &PackageError{ImportStack: stk.copy(), Err: err.Error()})
|
||||
|
@ -183,6 +219,17 @@ func download(arg string, stk *importStack, getTestDeps bool) {
|
|||
return
|
||||
}
|
||||
|
||||
// Warn that code.google.com is shutting down. We
|
||||
// issue the warning here because this is where we
|
||||
// have the import stack.
|
||||
if strings.HasPrefix(p.ImportPath, "code.google.com") {
|
||||
fmt.Fprintf(os.Stderr, "warning: code.google.com is shutting down; import path %v will stop working\n", p.ImportPath)
|
||||
if len(*stk) > 1 {
|
||||
fmt.Fprintf(os.Stderr, "warning: package %v\n", strings.Join(*stk, "\n\timports "))
|
||||
}
|
||||
}
|
||||
stk.pop()
|
||||
|
||||
args := []string{arg}
|
||||
// If the argument has a wildcard in it, re-evaluate the wildcard.
|
||||
// We delay this until after reloadPackage so that the old entry
|
||||
|
@ -208,9 +255,10 @@ func download(arg string, stk *importStack, getTestDeps bool) {
|
|||
|
||||
pkgs = pkgs[:0]
|
||||
for _, arg := range args {
|
||||
stk.push(arg)
|
||||
p := loadPackage(arg, stk)
|
||||
stk.pop()
|
||||
// Note: load calls loadPackage or loadImport,
|
||||
// which push arg onto stk already.
|
||||
// Do not push here too, or else stk will say arg imports arg.
|
||||
p := load(arg, mode)
|
||||
if p.Error != nil {
|
||||
errorf("%s", p.Error)
|
||||
continue
|
||||
|
@ -223,7 +271,7 @@ func download(arg string, stk *importStack, getTestDeps bool) {
|
|||
// due to wildcard expansion.
|
||||
for _, p := range pkgs {
|
||||
if *getFix {
|
||||
run(stringList(tool("fix"), relPaths(p.allgofiles)))
|
||||
run(buildToolExec, stringList(tool("fix"), relPaths(p.allgofiles)))
|
||||
|
||||
// The imports might have changed, so reload again.
|
||||
p = reloadPackage(arg, stk)
|
||||
|
@ -240,18 +288,31 @@ func download(arg string, stk *importStack, getTestDeps bool) {
|
|||
}
|
||||
|
||||
// Process dependencies, now that we know what they are.
|
||||
for _, dep := range p.deps {
|
||||
for _, path := range p.Imports {
|
||||
if path == "C" {
|
||||
continue
|
||||
}
|
||||
// Don't get test dependencies recursively.
|
||||
download(dep.ImportPath, stk, false)
|
||||
// Imports is already vendor-expanded.
|
||||
download(path, p, stk, 0)
|
||||
}
|
||||
if getTestDeps {
|
||||
if mode&getTestDeps != 0 {
|
||||
// Process test dependencies when -t is specified.
|
||||
// (Don't get test dependencies for test dependencies.)
|
||||
// We pass useVendor here because p.load does not
|
||||
// vendor-expand TestImports and XTestImports.
|
||||
// The call to loadImport inside download needs to do that.
|
||||
for _, path := range p.TestImports {
|
||||
download(path, stk, false)
|
||||
if path == "C" {
|
||||
continue
|
||||
}
|
||||
download(path, p, stk, useVendor)
|
||||
}
|
||||
for _, path := range p.XTestImports {
|
||||
download(path, stk, false)
|
||||
if path == "C" {
|
||||
continue
|
||||
}
|
||||
download(path, p, stk, useVendor)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -269,6 +330,12 @@ func downloadPackage(p *Package) error {
|
|||
repo, rootPath string
|
||||
err error
|
||||
)
|
||||
|
||||
security := secure
|
||||
if *getInsecure {
|
||||
security = insecure
|
||||
}
|
||||
|
||||
if p.build.SrcRoot != "" {
|
||||
// Directory exists. Look for checkout along path to src.
|
||||
vcs, rootPath, err = vcsForDir(p)
|
||||
|
@ -278,10 +345,15 @@ func downloadPackage(p *Package) error {
|
|||
repo = "<local>" // should be unused; make distinctive
|
||||
|
||||
// Double-check where it came from.
|
||||
if *getU && vcs.remoteRepo != nil && !*getF {
|
||||
if *getU && vcs.remoteRepo != nil {
|
||||
dir := filepath.Join(p.build.SrcRoot, rootPath)
|
||||
if remote, err := vcs.remoteRepo(vcs, dir); err == nil {
|
||||
if rr, err := repoRootForImportPath(p.ImportPath); err == nil {
|
||||
remote, err := vcs.remoteRepo(vcs, dir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
repo = remote
|
||||
if !*getF {
|
||||
if rr, err := repoRootForImportPath(p.ImportPath, security); err == nil {
|
||||
repo := rr.repo
|
||||
if rr.vcs.resolveRepo != nil {
|
||||
resolved, err := rr.vcs.resolveRepo(rr.vcs, dir, repo)
|
||||
|
@ -289,7 +361,7 @@ func downloadPackage(p *Package) error {
|
|||
repo = resolved
|
||||
}
|
||||
}
|
||||
if remote != repo {
|
||||
if remote != repo && p.ImportComment != "" {
|
||||
return fmt.Errorf("%s is a custom import path for %s, but %s is checked out from %s", rr.root, repo, dir, remote)
|
||||
}
|
||||
}
|
||||
|
@ -298,12 +370,15 @@ func downloadPackage(p *Package) error {
|
|||
} else {
|
||||
// Analyze the import path to determine the version control system,
|
||||
// repository, and the import path for the root of the repository.
|
||||
rr, err := repoRootForImportPath(p.ImportPath)
|
||||
rr, err := repoRootForImportPath(p.ImportPath, security)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vcs, repo, rootPath = rr.vcs, rr.repo, rr.root
|
||||
}
|
||||
if !vcs.isSecure(repo) && !*getInsecure {
|
||||
return fmt.Errorf("cannot download, %v uses insecure protocol", repo)
|
||||
}
|
||||
|
||||
if p.build.SrcRoot == "" {
|
||||
// Package not found. Put in first directory of $GOPATH.
|
||||
|
|
2389
libgo/go/cmd/go/go_test.go
Normal file
2389
libgo/go/cmd/go/go_test.go
Normal file
File diff suppressed because it is too large
Load diff
|
@ -11,7 +11,7 @@ var helpC = &Command{
|
|||
There are two different ways to call between Go and C/C++ code.
|
||||
|
||||
The first is the cgo tool, which is part of the Go distribution. For
|
||||
information on how to use it see the cgo documentation (godoc cmd/cgo).
|
||||
information on how to use it see the cgo documentation (go doc cmd/cgo).
|
||||
|
||||
The second is the SWIG program, which is a general tool for
|
||||
interfacing between languages. For information on SWIG see
|
||||
|
@ -47,7 +47,7 @@ environment variable (see 'go help gopath').
|
|||
If no import paths are given, the action applies to the
|
||||
package in the current directory.
|
||||
|
||||
There are three reserved names for paths that should not be used
|
||||
There are four reserved names for paths that should not be used
|
||||
for packages to be built with the go tool:
|
||||
|
||||
- "main" denotes the top-level package in a stand-alone executable.
|
||||
|
@ -59,6 +59,9 @@ system.
|
|||
- "std" is like all but expands to just the packages in the standard
|
||||
Go library.
|
||||
|
||||
- "cmd" expands to the Go repository's commands and their
|
||||
internal libraries.
|
||||
|
||||
An import path is a pattern if it includes one or more "..." wildcards,
|
||||
each of which can match any string, including the empty string and
|
||||
strings containing slashes. Such a pattern expands to all package
|
||||
|
@ -74,7 +77,7 @@ By convention, this is arranged by starting each path with a
|
|||
unique prefix that belongs to you. For example, paths used
|
||||
internally at Google all begin with 'google', and paths
|
||||
denoting remote repositories begin with the path to the code,
|
||||
such as 'code.google.com/p/project'.
|
||||
such as 'github.com/user/repo'.
|
||||
|
||||
As a special case, if the package list is a list of .go files from a
|
||||
single directory, the command is applied to a single synthesized
|
||||
|
@ -192,7 +195,7 @@ example.org/repo or repo.git.
|
|||
|
||||
When a version control system supports multiple protocols,
|
||||
each is tried in turn when downloading. For example, a Git
|
||||
download tries git://, then https://, then http://.
|
||||
download tries https://, then git+ssh://.
|
||||
|
||||
If the import path is not a known code hosting site and also lacks a
|
||||
version control qualifier, the go tool attempts to fetch the import
|
||||
|
@ -208,6 +211,10 @@ root. It must be a prefix or an exact match of the package being
|
|||
fetched with "go get". If it's not an exact match, another http
|
||||
request is made at the prefix to verify the <meta> tags match.
|
||||
|
||||
The meta tag should appear as early in the file as possible.
|
||||
In particular, it should appear before any raw JavaScript or CSS,
|
||||
to avoid confusing the go command's restricted parser.
|
||||
|
||||
The vcs is one of "git", "hg", "svn", etc,
|
||||
|
||||
The repo-root is the root of the version control system
|
||||
|
@ -217,10 +224,10 @@ For example,
|
|||
|
||||
import "example.org/pkg/foo"
|
||||
|
||||
will result in the following request(s):
|
||||
will result in the following requests:
|
||||
|
||||
https://example.org/pkg/foo?go-get=1 (preferred)
|
||||
http://example.org/pkg/foo?go-get=1 (fallback)
|
||||
http://example.org/pkg/foo?go-get=1 (fallback, only with -insecure)
|
||||
|
||||
If that page contains the meta tag
|
||||
|
||||
|
@ -254,6 +261,11 @@ unless it is being referred to by that import path. In this way, import comments
|
|||
let package authors make sure the custom import path is used and not a
|
||||
direct path to the underlying code hosting site.
|
||||
|
||||
If the vendoring experiment is enabled (see 'go help gopath'),
|
||||
then import path checking is disabled for code found within vendor trees.
|
||||
This makes it possible to copy code into alternate locations in vendor trees
|
||||
without needing to update import comments.
|
||||
|
||||
See https://golang.org/s/go14customimport for details.
|
||||
`,
|
||||
}
|
||||
|
@ -275,10 +287,10 @@ standard Go tree.
|
|||
|
||||
Each directory listed in GOPATH must have a prescribed structure:
|
||||
|
||||
The src/ directory holds source code. The path below 'src'
|
||||
The src directory holds source code. The path below src
|
||||
determines the import path or executable name.
|
||||
|
||||
The pkg/ directory holds installed package objects.
|
||||
The pkg directory holds installed package objects.
|
||||
As in the Go tree, each target operating system and
|
||||
architecture pair has its own subdirectory of pkg
|
||||
(pkg/GOOS_GOARCH).
|
||||
|
@ -287,11 +299,11 @@ If DIR is a directory listed in the GOPATH, a package with
|
|||
source in DIR/src/foo/bar can be imported as "foo/bar" and
|
||||
has its compiled form installed to "DIR/pkg/GOOS_GOARCH/foo/bar.a".
|
||||
|
||||
The bin/ directory holds compiled commands.
|
||||
The bin directory holds compiled commands.
|
||||
Each command is named for its source directory, but only
|
||||
the final element, not the entire path. That is, the
|
||||
command with source in DIR/src/foo/quux is installed into
|
||||
DIR/bin/quux, not DIR/bin/foo/quux. The foo/ is stripped
|
||||
DIR/bin/quux, not DIR/bin/foo/quux. The "foo/" prefix is stripped
|
||||
so that you can add DIR/bin to your PATH to get at the
|
||||
installed commands. If the GOBIN environment variable is
|
||||
set, commands are installed to the directory it names instead
|
||||
|
@ -318,6 +330,168 @@ Here's an example directory layout:
|
|||
Go searches each directory listed in GOPATH to find source code,
|
||||
but new packages are always downloaded into the first directory
|
||||
in the list.
|
||||
|
||||
See https://golang.org/doc/code.html for an example.
|
||||
|
||||
Internal Directories
|
||||
|
||||
Code in or below a directory named "internal" is importable only
|
||||
by code in the directory tree rooted at the parent of "internal".
|
||||
Here's an extended version of the directory layout above:
|
||||
|
||||
/home/user/gocode/
|
||||
src/
|
||||
crash/
|
||||
bang/ (go code in package bang)
|
||||
b.go
|
||||
foo/ (go code in package foo)
|
||||
f.go
|
||||
bar/ (go code in package bar)
|
||||
x.go
|
||||
internal/
|
||||
baz/ (go code in package baz)
|
||||
z.go
|
||||
quux/ (go code in package main)
|
||||
y.go
|
||||
|
||||
|
||||
The code in z.go is imported as "foo/internal/baz", but that
|
||||
import statement can only appear in source files in the subtree
|
||||
rooted at foo. The source files foo/f.go, foo/bar/x.go, and
|
||||
foo/quux/y.go can all import "foo/internal/baz", but the source file
|
||||
crash/bang/b.go cannot.
|
||||
|
||||
See https://golang.org/s/go14internal for details.
|
||||
|
||||
Vendor Directories
|
||||
|
||||
Go 1.5 includes experimental support for using local copies
|
||||
of external dependencies to satisfy imports of those dependencies,
|
||||
often referred to as vendoring. Setting the environment variable
|
||||
GO15VENDOREXPERIMENT=1 enables that experimental support.
|
||||
|
||||
When the vendor experiment is enabled,
|
||||
code below a directory named "vendor" is importable only
|
||||
by code in the directory tree rooted at the parent of "vendor",
|
||||
and only using an import path that omits the prefix up to and
|
||||
including the vendor element.
|
||||
|
||||
Here's the example from the previous section,
|
||||
but with the "internal" directory renamed to "vendor"
|
||||
and a new foo/vendor/crash/bang directory added:
|
||||
|
||||
/home/user/gocode/
|
||||
src/
|
||||
crash/
|
||||
bang/ (go code in package bang)
|
||||
b.go
|
||||
foo/ (go code in package foo)
|
||||
f.go
|
||||
bar/ (go code in package bar)
|
||||
x.go
|
||||
vendor/
|
||||
crash/
|
||||
bang/ (go code in package bang)
|
||||
b.go
|
||||
baz/ (go code in package baz)
|
||||
z.go
|
||||
quux/ (go code in package main)
|
||||
y.go
|
||||
|
||||
The same visibility rules apply as for internal, but the code
|
||||
in z.go is imported as "baz", not as "foo/vendor/baz".
|
||||
|
||||
Code in vendor directories deeper in the source tree shadows
|
||||
code in higher directories. Within the subtree rooted at foo, an import
|
||||
of "crash/bang" resolves to "foo/vendor/crash/bang", not the
|
||||
top-level "crash/bang".
|
||||
|
||||
Code in vendor directories is not subject to import path
|
||||
checking (see 'go help importpath').
|
||||
|
||||
When the vendor experiment is enabled, 'go get' checks out
|
||||
submodules when checking out or updating a git repository
|
||||
(see 'go help get').
|
||||
|
||||
The vendoring semantics are an experiment, and they may change
|
||||
in future releases. Once settled, they will be on by default.
|
||||
|
||||
See https://golang.org/s/go15vendor for details.
|
||||
`,
|
||||
}
|
||||
|
||||
var helpEnvironment = &Command{
|
||||
UsageLine: "environment",
|
||||
Short: "environment variables",
|
||||
Long: `
|
||||
|
||||
The go command, and the tools it invokes, examine a few different
|
||||
environment variables. For many of these, you can see the default
|
||||
value of on your system by running 'go env NAME', where NAME is the
|
||||
name of the variable.
|
||||
|
||||
General-purpose environment variables:
|
||||
|
||||
GCCGO
|
||||
The gccgo command to run for 'go build -compiler=gccgo'.
|
||||
GOARCH
|
||||
The architecture, or processor, for which to compile code.
|
||||
Examples are amd64, 386, arm, ppc64.
|
||||
GOBIN
|
||||
The directory where 'go install' will install a command.
|
||||
GOOS
|
||||
The operating system for which to compile code.
|
||||
Examples are linux, darwin, windows, netbsd.
|
||||
GOPATH
|
||||
See 'go help gopath'.
|
||||
GORACE
|
||||
Options for the race detector.
|
||||
See https://golang.org/doc/articles/race_detector.html.
|
||||
GOROOT
|
||||
The root of the go tree.
|
||||
|
||||
Environment variables for use with cgo:
|
||||
|
||||
CC
|
||||
The command to use to compile C code.
|
||||
CGO_ENABLED
|
||||
Whether the cgo command is supported. Either 0 or 1.
|
||||
CGO_CFLAGS
|
||||
Flags that cgo will pass to the compiler when compiling
|
||||
C code.
|
||||
CGO_CPPFLAGS
|
||||
Flags that cgo will pass to the compiler when compiling
|
||||
C or C++ code.
|
||||
CGO_CXXFLAGS
|
||||
Flags that cgo will pass to the compiler when compiling
|
||||
C++ code.
|
||||
CGO_LDFLAGS
|
||||
Flags that cgo will pass to the compiler when linking.
|
||||
CXX
|
||||
The command to use to compile C++ code.
|
||||
|
||||
Architecture-specific environment variables:
|
||||
|
||||
GOARM
|
||||
For GOARCH=arm, the ARM architecture for which to compile.
|
||||
Valid values are 5, 6, 7.
|
||||
GO386
|
||||
For GOARCH=386, the floating point instruction set.
|
||||
Valid values are 387, sse2.
|
||||
|
||||
Special-purpose environment variables:
|
||||
|
||||
GOROOT_FINAL
|
||||
The root of the installed Go tree, when it is
|
||||
installed in a location other than where it is built.
|
||||
File names in stack traces are rewritten from GOROOT to
|
||||
GOROOT_FINAL.
|
||||
GO15VENDOREXPERIMENT
|
||||
Set to 1 to enable the Go 1.5 vendoring experiment.
|
||||
GO_EXTLINK_ENABLED
|
||||
Whether the linker should use external linking mode
|
||||
when using -linkmode=auto with code that uses cgo.
|
||||
Set to 0 to disable external linking mode, 1 to enable it.
|
||||
`,
|
||||
}
|
||||
|
||||
|
@ -333,10 +507,9 @@ the extension of the file name. These extensions are:
|
|||
Go source files.
|
||||
.c, .h
|
||||
C source files.
|
||||
If the package uses cgo, these will be compiled with the
|
||||
OS-native compiler (typically gcc); otherwise they will be
|
||||
compiled with the Go-specific support compiler,
|
||||
5c, 6c, or 8c, etc. as appropriate.
|
||||
If the package uses cgo or SWIG, these will be compiled with the
|
||||
OS-native compiler (typically gcc); otherwise they will
|
||||
trigger an error.
|
||||
.cc, .cpp, .cxx, .hh, .hpp, .hxx
|
||||
C++ source files. Only useful with cgo or SWIG, and always
|
||||
compiled with the OS-native compiler.
|
||||
|
@ -345,10 +518,9 @@ the extension of the file name. These extensions are:
|
|||
compiled with the OS-native compiler.
|
||||
.s, .S
|
||||
Assembler source files.
|
||||
If the package uses cgo, these will be assembled with the
|
||||
If the package uses cgo or SWIG, these will be assembled with the
|
||||
OS-native assembler (typically gcc (sic)); otherwise they
|
||||
will be assembled with the Go-specific support assembler,
|
||||
5a, 6a, or 8a, etc., as appropriate.
|
||||
will be assembled with the Go assembler.
|
||||
.swig, .swigcxx
|
||||
SWIG definition files.
|
||||
.syso
|
||||
|
@ -360,3 +532,43 @@ at the first item in the file that is not a blank line or //-style
|
|||
line comment.
|
||||
`,
|
||||
}
|
||||
|
||||
var helpBuildmode = &Command{
|
||||
UsageLine: "buildmode",
|
||||
Short: "description of build modes",
|
||||
Long: `
|
||||
The 'go build' and 'go install' commands take a -buildmode argument which
|
||||
indicates which kind of object file is to be built. Currently supported values
|
||||
are:
|
||||
|
||||
-buildmode=archive
|
||||
Build the listed non-main packages into .a files. Packages named
|
||||
main are ignored.
|
||||
|
||||
-buildmode=c-archive
|
||||
Build the listed main package, plus all packages it imports,
|
||||
into a C archive file. The only callable symbols will be those
|
||||
functions exported using a cgo //export comment. Requires
|
||||
exactly one main package to be listed.
|
||||
|
||||
-buildmode=c-shared
|
||||
Build the listed main packages, plus all packages that they
|
||||
import, into C shared libraries. The only callable symbols will
|
||||
be those functions exported using a cgo //export comment.
|
||||
Non-main packages are ignored.
|
||||
|
||||
-buildmode=default
|
||||
Listed main packages are built into executables and listed
|
||||
non-main packages are built into .a files (the default
|
||||
behavior).
|
||||
|
||||
-buildmode=shared
|
||||
Combine all the listed non-main packages into a single shared
|
||||
library that will be used when building with the -linkshared
|
||||
option. Packages named main are ignored.
|
||||
|
||||
-buildmode=exe
|
||||
Build the listed main packages and everything they import into
|
||||
executables. Packages not named main are ignored.
|
||||
`,
|
||||
}
|
||||
|
|
|
@ -18,11 +18,25 @@ import (
|
|||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"time"
|
||||
)
|
||||
|
||||
// httpClient is the default HTTP client, but a variable so it can be
|
||||
// changed by tests, without modifying http.DefaultClient.
|
||||
var httpClient = http.DefaultClient
|
||||
var impatientHTTPClient = &http.Client{
|
||||
Timeout: time.Duration(5 * time.Second),
|
||||
}
|
||||
|
||||
type httpError struct {
|
||||
status string
|
||||
statusCode int
|
||||
url string
|
||||
}
|
||||
|
||||
func (e *httpError) Error() string {
|
||||
return fmt.Sprintf("%s: %s", e.url, e.status)
|
||||
}
|
||||
|
||||
// httpGET returns the data from an HTTP GET request for the given URL.
|
||||
func httpGET(url string) ([]byte, error) {
|
||||
|
@ -32,7 +46,9 @@ func httpGET(url string) ([]byte, error) {
|
|||
}
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode != 200 {
|
||||
return nil, fmt.Errorf("%s: %s", url, resp.Status)
|
||||
err := &httpError{status: resp.Status, statusCode: resp.StatusCode, url: url}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
b, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
|
@ -43,7 +59,7 @@ func httpGET(url string) ([]byte, error) {
|
|||
|
||||
// httpsOrHTTP returns the body of either the importPath's
|
||||
// https resource or, if unavailable, the http resource.
|
||||
func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err error) {
|
||||
func httpsOrHTTP(importPath string, security securityMode) (urlStr string, body io.ReadCloser, err error) {
|
||||
fetch := func(scheme string) (urlStr string, res *http.Response, err error) {
|
||||
u, err := url.Parse(scheme + "://" + importPath)
|
||||
if err != nil {
|
||||
|
@ -54,7 +70,11 @@ func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err erro
|
|||
if buildV {
|
||||
log.Printf("Fetching %s", urlStr)
|
||||
}
|
||||
res, err = httpClient.Get(urlStr)
|
||||
if security == insecure && scheme == "https" { // fail earlier
|
||||
res, err = impatientHTTPClient.Get(urlStr)
|
||||
} else {
|
||||
res, err = httpClient.Get(urlStr)
|
||||
}
|
||||
return
|
||||
}
|
||||
closeBody := func(res *http.Response) {
|
||||
|
@ -72,7 +92,9 @@ func httpsOrHTTP(importPath string) (urlStr string, body io.ReadCloser, err erro
|
|||
}
|
||||
}
|
||||
closeBody(res)
|
||||
urlStr, res, err = fetch("http")
|
||||
if security == insecure {
|
||||
urlStr, res, err = fetch("http")
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
closeBody(res)
|
||||
|
|
|
@ -21,9 +21,10 @@ List lists the packages named by the import paths, one per line.
|
|||
|
||||
The default output shows the package import path:
|
||||
|
||||
code.google.com/p/google-api-go-client/books/v1
|
||||
code.google.com/p/goauth2/oauth
|
||||
code.google.com/p/sqlite
|
||||
bytes
|
||||
encoding/json
|
||||
github.com/gorilla/mux
|
||||
golang.org/x/net/html
|
||||
|
||||
The -f flag specifies an alternate format for the list, using the
|
||||
syntax of package template. The default output is equivalent to -f
|
||||
|
@ -36,6 +37,7 @@ syntax of package template. The default output is equivalent to -f
|
|||
Name string // package name
|
||||
Doc string // package documentation string
|
||||
Target string // install path
|
||||
Shlib string // the shared library that contains this package (only set when -linkshared)
|
||||
Goroot bool // is this package in the Go root?
|
||||
Standard bool // is this package part of the standard Go library?
|
||||
Stale bool // would 'go install' do anything for this package?
|
||||
|
@ -126,6 +128,7 @@ var listJson = cmdList.Flag.Bool("json", false, "")
|
|||
var nl = []byte{'\n'}
|
||||
|
||||
func runList(cmd *Command, args []string) {
|
||||
buildModeInit()
|
||||
out := newTrackingWriter(os.Stdout)
|
||||
defer out.w.Flush()
|
||||
|
||||
|
@ -173,6 +176,10 @@ func runList(cmd *Command, args []string) {
|
|||
}
|
||||
|
||||
for _, pkg := range load(args) {
|
||||
// Show vendor-expanded paths in listing
|
||||
pkg.TestImports = pkg.vendored(pkg.TestImports)
|
||||
pkg.XTestImports = pkg.vendored(pkg.XTestImports)
|
||||
|
||||
do(pkg)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"flag"
|
||||
"fmt"
|
||||
|
@ -76,6 +77,7 @@ func (c *Command) Runnable() bool {
|
|||
var commands = []*Command{
|
||||
cmdBuild,
|
||||
cmdClean,
|
||||
cmdDoc,
|
||||
cmdEnv,
|
||||
cmdFix,
|
||||
cmdFmt,
|
||||
|
@ -90,8 +92,10 @@ var commands = []*Command{
|
|||
cmdVet,
|
||||
|
||||
helpC,
|
||||
helpBuildmode,
|
||||
helpFileType,
|
||||
helpGopath,
|
||||
helpEnvironment,
|
||||
helpImportPath,
|
||||
helpPackages,
|
||||
helpTestflag,
|
||||
|
@ -109,6 +113,8 @@ func setExitStatus(n int) {
|
|||
exitMu.Unlock()
|
||||
}
|
||||
|
||||
var origEnv []string
|
||||
|
||||
func main() {
|
||||
_ = go11tag
|
||||
flag.Usage = usage
|
||||
|
@ -139,7 +145,7 @@ func main() {
|
|||
fmt.Fprintf(os.Stderr, "go: GOPATH entry cannot start with shell metacharacter '~': %q\n", p)
|
||||
os.Exit(2)
|
||||
}
|
||||
if build.IsLocalImport(p) {
|
||||
if !filepath.IsAbs(p) {
|
||||
fmt.Fprintf(os.Stderr, "go: GOPATH entry is relative; must be absolute path: %q.\nRun 'go help gopath' for usage.\n", p)
|
||||
os.Exit(2)
|
||||
}
|
||||
|
@ -151,8 +157,20 @@ func main() {
|
|||
os.Exit(2)
|
||||
}
|
||||
|
||||
// Set environment (GOOS, GOARCH, etc) explicitly.
|
||||
// In theory all the commands we invoke should have
|
||||
// the same default computation of these as we do,
|
||||
// but in practice there might be skew
|
||||
// This makes sure we all agree.
|
||||
origEnv = os.Environ()
|
||||
for _, env := range mkEnv() {
|
||||
if os.Getenv(env.name) != env.value {
|
||||
os.Setenv(env.name, env.value)
|
||||
}
|
||||
}
|
||||
|
||||
for _, cmd := range commands {
|
||||
if cmd.Name() == args[0] && cmd.Run != nil {
|
||||
if cmd.Name() == args[0] && cmd.Runnable() {
|
||||
cmd.Flag.Usage = func() { cmd.Usage() }
|
||||
if cmd.CustomFlags {
|
||||
args = args[1:]
|
||||
|
@ -179,13 +197,13 @@ Usage:
|
|||
|
||||
The commands are:
|
||||
{{range .}}{{if .Runnable}}
|
||||
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
|
||||
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
|
||||
|
||||
Use "go help [command]" for more information about a command.
|
||||
|
||||
Additional help topics:
|
||||
{{range .}}{{if not .Runnable}}
|
||||
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
|
||||
{{.Name | printf "%-11s"}} {{.Short}}{{end}}{{end}}
|
||||
|
||||
Use "go help [topic]" for more information about that topic.
|
||||
|
||||
|
@ -200,8 +218,8 @@ var documentationTemplate = `// Copyright 2011 The Go Authors. All rights reser
|
|||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// DO NOT EDIT THIS FILE. GENERATED BY mkdoc.sh.
|
||||
// Edit the documentation in other files and rerun mkdoc.sh to generate this one.
|
||||
// DO NOT EDIT THIS FILE. GENERATED BY mkalldocs.sh.
|
||||
// Edit the documentation in other files and rerun mkalldocs.sh to generate this one.
|
||||
|
||||
/*
|
||||
{{range .}}{{if .Short}}{{.Short | capitalize}}
|
||||
|
@ -217,12 +235,35 @@ var documentationTemplate = `// Copyright 2011 The Go Authors. All rights reser
|
|||
package main
|
||||
`
|
||||
|
||||
// An errWriter wraps a writer, recording whether a write error occurred.
|
||||
type errWriter struct {
|
||||
w io.Writer
|
||||
err error
|
||||
}
|
||||
|
||||
func (w *errWriter) Write(b []byte) (int, error) {
|
||||
n, err := w.w.Write(b)
|
||||
if err != nil {
|
||||
w.err = err
|
||||
}
|
||||
return n, err
|
||||
}
|
||||
|
||||
// tmpl executes the given template text on data, writing the result to w.
|
||||
func tmpl(w io.Writer, text string, data interface{}) {
|
||||
t := template.New("top")
|
||||
t.Funcs(template.FuncMap{"trim": strings.TrimSpace, "capitalize": capitalize})
|
||||
template.Must(t.Parse(text))
|
||||
if err := t.Execute(w, data); err != nil {
|
||||
ew := &errWriter{w: w}
|
||||
err := t.Execute(ew, data)
|
||||
if ew.err != nil {
|
||||
// I/O error writing. Ignore write on closed pipe.
|
||||
if strings.Contains(ew.err.Error(), "pipe") {
|
||||
os.Exit(1)
|
||||
}
|
||||
fatalf("writing output: %v", ew.err)
|
||||
}
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
@ -236,13 +277,17 @@ func capitalize(s string) string {
|
|||
}
|
||||
|
||||
func printUsage(w io.Writer) {
|
||||
tmpl(w, usageTemplate, commands)
|
||||
bw := bufio.NewWriter(w)
|
||||
tmpl(bw, usageTemplate, commands)
|
||||
bw.Flush()
|
||||
}
|
||||
|
||||
func usage() {
|
||||
// special case "go test -h"
|
||||
if len(os.Args) > 1 && os.Args[1] == "test" {
|
||||
help([]string{"testflag"})
|
||||
os.Stdout.WriteString(testUsage + "\n\n" +
|
||||
strings.TrimSpace(testFlag1) + "\n\n" +
|
||||
strings.TrimSpace(testFlag2) + "\n")
|
||||
os.Exit(2)
|
||||
}
|
||||
printUsage(os.Stderr)
|
||||
|
@ -308,7 +353,7 @@ func importPathsNoDotExpansion(args []string) []string {
|
|||
} else {
|
||||
a = path.Clean(a)
|
||||
}
|
||||
if a == "all" || a == "std" {
|
||||
if a == "all" || a == "std" || a == "cmd" {
|
||||
out = append(out, allPackages(a)...)
|
||||
continue
|
||||
}
|
||||
|
@ -401,11 +446,10 @@ func runOut(dir string, cmdargs ...interface{}) []byte {
|
|||
// The environment is the current process's environment
|
||||
// but with an updated $PWD, so that an os.Getwd in the
|
||||
// child will be faster.
|
||||
func envForDir(dir string) []string {
|
||||
env := os.Environ()
|
||||
func envForDir(dir string, base []string) []string {
|
||||
// Internally we only use rooted paths, so dir is rooted.
|
||||
// Even if dir is not rooted, no harm done.
|
||||
return mergeEnvLists([]string{"PWD=" + dir}, env)
|
||||
return mergeEnvLists([]string{"PWD=" + dir}, base)
|
||||
}
|
||||
|
||||
// mergeEnvLists merges the two environment lists such that
|
||||
|
@ -458,6 +502,28 @@ func hasPathPrefix(s, prefix string) bool {
|
|||
}
|
||||
}
|
||||
|
||||
// hasFilePathPrefix reports whether the filesystem path s begins with the
|
||||
// elements in prefix.
|
||||
func hasFilePathPrefix(s, prefix string) bool {
|
||||
sv := strings.ToUpper(filepath.VolumeName(s))
|
||||
pv := strings.ToUpper(filepath.VolumeName(prefix))
|
||||
s = s[len(sv):]
|
||||
prefix = prefix[len(pv):]
|
||||
switch {
|
||||
default:
|
||||
return false
|
||||
case sv != pv:
|
||||
return false
|
||||
case len(s) == len(prefix):
|
||||
return s == prefix
|
||||
case len(s) > len(prefix):
|
||||
if prefix != "" && prefix[len(prefix)-1] == filepath.Separator {
|
||||
return strings.HasPrefix(s, prefix)
|
||||
}
|
||||
return s[len(prefix)] == filepath.Separator && s[:len(prefix)] == prefix
|
||||
}
|
||||
}
|
||||
|
||||
// treeCanMatchPattern(pattern)(name) reports whether
|
||||
// name or children of name can possibly match pattern.
|
||||
// Pattern is the same limited glob accepted by matchPattern.
|
||||
|
@ -475,8 +541,8 @@ func treeCanMatchPattern(pattern string) func(name string) bool {
|
|||
|
||||
// allPackages returns all the packages that can be found
|
||||
// under the $GOPATH directories and $GOROOT matching pattern.
|
||||
// The pattern is either "all" (all packages), "std" (standard packages)
|
||||
// or a path including "...".
|
||||
// The pattern is either "all" (all packages), "std" (standard packages),
|
||||
// "cmd" (standard commands), or a path including "...".
|
||||
func allPackages(pattern string) []string {
|
||||
pkgs := matchPackages(pattern)
|
||||
if len(pkgs) == 0 {
|
||||
|
@ -488,7 +554,7 @@ func allPackages(pattern string) []string {
|
|||
func matchPackages(pattern string) []string {
|
||||
match := func(string) bool { return true }
|
||||
treeCanMatch := func(string) bool { return true }
|
||||
if pattern != "all" && pattern != "std" {
|
||||
if pattern != "all" && pattern != "std" && pattern != "cmd" {
|
||||
match = matchPattern(pattern)
|
||||
treeCanMatch = treeCanMatchPattern(pattern)
|
||||
}
|
||||
|
@ -501,47 +567,16 @@ func matchPackages(pattern string) []string {
|
|||
}
|
||||
var pkgs []string
|
||||
|
||||
// Commands
|
||||
cmd := filepath.Join(goroot, "src/cmd") + string(filepath.Separator)
|
||||
filepath.Walk(cmd, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil || !fi.IsDir() || path == cmd {
|
||||
return nil
|
||||
}
|
||||
name := path[len(cmd):]
|
||||
if !treeCanMatch(name) {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
// Commands are all in cmd/, not in subdirectories.
|
||||
if strings.Contains(name, string(filepath.Separator)) {
|
||||
return filepath.SkipDir
|
||||
}
|
||||
|
||||
// We use, e.g., cmd/gofmt as the pseudo import path for gofmt.
|
||||
name = "cmd/" + name
|
||||
if have[name] {
|
||||
return nil
|
||||
}
|
||||
have[name] = true
|
||||
if !match(name) {
|
||||
return nil
|
||||
}
|
||||
_, err = buildContext.ImportDir(path, 0)
|
||||
if err != nil {
|
||||
if _, noGo := err.(*build.NoGoError); !noGo {
|
||||
log.Print(err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
pkgs = append(pkgs, name)
|
||||
return nil
|
||||
})
|
||||
|
||||
for _, src := range buildContext.SrcDirs() {
|
||||
if pattern == "std" && src != gorootSrc {
|
||||
if (pattern == "std" || pattern == "cmd") && src != gorootSrc {
|
||||
continue
|
||||
}
|
||||
src = filepath.Clean(src) + string(filepath.Separator)
|
||||
filepath.Walk(src, func(path string, fi os.FileInfo, err error) error {
|
||||
root := src
|
||||
if pattern == "cmd" {
|
||||
root += "cmd" + string(filepath.Separator)
|
||||
}
|
||||
filepath.Walk(root, func(path string, fi os.FileInfo, err error) error {
|
||||
if err != nil || !fi.IsDir() || path == src {
|
||||
return nil
|
||||
}
|
||||
|
@ -553,7 +588,10 @@ func matchPackages(pattern string) []string {
|
|||
}
|
||||
|
||||
name := filepath.ToSlash(path[len(src):])
|
||||
if pattern == "std" && strings.Contains(name, ".") {
|
||||
if pattern == "std" && (strings.Contains(name, ".") || name == "cmd") {
|
||||
// The name "std" is only the standard library.
|
||||
// If the name has a dot, assume it's a domain name for go get,
|
||||
// and if the name is cmd, it's the root of the command tree.
|
||||
return filepath.SkipDir
|
||||
}
|
||||
if !treeCanMatch(name) {
|
||||
|
@ -659,7 +697,7 @@ func stringList(args ...interface{}) []string {
|
|||
case string:
|
||||
x = append(x, arg)
|
||||
default:
|
||||
panic("stringList: invalid argument")
|
||||
panic("stringList: invalid argument of type " + fmt.Sprintf("%T", arg))
|
||||
}
|
||||
}
|
||||
return x
|
||||
|
|
116
libgo/go/cmd/go/note.go
Normal file
116
libgo/go/cmd/go/note.go
Normal file
|
@ -0,0 +1,116 @@
|
|||
// Copyright 2015 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"
|
||||
"debug/elf"
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
)
|
||||
|
||||
func readAligned4(r io.Reader, sz int32) ([]byte, error) {
|
||||
full := (sz + 3) &^ 3
|
||||
data := make([]byte, full)
|
||||
_, err := io.ReadFull(r, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data = data[:sz]
|
||||
return data, nil
|
||||
}
|
||||
|
||||
func readELFNote(filename, name string, typ int32) ([]byte, error) {
|
||||
f, err := elf.Open(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, sect := range f.Sections {
|
||||
if sect.Type != elf.SHT_NOTE {
|
||||
continue
|
||||
}
|
||||
r := sect.Open()
|
||||
for {
|
||||
var namesize, descsize, noteType int32
|
||||
err = binary.Read(r, f.ByteOrder, &namesize)
|
||||
if err != nil {
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
return nil, fmt.Errorf("read namesize failed: %v", err)
|
||||
}
|
||||
err = binary.Read(r, f.ByteOrder, &descsize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read descsize failed: %v", err)
|
||||
}
|
||||
err = binary.Read(r, f.ByteOrder, ¬eType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read type failed: %v", err)
|
||||
}
|
||||
noteName, err := readAligned4(r, namesize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read name failed: %v", err)
|
||||
}
|
||||
desc, err := readAligned4(r, descsize)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("read desc failed: %v", err)
|
||||
}
|
||||
if name == string(noteName) && typ == noteType {
|
||||
return desc, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var elfGoNote = []byte("Go\x00\x00")
|
||||
|
||||
// readELFGoBuildID the Go build ID string from an ELF binary.
|
||||
// The Go build ID is stored in a note described by an ELF PT_NOTE prog header.
|
||||
// The caller has already opened filename, to get f, and read the first 4 kB out, in data.
|
||||
func readELFGoBuildID(filename string, f *os.File, data []byte) (buildid string, err error) {
|
||||
// Assume the note content is in the first 4 kB, already read.
|
||||
// Rewrite the ELF header to set shnum to 0, so that we can pass
|
||||
// the data to elf.NewFile and it will decode the Prog list but not
|
||||
// try to read the section headers and the string table from disk.
|
||||
// That's a waste of I/O when all we care about is the Prog list
|
||||
// and the one ELF note.
|
||||
switch elf.Class(data[elf.EI_CLASS]) {
|
||||
case elf.ELFCLASS32:
|
||||
data[48] = 0
|
||||
data[49] = 0
|
||||
case elf.ELFCLASS64:
|
||||
data[60] = 0
|
||||
data[61] = 0
|
||||
}
|
||||
|
||||
const elfGoBuildIDTag = 4
|
||||
|
||||
ef, err := elf.NewFile(bytes.NewReader(data))
|
||||
if err != nil {
|
||||
return "", &os.PathError{Path: filename, Op: "parse", Err: err}
|
||||
}
|
||||
for _, p := range ef.Progs {
|
||||
if p.Type != elf.PT_NOTE || p.Off >= uint64(len(data)) || p.Off+p.Filesz >= uint64(len(data)) || p.Filesz < 16 {
|
||||
continue
|
||||
}
|
||||
|
||||
note := data[p.Off : p.Off+p.Filesz]
|
||||
nameSize := ef.ByteOrder.Uint32(note)
|
||||
valSize := ef.ByteOrder.Uint32(note[4:])
|
||||
tag := ef.ByteOrder.Uint32(note[8:])
|
||||
name := note[12:16]
|
||||
if nameSize != 4 || 16+valSize > uint32(len(note)) || tag != elfGoBuildIDTag || !bytes.Equal(name, elfGoNote) {
|
||||
continue
|
||||
}
|
||||
|
||||
return string(note[16 : 16+valSize]), nil
|
||||
}
|
||||
|
||||
// No note. Treat as successful but build ID empty.
|
||||
return "", nil
|
||||
}
|
49
libgo/go/cmd/go/note_test.go
Normal file
49
libgo/go/cmd/go/note_test.go
Normal file
|
@ -0,0 +1,49 @@
|
|||
// Copyright 2015 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_test
|
||||
|
||||
import (
|
||||
main "cmd/go"
|
||||
"runtime"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestNoteReading(t *testing.T) {
|
||||
tg := testgo(t)
|
||||
defer tg.cleanup()
|
||||
tg.tempFile("hello.go", `package main; func main() { print("hello, world\n") }`)
|
||||
const buildID = "TestNoteReading-Build-ID"
|
||||
tg.run("build", "-ldflags", "-buildid="+buildID, "-o", tg.path("hello.exe"), tg.path("hello.go"))
|
||||
id, err := main.ReadBuildIDFromBinary(tg.path("hello.exe"))
|
||||
if err != nil {
|
||||
t.Fatalf("reading build ID from hello binary: %v", err)
|
||||
}
|
||||
if id != buildID {
|
||||
t.Fatalf("buildID in hello binary = %q, want %q", id, buildID)
|
||||
}
|
||||
|
||||
if runtime.GOOS == "linux" && runtime.GOARCH == "ppc64le" {
|
||||
t.Skipf("skipping - golang.org/issue/11184")
|
||||
}
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "plan9":
|
||||
// no external linking
|
||||
t.Logf("no external linking - skipping linkmode=external test")
|
||||
|
||||
case "solaris":
|
||||
t.Logf("skipping - golang.org/issue/12178")
|
||||
|
||||
default:
|
||||
tg.run("build", "-ldflags", "-buildid="+buildID+" -linkmode=external", "-o", tg.path("hello.exe"), tg.path("hello.go"))
|
||||
id, err := main.ReadBuildIDFromBinary(tg.path("hello.exe"))
|
||||
if err != nil {
|
||||
t.Fatalf("reading build ID from hello binary (linkmode=external): %v", err)
|
||||
}
|
||||
if id != buildID {
|
||||
t.Fatalf("buildID in hello binary = %q, want %q (linkmode=external)", id, buildID)
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -37,7 +37,8 @@ Run compiles and runs the main package comprising the named Go source files.
|
|||
A Go source file is defined to be a file ending in a literal ".go" suffix.
|
||||
|
||||
By default, 'go run' runs the compiled binary directly: 'a.out arguments...'.
|
||||
If the -exec flag is given, 'go run' invokes the binary using xprog: 'xprog a.out arguments...'.
|
||||
If the -exec flag is given, 'go run' invokes the binary using xprog:
|
||||
'xprog a.out arguments...'.
|
||||
If the -exec flag is not given, GOOS or GOARCH is different from the system
|
||||
default, and a program named go_$GOOS_$GOARCH_exec can be found
|
||||
on the current search path, 'go run' invokes the binary using that program,
|
||||
|
@ -64,6 +65,7 @@ func printStderr(args ...interface{}) (int, error) {
|
|||
|
||||
func runRun(cmd *Command, args []string) {
|
||||
raceInit()
|
||||
buildModeInit()
|
||||
var b builder
|
||||
b.init()
|
||||
b.print = printStderr
|
||||
|
@ -136,6 +138,7 @@ func runStdin(cmdline []string) {
|
|||
cmd.Stdin = os.Stdin
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
cmd.Env = origEnv
|
||||
startSigHandlers()
|
||||
if err := cmd.Run(); err != nil {
|
||||
errorf("%v", err)
|
||||
|
|
|
@ -33,9 +33,11 @@ func init() {
|
|||
cmdTest.Run = runTest
|
||||
}
|
||||
|
||||
const testUsage = "test [-c] [-i] [build and test flags] [packages] [flags for test binary]"
|
||||
|
||||
var cmdTest = &Command{
|
||||
CustomFlags: true,
|
||||
UsageLine: "test [-c] [-i] [build and test flags] [packages] [flags for test binary]",
|
||||
UsageLine: testUsage,
|
||||
Short: "test packages",
|
||||
Long: `
|
||||
'Go test' automates testing the packages named by the import paths.
|
||||
|
@ -64,6 +66,21 @@ with source in the current directory, including tests, and runs the tests.
|
|||
The package is built in a temporary directory so it does not interfere with the
|
||||
non-test installation.
|
||||
|
||||
` + strings.TrimSpace(testFlag1) + ` See 'go help testflag' for details.
|
||||
|
||||
If the test binary needs any other flags, they should be presented after the
|
||||
package names. The go tool treats as a flag the first argument that begins with
|
||||
a minus sign that it does not recognize itself; that argument and all subsequent
|
||||
arguments are passed as arguments to the test binary.
|
||||
|
||||
For more about build flags, see 'go help build'.
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
See also: go build, go vet.
|
||||
`,
|
||||
}
|
||||
|
||||
const testFlag1 = `
|
||||
In addition to the build flags, the flags handled by 'go test' itself are:
|
||||
|
||||
-c
|
||||
|
@ -83,21 +100,9 @@ In addition to the build flags, the flags handled by 'go test' itself are:
|
|||
Compile the test binary to the named file.
|
||||
The test still runs (unless -c or -i is specified).
|
||||
|
||||
|
||||
The test binary also accepts flags that control execution of the test; these
|
||||
flags are also accessible by 'go test'. See 'go help testflag' for details.
|
||||
|
||||
If the test binary needs any other flags, they should be presented after the
|
||||
package names. The go tool treats as a flag the first argument that begins with
|
||||
a minus sign that it does not recognize itself; that argument and all subsequent
|
||||
arguments are passed as arguments to the test binary.
|
||||
|
||||
For more about build flags, see 'go help build'.
|
||||
For more about specifying packages, see 'go help packages'.
|
||||
|
||||
See also: go build, go vet.
|
||||
`,
|
||||
}
|
||||
flags are also accessible by 'go test'.
|
||||
`
|
||||
|
||||
var helpTestflag = &Command{
|
||||
UsageLine: "testflag",
|
||||
|
@ -107,13 +112,18 @@ The 'go test' command takes both flags that apply to 'go test' itself
|
|||
and flags that apply to the resulting test binary.
|
||||
|
||||
Several of the flags control profiling and write an execution profile
|
||||
suitable for "go tool pprof"; run "go tool pprof help" for more
|
||||
suitable for "go tool pprof"; run "go tool pprof -h" for more
|
||||
information. The --alloc_space, --alloc_objects, and --show_bytes
|
||||
options of pprof control how the information is presented.
|
||||
|
||||
The following flags are recognized by the 'go test' command and
|
||||
control the execution of any test:
|
||||
|
||||
` + strings.TrimSpace(testFlag2) + `
|
||||
`,
|
||||
}
|
||||
|
||||
const testFlag2 = `
|
||||
-bench regexp
|
||||
Run benchmarks matching the regular expression.
|
||||
By default, no benchmarks run. To run all benchmarks,
|
||||
|
@ -135,12 +145,17 @@ control the execution of any test:
|
|||
-blockprofilerate n
|
||||
Control the detail provided in goroutine blocking profiles by
|
||||
calling runtime.SetBlockProfileRate with n.
|
||||
See 'godoc runtime SetBlockProfileRate'.
|
||||
See 'go doc runtime.SetBlockProfileRate'.
|
||||
The profiler aims to sample, on average, one blocking event every
|
||||
n nanoseconds the program spends blocked. By default,
|
||||
if -test.blockprofile is set without this flag, all blocking events
|
||||
are recorded, equivalent to -test.blockprofilerate=1.
|
||||
|
||||
-count n
|
||||
Run each test and benchmark n times (default 1).
|
||||
If -cpu is set, run n times for each GOMAXPROCS value.
|
||||
Examples are always run once.
|
||||
|
||||
-cover
|
||||
Enable coverage analysis.
|
||||
|
||||
|
@ -180,7 +195,7 @@ control the execution of any test:
|
|||
|
||||
-memprofilerate n
|
||||
Enable more precise (and expensive) memory profiles by setting
|
||||
runtime.MemProfileRate. See 'godoc runtime MemProfileRate'.
|
||||
runtime.MemProfileRate. See 'go doc runtime.MemProfileRate'.
|
||||
To profile all memory allocations, use -test.memprofilerate=1
|
||||
and pass --alloc_space flag to the pprof tool.
|
||||
|
||||
|
@ -205,6 +220,11 @@ control the execution of any test:
|
|||
|
||||
-timeout t
|
||||
If a test runs longer than t, panic.
|
||||
The default is 10 minutes (10m).
|
||||
|
||||
-trace trace.out
|
||||
Write an execution trace to the specified file before exiting.
|
||||
Writes test binary as -c would.
|
||||
|
||||
-v
|
||||
Verbose output: log all tests as they are run. Also print all
|
||||
|
@ -229,8 +249,7 @@ The test flags that generate profiles (other than for coverage) also
|
|||
leave the test binary in pkg.test for use when analyzing the profiles.
|
||||
|
||||
Flags not recognized by 'go test' must be placed after any specified packages.
|
||||
`,
|
||||
}
|
||||
`
|
||||
|
||||
var helpTestfunc = &Command{
|
||||
UsageLine: "testfunc",
|
||||
|
@ -310,6 +329,7 @@ func runTest(cmd *Command, args []string) {
|
|||
findExecCmd() // initialize cached result
|
||||
|
||||
raceInit()
|
||||
buildModeInit()
|
||||
pkgs := packagesForBuild(pkgArgs)
|
||||
if len(pkgs) == 0 {
|
||||
fatalf("no packages to test")
|
||||
|
@ -342,11 +362,11 @@ func runTest(cmd *Command, args []string) {
|
|||
// been given on the command line (implicit current directory)
|
||||
// or when benchmarking.
|
||||
// Also stream if we're showing output anyway with a
|
||||
// single package under test. In that case, streaming the
|
||||
// output produces the same result as not streaming,
|
||||
// just more immediately.
|
||||
// single package under test or if parallelism is set to 1.
|
||||
// In these cases, streaming the output produces the same result
|
||||
// as not streaming, just more immediately.
|
||||
testStreamOutput = len(pkgArgs) == 0 || testBench ||
|
||||
(len(pkgs) <= 1 && testShowPass)
|
||||
(testShowPass && (len(pkgs) == 1 || buildP == 1))
|
||||
|
||||
var b builder
|
||||
b.init()
|
||||
|
@ -364,10 +384,10 @@ func runTest(cmd *Command, args []string) {
|
|||
for _, path := range p.Imports {
|
||||
deps[path] = true
|
||||
}
|
||||
for _, path := range p.TestImports {
|
||||
for _, path := range p.vendored(p.TestImports) {
|
||||
deps[path] = true
|
||||
}
|
||||
for _, path := range p.XTestImports {
|
||||
for _, path := range p.vendored(p.XTestImports) {
|
||||
deps[path] = true
|
||||
}
|
||||
}
|
||||
|
@ -376,7 +396,7 @@ func runTest(cmd *Command, args []string) {
|
|||
if deps["C"] {
|
||||
delete(deps, "C")
|
||||
deps["runtime/cgo"] = true
|
||||
if buildContext.GOOS == runtime.GOOS && buildContext.GOARCH == runtime.GOARCH {
|
||||
if goos == runtime.GOOS && goarch == runtime.GOARCH && !buildRace {
|
||||
deps["cmd/cgo"] = true
|
||||
}
|
||||
}
|
||||
|
@ -428,6 +448,10 @@ func runTest(cmd *Command, args []string) {
|
|||
|
||||
// Mark all the coverage packages for rebuilding with coverage.
|
||||
for _, p := range testCoverPkgs {
|
||||
// There is nothing to cover in package unsafe; it comes from the compiler.
|
||||
if p.ImportPath == "unsafe" {
|
||||
continue
|
||||
}
|
||||
p.Stale = true // rebuild
|
||||
p.fake = true // do not warn about rebuild
|
||||
p.coverMode = testCoverMode
|
||||
|
@ -562,15 +586,20 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
|
|||
var imports, ximports []*Package
|
||||
var stk importStack
|
||||
stk.push(p.ImportPath + " (test)")
|
||||
for _, path := range p.TestImports {
|
||||
p1 := loadImport(path, p.Dir, &stk, p.build.TestImportPos[path])
|
||||
for i, path := range p.TestImports {
|
||||
p1 := loadImport(path, p.Dir, p, &stk, p.build.TestImportPos[path], useVendor)
|
||||
if !reqStdPkgSrc && p1.Standard {
|
||||
continue
|
||||
}
|
||||
if p1.Error != nil {
|
||||
return nil, nil, nil, p1.Error
|
||||
}
|
||||
if contains(p1.Deps, p.ImportPath) {
|
||||
if len(p1.DepsErrors) > 0 {
|
||||
err := p1.DepsErrors[0]
|
||||
err.Pos = "" // show full import stack
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if contains(p1.Deps, p.ImportPath) || p1.ImportPath == p.ImportPath {
|
||||
// Same error that loadPackage returns (via reusePackage) in pkg.go.
|
||||
// Can't change that code, because that code is only for loading the
|
||||
// non-test copy of a package.
|
||||
|
@ -581,24 +610,31 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
|
|||
}
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
p.TestImports[i] = p1.ImportPath
|
||||
imports = append(imports, p1)
|
||||
}
|
||||
stk.pop()
|
||||
stk.push(p.ImportPath + "_test")
|
||||
pxtestNeedsPtest := false
|
||||
for _, path := range p.XTestImports {
|
||||
if path == p.ImportPath {
|
||||
pxtestNeedsPtest = true
|
||||
continue
|
||||
}
|
||||
p1 := loadImport(path, p.Dir, &stk, p.build.XTestImportPos[path])
|
||||
for i, path := range p.XTestImports {
|
||||
p1 := loadImport(path, p.Dir, p, &stk, p.build.XTestImportPos[path], useVendor)
|
||||
if !reqStdPkgSrc && p1.Standard {
|
||||
continue
|
||||
}
|
||||
if p1.Error != nil {
|
||||
return nil, nil, nil, p1.Error
|
||||
}
|
||||
ximports = append(ximports, p1)
|
||||
if len(p1.DepsErrors) > 0 {
|
||||
err := p1.DepsErrors[0]
|
||||
err.Pos = "" // show full import stack
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
if p1.ImportPath == p.ImportPath {
|
||||
pxtestNeedsPtest = true
|
||||
} else {
|
||||
ximports = append(ximports, p1)
|
||||
}
|
||||
p.XTestImports[i] = p1.ImportPath
|
||||
}
|
||||
stk.pop()
|
||||
|
||||
|
@ -723,7 +759,7 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
|
|||
if dep == ptest.ImportPath {
|
||||
pmain.imports = append(pmain.imports, ptest)
|
||||
} else {
|
||||
p1 := loadImport(dep, "", &stk, nil)
|
||||
p1 := loadImport(dep, "", nil, &stk, nil, 0)
|
||||
if !reqStdPkgSrc && p1.Standard {
|
||||
continue
|
||||
}
|
||||
|
@ -781,6 +817,12 @@ func (b *builder) test(p *Package) (buildAction, runAction, printAction *action,
|
|||
recompileForTest(pmain, p, ptest, testDir)
|
||||
}
|
||||
|
||||
if buildContext.GOOS == "darwin" {
|
||||
if buildContext.GOARCH == "arm" || buildContext.GOARCH == "arm64" {
|
||||
t.NeedCgo = true
|
||||
}
|
||||
}
|
||||
|
||||
for _, cp := range pmain.imports {
|
||||
if len(cp.coverVars) > 0 {
|
||||
t.Cover = append(t.Cover, coverInfo{cp, cp.coverVars})
|
||||
|
@ -997,7 +1039,7 @@ func (b *builder) runTest(a *action) error {
|
|||
|
||||
cmd := exec.Command(args[0], args[1:]...)
|
||||
cmd.Dir = a.p.Dir
|
||||
cmd.Env = envForDir(cmd.Dir)
|
||||
cmd.Env = envForDir(cmd.Dir, origEnv)
|
||||
var buf bytes.Buffer
|
||||
if testStreamOutput {
|
||||
cmd.Stdout = os.Stdout
|
||||
|
@ -1216,6 +1258,7 @@ type testFuncs struct {
|
|||
NeedTest bool
|
||||
ImportXtest bool
|
||||
NeedXtest bool
|
||||
NeedCgo bool
|
||||
Cover []coverInfo
|
||||
}
|
||||
|
||||
|
@ -1319,6 +1362,10 @@ import (
|
|||
{{range $i, $p := .Cover}}
|
||||
_cover{{$i}} {{$p.Package.ImportPath | printf "%q"}}
|
||||
{{end}}
|
||||
|
||||
{{if .NeedCgo}}
|
||||
_ "runtime/cgo"
|
||||
{{end}}
|
||||
)
|
||||
|
||||
var tests = []testing.InternalTest{
|
||||
|
|
2
libgo/go/cmd/go/testdata/generate/test3.go
vendored
2
libgo/go/cmd/go/testdata/generate/test3.go
vendored
|
@ -4,6 +4,6 @@
|
|||
|
||||
// Test go generate variable substitution.
|
||||
|
||||
//go:generate echo $GOARCH $GOFILE $GOPACKAGE xyz$GOPACKAGE/$GOFILE/123
|
||||
//go:generate echo $GOARCH $GOFILE:$GOLINE ${GOPACKAGE}abc xyz$GOPACKAGE/$GOFILE/123
|
||||
|
||||
package p
|
||||
|
|
10
libgo/go/cmd/go/testdata/generate/test4.go
vendored
Normal file
10
libgo/go/cmd/go/testdata/generate/test4.go
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
// Copyright 2015 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Test -run flag
|
||||
|
||||
//go:generate echo oh yes my man
|
||||
//go:generate echo no, no, a thousand times no
|
||||
|
||||
package p
|
1
libgo/go/cmd/go/testdata/rundir/sub/sub.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/rundir/sub/sub.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package main
|
1
libgo/go/cmd/go/testdata/rundir/x.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/rundir/x.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package main
|
1
libgo/go/cmd/go/testdata/src/testcycle/q1/q1.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/src/testcycle/q1/q1.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package q1
|
6
libgo/go/cmd/go/testdata/src/testcycle/q1/q1_test.go
vendored
Normal file
6
libgo/go/cmd/go/testdata/src/testcycle/q1/q1_test.go
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
package q1
|
||||
|
||||
import "testing"
|
||||
import _ "testcycle/q1"
|
||||
|
||||
func Test(t *testing.T) {}
|
1
libgo/go/cmd/go/testdata/src/testdep/p1/p1.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/src/testdep/p1/p1.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package p1
|
3
libgo/go/cmd/go/testdata/src/testdep/p1/p1_test.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/testdep/p1/p1_test.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package p1
|
||||
|
||||
import _ "testdep/p2"
|
3
libgo/go/cmd/go/testdata/src/testdep/p2/p2.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/testdep/p2/p2.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package p2
|
||||
|
||||
import _ "testdep/p3"
|
3
libgo/go/cmd/go/testdata/src/testdep/p3/p3.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/testdep/p3/p3.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
// +build ignore
|
||||
|
||||
package ignored
|
3
libgo/go/cmd/go/testdata/src/vend/bad.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/vend/bad.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package vend
|
||||
|
||||
import _ "r"
|
3
libgo/go/cmd/go/testdata/src/vend/good.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/vend/good.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package vend
|
||||
|
||||
import _ "p"
|
10
libgo/go/cmd/go/testdata/src/vend/hello/hello.go
vendored
Normal file
10
libgo/go/cmd/go/testdata/src/vend/hello/hello.go
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings" // really ../vendor/strings
|
||||
)
|
||||
|
||||
func main() {
|
||||
fmt.Printf("%s\n", strings.Msg)
|
||||
}
|
12
libgo/go/cmd/go/testdata/src/vend/hello/hello_test.go
vendored
Normal file
12
libgo/go/cmd/go/testdata/src/vend/hello/hello_test.go
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"strings" // really ../vendor/strings
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMsgInternal(t *testing.T) {
|
||||
if strings.Msg != "hello, world" {
|
||||
t.Fatal("unexpected msg: %v", strings.Msg)
|
||||
}
|
||||
}
|
12
libgo/go/cmd/go/testdata/src/vend/hello/hellox_test.go
vendored
Normal file
12
libgo/go/cmd/go/testdata/src/vend/hello/hellox_test.go
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
package main_test
|
||||
|
||||
import (
|
||||
"strings" // really ../vendor/strings
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestMsgExternal(t *testing.T) {
|
||||
if strings.Msg != "hello, world" {
|
||||
t.Fatal("unexpected msg: %v", strings.Msg)
|
||||
}
|
||||
}
|
3
libgo/go/cmd/go/testdata/src/vend/subdir/bad.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/vend/subdir/bad.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package subdir
|
||||
|
||||
import _ "r"
|
3
libgo/go/cmd/go/testdata/src/vend/subdir/good.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/vend/subdir/good.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package subdir
|
||||
|
||||
import _ "p"
|
1
libgo/go/cmd/go/testdata/src/vend/vendor/p/p.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/src/vend/vendor/p/p.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package p
|
1
libgo/go/cmd/go/testdata/src/vend/vendor/q/q.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/src/vend/vendor/q/q.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package q
|
3
libgo/go/cmd/go/testdata/src/vend/vendor/strings/msg.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/vend/vendor/strings/msg.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package strings
|
||||
|
||||
var Msg = "hello, world"
|
3
libgo/go/cmd/go/testdata/src/vend/x/invalid/invalid.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/vend/x/invalid/invalid.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package invalid
|
||||
|
||||
import "vend/x/invalid/vendor/foo"
|
1
libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package p
|
3
libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p/p.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/src/vend/x/vendor/p/p/p.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package p
|
||||
|
||||
import _ "notfound"
|
1
libgo/go/cmd/go/testdata/src/vend/x/vendor/r/r.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/src/vend/x/vendor/r/r.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package r
|
5
libgo/go/cmd/go/testdata/src/vend/x/x.go
vendored
Normal file
5
libgo/go/cmd/go/testdata/src/vend/x/x.go
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
package x
|
||||
|
||||
import _ "p"
|
||||
import _ "q"
|
||||
import _ "r"
|
9
libgo/go/cmd/go/testdata/src/vetpkg/c.go
vendored
Normal file
9
libgo/go/cmd/go/testdata/src/vetpkg/c.go
vendored
Normal file
|
@ -0,0 +1,9 @@
|
|||
// +build tagtest
|
||||
|
||||
package p
|
||||
|
||||
import "fmt"
|
||||
|
||||
func g() {
|
||||
fmt.Printf("%d", 3, 4)
|
||||
}
|
3
libgo/go/cmd/go/testdata/testinternal3/t.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/testinternal3/t.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package t
|
||||
|
||||
import _ "internal/does-not-exist"
|
6
libgo/go/cmd/go/testdata/testinternal4/src/p/p.go
vendored
Normal file
6
libgo/go/cmd/go/testdata/testinternal4/src/p/p.go
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
package p
|
||||
|
||||
import (
|
||||
_ "q/internal/x"
|
||||
_ "q/j"
|
||||
)
|
1
libgo/go/cmd/go/testdata/testinternal4/src/q/internal/x/x.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/testinternal4/src/q/internal/x/x.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package x
|
3
libgo/go/cmd/go/testdata/testinternal4/src/q/j/j.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/testinternal4/src/q/j/j.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package j
|
||||
|
||||
import _ "q/internal/x"
|
6
libgo/go/cmd/go/testdata/testvendor/src/p/p.go
vendored
Normal file
6
libgo/go/cmd/go/testdata/testvendor/src/p/p.go
vendored
Normal file
|
@ -0,0 +1,6 @@
|
|||
package p
|
||||
|
||||
import (
|
||||
_ "q/y"
|
||||
_ "q/z"
|
||||
)
|
1
libgo/go/cmd/go/testdata/testvendor/src/q/vendor/x/x.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/testvendor/src/q/vendor/x/x.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package x
|
3
libgo/go/cmd/go/testdata/testvendor/src/q/y/y.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/testvendor/src/q/y/y.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package y
|
||||
|
||||
import _ "x"
|
3
libgo/go/cmd/go/testdata/testvendor/src/q/z/z.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/testvendor/src/q/z/z.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package z
|
||||
|
||||
import _ "q/vendor/x"
|
3
libgo/go/cmd/go/testdata/testvendor2/src/p/p.go
vendored
Normal file
3
libgo/go/cmd/go/testdata/testvendor2/src/p/p.go
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
package p
|
||||
|
||||
import "x"
|
1
libgo/go/cmd/go/testdata/testvendor2/vendor/x/x.go
vendored
Normal file
1
libgo/go/cmd/go/testdata/testvendor2/vendor/x/x.go
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
package x
|
|
@ -5,6 +5,7 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
|
@ -16,46 +17,11 @@ import (
|
|||
// our command line are for us, and some are for 6.out, and
|
||||
// some are for both.
|
||||
|
||||
var usageMessage = `Usage of go test:
|
||||
-c=false: compile but do not run the test binary
|
||||
-file=file_test.go: specify file to use for tests;
|
||||
use multiple times for multiple files
|
||||
-p=n: build and test up to n packages in parallel
|
||||
-x=false: print command lines as they are executed
|
||||
|
||||
// These flags can be passed with or without a "test." prefix: -v or -test.v.
|
||||
-bench="": passes -test.bench to test
|
||||
-benchmem=false: print memory allocation statistics for benchmarks
|
||||
-benchtime=1s: passes -test.benchtime to test
|
||||
-cover=false: enable coverage analysis
|
||||
-covermode="set": specifies mode for coverage analysis
|
||||
-coverpkg="": comma-separated list of packages for coverage analysis
|
||||
-coverprofile="": passes -test.coverprofile to test if -cover
|
||||
-cpu="": passes -test.cpu to test
|
||||
-cpuprofile="": passes -test.cpuprofile to test
|
||||
-memprofile="": passes -test.memprofile to test
|
||||
-memprofilerate=0: passes -test.memprofilerate to test
|
||||
-blockprofile="": pases -test.blockprofile to test
|
||||
-blockprofilerate=0: passes -test.blockprofilerate to test
|
||||
-outputdir=$PWD: passes -test.outputdir to test
|
||||
-parallel=0: passes -test.parallel to test
|
||||
-run="": passes -test.run to test
|
||||
-short=false: passes -test.short to test
|
||||
-timeout=0: passes -test.timeout to test
|
||||
-v=false: passes -test.v to test
|
||||
`
|
||||
|
||||
// usage prints a usage message and exits.
|
||||
func testUsage() {
|
||||
fmt.Fprint(os.Stderr, usageMessage)
|
||||
setExitStatus(2)
|
||||
exit()
|
||||
}
|
||||
|
||||
// testFlagSpec defines a flag we know about.
|
||||
type testFlagSpec struct {
|
||||
name string
|
||||
boolVar *bool
|
||||
flagValue flag.Value
|
||||
passToTest bool // pass to Test
|
||||
multiOK bool // OK to have multiple instances
|
||||
present bool // flag has been seen
|
||||
|
@ -65,32 +31,18 @@ type testFlagSpec struct {
|
|||
var testFlagDefn = []*testFlagSpec{
|
||||
// local.
|
||||
{name: "c", boolVar: &testC},
|
||||
{name: "cover", boolVar: &testCover},
|
||||
{name: "coverpkg"},
|
||||
{name: "o"},
|
||||
|
||||
// build flags.
|
||||
{name: "a", boolVar: &buildA},
|
||||
{name: "n", boolVar: &buildN},
|
||||
{name: "p"},
|
||||
{name: "x", boolVar: &buildX},
|
||||
{name: "i", boolVar: &buildI},
|
||||
{name: "work", boolVar: &buildWork},
|
||||
{name: "ccflags"},
|
||||
{name: "gcflags"},
|
||||
{name: "o"},
|
||||
{name: "cover", boolVar: &testCover},
|
||||
{name: "covermode"},
|
||||
{name: "coverpkg"},
|
||||
{name: "exec"},
|
||||
{name: "ldflags"},
|
||||
{name: "gccgoflags"},
|
||||
{name: "tags"},
|
||||
{name: "compiler"},
|
||||
{name: "race", boolVar: &buildRace},
|
||||
{name: "installsuffix"},
|
||||
|
||||
// passed to 6.out, adding a "test." prefix to the name if necessary: -v becomes -test.v.
|
||||
{name: "bench", passToTest: true},
|
||||
{name: "benchmem", boolVar: new(bool), passToTest: true},
|
||||
{name: "benchtime", passToTest: true},
|
||||
{name: "covermode"},
|
||||
{name: "count", passToTest: true},
|
||||
{name: "coverprofile", passToTest: true},
|
||||
{name: "cpu", passToTest: true},
|
||||
{name: "cpuprofile", passToTest: true},
|
||||
|
@ -103,9 +55,26 @@ var testFlagDefn = []*testFlagSpec{
|
|||
{name: "run", passToTest: true},
|
||||
{name: "short", boolVar: new(bool), passToTest: true},
|
||||
{name: "timeout", passToTest: true},
|
||||
{name: "trace", passToTest: true},
|
||||
{name: "v", boolVar: &testV, passToTest: true},
|
||||
}
|
||||
|
||||
// add build flags to testFlagDefn
|
||||
func init() {
|
||||
var cmd Command
|
||||
addBuildFlags(&cmd)
|
||||
cmd.Flag.VisitAll(func(f *flag.Flag) {
|
||||
if f.Name == "v" {
|
||||
// test overrides the build -v flag
|
||||
return
|
||||
}
|
||||
testFlagDefn = append(testFlagDefn, &testFlagSpec{
|
||||
name: f.Name,
|
||||
flagValue: f.Value,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// testFlags processes the command line, grabbing -x and -c, rewriting known flags
|
||||
// to have "test" before them, and reading the command line for the 6.out.
|
||||
// Unfortunately for us, we need to do our own flag processing because go test
|
||||
|
@ -148,73 +117,55 @@ func testFlags(args []string) (packageNames, passToTest []string) {
|
|||
passToTest = append(passToTest, args[i])
|
||||
continue
|
||||
}
|
||||
var err error
|
||||
switch f.name {
|
||||
// bool flags.
|
||||
case "a", "c", "i", "n", "x", "v", "race", "cover", "work":
|
||||
setBoolFlag(f.boolVar, value)
|
||||
case "o":
|
||||
testO = value
|
||||
testNeedBinary = true
|
||||
case "p":
|
||||
setIntFlag(&buildP, value)
|
||||
case "exec":
|
||||
execCmd, err = splitQuotedFields(value)
|
||||
if err != nil {
|
||||
if f.flagValue != nil {
|
||||
if err := f.flagValue.Set(value); err != nil {
|
||||
fatalf("invalid flag argument for -%s: %v", f.name, err)
|
||||
}
|
||||
case "ccflags":
|
||||
buildCcflags, err = splitQuotedFields(value)
|
||||
if err != nil {
|
||||
fatalf("invalid flag argument for -%s: %v", f.name, err)
|
||||
} else {
|
||||
// Test-only flags.
|
||||
// Arguably should be handled by f.flagValue, but aren't.
|
||||
var err error
|
||||
switch f.name {
|
||||
// bool flags.
|
||||
case "c", "i", "v", "cover":
|
||||
setBoolFlag(f.boolVar, value)
|
||||
case "o":
|
||||
testO = value
|
||||
testNeedBinary = true
|
||||
case "exec":
|
||||
execCmd, err = splitQuotedFields(value)
|
||||
if err != nil {
|
||||
fatalf("invalid flag argument for -%s: %v", f.name, err)
|
||||
}
|
||||
case "bench":
|
||||
// record that we saw the flag; don't care about the value
|
||||
testBench = true
|
||||
case "timeout":
|
||||
testTimeout = value
|
||||
case "blockprofile", "cpuprofile", "memprofile", "trace":
|
||||
testProfile = true
|
||||
testNeedBinary = true
|
||||
case "coverpkg":
|
||||
testCover = true
|
||||
if value == "" {
|
||||
testCoverPaths = nil
|
||||
} else {
|
||||
testCoverPaths = strings.Split(value, ",")
|
||||
}
|
||||
case "coverprofile":
|
||||
testCover = true
|
||||
testProfile = true
|
||||
case "covermode":
|
||||
switch value {
|
||||
case "set", "count", "atomic":
|
||||
testCoverMode = value
|
||||
default:
|
||||
fatalf("invalid flag argument for -covermode: %q", value)
|
||||
}
|
||||
testCover = true
|
||||
case "outputdir":
|
||||
outputDir = value
|
||||
}
|
||||
case "gcflags":
|
||||
buildGcflags, err = splitQuotedFields(value)
|
||||
if err != nil {
|
||||
fatalf("invalid flag argument for -%s: %v", f.name, err)
|
||||
}
|
||||
case "ldflags":
|
||||
buildLdflags, err = splitQuotedFields(value)
|
||||
if err != nil {
|
||||
fatalf("invalid flag argument for -%s: %v", f.name, err)
|
||||
}
|
||||
case "gccgoflags":
|
||||
buildGccgoflags, err = splitQuotedFields(value)
|
||||
if err != nil {
|
||||
fatalf("invalid flag argument for -%s: %v", f.name, err)
|
||||
}
|
||||
case "tags":
|
||||
buildContext.BuildTags = strings.Fields(value)
|
||||
case "compiler":
|
||||
buildCompiler{}.Set(value)
|
||||
case "bench":
|
||||
// record that we saw the flag; don't care about the value
|
||||
testBench = true
|
||||
case "timeout":
|
||||
testTimeout = value
|
||||
case "blockprofile", "cpuprofile", "memprofile":
|
||||
testProfile = true
|
||||
testNeedBinary = true
|
||||
case "coverpkg":
|
||||
testCover = true
|
||||
if value == "" {
|
||||
testCoverPaths = nil
|
||||
} else {
|
||||
testCoverPaths = strings.Split(value, ",")
|
||||
}
|
||||
case "coverprofile":
|
||||
testCover = true
|
||||
testProfile = true
|
||||
case "covermode":
|
||||
switch value {
|
||||
case "set", "count", "atomic":
|
||||
testCoverMode = value
|
||||
default:
|
||||
fatalf("invalid flag argument for -cover: %q", value)
|
||||
}
|
||||
testCover = true
|
||||
case "outputdir":
|
||||
outputDir = value
|
||||
}
|
||||
if extraWord {
|
||||
i++
|
||||
|
@ -267,7 +218,7 @@ func testFlag(args []string, i int) (f *testFlagSpec, value string, extra bool)
|
|||
for _, f = range testFlagDefn {
|
||||
if name == f.name {
|
||||
// Booleans are special because they have modes -x, -x=true, -x=false.
|
||||
if f.boolVar != nil {
|
||||
if f.boolVar != nil || isBoolFlag(f.flagValue) {
|
||||
if equals < 0 { // otherwise, it's been set and will be verified in setBoolFlag
|
||||
value = "true"
|
||||
} else {
|
||||
|
@ -294,6 +245,17 @@ func testFlag(args []string, i int) (f *testFlagSpec, value string, extra bool)
|
|||
return
|
||||
}
|
||||
|
||||
// isBoolFlag reports whether v is a bool flag.
|
||||
func isBoolFlag(v flag.Value) bool {
|
||||
vv, ok := v.(interface {
|
||||
IsBoolFlag() bool
|
||||
})
|
||||
if ok {
|
||||
return vv.IsBoolFlag()
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// setBoolFlag sets the addressed boolean to the value.
|
||||
func setBoolFlag(flag *bool, value string) {
|
||||
x, err := strconv.ParseBool(value)
|
||||
|
|
|
@ -50,6 +50,9 @@ func tool(toolName string) string {
|
|||
if toolIsWindows {
|
||||
toolPath += toolWindowsExtension
|
||||
}
|
||||
if len(buildToolExec) > 0 {
|
||||
return toolPath
|
||||
}
|
||||
// Give a nice message if there is no tool with that name.
|
||||
if _, err := os.Stat(toolPath); err != nil {
|
||||
if isInGoToolsRepo(toolName) {
|
||||
|
@ -64,10 +67,6 @@ func tool(toolName string) string {
|
|||
}
|
||||
|
||||
func isInGoToolsRepo(toolName string) bool {
|
||||
switch toolName {
|
||||
case "cover", "vet":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
|
@ -92,7 +91,11 @@ func runTool(cmd *Command, args []string) {
|
|||
return
|
||||
}
|
||||
if toolN {
|
||||
fmt.Printf("%s %s\n", toolPath, strings.Join(args[1:], " "))
|
||||
cmd := toolPath
|
||||
if len(args) > 1 {
|
||||
cmd += " " + strings.Join(args[1:], " ")
|
||||
}
|
||||
fmt.Printf("%s\n", cmd)
|
||||
return
|
||||
}
|
||||
toolCmd := &exec.Cmd{
|
||||
|
@ -101,6 +104,8 @@ func runTool(cmd *Command, args []string) {
|
|||
Stdin: os.Stdin,
|
||||
Stdout: os.Stdout,
|
||||
Stderr: os.Stderr,
|
||||
// Set $GOROOT, mainly for go tool dist.
|
||||
Env: mergeEnvLists([]string{"GOROOT=" + goroot}, os.Environ()),
|
||||
}
|
||||
err := toolCmd.Run()
|
||||
if err != nil {
|
||||
|
|
|
@ -9,12 +9,15 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"internal/singleflight"
|
||||
"log"
|
||||
"net/url"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// A vcsCmd describes how to use a version control system
|
||||
|
@ -23,13 +26,13 @@ type vcsCmd struct {
|
|||
name string
|
||||
cmd string // name of binary to invoke command
|
||||
|
||||
createCmd string // command to download a fresh copy of a repository
|
||||
downloadCmd string // command to download updates into an existing repository
|
||||
createCmd []string // commands to download a fresh copy of a repository
|
||||
downloadCmd []string // commands to download updates into an existing repository
|
||||
|
||||
tagCmd []tagCmd // commands to list tags
|
||||
tagLookupCmd []tagCmd // commands to lookup tags before running tagSyncCmd
|
||||
tagSyncCmd string // command to sync to specific tag
|
||||
tagSyncDefault string // command to sync to default tag
|
||||
tagSyncCmd []string // commands to sync to specific tag
|
||||
tagSyncDefault []string // commands to sync to default tag
|
||||
|
||||
scheme []string
|
||||
pingCmd string
|
||||
|
@ -38,6 +41,23 @@ type vcsCmd struct {
|
|||
resolveRepo func(v *vcsCmd, rootDir, remoteRepo string) (realRepo string, err error)
|
||||
}
|
||||
|
||||
var isSecureScheme = map[string]bool{
|
||||
"https": true,
|
||||
"git+ssh": true,
|
||||
"bzr+ssh": true,
|
||||
"svn+ssh": true,
|
||||
"ssh": true,
|
||||
}
|
||||
|
||||
func (v *vcsCmd) isSecure(repo string) bool {
|
||||
u, err := url.Parse(repo)
|
||||
if err != nil {
|
||||
// If repo is not a URL, it's not secure.
|
||||
return false
|
||||
}
|
||||
return isSecureScheme[u.Scheme]
|
||||
}
|
||||
|
||||
// A tagCmd describes a command to list available tags
|
||||
// that can be passed to tagSyncCmd.
|
||||
type tagCmd struct {
|
||||
|
@ -69,8 +89,8 @@ var vcsHg = &vcsCmd{
|
|||
name: "Mercurial",
|
||||
cmd: "hg",
|
||||
|
||||
createCmd: "clone -U {repo} {dir}",
|
||||
downloadCmd: "pull",
|
||||
createCmd: []string{"clone -U {repo} {dir}"},
|
||||
downloadCmd: []string{"pull"},
|
||||
|
||||
// We allow both tag and branch names as 'tags'
|
||||
// for selecting a version. This lets people have
|
||||
|
@ -81,8 +101,8 @@ var vcsHg = &vcsCmd{
|
|||
{"tags", `^(\S+)`},
|
||||
{"branches", `^(\S+)`},
|
||||
},
|
||||
tagSyncCmd: "update -r {tag}",
|
||||
tagSyncDefault: "update default",
|
||||
tagSyncCmd: []string{"update -r {tag}"},
|
||||
tagSyncDefault: []string{"update default"},
|
||||
|
||||
scheme: []string{"https", "http", "ssh"},
|
||||
pingCmd: "identify {scheme}://{repo}",
|
||||
|
@ -102,8 +122,8 @@ var vcsGit = &vcsCmd{
|
|||
name: "Git",
|
||||
cmd: "git",
|
||||
|
||||
createCmd: "clone {repo} {dir}",
|
||||
downloadCmd: "pull --ff-only",
|
||||
createCmd: []string{"clone {repo} {dir}", "--git-dir={dir}/.git submodule update --init --recursive"},
|
||||
downloadCmd: []string{"pull --ff-only", "submodule update --init --recursive"},
|
||||
|
||||
tagCmd: []tagCmd{
|
||||
// tags/xxx matches a git tag named xxx
|
||||
|
@ -113,41 +133,64 @@ var vcsGit = &vcsCmd{
|
|||
tagLookupCmd: []tagCmd{
|
||||
{"show-ref tags/{tag} origin/{tag}", `((?:tags|origin)/\S+)$`},
|
||||
},
|
||||
tagSyncCmd: "checkout {tag}",
|
||||
tagSyncDefault: "checkout master",
|
||||
tagSyncCmd: []string{"checkout {tag}", "submodule update --init --recursive"},
|
||||
// both createCmd and downloadCmd update the working dir.
|
||||
// No need to do more here. We used to 'checkout master'
|
||||
// but that doesn't work if the default branch is not named master.
|
||||
// See golang.org/issue/9032.
|
||||
tagSyncDefault: []string{"checkout master", "submodule update --init --recursive"},
|
||||
|
||||
scheme: []string{"git", "https", "http", "git+ssh"},
|
||||
scheme: []string{"git", "https", "http", "git+ssh", "ssh"},
|
||||
pingCmd: "ls-remote {scheme}://{repo}",
|
||||
remoteRepo: gitRemoteRepo,
|
||||
}
|
||||
|
||||
// scpSyntaxRe matches the SCP-like addresses used by Git to access
|
||||
// repositories by SSH.
|
||||
var scpSyntaxRe = regexp.MustCompile(`^([a-zA-Z0-9_]+)@([a-zA-Z0-9._-]+):(.*)$`)
|
||||
|
||||
func gitRemoteRepo(vcsGit *vcsCmd, rootDir string) (remoteRepo string, err error) {
|
||||
outb, err := vcsGit.runOutput(rootDir, "remote -v")
|
||||
cmd := "config remote.origin.url"
|
||||
errParse := errors.New("unable to parse output of git " + cmd)
|
||||
errRemoteOriginNotFound := errors.New("remote origin not found")
|
||||
outb, err := vcsGit.run1(rootDir, cmd, nil, false)
|
||||
if err != nil {
|
||||
// if it doesn't output any message, it means the config argument is correct,
|
||||
// but the config value itself doesn't exist
|
||||
if outb != nil && len(outb) == 0 {
|
||||
return "", errRemoteOriginNotFound
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
out := string(outb)
|
||||
out := strings.TrimSpace(string(outb))
|
||||
|
||||
// Expect:
|
||||
// origin https://github.com/rsc/pdf (fetch)
|
||||
// origin https://github.com/rsc/pdf (push)
|
||||
// use first line only.
|
||||
var repoURL *url.URL
|
||||
if m := scpSyntaxRe.FindStringSubmatch(out); m != nil {
|
||||
// Match SCP-like syntax and convert it to a URL.
|
||||
// Eg, "git@github.com:user/repo" becomes
|
||||
// "ssh://git@github.com/user/repo".
|
||||
repoURL = &url.URL{
|
||||
Scheme: "ssh",
|
||||
User: url.User(m[1]),
|
||||
Host: m[2],
|
||||
RawPath: m[3],
|
||||
}
|
||||
} else {
|
||||
repoURL, err = url.Parse(out)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if !strings.HasPrefix(out, "origin\t") {
|
||||
return "", fmt.Errorf("unable to parse output of git remote -v")
|
||||
// Iterate over insecure schemes too, because this function simply
|
||||
// reports the state of the repo. If we can't see insecure schemes then
|
||||
// we can't report the actual repo URL.
|
||||
for _, s := range vcsGit.scheme {
|
||||
if repoURL.Scheme == s {
|
||||
return repoURL.String(), nil
|
||||
}
|
||||
}
|
||||
out = strings.TrimPrefix(out, "origin\t")
|
||||
i := strings.Index(out, "\n")
|
||||
if i < 0 {
|
||||
return "", fmt.Errorf("unable to parse output of git remote -v")
|
||||
}
|
||||
out = out[:i]
|
||||
i = strings.LastIndex(out, " ")
|
||||
if i < 0 {
|
||||
return "", fmt.Errorf("unable to parse output of git remote -v")
|
||||
}
|
||||
out = out[:i]
|
||||
return strings.TrimSpace(string(out)), nil
|
||||
return "", errParse
|
||||
}
|
||||
|
||||
// vcsBzr describes how to use Bazaar.
|
||||
|
@ -155,15 +198,15 @@ var vcsBzr = &vcsCmd{
|
|||
name: "Bazaar",
|
||||
cmd: "bzr",
|
||||
|
||||
createCmd: "branch {repo} {dir}",
|
||||
createCmd: []string{"branch {repo} {dir}"},
|
||||
|
||||
// Without --overwrite bzr will not pull tags that changed.
|
||||
// Replace by --overwrite-tags after http://pad.lv/681792 goes in.
|
||||
downloadCmd: "pull --overwrite",
|
||||
downloadCmd: []string{"pull --overwrite"},
|
||||
|
||||
tagCmd: []tagCmd{{"tags", `^(\S+)`}},
|
||||
tagSyncCmd: "update -r {tag}",
|
||||
tagSyncDefault: "update -r revno:-1",
|
||||
tagSyncCmd: []string{"update -r {tag}"},
|
||||
tagSyncDefault: []string{"update -r revno:-1"},
|
||||
|
||||
scheme: []string{"https", "http", "bzr", "bzr+ssh"},
|
||||
pingCmd: "info {scheme}://{repo}",
|
||||
|
@ -217,8 +260,8 @@ var vcsSvn = &vcsCmd{
|
|||
name: "Subversion",
|
||||
cmd: "svn",
|
||||
|
||||
createCmd: "checkout {repo} {dir}",
|
||||
downloadCmd: "update",
|
||||
createCmd: []string{"checkout {repo} {dir}"},
|
||||
downloadCmd: []string{"update"},
|
||||
|
||||
// There is no tag command in subversion.
|
||||
// The branch information is all in the path names.
|
||||
|
@ -294,14 +337,14 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
|
|||
_, err := exec.LookPath(v.cmd)
|
||||
if err != nil {
|
||||
fmt.Fprintf(os.Stderr,
|
||||
"go: missing %s command. See http://golang.org/s/gogetcmd\n",
|
||||
"go: missing %s command. See https://golang.org/s/gogetcmd\n",
|
||||
v.name)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cmd := exec.Command(v.cmd, args...)
|
||||
cmd.Dir = dir
|
||||
cmd.Env = envForDir(cmd.Dir)
|
||||
cmd.Env = envForDir(cmd.Dir, os.Environ())
|
||||
if buildX {
|
||||
fmt.Printf("cd %s\n", dir)
|
||||
fmt.Printf("%s %s\n", v.cmd, strings.Join(args, " "))
|
||||
|
@ -316,7 +359,7 @@ func (v *vcsCmd) run1(dir string, cmdline string, keyval []string, verbose bool)
|
|||
fmt.Fprintf(os.Stderr, "# cd %s; %s %s\n", dir, v.cmd, strings.Join(args, " "))
|
||||
os.Stderr.Write(out)
|
||||
}
|
||||
return nil, err
|
||||
return out, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
@ -329,7 +372,15 @@ func (v *vcsCmd) ping(scheme, repo string) error {
|
|||
// create creates a new copy of repo in dir.
|
||||
// The parent of dir must exist; dir must not.
|
||||
func (v *vcsCmd) create(dir, repo string) error {
|
||||
return v.run(".", v.createCmd, "dir", dir, "repo", repo)
|
||||
for _, cmd := range v.createCmd {
|
||||
if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
|
||||
continue
|
||||
}
|
||||
if err := v.run(".", cmd, "dir", dir, "repo", repo); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// download downloads any new changes for the repo in dir.
|
||||
|
@ -337,7 +388,15 @@ func (v *vcsCmd) download(dir string) error {
|
|||
if err := v.fixDetachedHead(dir); err != nil {
|
||||
return err
|
||||
}
|
||||
return v.run(dir, v.downloadCmd)
|
||||
for _, cmd := range v.downloadCmd {
|
||||
if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
|
||||
continue
|
||||
}
|
||||
if err := v.run(dir, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// fixDetachedHead switches a Git repository in dir from a detached head to the master branch.
|
||||
|
@ -383,7 +442,7 @@ func (v *vcsCmd) tags(dir string) ([]string, error) {
|
|||
// tagSync syncs the repo in dir to the named tag,
|
||||
// which either is a tag returned by tags or is v.tagDefault.
|
||||
func (v *vcsCmd) tagSync(dir, tag string) error {
|
||||
if v.tagSyncCmd == "" {
|
||||
if v.tagSyncCmd == nil {
|
||||
return nil
|
||||
}
|
||||
if tag != "" {
|
||||
|
@ -400,10 +459,28 @@ func (v *vcsCmd) tagSync(dir, tag string) error {
|
|||
}
|
||||
}
|
||||
}
|
||||
if tag == "" && v.tagSyncDefault != "" {
|
||||
return v.run(dir, v.tagSyncDefault)
|
||||
|
||||
if tag == "" && v.tagSyncDefault != nil {
|
||||
for _, cmd := range v.tagSyncDefault {
|
||||
if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
|
||||
continue
|
||||
}
|
||||
if err := v.run(dir, cmd); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return v.run(dir, v.tagSyncCmd, "tag", tag)
|
||||
|
||||
for _, cmd := range v.tagSyncCmd {
|
||||
if !go15VendorExperiment && strings.Contains(cmd, "submodule") {
|
||||
continue
|
||||
}
|
||||
if err := v.run(dir, cmd, "tag", tag); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// A vcsPath describes how to convert an import path into a
|
||||
|
@ -467,10 +544,20 @@ type repoRoot struct {
|
|||
|
||||
var httpPrefixRE = regexp.MustCompile(`^https?:`)
|
||||
|
||||
// securityMode specifies whether a function should make network
|
||||
// calls using insecure transports (eg, plain text HTTP).
|
||||
// The zero value is "secure".
|
||||
type securityMode int
|
||||
|
||||
const (
|
||||
secure securityMode = iota
|
||||
insecure
|
||||
)
|
||||
|
||||
// repoRootForImportPath analyzes importPath to determine the
|
||||
// version control system, and code repository to use.
|
||||
func repoRootForImportPath(importPath string) (*repoRoot, error) {
|
||||
rr, err := repoRootForImportPathStatic(importPath, "")
|
||||
func repoRootForImportPath(importPath string, security securityMode) (*repoRoot, error) {
|
||||
rr, err := repoRootFromVCSPaths(importPath, "", security, vcsPaths)
|
||||
if err == errUnknownSite {
|
||||
// If there are wildcards, look up the thing before the wildcard,
|
||||
// hoping it applies to the wildcarded parts too.
|
||||
|
@ -479,7 +566,7 @@ func repoRootForImportPath(importPath string) (*repoRoot, error) {
|
|||
if i := strings.Index(lookup, "/.../"); i >= 0 {
|
||||
lookup = lookup[:i]
|
||||
}
|
||||
rr, err = repoRootForImportDynamic(lookup)
|
||||
rr, err = repoRootForImportDynamic(lookup, security)
|
||||
|
||||
// repoRootForImportDynamic returns error detail
|
||||
// that is irrelevant if the user didn't intend to use a
|
||||
|
@ -492,6 +579,13 @@ func repoRootForImportPath(importPath string) (*repoRoot, error) {
|
|||
err = fmt.Errorf("unrecognized import path %q", importPath)
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
rr1, err1 := repoRootFromVCSPaths(importPath, "", security, vcsPathsAfterDynamic)
|
||||
if err1 == nil {
|
||||
rr = rr1
|
||||
err = nil
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil && strings.Contains(importPath, "...") && strings.Contains(rr.root, "...") {
|
||||
// Do not allow wildcards in the repo root.
|
||||
|
@ -503,13 +597,10 @@ func repoRootForImportPath(importPath string) (*repoRoot, error) {
|
|||
|
||||
var errUnknownSite = errors.New("dynamic lookup required to find mapping")
|
||||
|
||||
// repoRootForImportPathStatic attempts to map importPath to a
|
||||
// repoRoot using the commonly-used VCS hosting sites in vcsPaths
|
||||
// (github.com/user/dir), or from a fully-qualified importPath already
|
||||
// containing its VCS type (foo.com/repo.git/dir)
|
||||
//
|
||||
// repoRootFromVCSPaths attempts to map importPath to a repoRoot
|
||||
// using the mappings defined in vcsPaths.
|
||||
// If scheme is non-empty, that scheme is forced.
|
||||
func repoRootForImportPathStatic(importPath, scheme string) (*repoRoot, error) {
|
||||
func repoRootFromVCSPaths(importPath, scheme string, security securityMode, vcsPaths []*vcsPath) (*repoRoot, error) {
|
||||
// A common error is to use https://packagepath because that's what
|
||||
// hg and git require. Diagnose this helpfully.
|
||||
if loc := httpPrefixRE.FindStringIndex(importPath); loc != nil {
|
||||
|
@ -559,6 +650,9 @@ func repoRootForImportPathStatic(importPath, scheme string) (*repoRoot, error) {
|
|||
match["repo"] = scheme + "://" + match["repo"]
|
||||
} else {
|
||||
for _, scheme := range vcs.scheme {
|
||||
if security == secure && !isSecureScheme[scheme] {
|
||||
continue
|
||||
}
|
||||
if vcs.ping(scheme, match["repo"]) == nil {
|
||||
match["repo"] = scheme + "://" + match["repo"]
|
||||
break
|
||||
|
@ -579,26 +673,31 @@ func repoRootForImportPathStatic(importPath, scheme string) (*repoRoot, error) {
|
|||
// repoRootForImportDynamic finds a *repoRoot for a custom domain that's not
|
||||
// statically known by repoRootForImportPathStatic.
|
||||
//
|
||||
// This handles "vanity import paths" like "name.tld/pkg/foo".
|
||||
func repoRootForImportDynamic(importPath string) (*repoRoot, error) {
|
||||
// This handles custom import paths like "name.tld/pkg/foo" or just "name.tld".
|
||||
func repoRootForImportDynamic(importPath string, security securityMode) (*repoRoot, error) {
|
||||
slash := strings.Index(importPath, "/")
|
||||
if slash < 0 {
|
||||
return nil, errors.New("import path does not contain a slash")
|
||||
slash = len(importPath)
|
||||
}
|
||||
host := importPath[:slash]
|
||||
if !strings.Contains(host, ".") {
|
||||
return nil, errors.New("import path does not begin with hostname")
|
||||
}
|
||||
urlStr, body, err := httpsOrHTTP(importPath)
|
||||
urlStr, body, err := httpsOrHTTP(importPath, security)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("http/https fetch: %v", err)
|
||||
msg := "https fetch: %v"
|
||||
if security == insecure {
|
||||
msg = "http/" + msg
|
||||
}
|
||||
return nil, fmt.Errorf(msg, err)
|
||||
}
|
||||
defer body.Close()
|
||||
imports, err := parseMetaGoImports(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing %s: %v", importPath, err)
|
||||
}
|
||||
metaImport, err := matchGoImport(imports, importPath)
|
||||
// Find the matched meta import.
|
||||
mmi, err := matchGoImport(imports, importPath)
|
||||
if err != nil {
|
||||
if err != errNoMatch {
|
||||
return nil, fmt.Errorf("parse %s: %v", urlStr, err)
|
||||
|
@ -606,7 +705,7 @@ func repoRootForImportDynamic(importPath string) (*repoRoot, error) {
|
|||
return nil, fmt.Errorf("parse %s: no go-import meta tags", urlStr)
|
||||
}
|
||||
if buildV {
|
||||
log.Printf("get %q: found meta tag %#v at %s", importPath, metaImport, urlStr)
|
||||
log.Printf("get %q: found meta tag %#v at %s", importPath, mmi, urlStr)
|
||||
}
|
||||
// If the import was "uni.edu/bob/project", which said the
|
||||
// prefix was "uni.edu" and the RepoRoot was "evilroot.com",
|
||||
|
@ -614,42 +713,89 @@ func repoRootForImportDynamic(importPath string) (*repoRoot, error) {
|
|||
// "uni.edu" yet (possibly overwriting/preempting another
|
||||
// non-evil student). Instead, first verify the root and see
|
||||
// if it matches Bob's claim.
|
||||
if metaImport.Prefix != importPath {
|
||||
if mmi.Prefix != importPath {
|
||||
if buildV {
|
||||
log.Printf("get %q: verifying non-authoritative meta tag", importPath)
|
||||
}
|
||||
urlStr0 := urlStr
|
||||
urlStr, body, err = httpsOrHTTP(metaImport.Prefix)
|
||||
var imports []metaImport
|
||||
urlStr, imports, err = metaImportsForPrefix(mmi.Prefix, security)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("fetch %s: %v", urlStr, err)
|
||||
}
|
||||
imports, err := parseMetaGoImports(body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parsing %s: %v", importPath, err)
|
||||
}
|
||||
if len(imports) == 0 {
|
||||
return nil, fmt.Errorf("fetch %s: no go-import meta tag", urlStr)
|
||||
return nil, err
|
||||
}
|
||||
metaImport2, err := matchGoImport(imports, importPath)
|
||||
if err != nil || metaImport != metaImport2 {
|
||||
return nil, fmt.Errorf("%s and %s disagree about go-import for %s", urlStr0, urlStr, metaImport.Prefix)
|
||||
if err != nil || mmi != metaImport2 {
|
||||
return nil, fmt.Errorf("%s and %s disagree about go-import for %s", urlStr0, urlStr, mmi.Prefix)
|
||||
}
|
||||
}
|
||||
|
||||
if !strings.Contains(metaImport.RepoRoot, "://") {
|
||||
return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, metaImport.RepoRoot)
|
||||
if !strings.Contains(mmi.RepoRoot, "://") {
|
||||
return nil, fmt.Errorf("%s: invalid repo root %q; no scheme", urlStr, mmi.RepoRoot)
|
||||
}
|
||||
rr := &repoRoot{
|
||||
vcs: vcsByCmd(metaImport.VCS),
|
||||
repo: metaImport.RepoRoot,
|
||||
root: metaImport.Prefix,
|
||||
vcs: vcsByCmd(mmi.VCS),
|
||||
repo: mmi.RepoRoot,
|
||||
root: mmi.Prefix,
|
||||
}
|
||||
if rr.vcs == nil {
|
||||
return nil, fmt.Errorf("%s: unknown vcs %q", urlStr, metaImport.VCS)
|
||||
return nil, fmt.Errorf("%s: unknown vcs %q", urlStr, mmi.VCS)
|
||||
}
|
||||
return rr, nil
|
||||
}
|
||||
|
||||
var fetchGroup singleflight.Group
|
||||
var (
|
||||
fetchCacheMu sync.Mutex
|
||||
fetchCache = map[string]fetchResult{} // key is metaImportsForPrefix's importPrefix
|
||||
)
|
||||
|
||||
// metaImportsForPrefix takes a package's root import path as declared in a <meta> tag
|
||||
// and returns its HTML discovery URL and the parsed metaImport lines
|
||||
// found on the page.
|
||||
//
|
||||
// The importPath is of the form "golang.org/x/tools".
|
||||
// It is an error if no imports are found.
|
||||
// urlStr will still be valid if err != nil.
|
||||
// The returned urlStr will be of the form "https://golang.org/x/tools?go-get=1"
|
||||
func metaImportsForPrefix(importPrefix string, security securityMode) (urlStr string, imports []metaImport, err error) {
|
||||
setCache := func(res fetchResult) (fetchResult, error) {
|
||||
fetchCacheMu.Lock()
|
||||
defer fetchCacheMu.Unlock()
|
||||
fetchCache[importPrefix] = res
|
||||
return res, nil
|
||||
}
|
||||
|
||||
resi, _, _ := fetchGroup.Do(importPrefix, func() (resi interface{}, err error) {
|
||||
fetchCacheMu.Lock()
|
||||
if res, ok := fetchCache[importPrefix]; ok {
|
||||
fetchCacheMu.Unlock()
|
||||
return res, nil
|
||||
}
|
||||
fetchCacheMu.Unlock()
|
||||
|
||||
urlStr, body, err := httpsOrHTTP(importPrefix, security)
|
||||
if err != nil {
|
||||
return setCache(fetchResult{urlStr: urlStr, err: fmt.Errorf("fetch %s: %v", urlStr, err)})
|
||||
}
|
||||
imports, err := parseMetaGoImports(body)
|
||||
if err != nil {
|
||||
return setCache(fetchResult{urlStr: urlStr, err: fmt.Errorf("parsing %s: %v", urlStr, err)})
|
||||
}
|
||||
if len(imports) == 0 {
|
||||
err = fmt.Errorf("fetch %s: no go-import meta tag", urlStr)
|
||||
}
|
||||
return setCache(fetchResult{urlStr: urlStr, imports: imports, err: err})
|
||||
})
|
||||
res := resi.(fetchResult)
|
||||
return res.urlStr, res.imports, res.err
|
||||
}
|
||||
|
||||
type fetchResult struct {
|
||||
urlStr string // e.g. "https://foo.com/x/bar?go-get=1"
|
||||
imports []metaImport
|
||||
err error
|
||||
}
|
||||
|
||||
// metaImport represents the parsed <meta name="go-import"
|
||||
// content="prefix vcs reporoot" /> tags from HTML files.
|
||||
type metaImport struct {
|
||||
|
@ -689,7 +835,10 @@ func expand(match map[string]string, s string) string {
|
|||
return s
|
||||
}
|
||||
|
||||
// vcsPaths lists the known vcs paths.
|
||||
// vcsPaths defines the meaning of import paths referring to
|
||||
// commonly-used VCS hosting sites (github.com/user/dir)
|
||||
// and import paths referring to a fully-qualified importPath
|
||||
// containing a VCS type (foo.com/repo.git/dir)
|
||||
var vcsPaths = []*vcsPath{
|
||||
// Google Code - new syntax
|
||||
{
|
||||
|
@ -722,15 +871,6 @@ var vcsPaths = []*vcsPath{
|
|||
check: bitbucketVCS,
|
||||
},
|
||||
|
||||
// Launchpad
|
||||
{
|
||||
prefix: "launchpad.net/",
|
||||
re: `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
|
||||
vcs: "bzr",
|
||||
repo: "https://{root}",
|
||||
check: launchpadVCS,
|
||||
},
|
||||
|
||||
// IBM DevOps Services (JazzHub)
|
||||
{
|
||||
prefix: "hub.jazz.net/git",
|
||||
|
@ -740,13 +880,37 @@ var vcsPaths = []*vcsPath{
|
|||
check: noVCSSuffix,
|
||||
},
|
||||
|
||||
// Git at Apache
|
||||
{
|
||||
prefix: "git.apache.org",
|
||||
re: `^(?P<root>git.apache.org/[a-z0-9_.\-]+\.git)(/[A-Za-z0-9_.\-]+)*$`,
|
||||
vcs: "git",
|
||||
repo: "https://{root}",
|
||||
},
|
||||
|
||||
// General syntax for any server.
|
||||
// Must be last.
|
||||
{
|
||||
re: `^(?P<root>(?P<repo>([a-z0-9.\-]+\.)+[a-z0-9.\-]+(:[0-9]+)?/[A-Za-z0-9_.\-/]*?)\.(?P<vcs>bzr|git|hg|svn))(/[A-Za-z0-9_.\-]+)*$`,
|
||||
ping: true,
|
||||
},
|
||||
}
|
||||
|
||||
// vcsPathsAfterDynamic gives additional vcsPaths entries
|
||||
// to try after the dynamic HTML check.
|
||||
// This gives those sites a chance to introduce <meta> tags
|
||||
// as part of a graceful transition away from the hard-coded logic.
|
||||
var vcsPathsAfterDynamic = []*vcsPath{
|
||||
// Launchpad. See golang.org/issue/11436.
|
||||
{
|
||||
prefix: "launchpad.net/",
|
||||
re: `^(?P<root>launchpad\.net/((?P<project>[A-Za-z0-9_.\-]+)(?P<series>/[A-Za-z0-9_.\-]+)?|~[A-Za-z0-9_.\-]+/(\+junk|[A-Za-z0-9_.\-]+)/[A-Za-z0-9_.\-]+))(/[A-Za-z0-9_.\-]+)*$`,
|
||||
vcs: "bzr",
|
||||
repo: "https://{root}",
|
||||
check: launchpadVCS,
|
||||
},
|
||||
}
|
||||
|
||||
func init() {
|
||||
// fill in cached regexps.
|
||||
// Doing this eagerly discovers invalid regexp syntax
|
||||
|
@ -754,6 +918,9 @@ func init() {
|
|||
for _, srv := range vcsPaths {
|
||||
srv.regexp = regexp.MustCompile(srv.re)
|
||||
}
|
||||
for _, srv := range vcsPathsAfterDynamic {
|
||||
srv.regexp = regexp.MustCompile(srv.re)
|
||||
}
|
||||
}
|
||||
|
||||
// noVCSSuffix checks that the repository name does not
|
||||
|
@ -821,10 +988,25 @@ func bitbucketVCS(match map[string]string) error {
|
|||
url := expand(match, "https://api.bitbucket.org/1.0/repositories/{bitname}")
|
||||
data, err := httpGET(url)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := json.Unmarshal(data, &resp); err != nil {
|
||||
return fmt.Errorf("decoding %s: %v", url, err)
|
||||
if httpErr, ok := err.(*httpError); ok && httpErr.statusCode == 403 {
|
||||
// this may be a private repository. If so, attempt to determine which
|
||||
// VCS it uses. See issue 5375.
|
||||
root := match["root"]
|
||||
for _, vcs := range []string{"git", "hg"} {
|
||||
if vcsByCmd(vcs).ping("https", root) == nil {
|
||||
resp.SCM = vcs
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if resp.SCM == "" {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if err := json.Unmarshal(data, &resp); err != nil {
|
||||
return fmt.Errorf("decoding %s: %v", url, err)
|
||||
}
|
||||
}
|
||||
|
||||
if vcsByCmd(resp.SCM) != nil {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue