mirror of
https://github.com/golang/go.git
synced 2026-02-06 02:45:06 +03:00
Compare commits
96 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
7f36edc26d | ||
|
|
83b4a5db24 | ||
|
|
0f5133b742 | ||
|
|
6e1c4529e4 | ||
|
|
731de13dc3 | ||
|
|
390ffce7d6 | ||
|
|
b454859a8a | ||
|
|
9d828e80fa | ||
|
|
825eeee3f7 | ||
|
|
dbf30d88f3 | ||
|
|
6b51660c8c | ||
|
|
cc604130c8 | ||
|
|
21b488bb60 | ||
|
|
e038690847 | ||
|
|
1575127ef8 | ||
|
|
7d08a16fba | ||
|
|
5f2cbe1f64 | ||
|
|
6796ebb2cb | ||
|
|
85897ca220 | ||
|
|
9f9cf28f8f | ||
|
|
a31c931adf | ||
|
|
03811ab1b3 | ||
|
|
04a9473847 | ||
|
|
db8f1dc948 | ||
|
|
664cf832ec | ||
|
|
431f75a0b9 | ||
|
|
34c8b14ca9 | ||
|
|
8947f3395e | ||
|
|
06fd2f115b | ||
|
|
f66ab6521c | ||
|
|
c1f9c2c7b0 | ||
|
|
0ab64e2caa | ||
|
|
56eb99859d | ||
|
|
43130aff52 | ||
|
|
b2c005e7b2 | ||
|
|
a9d9b55709 | ||
|
|
fa7217f74d | ||
|
|
49860cf92a | ||
|
|
f3a302358f | ||
|
|
1d755aa488 | ||
|
|
9204aca6c2 | ||
|
|
0ae3ca0a20 | ||
|
|
dae59b594c | ||
|
|
b7fd97ae3e | ||
|
|
311096a6a2 | ||
|
|
e9162e7e22 | ||
|
|
d107ee90df | ||
|
|
213f1566ee | ||
|
|
ac1f5aa3d6 | ||
|
|
fd29397dca | ||
|
|
4524009ba6 | ||
|
|
bd1bc8a6e7 | ||
|
|
c2a34bedee | ||
|
|
0ace2d8aca | ||
|
|
e4119e9b74 | ||
|
|
339c903a75 | ||
|
|
334de7982f | ||
|
|
5d6920842b | ||
|
|
949eae84df | ||
|
|
0bfde51e0d | ||
|
|
45a52718e3 | ||
|
|
7f375e2c22 | ||
|
|
4070531920 | ||
|
|
5ffdb9c88b | ||
|
|
becc17ebcd | ||
|
|
d418e224ae | ||
|
|
456eaf5c29 | ||
|
|
e4ef83383e | ||
|
|
4e6d3468cc | ||
|
|
f5c388313f | ||
|
|
af236716b2 | ||
|
|
0f7b7600fb | ||
|
|
eb58df7dbf | ||
|
|
30f4d9e117 | ||
|
|
bb0e5c2045 | ||
|
|
cd0e528d3d | ||
|
|
80e2e474b8 | ||
|
|
3901409b5d | ||
|
|
35c0ea22a9 | ||
|
|
6d399e9da6 | ||
|
|
b7b4c60585 | ||
|
|
18068cb96a | ||
|
|
c43ac38b3b | ||
|
|
4241f582fc | ||
|
|
8a4c24f9bb | ||
|
|
3de5aca7d0 | ||
|
|
8336dfde70 | ||
|
|
6b60550504 | ||
|
|
468fad45a2 | ||
|
|
e06b6fc58d | ||
|
|
b3799ba634 | ||
|
|
16afa6a740 | ||
|
|
817d7bdc0a | ||
|
|
14bb1e11b9 | ||
|
|
2297c34cdf | ||
|
|
26682773ca |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -30,7 +30,6 @@ _testmain.go
|
||||
/misc/cgo/testso/main
|
||||
/pkg/
|
||||
/src/*.*/
|
||||
/src/_artifacts/
|
||||
/src/cmd/cgo/zdefaultcc.go
|
||||
/src/cmd/dist/dist
|
||||
/src/cmd/go/internal/cfg/zdefaultcc.go
|
||||
|
||||
@@ -503,7 +503,6 @@ pkg unicode, const Version = "10.0.0"
|
||||
pkg unicode, const Version = "11.0.0"
|
||||
pkg unicode, const Version = "12.0.0"
|
||||
pkg unicode, const Version = "13.0.0"
|
||||
pkg unicode, const Version = "15.0.0"
|
||||
pkg unicode, const Version = "6.2.0"
|
||||
pkg unicode, const Version = "6.3.0"
|
||||
pkg unicode, const Version = "7.0.0"
|
||||
|
||||
111
api/go1.25.txt
111
api/go1.25.txt
@@ -1,111 +0,0 @@
|
||||
pkg crypto, func SignMessage(Signer, io.Reader, []uint8, SignerOpts) ([]uint8, error) #63405
|
||||
pkg crypto, type MessageSigner interface { Public, Sign, SignMessage } #63405
|
||||
pkg crypto, type MessageSigner interface, Public() PublicKey #63405
|
||||
pkg crypto, type MessageSigner interface, Sign(io.Reader, []uint8, SignerOpts) ([]uint8, error) #63405
|
||||
pkg crypto, type MessageSigner interface, SignMessage(io.Reader, []uint8, SignerOpts) ([]uint8, error) #63405
|
||||
pkg crypto/ecdsa, func ParseRawPrivateKey(elliptic.Curve, []uint8) (*PrivateKey, error) #63963
|
||||
pkg crypto/ecdsa, func ParseUncompressedPublicKey(elliptic.Curve, []uint8) (*PublicKey, error) #63963
|
||||
pkg crypto/ecdsa, method (*PrivateKey) Bytes() ([]uint8, error) #63963
|
||||
pkg crypto/ecdsa, method (*PublicKey) Bytes() ([]uint8, error) #63963
|
||||
pkg crypto/sha3, method (*SHA3) Clone() (hash.Cloner, error) #69521
|
||||
pkg crypto/tls, type Config struct, GetEncryptedClientHelloKeys func(*ClientHelloInfo) ([]EncryptedClientHelloKey, error) #71920
|
||||
pkg crypto/tls, type ConnectionState struct, CurveID CurveID #67516
|
||||
pkg debug/elf, const PT_RISCV_ATTRIBUTES = 1879048195 #72843
|
||||
pkg debug/elf, const PT_RISCV_ATTRIBUTES ProgType #72843
|
||||
pkg debug/elf, const SHT_RISCV_ATTRIBUTES = 1879048195 #72843
|
||||
pkg debug/elf, const SHT_RISCV_ATTRIBUTES SectionType #72843
|
||||
pkg go/ast, const FilterFuncDuplicates //deprecated #73088
|
||||
pkg go/ast, const FilterImportDuplicates //deprecated #73088
|
||||
pkg go/ast, const FilterUnassociatedComments //deprecated #73088
|
||||
pkg go/ast, func FilterPackage //deprecated #73088
|
||||
pkg go/ast, func MergePackageFiles //deprecated #73088
|
||||
pkg go/ast, func PackageExports //deprecated #73088
|
||||
pkg go/ast, func PreorderStack(Node, []Node, func(Node, []Node) bool) #73319
|
||||
pkg go/ast, type MergeMode //deprecated #73088
|
||||
pkg go/parser, func ParseDir //deprecated #71122
|
||||
pkg go/token, method (*FileSet) AddExistingFiles(...*File) #73205
|
||||
pkg go/types, const FieldVar = 6 #70250
|
||||
pkg go/types, const FieldVar VarKind #70250
|
||||
pkg go/types, const LocalVar = 2 #70250
|
||||
pkg go/types, const LocalVar VarKind #70250
|
||||
pkg go/types, const PackageVar = 1 #70250
|
||||
pkg go/types, const PackageVar VarKind #70250
|
||||
pkg go/types, const ParamVar = 4 #70250
|
||||
pkg go/types, const ParamVar VarKind #70250
|
||||
pkg go/types, const RecvVar = 3 #70250
|
||||
pkg go/types, const RecvVar VarKind #70250
|
||||
pkg go/types, const ResultVar = 5 #70250
|
||||
pkg go/types, const ResultVar VarKind #70250
|
||||
pkg go/types, func LookupSelection(Type, bool, *Package, string) (Selection, bool) #70737
|
||||
pkg go/types, method (*Var) Kind() VarKind #70250
|
||||
pkg go/types, method (*Var) SetKind(VarKind) #70250
|
||||
pkg go/types, method (VarKind) String() string #70250
|
||||
pkg go/types, type VarKind uint8 #70250
|
||||
pkg hash, type Cloner interface { BlockSize, Clone, Reset, Size, Sum, Write } #69521
|
||||
pkg hash, type Cloner interface, BlockSize() int #69521
|
||||
pkg hash, type Cloner interface, Clone() (Cloner, error) #69521
|
||||
pkg hash, type Cloner interface, Reset() #69521
|
||||
pkg hash, type Cloner interface, Size() int #69521
|
||||
pkg hash, type Cloner interface, Sum([]uint8) []uint8 #69521
|
||||
pkg hash, type Cloner interface, Write([]uint8) (int, error) #69521
|
||||
pkg hash, type XOF interface { BlockSize, Read, Reset, Write } #69518
|
||||
pkg hash, type XOF interface, BlockSize() int #69518
|
||||
pkg hash, type XOF interface, Read([]uint8) (int, error) #69518
|
||||
pkg hash, type XOF interface, Reset() #69518
|
||||
pkg hash, type XOF interface, Write([]uint8) (int, error) #69518
|
||||
pkg hash/maphash, method (*Hash) Clone() (hash.Cloner, error) #69521
|
||||
pkg io/fs, func Lstat(FS, string) (FileInfo, error) #49580
|
||||
pkg io/fs, func ReadLink(FS, string) (string, error) #49580
|
||||
pkg io/fs, type ReadLinkFS interface { Lstat, Open, ReadLink } #49580
|
||||
pkg io/fs, type ReadLinkFS interface, Lstat(string) (FileInfo, error) #49580
|
||||
pkg io/fs, type ReadLinkFS interface, Open(string) (File, error) #49580
|
||||
pkg io/fs, type ReadLinkFS interface, ReadLink(string) (string, error) #49580
|
||||
pkg log/slog, func GroupAttrs(string, ...Attr) Attr #66365
|
||||
pkg log/slog, method (Record) Source() *Source #70280
|
||||
pkg mime/multipart, func FileContentDisposition(string, string) string #46771
|
||||
pkg net/http, func NewCrossOriginProtection() *CrossOriginProtection #73626
|
||||
pkg net/http, method (*CrossOriginProtection) AddInsecureBypassPattern(string) #73626
|
||||
pkg net/http, method (*CrossOriginProtection) AddTrustedOrigin(string) error #73626
|
||||
pkg net/http, method (*CrossOriginProtection) Check(*Request) error #73626
|
||||
pkg net/http, method (*CrossOriginProtection) Handler(Handler) Handler #73626
|
||||
pkg net/http, method (*CrossOriginProtection) SetDenyHandler(Handler) #73626
|
||||
pkg net/http, type CrossOriginProtection struct #73626
|
||||
pkg os, method (*Root) Chmod(string, fs.FileMode) error #67002
|
||||
pkg os, method (*Root) Chown(string, int, int) error #67002
|
||||
pkg os, method (*Root) Chtimes(string, time.Time, time.Time) error #67002
|
||||
pkg os, method (*Root) Lchown(string, int, int) error #67002
|
||||
pkg os, method (*Root) Link(string, string) error #67002
|
||||
pkg os, method (*Root) MkdirAll(string, fs.FileMode) error #67002
|
||||
pkg os, method (*Root) ReadFile(string) ([]uint8, error) #73126
|
||||
pkg os, method (*Root) Readlink(string) (string, error) #67002
|
||||
pkg os, method (*Root) RemoveAll(string) error #67002
|
||||
pkg os, method (*Root) Rename(string, string) error #67002
|
||||
pkg os, method (*Root) Symlink(string, string) error #67002
|
||||
pkg os, method (*Root) WriteFile(string, []uint8, fs.FileMode) error #73126
|
||||
pkg reflect, func TypeAssert[$0 interface{}](Value) ($0, bool) #62121
|
||||
pkg runtime, func SetDefaultGOMAXPROCS() #73193
|
||||
pkg runtime/trace, func NewFlightRecorder(FlightRecorderConfig) *FlightRecorder #63185
|
||||
pkg runtime/trace, method (*FlightRecorder) Enabled() bool #63185
|
||||
pkg runtime/trace, method (*FlightRecorder) Start() error #63185
|
||||
pkg runtime/trace, method (*FlightRecorder) Stop() #63185
|
||||
pkg runtime/trace, method (*FlightRecorder) WriteTo(io.Writer) (int64, error) #63185
|
||||
pkg runtime/trace, type FlightRecorder struct #63185
|
||||
pkg runtime/trace, type FlightRecorderConfig struct #63185
|
||||
pkg runtime/trace, type FlightRecorderConfig struct, MaxBytes uint64 #63185
|
||||
pkg runtime/trace, type FlightRecorderConfig struct, MinAge time.Duration #63185
|
||||
pkg sync, method (*WaitGroup) Go(func()) #63796
|
||||
pkg testing, method (*B) Attr(string, string) #43936
|
||||
pkg testing, method (*B) Output() io.Writer #59928
|
||||
pkg testing, method (*F) Attr(string, string) #43936
|
||||
pkg testing, method (*F) Output() io.Writer #59928
|
||||
pkg testing, method (*T) Attr(string, string) #43936
|
||||
pkg testing, method (*T) Output() io.Writer #59928
|
||||
pkg testing, type TB interface, Attr(string, string) #43936
|
||||
pkg testing, type TB interface, Output() io.Writer #59928
|
||||
pkg testing/fstest, method (MapFS) Lstat(string) (fs.FileInfo, error) #49580
|
||||
pkg testing/fstest, method (MapFS) ReadLink(string) (string, error) #49580
|
||||
pkg testing/synctest, func Test(*testing.T, func(*testing.T)) #67434
|
||||
pkg testing/synctest, func Wait() #67434
|
||||
pkg unicode, var CategoryAliases map[string]string #70780
|
||||
pkg unicode, var Cn *RangeTable #70780
|
||||
pkg unicode, var LC *RangeTable #70780
|
||||
180
api/go1.26.txt
180
api/go1.26.txt
@@ -1,180 +0,0 @@
|
||||
pkg bytes, method (*Buffer) Peek(int) ([]uint8, error) #73794
|
||||
pkg crypto, type Decapsulator interface { Decapsulate, Encapsulator } #75300
|
||||
pkg crypto, type Decapsulator interface, Decapsulate([]uint8) ([]uint8, error) #75300
|
||||
pkg crypto, type Decapsulator interface, Encapsulator() Encapsulator #75300
|
||||
pkg crypto, type Encapsulator interface { Bytes, Encapsulate } #75300
|
||||
pkg crypto, type Encapsulator interface, Bytes() []uint8 #75300
|
||||
pkg crypto, type Encapsulator interface, Encapsulate() ([]uint8, []uint8) #75300
|
||||
pkg crypto/ecdh, type KeyExchanger interface { Curve, ECDH, PublicKey } #75300
|
||||
pkg crypto/ecdh, type KeyExchanger interface, Curve() Curve #75300
|
||||
pkg crypto/ecdh, type KeyExchanger interface, ECDH(*PublicKey) ([]uint8, error) #75300
|
||||
pkg crypto/ecdh, type KeyExchanger interface, PublicKey() *PublicKey #75300
|
||||
pkg crypto/ecdsa, type PrivateKey struct, D //deprecated #63963
|
||||
pkg crypto/ecdsa, type PublicKey struct, X //deprecated #63963
|
||||
pkg crypto/ecdsa, type PublicKey struct, Y //deprecated #63963
|
||||
pkg crypto/fips140, func Enforced() bool #74630
|
||||
pkg crypto/fips140, func Version() string #75301
|
||||
pkg crypto/fips140, func WithoutEnforcement(func()) #74630
|
||||
pkg crypto/hpke, func AES128GCM() AEAD #75300
|
||||
pkg crypto/hpke, func AES256GCM() AEAD #75300
|
||||
pkg crypto/hpke, func ChaCha20Poly1305() AEAD #75300
|
||||
pkg crypto/hpke, func DHKEM(ecdh.Curve) KEM #75300
|
||||
pkg crypto/hpke, func ExportOnly() AEAD #75300
|
||||
pkg crypto/hpke, func HKDFSHA256() KDF #75300
|
||||
pkg crypto/hpke, func HKDFSHA384() KDF #75300
|
||||
pkg crypto/hpke, func HKDFSHA512() KDF #75300
|
||||
pkg crypto/hpke, func MLKEM1024() KEM #75300
|
||||
pkg crypto/hpke, func MLKEM1024P384() KEM #75300
|
||||
pkg crypto/hpke, func MLKEM768() KEM #75300
|
||||
pkg crypto/hpke, func MLKEM768P256() KEM #75300
|
||||
pkg crypto/hpke, func MLKEM768X25519() KEM #75300
|
||||
pkg crypto/hpke, func NewAEAD(uint16) (AEAD, error) #75300
|
||||
pkg crypto/hpke, func NewDHKEMPrivateKey(ecdh.KeyExchanger) (PrivateKey, error) #75300
|
||||
pkg crypto/hpke, func NewDHKEMPublicKey(*ecdh.PublicKey) (PublicKey, error) #75300
|
||||
pkg crypto/hpke, func NewHybridPrivateKey(crypto.Decapsulator, ecdh.KeyExchanger) (PrivateKey, error) #75300
|
||||
pkg crypto/hpke, func NewHybridPublicKey(crypto.Encapsulator, *ecdh.PublicKey) (PublicKey, error) #75300
|
||||
pkg crypto/hpke, func NewKDF(uint16) (KDF, error) #75300
|
||||
pkg crypto/hpke, func NewKEM(uint16) (KEM, error) #75300
|
||||
pkg crypto/hpke, func NewMLKEMPrivateKey(crypto.Decapsulator) (PrivateKey, error) #75300
|
||||
pkg crypto/hpke, func NewMLKEMPublicKey(crypto.Encapsulator) (PublicKey, error) #75300
|
||||
pkg crypto/hpke, func NewRecipient([]uint8, PrivateKey, KDF, AEAD, []uint8) (*Recipient, error) #75300
|
||||
pkg crypto/hpke, func NewSender(PublicKey, KDF, AEAD, []uint8) ([]uint8, *Sender, error) #75300
|
||||
pkg crypto/hpke, func Open(PrivateKey, KDF, AEAD, []uint8, []uint8) ([]uint8, error) #75300
|
||||
pkg crypto/hpke, func SHAKE128() KDF #75300
|
||||
pkg crypto/hpke, func SHAKE256() KDF #75300
|
||||
pkg crypto/hpke, func Seal(PublicKey, KDF, AEAD, []uint8, []uint8) ([]uint8, error) #75300
|
||||
pkg crypto/hpke, method (*Recipient) Export(string, int) ([]uint8, error) #75300
|
||||
pkg crypto/hpke, method (*Recipient) Open([]uint8, []uint8) ([]uint8, error) #75300
|
||||
pkg crypto/hpke, method (*Sender) Export(string, int) ([]uint8, error) #75300
|
||||
pkg crypto/hpke, method (*Sender) Seal([]uint8, []uint8) ([]uint8, error) #75300
|
||||
pkg crypto/hpke, type AEAD interface, ID() uint16 #75300
|
||||
pkg crypto/hpke, type AEAD interface, unexported methods #75300
|
||||
pkg crypto/hpke, type KDF interface, ID() uint16 #75300
|
||||
pkg crypto/hpke, type KDF interface, unexported methods #75300
|
||||
pkg crypto/hpke, type KEM interface, DeriveKeyPair([]uint8) (PrivateKey, error) #75300
|
||||
pkg crypto/hpke, type KEM interface, GenerateKey() (PrivateKey, error) #75300
|
||||
pkg crypto/hpke, type KEM interface, ID() uint16 #75300
|
||||
pkg crypto/hpke, type KEM interface, NewPrivateKey([]uint8) (PrivateKey, error) #75300
|
||||
pkg crypto/hpke, type KEM interface, NewPublicKey([]uint8) (PublicKey, error) #75300
|
||||
pkg crypto/hpke, type KEM interface, unexported methods #75300
|
||||
pkg crypto/hpke, type PrivateKey interface, Bytes() ([]uint8, error) #75300
|
||||
pkg crypto/hpke, type PrivateKey interface, KEM() KEM #75300
|
||||
pkg crypto/hpke, type PrivateKey interface, PublicKey() PublicKey #75300
|
||||
pkg crypto/hpke, type PrivateKey interface, unexported methods #75300
|
||||
pkg crypto/hpke, type PublicKey interface, Bytes() []uint8 #75300
|
||||
pkg crypto/hpke, type PublicKey interface, KEM() KEM #75300
|
||||
pkg crypto/hpke, type PublicKey interface, unexported methods #75300
|
||||
pkg crypto/hpke, type Recipient struct #75300
|
||||
pkg crypto/hpke, type Sender struct #75300
|
||||
pkg crypto/mlkem, method (*DecapsulationKey1024) Encapsulator() crypto.Encapsulator #75300
|
||||
pkg crypto/mlkem, method (*DecapsulationKey768) Encapsulator() crypto.Encapsulator #75300
|
||||
pkg crypto/mlkem/mlkemtest, func Encapsulate1024(*mlkem.EncapsulationKey1024, []uint8) ([]uint8, []uint8, error) #73627
|
||||
pkg crypto/mlkem/mlkemtest, func Encapsulate768(*mlkem.EncapsulationKey768, []uint8) ([]uint8, []uint8, error) #73627
|
||||
pkg crypto/rsa, func DecryptPKCS1v15 //deprecated #75302
|
||||
pkg crypto/rsa, func DecryptPKCS1v15SessionKey //deprecated #75302
|
||||
pkg crypto/rsa, func EncryptOAEPWithOptions(io.Reader, *PublicKey, []uint8, *OAEPOptions) ([]uint8, error) #65716
|
||||
pkg crypto/rsa, func EncryptPKCS1v15 //deprecated #75302
|
||||
pkg crypto/rsa, type PKCS1v15DecryptOptions //deprecated #75302
|
||||
pkg crypto/tls, const QUICErrorEvent = 10 #75108
|
||||
pkg crypto/tls, const QUICErrorEvent QUICEventKind #75108
|
||||
pkg crypto/tls, const SecP256r1MLKEM768 = 4587 #71206
|
||||
pkg crypto/tls, const SecP256r1MLKEM768 CurveID #71206
|
||||
pkg crypto/tls, const SecP384r1MLKEM1024 = 4589 #71206
|
||||
pkg crypto/tls, const SecP384r1MLKEM1024 CurveID #71206
|
||||
pkg crypto/tls, type ClientHelloInfo struct, HelloRetryRequest bool #74425
|
||||
pkg crypto/tls, type ConnectionState struct, HelloRetryRequest bool #74425
|
||||
pkg crypto/tls, type QUICEvent struct, Err error #75108
|
||||
pkg crypto/x509, func OIDFromASN1OID(asn1.ObjectIdentifier) (OID, error) #75325
|
||||
pkg crypto/x509, method (ExtKeyUsage) OID() OID #75325
|
||||
pkg crypto/x509, method (ExtKeyUsage) String() string #56866
|
||||
pkg crypto/x509, method (KeyUsage) String() string #56866
|
||||
pkg debug/elf, const R_LARCH_CALL36 = 110 #75562
|
||||
pkg debug/elf, const R_LARCH_CALL36 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC32 = 13 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC32 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64 = 14 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64_HI12 = 118 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64_HI12 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64_LO20 = 117 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64_LO20 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64_PC_HI12 = 114 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64_PC_HI12 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64_PC_LO20 = 113 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC64_PC_LO20 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_CALL = 120 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_CALL R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_HI20 = 115 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_HI20 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_LD = 119 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_LD R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_LO12 = 116 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_LO12 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_PCREL20_S2 = 126 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_PCREL20_S2 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_PC_HI20 = 111 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_PC_HI20 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_PC_LO12 = 112 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_DESC_PC_LO12 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_GD_PCREL20_S2 = 125 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_GD_PCREL20_S2 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_LD_PCREL20_S2 = 124 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_LD_PCREL20_S2 R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_LE_ADD_R = 122 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_LE_ADD_R R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_LE_HI20_R = 121 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_LE_HI20_R R_LARCH #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_LE_LO12_R = 123 #75562
|
||||
pkg debug/elf, const R_LARCH_TLS_LE_LO12_R R_LARCH #75562
|
||||
pkg errors, func AsType[$0 error](error) ($0, bool) #51945
|
||||
pkg go/ast, func ParseDirective(token.Pos, string) (Directive, bool) #68021
|
||||
pkg go/ast, method (*Directive) End() token.Pos #68021
|
||||
pkg go/ast, method (*Directive) ParseArgs() ([]DirectiveArg, error) #68021
|
||||
pkg go/ast, method (*Directive) Pos() token.Pos #68021
|
||||
pkg go/ast, type BasicLit struct, ValueEnd token.Pos #76031
|
||||
pkg go/ast, type Directive struct #68021
|
||||
pkg go/ast, type Directive struct, Args string #68021
|
||||
pkg go/ast, type Directive struct, ArgsPos token.Pos #68021
|
||||
pkg go/ast, type Directive struct, Name string #68021
|
||||
pkg go/ast, type Directive struct, Slash token.Pos #68021
|
||||
pkg go/ast, type Directive struct, Tool string #68021
|
||||
pkg go/ast, type DirectiveArg struct #68021
|
||||
pkg go/ast, type DirectiveArg struct, Arg string #68021
|
||||
pkg go/ast, type DirectiveArg struct, Pos token.Pos #68021
|
||||
pkg go/token, method (*File) End() Pos #75849
|
||||
pkg log/slog, func NewMultiHandler(...Handler) *MultiHandler #65954
|
||||
pkg log/slog, method (*MultiHandler) Enabled(context.Context, Level) bool #65954
|
||||
pkg log/slog, method (*MultiHandler) Handle(context.Context, Record) error #65954
|
||||
pkg log/slog, method (*MultiHandler) WithAttrs([]Attr) Handler #65954
|
||||
pkg log/slog, method (*MultiHandler) WithGroup(string) Handler #65954
|
||||
pkg log/slog, type MultiHandler struct #65954
|
||||
pkg net, method (*Dialer) DialIP(context.Context, string, netip.Addr, netip.Addr) (*IPConn, error) #49097
|
||||
pkg net, method (*Dialer) DialTCP(context.Context, string, netip.AddrPort, netip.AddrPort) (*TCPConn, error) #49097
|
||||
pkg net, method (*Dialer) DialUDP(context.Context, string, netip.AddrPort, netip.AddrPort) (*UDPConn, error) #49097
|
||||
pkg net, method (*Dialer) DialUnix(context.Context, string, *UnixAddr, *UnixAddr) (*UnixConn, error) #49097
|
||||
pkg net/http, method (*ClientConn) Available() int #75772
|
||||
pkg net/http, method (*ClientConn) Close() error #75772
|
||||
pkg net/http, method (*ClientConn) Err() error #75772
|
||||
pkg net/http, method (*ClientConn) InFlight() int #75772
|
||||
pkg net/http, method (*ClientConn) Release() #75772
|
||||
pkg net/http, method (*ClientConn) Reserve() error #75772
|
||||
pkg net/http, method (*ClientConn) RoundTrip(*Request) (*Response, error) #75772
|
||||
pkg net/http, method (*ClientConn) SetStateHook(func(*ClientConn)) #75772
|
||||
pkg net/http, method (*Transport) NewClientConn(context.Context, string, string) (*ClientConn, error) #75772
|
||||
pkg net/http, type ClientConn struct #75772
|
||||
pkg net/http, type HTTP2Config struct, StrictMaxConcurrentRequests bool #67813
|
||||
pkg net/http/httputil, type ReverseProxy struct, Director //deprecated #73161
|
||||
pkg net/netip, method (Prefix) Compare(Prefix) int #61642
|
||||
pkg os, method (*Process) WithHandle(func(uintptr)) error #70352
|
||||
pkg os, var ErrNoHandle error #70352
|
||||
pkg reflect, method (Value) Fields() iter.Seq2[StructField, Value] #66631
|
||||
pkg reflect, method (Value) Methods() iter.Seq2[Method, Value] #66631
|
||||
pkg reflect, type Type interface, Fields() iter.Seq[StructField] #66631
|
||||
pkg reflect, type Type interface, Ins() iter.Seq[Type] #66631
|
||||
pkg reflect, type Type interface, Methods() iter.Seq[Method] #66631
|
||||
pkg reflect, type Type interface, Outs() iter.Seq[Type] #66631
|
||||
pkg testing, method (*B) ArtifactDir() string #71287
|
||||
pkg testing, method (*F) ArtifactDir() string #71287
|
||||
pkg testing, method (*T) ArtifactDir() string #71287
|
||||
pkg testing, type TB interface, ArtifactDir() string #71287
|
||||
pkg testing/cryptotest, func SetGlobalRandom(*testing.T, uint64) #70942
|
||||
@@ -1 +0,0 @@
|
||||
pkg go/scanner, method (*Scanner) End() token.Pos #74958
|
||||
@@ -1 +0,0 @@
|
||||
pkg net/http, type Server struct, DisableClientPriority bool #75500
|
||||
@@ -1 +0,0 @@
|
||||
pkg testing/synctest, func Sleep(time.Duration) #77169
|
||||
@@ -1,16 +0,0 @@
|
||||
pkg unicode, const Version = "17.0.0" #77266
|
||||
pkg unicode, var Beria_Erfe *RangeTable #77266
|
||||
pkg unicode, var Garay *RangeTable #77266
|
||||
pkg unicode, var Gurung_Khema *RangeTable #77266
|
||||
pkg unicode, var IDS_Unary_Operator *RangeTable #77266
|
||||
pkg unicode, var ID_Compat_Math_Continue *RangeTable #77266
|
||||
pkg unicode, var ID_Compat_Math_Start *RangeTable #77266
|
||||
pkg unicode, var Kirat_Rai *RangeTable #77266
|
||||
pkg unicode, var Modifier_Combining_Mark *RangeTable #77266
|
||||
pkg unicode, var Ol_Onal *RangeTable #77266
|
||||
pkg unicode, var Sidetic *RangeTable #77266
|
||||
pkg unicode, var Sunuwar *RangeTable #77266
|
||||
pkg unicode, var Tai_Yo *RangeTable #77266
|
||||
pkg unicode, var Todhri *RangeTable #77266
|
||||
pkg unicode, var Tolong_Siki *RangeTable #77266
|
||||
pkg unicode, var Tulu_Tigalari *RangeTable #77266
|
||||
@@ -1 +1,2 @@
|
||||
branch: master
|
||||
branch: release-branch.go1.24
|
||||
parent-branch: master
|
||||
|
||||
@@ -1039,12 +1039,6 @@ The value of <code>GOMIPS64</code> environment variable (<code>hardfloat</code>
|
||||
<code>GOMIPS64_hardfloat</code> or <code>GOMIPS64_softfloat</code>.
|
||||
</p>
|
||||
|
||||
<h3 id="riscv64">RISCV64</h3>
|
||||
|
||||
<p>
|
||||
Reference: <a href="/pkg/cmd/internal/obj/riscv">Go RISCV64 Assembly Instructions Reference Manual</a>
|
||||
</p>
|
||||
|
||||
<h3 id="unsupported_opcodes">Unsupported opcodes</h3>
|
||||
|
||||
<p>
|
||||
|
||||
6864
doc/go1.17_spec.html
Normal file
6864
doc/go1.17_spec.html
Normal file
File diff suppressed because it is too large
Load Diff
@@ -231,7 +231,7 @@ do exactly this.
|
||||
|
||||
<p>
|
||||
A read of an array, struct, or complex number
|
||||
may be implemented as a read of each individual sub-value
|
||||
may by implemented as a read of each individual sub-value
|
||||
(array element, struct field, or real/imaginary component),
|
||||
in any order.
|
||||
Similarly, a write of an array, struct, or complex number
|
||||
@@ -453,7 +453,7 @@ crash, or do something else.)
|
||||
</p>
|
||||
|
||||
<p class="rule">
|
||||
The <i>k</i>th receive from a channel with capacity <i>C</i> is synchronized before the completion of the <i>k</i>+<i>C</i>th send on that channel.
|
||||
The <i>k</i>th receive on a channel with capacity <i>C</i> is synchronized before the completion of the <i>k</i>+<i>C</i>th send from that channel completes.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
|
||||
464
doc/go_spec.html
464
doc/go_spec.html
@@ -1,6 +1,6 @@
|
||||
<!--{
|
||||
"Title": "The Go Programming Language Specification",
|
||||
"Subtitle": "Language version go1.26 (Jan 12, 2026)",
|
||||
"Subtitle": "Language version go1.24 (Dec 30, 2024)",
|
||||
"Path": "/ref/spec"
|
||||
}-->
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
<p>
|
||||
This is the reference manual for the Go programming language.
|
||||
The pre-Go1.18 version, without generics, can be found
|
||||
<a href="/doc/go1.17_spec.html">here</a>.
|
||||
For more information and other documents, see <a href="/">go.dev</a>.
|
||||
</p>
|
||||
|
||||
@@ -1856,10 +1858,110 @@ The underlying type of <code>[]B1</code>, <code>B3</code>, and <code>B4</code> i
|
||||
The underlying type of <code>P</code> is <code>interface{}</code>.
|
||||
</p>
|
||||
|
||||
<h3 id="Core_types">Core types</h3>
|
||||
|
||||
<p>
|
||||
Each non-interface type <code>T</code> has a <i>core type</i>, which is the same as the
|
||||
<a href="#Underlying_types">underlying type</a> of <code>T</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
An interface <code>T</code> has a core type if one of the following
|
||||
conditions is satisfied:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
There is a single type <code>U</code> which is the <a href="#Underlying_types">underlying type</a>
|
||||
of all types in the <a href="#Interface_types">type set</a> of <code>T</code>; or
|
||||
</li>
|
||||
<li>
|
||||
the type set of <code>T</code> contains only <a href="#Channel_types">channel types</a>
|
||||
with identical element type <code>E</code>, and all directional channels have the same
|
||||
direction.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
No other interfaces have a core type.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The core type of an interface is, depending on the condition that is satisfied, either:
|
||||
</p>
|
||||
|
||||
<ol>
|
||||
<li>
|
||||
the type <code>U</code>; or
|
||||
</li>
|
||||
<li>
|
||||
the type <code>chan E</code> if <code>T</code> contains only bidirectional
|
||||
channels, or the type <code>chan<- E</code> or <code><-chan E</code>
|
||||
depending on the direction of the directional channels present.
|
||||
</li>
|
||||
</ol>
|
||||
|
||||
<p>
|
||||
By definition, a core type is never a <a href="#Type_definitions">defined type</a>,
|
||||
<a href="#Type_parameter_declarations">type parameter</a>, or
|
||||
<a href="#Interface_types">interface type</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Examples of interfaces with core types:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
type Celsius float32
|
||||
type Kelvin float32
|
||||
|
||||
interface{ int } // int
|
||||
interface{ Celsius|Kelvin } // float32
|
||||
interface{ ~chan int } // chan int
|
||||
interface{ ~chan int|~chan<- int } // chan<- int
|
||||
interface{ ~[]*data; String() string } // []*data
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Examples of interfaces without core types:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
interface{} // no single underlying type
|
||||
interface{ Celsius|float64 } // no single underlying type
|
||||
interface{ chan int | chan<- string } // channels have different element types
|
||||
interface{ <-chan int | chan<- int } // directional channels have different directions
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Some operations (<a href="#Slice_expressions">slice expressions</a>,
|
||||
<a href="#Appending_and_copying_slices"><code>append</code> and <code>copy</code></a>)
|
||||
rely on a slightly more loose form of core types which accept byte slices and strings.
|
||||
Specifically, if there are exactly two types, <code>[]byte</code> and <code>string</code>,
|
||||
which are the underlying types of all types in the type set of interface <code>T</code>,
|
||||
the core type of <code>T</code> is called <code>bytestring</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Examples of interfaces with <code>bytestring</code> core types:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
interface{ int } // int (same as ordinary core type)
|
||||
interface{ []byte | string } // bytestring
|
||||
interface{ ~[]byte | myString } // bytestring
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Note that <code>bytestring</code> is not a real type; it cannot be used to declare
|
||||
variables or compose other types. It exists solely to describe the behavior of some
|
||||
operations that read from a sequence of bytes, which may be a byte slice or a string.
|
||||
</p>
|
||||
|
||||
<h3 id="Type_identity">Type identity</h3>
|
||||
|
||||
<p>
|
||||
Two types are either <i>identical</i> ("the same") or <i>different</i>.
|
||||
Two types are either <i>identical</i> or <i>different</i>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
@@ -2487,15 +2589,11 @@ type set[P comparable] = map[P]bool
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
In an alias declaration the given type cannot be a type parameter declared in the same declaration.
|
||||
In an alias declaration the given type cannot be a type parameter.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
type A[P any] = P // illegal: P is a type parameter declared in the declaration of A
|
||||
|
||||
func f[P any]() {
|
||||
type A = P // ok: T is a type parameter declared by the enclosing function
|
||||
}
|
||||
type A[P any] = P // illegal: P is a type parameter
|
||||
</pre>
|
||||
|
||||
<h4 id="Type_definitions">Type definitions</h4>
|
||||
@@ -2605,8 +2703,8 @@ In a type definition the given type cannot be a type parameter.
|
||||
<pre>
|
||||
type T[P any] P // illegal: P is a type parameter
|
||||
|
||||
func f[P any]() {
|
||||
type L P // illegal: P is a type parameter declared by the enclosing function
|
||||
func f[T any]() {
|
||||
type L T // illegal: T is a type parameter declared by the enclosing function
|
||||
}
|
||||
</pre>
|
||||
|
||||
@@ -2690,6 +2788,22 @@ of a <a href="#Method_declarations">method declaration</a> associated
|
||||
with a generic type.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Within a type parameter list of a generic type <code>T</code>, a type constraint
|
||||
may not (directly, or indirectly through the type parameter list of another
|
||||
generic type) refer to <code>T</code>.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
type T1[P T1[P]] … // illegal: T1 refers to itself
|
||||
type T2[P interface{ T2[int] }] … // illegal: T2 refers to itself
|
||||
type T3[P interface{ m(T3[int])}] … // illegal: T3 refers to itself
|
||||
type T4[P T5[P]] … // illegal: T4 refers to T5 and
|
||||
type T5[P T4[P]] … // T5 refers to T4
|
||||
|
||||
type T6[P int] struct{ f *T6[P] } // ok: reference to T6 is not in type parameter list
|
||||
</pre>
|
||||
|
||||
<h4 id="Type_constraints">Type constraints</h4>
|
||||
|
||||
<p>
|
||||
@@ -3141,10 +3255,8 @@ math.Sin // denotes the Sin function in package math
|
||||
<h3 id="Composite_literals">Composite literals</h3>
|
||||
|
||||
<p>
|
||||
Composite literals construct new values for structs, arrays, slices, and maps
|
||||
each time they are evaluated.
|
||||
They consist of the type of the literal followed by a (possibly empty)
|
||||
brace-bound list of elements.
|
||||
Composite literals construct new composite values each time they are evaluated.
|
||||
They consist of the type of the literal followed by a brace-bound list of elements.
|
||||
Each element may optionally be preceded by a corresponding key.
|
||||
</p>
|
||||
|
||||
@@ -3161,61 +3273,39 @@ Element = Expression | LiteralValue .
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Unless the LiteralType is a type parameter,
|
||||
its <a href="#Underlying_types">underlying type</a>
|
||||
The LiteralType's <a href="#Core_types">core type</a> <code>T</code>
|
||||
must be a struct, array, slice, or map type
|
||||
(the syntax enforces this constraint except when the type is given
|
||||
as a TypeName).
|
||||
If the LiteralType is a type parameter, all types in its type set
|
||||
must have the same underlying type which must be
|
||||
a valid composite literal type.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The types of the elements and keys must be <a href="#Assignability">assignable</a>
|
||||
to the respective field, element, and key types of the LiteralType;
|
||||
to the respective field, element, and key types of type <code>T</code>;
|
||||
there is no additional conversion.
|
||||
The key is interpreted as a field name for struct literals,
|
||||
an index for array and slice literals, and a key for map literals.
|
||||
It is an error to specify multiple elements with the same field name
|
||||
or constant key value.
|
||||
A literal may omit the element list; such a literal evaluates
|
||||
to the zero value for its type.
|
||||
For map literals, all elements must have a key. It is an error
|
||||
to specify multiple elements with the same field name or
|
||||
constant key value. For non-constant map keys, see the section on
|
||||
<a href="#Order_of_evaluation">evaluation order</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A parsing ambiguity arises when a composite literal using the
|
||||
TypeName form of the LiteralType appears as an operand between the
|
||||
<a href="#Keywords">keyword</a> and the opening brace of the block
|
||||
of an "if", "for", or "switch" statement, and the composite literal
|
||||
is not enclosed in parentheses, square brackets, or curly braces.
|
||||
In this rare case, the opening brace of the literal is erroneously parsed
|
||||
as the one introducing the block of statements. To resolve the ambiguity,
|
||||
the composite literal must appear within parentheses.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
if x == (T{a,b,c}[i]) { … }
|
||||
if (x == T{a,b,c}[i]) { … }
|
||||
</pre>
|
||||
|
||||
<h4>Struct literals</h4>
|
||||
|
||||
<p>
|
||||
For struct literals without keys, the element list must contain an element
|
||||
for each struct field in the order in which the fields are declared.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For struct literals with keys the following rules apply:
|
||||
For struct literals the following rules apply:
|
||||
</p>
|
||||
<ul>
|
||||
<li>Every element must have a key.
|
||||
<li>A key must be a field name declared in the struct type.
|
||||
</li>
|
||||
<li>Each key must be a field name declared in the struct type.
|
||||
<li>An element list that does not contain any keys must
|
||||
list an element for each struct field in the
|
||||
order in which the fields are declared.
|
||||
</li>
|
||||
<li>The element list does not need to have an element for each struct field.
|
||||
Omitted fields get the zero value for that field.
|
||||
<li>If any element has a key, every element must have a key.
|
||||
</li>
|
||||
<li>An element list that contains keys does not need to
|
||||
have an element for each struct field. Omitted fields
|
||||
get the zero value for that field.
|
||||
</li>
|
||||
<li>A literal may omit the element list; such a literal evaluates
|
||||
to the zero value for its type.
|
||||
</li>
|
||||
<li>It is an error to specify an element for a non-exported
|
||||
field of a struct belonging to a different package.
|
||||
@@ -3239,8 +3329,6 @@ origin := Point3D{} // zero value for Point3D
|
||||
line := Line{origin, Point3D{y: -4, z: 12.3}} // zero value for line.q.x
|
||||
</pre>
|
||||
|
||||
<h4>Array and slice literals</h4>
|
||||
|
||||
<p>
|
||||
For array and slice literals the following rules apply:
|
||||
</p>
|
||||
@@ -3316,16 +3404,6 @@ tmp := [n]T{x1, x2, … xn}
|
||||
tmp[0 : n]
|
||||
</pre>
|
||||
|
||||
<h4>Map literals</h4>
|
||||
|
||||
<p>
|
||||
For map literals, each element must have a key.
|
||||
For non-constant map keys, see the section on
|
||||
<a href="#Order_of_evaluation">evaluation order</a>.
|
||||
</p>
|
||||
|
||||
<h4>Elision of element types</h4>
|
||||
|
||||
<p>
|
||||
Within a composite literal of array, slice, or map type <code>T</code>,
|
||||
elements or map keys that are themselves composite literals may elide the respective
|
||||
@@ -3346,6 +3424,22 @@ type PPoint *Point
|
||||
[2]PPoint{{1.5, -3.5}, {}} // same as [2]PPoint{PPoint(&Point{1.5, -3.5}), PPoint(&Point{})}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
A parsing ambiguity arises when a composite literal using the
|
||||
TypeName form of the LiteralType appears as an operand between the
|
||||
<a href="#Keywords">keyword</a> and the opening brace of the block
|
||||
of an "if", "for", or "switch" statement, and the composite literal
|
||||
is not enclosed in parentheses, square brackets, or curly braces.
|
||||
In this rare case, the opening brace of the literal is erroneously parsed
|
||||
as the one introducing the block of statements. To resolve the ambiguity,
|
||||
the composite literal must appear within parentheses.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
if x == (T{a,b,c}[i]) { … }
|
||||
if (x == T{a,b,c}[i]) { … }
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
Examples of valid array, slice, and map literals:
|
||||
</p>
|
||||
@@ -3367,6 +3461,7 @@ noteFrequency := map[string]float32{
|
||||
}
|
||||
</pre>
|
||||
|
||||
|
||||
<h3 id="Function_literals">Function literals</h3>
|
||||
|
||||
<p>
|
||||
@@ -3839,12 +3934,11 @@ The following rules apply:
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If <code>a</code> is neither a map nor a <a href="#Type_parameter_declarations">type parameter</a>:
|
||||
If <code>a</code> is neither a map nor a type parameter:
|
||||
</p>
|
||||
<ul>
|
||||
<li>the index <code>x</code> must be an untyped constant, or its type must be
|
||||
an <a href="#Numeric_types">integer</a> or a type parameter whose type set
|
||||
contains only integer types</li>
|
||||
<li>the index <code>x</code> must be an untyped constant or its
|
||||
<a href="#Core_types">core type</a> must be an <a href="#Numeric_types">integer</a></li>
|
||||
<li>a constant index must be non-negative and
|
||||
<a href="#Representability">representable</a> by a value of type <code>int</code></li>
|
||||
<li>a constant index that is untyped is given type <code>int</code></li>
|
||||
@@ -3958,26 +4052,14 @@ Assigning to an element of a <code>nil</code> map causes a
|
||||
|
||||
<p>
|
||||
Slice expressions construct a substring or slice from a string, array, pointer
|
||||
to array, or slice operand.
|
||||
There are two variants: a simple form that specifies a low
|
||||
to array, or slice. There are two variants: a simple form that specifies a low
|
||||
and high bound, and a full form that also specifies a bound on the capacity.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the operand type is a <a href="#Type_parameter_declarations">type parameter</a>,
|
||||
unless its type set contains string types,
|
||||
all types in the type set must have the same underlying type, and the slice expression
|
||||
must be valid for an operand of that type.
|
||||
If the type set contains string types it may also contain byte slices with underlying
|
||||
type <code>[]byte</code>.
|
||||
In this case, the slice expression must be valid for an operand of <code>string</code>
|
||||
type.
|
||||
</p>
|
||||
|
||||
<h4>Simple slice expressions</h4>
|
||||
|
||||
<p>
|
||||
For a string, array, pointer to array, or slice <code>a</code>, the primary expression
|
||||
The primary expression
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -3985,7 +4067,9 @@ a[low : high]
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
constructs a substring or slice.
|
||||
constructs a substring or slice. The <a href="#Core_types">core type</a> of
|
||||
<code>a</code> must be a string, array, pointer to array, slice, or a
|
||||
<a href="#Core_types"><code>bytestring</code></a>.
|
||||
The <i>indices</i> <code>low</code> and
|
||||
<code>high</code> select which elements of operand <code>a</code> appear
|
||||
in the result. The result has indices starting at 0 and length equal to
|
||||
@@ -4065,7 +4149,7 @@ s3 := s[:0] // s3 == nil
|
||||
<h4>Full slice expressions</h4>
|
||||
|
||||
<p>
|
||||
For an array, pointer to array, or slice <code>a</code> (but not a string), the primary expression
|
||||
The primary expression
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -4076,6 +4160,8 @@ a[low : high : max]
|
||||
constructs a slice of the same type, and with the same length and elements as the simple slice
|
||||
expression <code>a[low : high]</code>. Additionally, it controls the resulting slice's capacity
|
||||
by setting it to <code>max - low</code>. Only the first index may be omitted; it defaults to 0.
|
||||
The <a href="#Core_types">core type</a> of <code>a</code> must be an array, pointer to array,
|
||||
or slice (but not a string).
|
||||
After slicing the array <code>a</code>
|
||||
</p>
|
||||
|
||||
@@ -4181,8 +4267,8 @@ No <a href="#Run_time_panics">run-time panic</a> occurs in this case.
|
||||
<h3 id="Calls">Calls</h3>
|
||||
|
||||
<p>
|
||||
Given an expression <code>f</code> of <a href="#Function_types">function type</a>
|
||||
<code>F</code>,
|
||||
Given an expression <code>f</code> with a <a href="#Core_types">core type</a>
|
||||
<code>F</code> of <a href="#Function_types">function type</a>,
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -4212,12 +4298,6 @@ If <code>f</code> denotes a generic function, it must be
|
||||
or used as a function value.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the type of <code>f</code> is a <a href="#Type_parameter_declarations">type parameter</a>,
|
||||
all types in its type set must have the same underlying type, which must be a function type,
|
||||
and the function call must be valid for that type.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In a function call, the function value and arguments are evaluated in
|
||||
<a href="#Order_of_evaluation">the usual order</a>.
|
||||
@@ -4731,28 +4811,17 @@ more complicated:
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
If all types in <code>C</code>'s type set have the same
|
||||
underlying type <code>U</code>,
|
||||
If <code>C</code> has a <a href="#Core_types">core type</a>
|
||||
<code>core(C)</code>
|
||||
and <code>P</code> has a known type argument <code>A</code>,
|
||||
<code>U</code> and <code>A</code> must unify loosely.
|
||||
</li>
|
||||
<li>
|
||||
Similarly, if all types in <code>C</code>'s type set are
|
||||
channel types with the same element type and non-conflicting
|
||||
channel directions,
|
||||
and <code>P</code> has a known type argument <code>A</code>,
|
||||
the most restrictive channel type in <code>C</code>'s type
|
||||
set and <code>A</code> must unify loosely.
|
||||
</li>
|
||||
<li>
|
||||
<code>core(C)</code> and <code>A</code> must unify loosely.
|
||||
If <code>P</code> does not have a known type argument
|
||||
and <code>C</code> contains exactly one type term <code>T</code>
|
||||
that is not an underlying (tilde) type, unification adds the
|
||||
mapping <code>P ➞ T</code> to the map.
|
||||
</li>
|
||||
<li>
|
||||
If <code>C</code> does not have a type <code>U</code>
|
||||
as described above
|
||||
If <code>C</code> does not have a core type
|
||||
and <code>P</code> has a known type argument <code>A</code>,
|
||||
<code>A</code> must have all methods of <code>C</code>, if any,
|
||||
and corresponding method types must unify exactly.
|
||||
@@ -4876,7 +4945,7 @@ For instance, <code>x / y * z</code> is the same as <code>(x / y) * z</code>.
|
||||
x <= f() // x <= f()
|
||||
^a >> b // (^a) >> b
|
||||
f() || g() // f() || g()
|
||||
x == y+1 && <-chanInt > 0 // (x == (y+1)) && ((<-chanInt) > 0)
|
||||
x == y+1 && <-chanInt > 0 // (x == (y+1)) && ((<-chanInt) > 0)
|
||||
</pre>
|
||||
|
||||
|
||||
@@ -5303,10 +5372,10 @@ var x *int = nil
|
||||
<h3 id="Receive_operator">Receive operator</h3>
|
||||
|
||||
<p>
|
||||
For an operand <code>ch</code> of <a href="#Channel_types">channel type</a>,
|
||||
For an operand <code>ch</code> whose <a href="#Core_types">core type</a> is a
|
||||
<a href="#Channel_types">channel</a>,
|
||||
the value of the receive operation <code><-ch</code> is the value received
|
||||
from the channel <code>ch</code>.
|
||||
The channel direction must permit receive operations,
|
||||
from the channel <code>ch</code>. The channel direction must permit receive operations,
|
||||
and the type of the receive operation is the element type of the channel.
|
||||
The expression blocks until a value is available.
|
||||
Receiving from a <code>nil</code> channel blocks forever.
|
||||
@@ -5322,12 +5391,6 @@ f(<-ch)
|
||||
<-strobe // wait until clock pulse and discard received value
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If the operand type is a <a href="#Type_parameter_declarations">type parameter</a>,
|
||||
all types in its type set must be channel types that permit receive operations, and
|
||||
they must all have the same element type, which is the type of the receive operation.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
A receive expression used in an <a href="#Assignment_statements">assignment statement</a> or initialization of the special form
|
||||
</p>
|
||||
@@ -6063,7 +6126,8 @@ len("foo") // illegal if len is the built-in function
|
||||
|
||||
<p>
|
||||
A send statement sends a value on a channel.
|
||||
The channel expression must be of <a href="#Channel_types">channel type</a>,
|
||||
The channel expression's <a href="#Core_types">core type</a>
|
||||
must be a <a href="#Channel_types">channel</a>,
|
||||
the channel direction must permit send operations,
|
||||
and the type of the value to be sent must be <a href="#Assignability">assignable</a>
|
||||
to the channel's element type.
|
||||
@@ -6087,13 +6151,6 @@ A send on a <code>nil</code> channel blocks forever.
|
||||
ch <- 3 // send value 3 to channel ch
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If the type of the channel expression is a
|
||||
<a href="#Type_parameter_declarations">type parameter</a>,
|
||||
all types in its type set must be channel types that permit send operations,
|
||||
they must all have the same element type,
|
||||
and the type of the value to be sent must be assignable to that element type.
|
||||
</p>
|
||||
|
||||
<h3 id="IncDec_statements">IncDec statements</h3>
|
||||
|
||||
@@ -6638,7 +6695,7 @@ iteration's variable at that moment.
|
||||
|
||||
<pre>
|
||||
var prints []func()
|
||||
for i := 0; i < 5; i++ {
|
||||
for i := 0; i < 5; i++ {
|
||||
prints = append(prints, func() { println(i) })
|
||||
i++
|
||||
}
|
||||
@@ -6686,7 +6743,8 @@ RangeClause = [ ExpressionList "=" | IdentifierList ":=" ] "range" Expression .
|
||||
|
||||
<p>
|
||||
The expression on the right in the "range" clause is called the <i>range expression</i>,
|
||||
which may be an array, pointer to an array, slice, string, map, channel permitting
|
||||
its <a href="#Core_types">core type</a> must be
|
||||
an array, pointer to an array, slice, string, map, channel permitting
|
||||
<a href="#Receive_operator">receive operations</a>, an integer, or
|
||||
a function with specific signature (see below).
|
||||
As with an assignment, if present the operands on the left must be
|
||||
@@ -6775,7 +6833,7 @@ if the iteration variable is preexisting, the type of the iteration values is th
|
||||
variable, which must be of integer type.
|
||||
Otherwise, if the iteration variable is declared by the "range" clause or is absent,
|
||||
the type of the iteration values is the <a href="#Constants">default type</a> for <code>n</code>.
|
||||
If <code>n</code> <= 0, the loop does not run any iterations.
|
||||
If <code>n</code> <= 0, the loop does not run any iterations.
|
||||
</li>
|
||||
|
||||
<li>
|
||||
@@ -6886,7 +6944,7 @@ type Tree[K cmp.Ordered, V any] struct {
|
||||
}
|
||||
|
||||
func (t *Tree[K, V]) walk(yield func(key K, val V) bool) bool {
|
||||
return t == nil || t.left.walk(yield) && yield(t.key, t.value) && t.right.walk(yield)
|
||||
return t == nil || t.left.walk(yield) && yield(t.key, t.value) && t.right.walk(yield)
|
||||
}
|
||||
|
||||
func (t *Tree[K, V]) Walk(yield func(key K, val V) bool) {
|
||||
@@ -6900,12 +6958,6 @@ for k, v := range t.Walk {
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If the type of the range expression is a <a href="#Type_parameter_declarations">type parameter</a>,
|
||||
all types in its type set must have the same underlying type and the range expression must be valid
|
||||
for that type, or, if the type set contains channel types, it must only contain channel types with
|
||||
identical element types, and all channel types must permit receive operations.
|
||||
</p>
|
||||
|
||||
<h3 id="Go_statements">Go statements</h3>
|
||||
|
||||
@@ -7379,28 +7431,23 @@ by the arguments overlaps.
|
||||
|
||||
<p>
|
||||
The <a href="#Function_types">variadic</a> function <code>append</code>
|
||||
appends zero or more values <code>x</code> to a slice <code>s</code> of
|
||||
type <code>S</code> and returns the resulting slice, also of type
|
||||
<code>S</code>.
|
||||
appends zero or more values <code>x</code> to a slice <code>s</code>
|
||||
and returns the resulting slice of the same type as <code>s</code>.
|
||||
The <a href="#Core_types">core type</a> of <code>s</code> must be a slice
|
||||
of type <code>[]E</code>.
|
||||
The values <code>x</code> are passed to a parameter of type <code>...E</code>
|
||||
where <code>E</code> is the element type of <code>S</code>
|
||||
and the respective <a href="#Passing_arguments_to_..._parameters">parameter
|
||||
passing rules</a> apply.
|
||||
As a special case, <code>append</code> also accepts a slice whose type is assignable to
|
||||
type <code>[]byte</code> with a second argument of <code>string</code> type followed by
|
||||
<code>...</code>.
|
||||
This form appends the bytes of the string.
|
||||
As a special case, if the core type of <code>s</code> is <code>[]byte</code>,
|
||||
<code>append</code> also accepts a second argument with core type
|
||||
<a href="#Core_types"><code>bytestring</code></a> followed by <code>...</code>.
|
||||
This form appends the bytes of the byte slice or string.
|
||||
</p>
|
||||
|
||||
<pre class="grammar">
|
||||
append(s S, x ...E) S // E is the element type of S
|
||||
append(s S, x ...E) S // core type of S is []E
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If <code>S</code> is a <a href="#Type_parameter_declarations">type parameter</a>,
|
||||
all types in its type set must have the same underlying slice type <code>[]E</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the capacity of <code>s</code> is not large enough to fit the additional
|
||||
values, <code>append</code> <a href="#Allocation">allocates</a> a new, sufficiently large underlying
|
||||
@@ -7426,14 +7473,14 @@ b = append(b, "bar"...) // append string contents b is []byte{'b
|
||||
The function <code>copy</code> copies slice elements from
|
||||
a source <code>src</code> to a destination <code>dst</code> and returns the
|
||||
number of elements copied.
|
||||
Both arguments must have <a href="#Type_identity">identical</a> element type
|
||||
<code>E</code> and must be assignable to a slice of type <code>[]E</code>.
|
||||
The <a href="#Core_types">core types</a> of both arguments must be slices
|
||||
with <a href="#Type_identity">identical</a> element type.
|
||||
The number of elements copied is the minimum of
|
||||
<code>len(src)</code> and <code>len(dst)</code>.
|
||||
As a special case, <code>copy</code> also accepts a destination argument
|
||||
assignable to type <code>[]byte</code> with a source argument of a
|
||||
<code>string</code> type.
|
||||
This form copies the bytes from the string into the byte slice.
|
||||
As a special case, if the destination's core type is <code>[]byte</code>,
|
||||
<code>copy</code> also accepts a source argument with core type
|
||||
<a href="#Core_types"><code>bytestring</code></a>.
|
||||
This form copies the bytes from the byte slice or string into the byte slice.
|
||||
</p>
|
||||
|
||||
<pre class="grammar">
|
||||
@@ -7441,11 +7488,6 @@ copy(dst, src []T) int
|
||||
copy(dst []byte, src string) int
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If the type of one or both arguments is a <a href="#Type_parameter_declarations">type parameter</a>,
|
||||
all types in their respective type sets must have the same underlying slice type <code>[]E</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Examples:
|
||||
</p>
|
||||
@@ -7496,7 +7538,8 @@ If the map or slice is <code>nil</code>, <code>clear</code> is a no-op.
|
||||
<h3 id="Close">Close</h3>
|
||||
|
||||
<p>
|
||||
For a channel <code>ch</code>, the built-in function <code>close(ch)</code>
|
||||
For an argument <code>ch</code> with a <a href="#Core_types">core type</a>
|
||||
that is a <a href="#Channel_types">channel</a>, the built-in function <code>close</code>
|
||||
records that no more values will be sent on the channel.
|
||||
It is an error if <code>ch</code> is a receive-only channel.
|
||||
Sending to or closing a closed channel causes a <a href="#Run_time_panics">run-time panic</a>.
|
||||
@@ -7508,12 +7551,6 @@ The multi-valued <a href="#Receive_operator">receive operation</a>
|
||||
returns a received value along with an indication of whether the channel is closed.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the type of the argument to <code>close</code> is a
|
||||
<a href="#Type_parameter_declarations">type parameter</a>,
|
||||
all types in its type set must be channels.
|
||||
It is an error if any of those channels is a receive-only channel.
|
||||
</p>
|
||||
|
||||
<h3 id="Complex_numbers">Manipulating complex numbers</h3>
|
||||
|
||||
@@ -7683,36 +7720,27 @@ var z complex128
|
||||
|
||||
<p>
|
||||
The built-in function <code>make</code> takes a type <code>T</code>,
|
||||
which must be a slice, map or channel type, or a type parameter,
|
||||
optionally followed by a type-specific list of expressions.
|
||||
The <a href="#Core_types">core type</a> of <code>T</code> must
|
||||
be a slice, map or channel.
|
||||
It returns a value of type <code>T</code> (not <code>*T</code>).
|
||||
The memory is initialized as described in the section on
|
||||
<a href="#The_zero_value">initial values</a>.
|
||||
</p>
|
||||
|
||||
<pre class="grammar">
|
||||
Call Type T Result
|
||||
Call Core type Result
|
||||
|
||||
make(T, n) slice slice of type T with length n and capacity n
|
||||
make(T, n, m) slice slice of type T with length n and capacity m
|
||||
make(T, n) slice slice of type T with length n and capacity n
|
||||
make(T, n, m) slice slice of type T with length n and capacity m
|
||||
|
||||
make(T) map map of type T
|
||||
make(T, n) map map of type T with initial space for approximately n elements
|
||||
make(T) map map of type T
|
||||
make(T, n) map map of type T with initial space for approximately n elements
|
||||
|
||||
make(T) channel unbuffered channel of type T
|
||||
make(T, n) channel buffered channel of type T, buffer size n
|
||||
|
||||
make(T, n) type parameter see below
|
||||
make(T, n, m) type parameter see below
|
||||
make(T) channel unbuffered channel of type T
|
||||
make(T, n) channel buffered channel of type T, buffer size n
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If the first argument is a <a href="#Type_parameter_declarations">type parameter</a>,
|
||||
all types in its type set must have the same underlying type, which must be a slice
|
||||
or map type, or, if there are channel types, there must only be channel types, they
|
||||
must all have the same element type, and the channel directions must not conflict.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Each of the size arguments <code>n</code> and <code>m</code> must be of <a href="#Numeric_types">integer type</a>,
|
||||
have a <a href="#Interface_types">type set</a> containing only integer types,
|
||||
@@ -7802,39 +7830,27 @@ compared lexically byte-wise:
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
min(x, y) == if x <= y then x else y
|
||||
min(x, y) == if x <= y then x else y
|
||||
min(x, y, z) == min(min(x, y), z)
|
||||
</pre>
|
||||
|
||||
<h3 id="Allocation">Allocation</h3>
|
||||
|
||||
<p>
|
||||
The built-in function <code>new</code> creates a new, initialized
|
||||
<a href="#Variables">variable</a> and returns
|
||||
a <a href="#Pointer_types">pointer</a> to it.
|
||||
It accepts a single argument, which may be either a type or an expression.
|
||||
The built-in function <code>new</code> takes a type <code>T</code>,
|
||||
allocates storage for a <a href="#Variables">variable</a> of that type
|
||||
at run time, and returns a value of type <code>*T</code>
|
||||
<a href="#Pointer_types">pointing</a> to it.
|
||||
The variable is initialized as described in the section on
|
||||
<a href="#The_zero_value">initial values</a>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
If the argument is a type <code>T</code>, then <code>new(T)</code>
|
||||
allocates a variable of type <code>T</code> initialized to its
|
||||
<a href="#The_zero_value">zero value</a>.
|
||||
</p>
|
||||
<pre class="grammar">
|
||||
new(T)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
If the argument is an expression <code>x</code>, then <code>new(x)</code>
|
||||
allocates a variable of the type of <code>x</code> initialized to the value of <code>x</code>.
|
||||
If that value is an untyped constant, it is first implicitly <a href="#Conversions">converted</a>
|
||||
to its <a href="#Constants">default type</a>;
|
||||
if it is an untyped boolean value, it is first implicitly converted to type bool.
|
||||
The predeclared identifier <code>nil</code> cannot be used as an argument to <code>new</code>.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
For example, <code>new(int)</code> and <code>new(123)</code> each
|
||||
return a pointer to a new variable of type <code>int</code>.
|
||||
The value of the first variable is <code>0</code>, and the value
|
||||
of the second is <code>123</code>. Similarly
|
||||
For instance
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -7843,12 +7859,13 @@ new(S)
|
||||
</pre>
|
||||
|
||||
<p>
|
||||
allocates a variable of type <code>S</code>,
|
||||
allocates storage for a variable of type <code>S</code>,
|
||||
initializes it (<code>a=0</code>, <code>b=0.0</code>),
|
||||
and returns a value of type <code>*S</code> containing the address
|
||||
of the variable.
|
||||
of the location.
|
||||
</p>
|
||||
|
||||
|
||||
<h3 id="Handling_panics">Handling panics</h3>
|
||||
|
||||
<p> Two built-in functions, <code>panic</code> and <code>recover</code>,
|
||||
@@ -7908,7 +7925,7 @@ causes a <a href="#Run_time_panics">run-time panic</a>.
|
||||
<p>
|
||||
The <code>protect</code> function in the example below invokes
|
||||
the function argument <code>g</code> and protects callers from
|
||||
run-time panics caused by <code>g</code>.
|
||||
run-time panics raised by <code>g</code>.
|
||||
</p>
|
||||
|
||||
<pre>
|
||||
@@ -8466,14 +8483,17 @@ func String(ptr *byte, len IntegerType) string
|
||||
func StringData(str string) *byte
|
||||
</pre>
|
||||
|
||||
<!--
|
||||
These conversions also apply to type parameters with suitable core types.
|
||||
Determine if we can simply use core type instead of underlying type here,
|
||||
of if the general conversion rules take care of this.
|
||||
-->
|
||||
|
||||
<p>
|
||||
A <code>Pointer</code> is a <a href="#Pointer_types">pointer type</a> but a <code>Pointer</code>
|
||||
value may not be <a href="#Address_operators">dereferenced</a>.
|
||||
Any pointer or value of <a href="#Underlying_types">underlying type</a> <code>uintptr</code> can be
|
||||
<a href="#Conversions">converted</a> to a type of underlying type <code>Pointer</code> and vice versa.
|
||||
If the respective types are <a href="#Type_parameter_declarations">type parameters</a>, all types in
|
||||
their respective type sets must have the same underlying type, which must be <code>uintptr</code> and
|
||||
<code>Pointer</code>, respectively.
|
||||
Any pointer or value of <a href="#Core_types">core type</a> <code>uintptr</code> can be
|
||||
<a href="#Conversions">converted</a> to a type of core type <code>Pointer</code> and vice versa.
|
||||
The effect of converting between <code>Pointer</code> and <code>uintptr</code> is implementation-defined.
|
||||
</p>
|
||||
|
||||
@@ -8827,9 +8847,9 @@ following conditions is true:
|
||||
</li>
|
||||
<li>
|
||||
Exactly one type is an <a href="#Type_inference">unbound</a>
|
||||
type parameter, and all the types in its type set unify with
|
||||
the other type
|
||||
per the unification rules for <code>≡<sub>A</sub></code>
|
||||
type parameter with a <a href="#Core_types">core type</a>,
|
||||
and that core type unifies with the other type per the
|
||||
unification rules for <code>≡<sub>A</sub></code>
|
||||
(loose unification at the top level and exact unification
|
||||
for element types).
|
||||
</li>
|
||||
|
||||
105
doc/godebug.md
105
doc/godebug.md
@@ -109,9 +109,7 @@ Only the work module's `go.mod` is consulted for `godebug` directives.
|
||||
Any directives in required dependency modules are ignored.
|
||||
It is an error to list a `godebug` with an unrecognized setting.
|
||||
(Toolchains older than Go 1.23 reject all `godebug` lines, since they do not
|
||||
understand `godebug` at all.) When a workspace is in use, `godebug`
|
||||
directives in `go.mod` files are ignored, and `go.work` will be consulted
|
||||
for `godebug` directives instead.
|
||||
understand `godebug` at all.)
|
||||
|
||||
The defaults from the `go` and `godebug` lines apply to all main
|
||||
packages that are built. For more fine-grained control,
|
||||
@@ -153,84 +151,6 @@ for example,
|
||||
see the [runtime documentation](/pkg/runtime#hdr-Environment_Variables)
|
||||
and the [go command documentation](/cmd/go#hdr-Build_and_test_caching).
|
||||
|
||||
### Go 1.26
|
||||
|
||||
Go 1.26 added a new `httpcookiemaxnum` setting that controls the maximum number
|
||||
of cookies that net/http will accept when parsing HTTP headers. If the number of
|
||||
cookie in a header exceeds the number set in `httpcookiemaxnum`, cookie parsing
|
||||
will fail early. The default value is `httpcookiemaxnum=3000`. Setting
|
||||
`httpcookiemaxnum=0` will allow the cookie parsing to accept an indefinite
|
||||
number of cookies. To avoid denial of service attacks, this setting and default
|
||||
was backported to Go 1.25.2 and Go 1.24.8.
|
||||
|
||||
Go 1.26 added a new `urlmaxqueryparams` setting that controls the maximum number
|
||||
of query parameters that net/url will accept when parsing a URL-encoded query string.
|
||||
If the number of parameters exceeds the number set in `urlmaxqueryparams`,
|
||||
parsing will fail early. The default value is `urlmaxqueryparams=10000`.
|
||||
Setting `urlmaxqueryparams=0` disables the limit. To avoid denial of service
|
||||
attacks, this setting and default was backported to Go 1.25.6 and Go 1.24.12.
|
||||
|
||||
Go 1.26 added a new `urlstrictcolons` setting that controls whether `net/url.Parse`
|
||||
allows malformed hostnames containing colons outside of a bracketed IPv6 address.
|
||||
The default `urlstrictcolons=1` rejects URLs such as `http://localhost:1:2` or `http://::1/`.
|
||||
Colons are permitted as part of a bracketed IPv6 address, such as `http://[::1]/`.
|
||||
|
||||
Go 1.26 enabled two additional post-quantum key exchange mechanisms:
|
||||
SecP256r1MLKEM768 and SecP384r1MLKEM1024. The default can be reverted using the
|
||||
[`tlssecpmlkem` setting](/pkg/crypto/tls/#Config.CurvePreferences).
|
||||
|
||||
Go 1.26 added a new `tracebacklabels` setting that controls the inclusion of
|
||||
goroutine labels set through the the `runtime/pprof` package. Setting `tracebacklabels=1`
|
||||
includes these key/value pairs in the goroutine status header of runtime
|
||||
tracebacks and debug=2 runtime/pprof stack dumps. This format may change in the future.
|
||||
(see go.dev/issue/76349)
|
||||
|
||||
Go 1.26 added a new `cryptocustomrand` setting that controls whether most crypto/...
|
||||
APIs ignore the random `io.Reader` parameter. For Go 1.26, it defaults
|
||||
to `cryptocustomrand=0`, ignoring the random parameters. Using `cryptocustomrand=1`
|
||||
reverts to the pre-Go 1.26 behavior.
|
||||
|
||||
### Go 1.25
|
||||
|
||||
Go 1.25 added a new `decoratemappings` setting that controls whether the Go
|
||||
runtime annotates OS anonymous memory mappings with context about their
|
||||
purpose. These annotations appear in /proc/self/maps and /proc/self/smaps as
|
||||
"[anon: Go: ...]". This setting is only used on Linux. For Go 1.25, it defaults
|
||||
to `decoratemappings=1`, enabling annotations. Using `decoratemappings=0`
|
||||
reverts to the pre-Go 1.25 behavior. This setting is fixed at program startup
|
||||
time, and can't be modified by changing the `GODEBUG` environment variable
|
||||
after the program starts.
|
||||
|
||||
Go 1.25 added a new `embedfollowsymlinks` setting that controls whether the
|
||||
Go command will follow symlinks to regular files embedding files.
|
||||
The default value `embedfollowsymlinks=0` does not allow following
|
||||
symlinks. `embedfollowsymlinks=1` will allow following symlinks.
|
||||
|
||||
Go 1.25 added a new `containermaxprocs` setting that controls whether the Go
|
||||
runtime will consider cgroup CPU limits when setting the default GOMAXPROCS.
|
||||
The default value `containermaxprocs=1` will use cgroup limits in addition to
|
||||
the total logical CPU count and CPU affinity. `containermaxprocs=0` will
|
||||
disable consideration of cgroup limits. This setting only affects Linux.
|
||||
|
||||
Go 1.25 added a new `updatemaxprocs` setting that controls whether the Go
|
||||
runtime will periodically update GOMAXPROCS for new CPU affinity or cgroup
|
||||
limits. The default value `updatemaxprocs=1` will enable periodic updates.
|
||||
`updatemaxprocs=0` will disable periodic updates.
|
||||
|
||||
Go 1.25 disabled SHA-1 signature algorithms in TLS 1.2 according to RFC 9155.
|
||||
The default can be reverted using the `tlssha1=1` setting.
|
||||
|
||||
Go 1.25 switched to SHA-256 to fill in missing SubjectKeyId in
|
||||
crypto/x509.CreateCertificate. The setting `x509sha256skid=0` reverts to SHA-1.
|
||||
|
||||
Go 1.25 corrected the semantics of contention reports for runtime-internal locks,
|
||||
and so removed the [`runtimecontentionstacks` setting](/pkg/runtime#hdr-Environment_Variables).
|
||||
|
||||
Go 1.25 (starting with Go 1.25 RC 2) disabled build information stamping when
|
||||
multiple VCS are detected due to concerns around VCS injection attacks. This
|
||||
behavior and setting was backported to Go 1.24.5 and Go 1.23.11. This behavior
|
||||
can be renabled with the setting `allowmultiplevcs=1`.
|
||||
|
||||
### Go 1.24
|
||||
|
||||
Go 1.24 added a new `fips140` setting that controls whether the Go
|
||||
@@ -297,8 +217,6 @@ field by default.
|
||||
Go 1.24 enabled the post-quantum key exchange mechanism
|
||||
X25519MLKEM768 by default. The default can be reverted using the
|
||||
[`tlsmlkem` setting](/pkg/crypto/tls/#Config.CurvePreferences).
|
||||
This can be useful when dealing with buggy TLS servers that do not handle large records correctly,
|
||||
causing a timeout during the handshake (see [TLS post-quantum TL;DR fail](https://tldr.fail/)).
|
||||
Go 1.24 also removed X25519Kyber768Draft00 and the Go 1.23 `tlskyber` setting.
|
||||
|
||||
Go 1.24 made [`ParsePKCS1PrivateKey`](/pkg/crypto/x509/#ParsePKCS1PrivateKey)
|
||||
@@ -306,6 +224,10 @@ use and validate the CRT parameters in the encoded private key. This behavior
|
||||
can be controlled with the `x509rsacrt` setting. Using `x509rsacrt=0` restores
|
||||
the Go 1.23 behavior.
|
||||
|
||||
Go 1.24.5 disabled build information stamping when multiple VCS are detected due
|
||||
to concerns around VCS injection attacks. This behavior can be renabled with the
|
||||
setting `allowmultiplevcs=1`.
|
||||
|
||||
### Go 1.23
|
||||
|
||||
Go 1.23 changed the channels created by package time to be unbuffered
|
||||
@@ -313,7 +235,7 @@ Go 1.23 changed the channels created by package time to be unbuffered
|
||||
and [`Timer.Reset`](/pkg/time/#Timer.Reset) method results much easier.
|
||||
The [`asynctimerchan` setting](/pkg/time/#NewTimer) disables this change.
|
||||
There are no runtime metrics for this change,
|
||||
This setting will be removed in Go 1.27.
|
||||
This setting may be removed in a future release, Go 1.27 at the earliest.
|
||||
|
||||
Go 1.23 changed the mode bits reported by [`os.Lstat`](/pkg/os#Lstat) and [`os.Stat`](/pkg/os#Stat)
|
||||
for reparse points, which can be controlled with the `winsymlink` setting.
|
||||
@@ -335,8 +257,6 @@ Previous versions default to `winreadlinkvolume=0`.
|
||||
Go 1.23 enabled the experimental post-quantum key exchange mechanism
|
||||
X25519Kyber768Draft00 by default. The default can be reverted using the
|
||||
[`tlskyber` setting](/pkg/crypto/tls/#Config.CurvePreferences).
|
||||
This can be useful when dealing with buggy TLS servers that do not handle large records correctly,
|
||||
causing a timeout during the handshake (see [TLS post-quantum TL;DR fail](https://tldr.fail/)).
|
||||
|
||||
Go 1.23 changed the behavior of
|
||||
[crypto/x509.ParseCertificate](/pkg/crypto/x509/#ParseCertificate) to reject
|
||||
@@ -350,7 +270,6 @@ any effect.
|
||||
Go 1.23 changed the default TLS cipher suites used by clients and servers when
|
||||
not explicitly configured, removing 3DES cipher suites. The default can be reverted
|
||||
using the [`tls3des` setting](/pkg/crypto/tls/#Config.CipherSuites).
|
||||
This setting will be removed in Go 1.27.
|
||||
|
||||
Go 1.23 changed the behavior of [`tls.X509KeyPair`](/pkg/crypto/tls#X509KeyPair)
|
||||
and [`tls.LoadX509KeyPair`](/pkg/crypto/tls#LoadX509KeyPair) to populate the
|
||||
@@ -358,7 +277,6 @@ Leaf field of the returned [`tls.Certificate`](/pkg/crypto/tls#Certificate).
|
||||
This behavior is controlled by the `x509keypairleaf` setting. For Go 1.23, it
|
||||
defaults to `x509keypairleaf=1`. Previous versions default to
|
||||
`x509keypairleaf=0`.
|
||||
This setting will be removed in Go 1.27.
|
||||
|
||||
Go 1.23 changed
|
||||
[`net/http.ServeContent`](/pkg/net/http#ServeContent),
|
||||
@@ -392,31 +310,28 @@ Whether the type checker produces `Alias` types or not is controlled by the
|
||||
[`gotypesalias` setting](/pkg/go/types#Alias).
|
||||
For Go 1.22 it defaults to `gotypesalias=0`.
|
||||
For Go 1.23, `gotypesalias=1` will become the default.
|
||||
This setting will be removed in Go 1.27.
|
||||
This setting will be removed in a future release, Go 1.27 at the earliest.
|
||||
|
||||
Go 1.22 changed the default minimum TLS version supported by both servers
|
||||
and clients to TLS 1.2. The default can be reverted to TLS 1.0 using the
|
||||
[`tls10server` setting](/pkg/crypto/tls/#Config).
|
||||
This setting will be removed in Go 1.27.
|
||||
|
||||
Go 1.22 changed the default TLS cipher suites used by clients and servers when
|
||||
not explicitly configured, removing the cipher suites which used RSA based key
|
||||
exchange. The default can be reverted using the [`tlsrsakex` setting](/pkg/crypto/tls/#Config).
|
||||
This setting will be removed in Go 1.27.
|
||||
|
||||
Go 1.22 disabled
|
||||
[`ConnectionState.ExportKeyingMaterial`](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial)
|
||||
when the connection supports neither TLS 1.3 nor Extended Master Secret
|
||||
(implemented in Go 1.21). It can be reenabled with the [`tlsunsafeekm`
|
||||
setting](/pkg/crypto/tls/#ConnectionState.ExportKeyingMaterial).
|
||||
This setting will be removed in Go 1.27.
|
||||
|
||||
Go 1.22 changed how the runtime interacts with transparent huge pages on Linux.
|
||||
In particular, a common default Linux kernel configuration can result in
|
||||
significant memory overheads, and Go 1.22 no longer works around this default.
|
||||
To work around this issue without adjusting kernel settings, transparent huge
|
||||
pages can be disabled for Go memory with the
|
||||
[`disablethp` setting](/pkg/runtime#hdr-Environment_Variables).
|
||||
[`disablethp` setting](/pkg/runtime#hdr-Environment_Variable).
|
||||
This behavior was backported to Go 1.21.1, but the setting is only available
|
||||
starting with Go 1.21.6.
|
||||
This setting may be removed in a future release, and users impacted by this issue
|
||||
@@ -428,7 +343,7 @@ Go 1.22 added contention on runtime-internal locks to the [`mutex`
|
||||
profile](/pkg/runtime/pprof#Profile). Contention on these locks is always
|
||||
reported at `runtime._LostContendedRuntimeLock`. Complete stack traces of
|
||||
runtime locks can be enabled with the [`runtimecontentionstacks`
|
||||
setting](/pkg/runtime#hdr-Environment_Variables). These stack traces have
|
||||
setting](/pkg/runtime#hdr-Environment_Variable). These stack traces have
|
||||
non-standard semantics, see setting documentation for details.
|
||||
|
||||
Go 1.22 added a new [`crypto/x509.Certificate`](/pkg/crypto/x509/#Certificate)
|
||||
@@ -437,7 +352,7 @@ certificate policy OIDs with components larger than 31 bits. By default this
|
||||
field is only used during parsing, when it is populated with policy OIDs, but
|
||||
not used during marshaling. It can be used to marshal these larger OIDs, instead
|
||||
of the existing PolicyIdentifiers field, by using the
|
||||
[`x509usepolicies` setting](/pkg/crypto/x509/#CreateCertificate).
|
||||
[`x509usepolicies` setting.](/pkg/crypto/x509/#CreateCertificate).
|
||||
|
||||
|
||||
### Go 1.21
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
### Minor changes to the library {#minor_library_changes}
|
||||
|
||||
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
<style>
|
||||
main ul li { margin: 0.5em 0; }
|
||||
</style>
|
||||
|
||||
## DRAFT RELEASE NOTES — Introduction to Go 1.27 {#introduction}
|
||||
|
||||
**Go 1.27 is not yet released. These are work-in-progress release notes.
|
||||
Go 1.27 is expected to be released in August 2026.**
|
||||
@@ -1,3 +0,0 @@
|
||||
## Changes to the language {#language}
|
||||
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
## Tools {#tools}
|
||||
|
||||
### Go command {#go-command}
|
||||
|
||||
### Cgo {#cgo}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
## Runtime {#runtime}
|
||||
@@ -1,7 +0,0 @@
|
||||
## Compiler {#compiler}
|
||||
|
||||
## Assembler {#assembler}
|
||||
|
||||
## Linker {#linker}
|
||||
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
## Standard library {#library}
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
### Minor changes to the library {#minor_library_changes}
|
||||
@@ -1 +0,0 @@
|
||||
API changes and other small changes to the standard library go here.
|
||||
@@ -1 +0,0 @@
|
||||
The scanner now allows retrieving the end position of a token via the new [Scanner.End] method.
|
||||
@@ -1,4 +0,0 @@
|
||||
HTTP/2 server now accepts client priority signals, as defined in RFC 9218,
|
||||
allowing it to prioritize serving HTTP/2 streams with higher priority. If the
|
||||
old behavior is preferred, where streams are served in a round-robin manner
|
||||
regardless of priority, [Server.DisableClientPriority] can be set to `true`.
|
||||
@@ -1 +0,0 @@
|
||||
The new [Sleep] helper function combines [time.Sleep] and [testing/synctest.Wait].
|
||||
@@ -1,4 +0,0 @@
|
||||
The unicode package and associated support throughout the system has been upgraded from Unicode 15 to Unicode 17.
|
||||
See the [Unicode 16.0.0](https://www.unicode.org/versions/Unicode16.0.0/) and
|
||||
[Unicode 17.0.0](https://www.unicode.org/versions/Unicode17.0.0/)
|
||||
release notes for information about the changes.
|
||||
@@ -1,8 +0,0 @@
|
||||
## Ports {#ports}
|
||||
|
||||
### Darwin {#darwin}
|
||||
|
||||
<!-- go.dev/issue/75836 -->
|
||||
As [announced](go1.26#darwin) in the Go 1.26 release notes,
|
||||
Go 1.27 requires macOS 13 Ventura or later;
|
||||
support for previous versions has been discontinued.
|
||||
@@ -30,7 +30,7 @@ v%.zip:
|
||||
go run ../../src/cmd/go/internal/fips140/mkzip.go v$*
|
||||
|
||||
# normally mkzip refuses to overwrite an existing zip file.
|
||||
# make v1.2.3.rm removes the zip file and unpacked
|
||||
# make v1.2.3.rm removes the zip file and and unpacked
|
||||
# copy from the module cache.
|
||||
v%.rm:
|
||||
rm -f v$*.zip
|
||||
|
||||
@@ -9,5 +9,4 @@
|
||||
#
|
||||
# go test cmd/go/internal/fips140 -update
|
||||
#
|
||||
v1.0.0-c2097c7c.zip daf3614e0406f67ae6323c902db3f953a1effb199142362a039e7526dfb9368b
|
||||
v1.26.0.zip 9b28f847fdf1db4a36cb2b2f8ec09443c039383f085630a03ecfaddf6db7ea23
|
||||
v1.0.0.zip b50508feaeff05d22516b21e1fd210bbf5d6a1e422eaf2cfa23fe379342713b8
|
||||
|
||||
@@ -1 +1 @@
|
||||
v1.0.0-c2097c7c
|
||||
v1.0.0
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
v1.0.0-c2097c7c
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,64 +0,0 @@
|
||||
# Copyright 2025 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.
|
||||
|
||||
# Mercurial extension to add a 'goreposum' command that
|
||||
# computes a hash of a remote repo's tag state.
|
||||
# Tag definitions can come from the .hgtags file stored in
|
||||
# any head of any branch, and the server protocol does not
|
||||
# expose the tags directly. However, the protocol does expose
|
||||
# the hashes of all the branch heads, so we can use a hash of
|
||||
# all those branch names and heads as a conservative snapshot
|
||||
# of the entire remote repo state, and use that as the tag sum.
|
||||
# Any change on the server then invalidates the tag sum,
|
||||
# even if it didn't have anything to do with tags, but at least
|
||||
# we will avoid re-cloning a server when there have been no
|
||||
# changes at all.
|
||||
#
|
||||
# Separately, this extension also adds a 'golookup' command that
|
||||
# returns the hash of a specific reference, like 'default' or a tag.
|
||||
# And golookup of a hash confirms that it still exists on the server.
|
||||
# We can use that to revalidate that specific versions still exist and
|
||||
# have the same meaning they did the last time we checked.
|
||||
#
|
||||
# Usage:
|
||||
#
|
||||
# hg --config "extensions.goreposum=$GOROOT/lib/hg/goreposum.py" goreposum REPOURL
|
||||
|
||||
import base64, hashlib, sys
|
||||
from mercurial import registrar, ui, hg, node
|
||||
from mercurial.i18n import _
|
||||
cmdtable = {}
|
||||
command = registrar.command(cmdtable)
|
||||
@command(b'goreposum', [], _('url'), norepo=True)
|
||||
def goreposum(ui, url):
|
||||
"""
|
||||
goreposum computes a checksum of all the named state in the remote repo.
|
||||
It hashes together all the branch names and hashes
|
||||
and then all the bookmark names and hashes.
|
||||
Tags are stored in .hgtags files in any of the branches,
|
||||
so the branch metadata includes the tags as well.
|
||||
"""
|
||||
h = hashlib.sha256()
|
||||
peer = hg.peer(ui, {}, url)
|
||||
for name, revs in peer.branchmap().items():
|
||||
h.update(name)
|
||||
for r in revs:
|
||||
h.update(b' ')
|
||||
h.update(r)
|
||||
h.update(b'\n')
|
||||
if (b'bookmarks' in peer.listkeys(b'namespaces')):
|
||||
for name, rev in peer.listkeys(b'bookmarks').items():
|
||||
h.update(name)
|
||||
h.update(b'=')
|
||||
h.update(rev)
|
||||
h.update(b'\n')
|
||||
print('r1:'+base64.standard_b64encode(h.digest()).decode('utf-8'))
|
||||
|
||||
@command(b'golookup', [], _('url rev'), norepo=True)
|
||||
def golookup(ui, url, rev):
|
||||
"""
|
||||
golookup looks up a single identifier in the repo,
|
||||
printing its hash.
|
||||
"""
|
||||
print(node.hex(hg.peer(ui, {}, url).lookup(rev)).decode('utf-8'))
|
||||
@@ -24,8 +24,8 @@
|
||||
# in the CL match the update.bash in the CL.
|
||||
|
||||
# Versions to use.
|
||||
CODE=2025c
|
||||
DATA=2025c
|
||||
CODE=2025a
|
||||
DATA=2025a
|
||||
|
||||
set -e
|
||||
|
||||
@@ -40,12 +40,7 @@ curl -sS -L -O https://www.iana.org/time-zones/repository/releases/tzdata$DATA.t
|
||||
tar xzf tzcode$CODE.tar.gz
|
||||
tar xzf tzdata$DATA.tar.gz
|
||||
|
||||
# The PACKRATLIST and PACKRATDATA options are copied from Ubuntu:
|
||||
# https://git.launchpad.net/ubuntu/+source/tzdata/tree/debian/rules?h=debian/sid
|
||||
#
|
||||
# You can see the description of these make variables in the tzdata Makefile:
|
||||
# https://github.com/eggert/tz/blob/main/Makefile
|
||||
if ! make CFLAGS=-DSTD_INSPIRED AWK=awk TZDIR=zoneinfo PACKRATDATA=backzone PACKRATLIST=zone.tab posix_only >make.out 2>&1; then
|
||||
if ! make CFLAGS=-DSTD_INSPIRED AWK=awk TZDIR=zoneinfo posix_only >make.out 2>&1; then
|
||||
cat make.out
|
||||
exit 2
|
||||
fi
|
||||
|
||||
Binary file not shown.
@@ -14,7 +14,7 @@ case "$GOWASIRUNTIME" in
|
||||
exec wazero run -mount /:/ -env-inherit -cachedir "${TMPDIR:-/tmp}"/wazero ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}"
|
||||
;;
|
||||
"wasmtime" | "")
|
||||
exec wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" -W max-wasm-stack=8388608 ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}"
|
||||
exec wasmtime run --dir=/ --env PWD="$PWD" --env PATH="$PATH" -W max-wasm-stack=1048576 ${GOWASIRUNTIMEARGS:-} "$1" "${@:2}"
|
||||
;;
|
||||
*)
|
||||
echo "Unknown Go WASI runtime specified: $GOWASIRUNTIME"
|
||||
|
||||
@@ -212,7 +212,7 @@ func copyLocalData(dstbase string) (pkgpath string, err error) {
|
||||
// Copy all immediate files and testdata directories between
|
||||
// the package being tested and the source root.
|
||||
pkgpath = ""
|
||||
for element := range strings.SplitSeq(finalPkgpath, string(filepath.Separator)) {
|
||||
for _, element := range strings.Split(finalPkgpath, string(filepath.Separator)) {
|
||||
if debug {
|
||||
log.Printf("copying %s", pkgpath)
|
||||
}
|
||||
|
||||
191
misc/linkcheck/linkcheck.go
Normal file
191
misc/linkcheck/linkcheck.go
Normal file
@@ -0,0 +1,191 @@
|
||||
// Copyright 2013 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// The linkcheck command finds missing links in the godoc website.
|
||||
// It crawls a URL recursively and notes URLs and URL fragments
|
||||
// that it's seen and prints a report of missing links at the end.
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
root = flag.String("root", "http://localhost:6060", "Root to crawl")
|
||||
verbose = flag.Bool("verbose", false, "verbose")
|
||||
)
|
||||
|
||||
var wg sync.WaitGroup // outstanding fetches
|
||||
var urlq = make(chan string) // URLs to crawl
|
||||
|
||||
// urlFrag is a URL and its optional #fragment (without the #)
|
||||
type urlFrag struct {
|
||||
url, frag string
|
||||
}
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
crawled = make(map[string]bool) // URL without fragment -> true
|
||||
neededFrags = make(map[urlFrag][]string) // URL#frag -> who needs it
|
||||
)
|
||||
|
||||
var aRx = regexp.MustCompile(`<a href=['"]?(/[^\s'">]+)`)
|
||||
|
||||
// Owned by crawlLoop goroutine:
|
||||
var (
|
||||
linkSources = make(map[string][]string) // url no fragment -> sources
|
||||
fragExists = make(map[urlFrag]bool)
|
||||
problems []string
|
||||
)
|
||||
|
||||
func localLinks(body string) (links []string) {
|
||||
seen := map[string]bool{}
|
||||
mv := aRx.FindAllStringSubmatch(body, -1)
|
||||
for _, m := range mv {
|
||||
ref := m[1]
|
||||
if strings.HasPrefix(ref, "/src/") {
|
||||
continue
|
||||
}
|
||||
if !seen[ref] {
|
||||
seen[ref] = true
|
||||
links = append(links, m[1])
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var idRx = regexp.MustCompile(`\bid=['"]?([^\s'">]+)`)
|
||||
|
||||
func pageIDs(body string) (ids []string) {
|
||||
mv := idRx.FindAllStringSubmatch(body, -1)
|
||||
for _, m := range mv {
|
||||
ids = append(ids, m[1])
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// url may contain a #fragment, and the fragment is then noted as needing to exist.
|
||||
func crawl(url string, sourceURL string) {
|
||||
if strings.Contains(url, "/devel/release") {
|
||||
return
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if u, frag, ok := strings.Cut(url, "#"); ok {
|
||||
url = u
|
||||
if frag != "" {
|
||||
uf := urlFrag{url, frag}
|
||||
neededFrags[uf] = append(neededFrags[uf], sourceURL)
|
||||
}
|
||||
}
|
||||
if crawled[url] {
|
||||
return
|
||||
}
|
||||
crawled[url] = true
|
||||
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
urlq <- url
|
||||
}()
|
||||
}
|
||||
|
||||
func addProblem(url, errmsg string) {
|
||||
msg := fmt.Sprintf("Error on %s: %s (from %s)", url, errmsg, linkSources[url])
|
||||
if *verbose {
|
||||
log.Print(msg)
|
||||
}
|
||||
problems = append(problems, msg)
|
||||
}
|
||||
|
||||
func crawlLoop() {
|
||||
for url := range urlq {
|
||||
if err := doCrawl(url); err != nil {
|
||||
addProblem(url, err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func doCrawl(url string) error {
|
||||
defer wg.Done()
|
||||
|
||||
req, err := http.NewRequest("GET", url, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := http.DefaultTransport.RoundTrip(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Handle redirects.
|
||||
if res.StatusCode/100 == 3 {
|
||||
newURL, err := res.Location()
|
||||
if err != nil {
|
||||
return fmt.Errorf("resolving redirect: %v", err)
|
||||
}
|
||||
if !strings.HasPrefix(newURL.String(), *root) {
|
||||
// Skip off-site redirects.
|
||||
return nil
|
||||
}
|
||||
crawl(newURL.String(), url)
|
||||
return nil
|
||||
}
|
||||
if res.StatusCode != 200 {
|
||||
return errors.New(res.Status)
|
||||
}
|
||||
slurp, err := io.ReadAll(res.Body)
|
||||
res.Body.Close()
|
||||
if err != nil {
|
||||
log.Fatalf("Error reading %s body: %v", url, err)
|
||||
}
|
||||
if *verbose {
|
||||
log.Printf("Len of %s: %d", url, len(slurp))
|
||||
}
|
||||
body := string(slurp)
|
||||
for _, ref := range localLinks(body) {
|
||||
if *verbose {
|
||||
log.Printf(" links to %s", ref)
|
||||
}
|
||||
dest := *root + ref
|
||||
linkSources[dest] = append(linkSources[dest], url)
|
||||
crawl(dest, url)
|
||||
}
|
||||
for _, id := range pageIDs(body) {
|
||||
if *verbose {
|
||||
log.Printf(" url %s has #%s", url, id)
|
||||
}
|
||||
fragExists[urlFrag{url, id}] = true
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
flag.Parse()
|
||||
|
||||
go crawlLoop()
|
||||
crawl(*root, "")
|
||||
|
||||
wg.Wait()
|
||||
close(urlq)
|
||||
for uf, needers := range neededFrags {
|
||||
if !fragExists[uf] {
|
||||
problems = append(problems, fmt.Sprintf("Missing fragment for %+v from %v", uf, needers))
|
||||
}
|
||||
}
|
||||
|
||||
for _, s := range problems {
|
||||
fmt.Println(s)
|
||||
}
|
||||
if len(problems) > 0 {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
@@ -39,14 +39,12 @@ Go from source and use that 'go' binary to update its source tree.
|
||||
|
||||
Requirements may be added, updated, and removed with 'go get'.
|
||||
The vendor directory may be updated with 'go mod vendor'.
|
||||
Tree inconsistencies are reported by 'go test cmd/internal/moddeps'.
|
||||
A typical sequence might be:
|
||||
|
||||
cd src # or src/cmd
|
||||
go get golang.org/x/net@master
|
||||
go mod tidy
|
||||
go mod vendor
|
||||
go test cmd/internal/moddeps
|
||||
|
||||
Use caution when passing '-u' to 'go get'. The '-u' flag updates
|
||||
modules providing all transitively imported packages, not only
|
||||
@@ -55,22 +53,3 @@ the module providing the target package.
|
||||
Note that 'go mod vendor' only copies packages that are transitively
|
||||
imported by packages in the current module. If a new package is needed,
|
||||
it should be imported before running 'go mod vendor'.
|
||||
|
||||
Go release cycle considerations
|
||||
===============================
|
||||
|
||||
Applying changes to packages that are vendored follows the considerations
|
||||
written down at go.dev/s/release.
|
||||
|
||||
When the Go tree is open for development, a specific change may be pulled in
|
||||
at any time that it is needed. During the release freeze, the bar for changes
|
||||
in vendored packages is the same as it is for changes in non-vendored packages.
|
||||
After a major release is out, minor Go releases follow a more involved process
|
||||
documented at go.dev/wiki/MinorReleases#cherry-pick-cls-for-vendored-golangorgx-packages.
|
||||
|
||||
In addition to individual updates that happen on demand, all dependencies in
|
||||
the std and cmd modules are updated to their latest available versions at least
|
||||
twice during every major release cycle. This is done to avoid the possibility of
|
||||
some dependencies being left on very old versions and in turn make their eventual
|
||||
update more disruptive. This recurring process is tracked in go.dev/issue/36905.
|
||||
The golang.org/x/build/cmd/updatestd command exists to assist with that process.
|
||||
|
||||
@@ -10,4 +10,4 @@ if [ ! -f make.bash ]; then
|
||||
fi
|
||||
. ./make.bash "$@" --no-banner
|
||||
bash run.bash --no-rebuild
|
||||
../bin/go tool dist banner # print build info
|
||||
"$GOTOOLDIR/dist" banner # print build info
|
||||
|
||||
20
src/all.bat
20
src/all.bat
@@ -6,11 +6,17 @@
|
||||
|
||||
setlocal
|
||||
|
||||
if not exist make.bat (
|
||||
echo all.bat must be run from go\src
|
||||
exit /b 1
|
||||
)
|
||||
if exist make.bat goto ok
|
||||
echo all.bat must be run from go\src
|
||||
:: cannot exit: would kill parent command interpreter
|
||||
goto end
|
||||
:ok
|
||||
|
||||
call .\make.bat --no-banner || exit /b 1
|
||||
call .\run.bat --no-rebuild || exit /b 1
|
||||
..\bin\go tool dist banner
|
||||
call .\make.bat --no-banner --no-local
|
||||
if %GOBUILDFAIL%==1 goto end
|
||||
call .\run.bat --no-rebuild --no-local
|
||||
if %GOBUILDFAIL%==1 goto end
|
||||
"%GOTOOLDIR%/dist" banner
|
||||
|
||||
:end
|
||||
if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
|
||||
|
||||
@@ -13,4 +13,4 @@ if(! test -f make.rc){
|
||||
. ./make.rc --no-banner $*
|
||||
bind -b $GOROOT/bin /bin
|
||||
./run.rc --no-rebuild
|
||||
../bin/go tool dist banner # print build info
|
||||
$GOTOOLDIR/dist banner # print build info
|
||||
|
||||
@@ -39,7 +39,6 @@ var (
|
||||
errMissData = errors.New("archive/tar: sparse file references non-existent data")
|
||||
errUnrefData = errors.New("archive/tar: sparse file contains unreferenced data")
|
||||
errWriteHole = errors.New("archive/tar: write non-NUL byte in sparse hole")
|
||||
errSparseTooLong = errors.New("archive/tar: sparse map too long")
|
||||
)
|
||||
|
||||
type headerError []string
|
||||
|
||||
@@ -531,17 +531,12 @@ func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {
|
||||
cntNewline int64
|
||||
buf bytes.Buffer
|
||||
blk block
|
||||
totalSize int
|
||||
)
|
||||
|
||||
// feedTokens copies data in blocks from r into buf until there are
|
||||
// at least cnt newlines in buf. It will not read more blocks than needed.
|
||||
feedTokens := func(n int64) error {
|
||||
for cntNewline < n {
|
||||
totalSize += len(blk)
|
||||
if totalSize > maxSpecialFileSize {
|
||||
return errSparseTooLong
|
||||
}
|
||||
if _, err := mustReadFull(r, blk[:]); err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -574,8 +569,8 @@ func readGNUSparseMap1x0(r io.Reader) (sparseDatas, error) {
|
||||
}
|
||||
|
||||
// Parse for all member entries.
|
||||
// numEntries is trusted after this since feedTokens limits the number of
|
||||
// tokens based on maxSpecialFileSize.
|
||||
// numEntries is trusted after this since a potential attacker must have
|
||||
// committed resources proportional to what this library used.
|
||||
if err := feedTokens(2 * numEntries); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash/crc32"
|
||||
"internal/obscuretestdata"
|
||||
"io"
|
||||
"maps"
|
||||
"math"
|
||||
@@ -26,11 +25,10 @@ import (
|
||||
|
||||
func TestReader(t *testing.T) {
|
||||
vectors := []struct {
|
||||
file string // Test input file
|
||||
obscured bool // Obscured with obscuretestdata package
|
||||
headers []*Header // Expected output headers
|
||||
chksums []string // CRC32 checksum of files, leave as nil if not checked
|
||||
err error // Expected error to occur
|
||||
file string // Test input file
|
||||
headers []*Header // Expected output headers
|
||||
chksums []string // CRC32 checksum of files, leave as nil if not checked
|
||||
err error // Expected error to occur
|
||||
}{{
|
||||
file: "testdata/gnu.tar",
|
||||
headers: []*Header{{
|
||||
@@ -525,9 +523,8 @@ func TestReader(t *testing.T) {
|
||||
file: "testdata/pax-nul-path.tar",
|
||||
err: ErrHeader,
|
||||
}, {
|
||||
file: "testdata/neg-size.tar.base64",
|
||||
obscured: true,
|
||||
err: ErrHeader,
|
||||
file: "testdata/neg-size.tar",
|
||||
err: ErrHeader,
|
||||
}, {
|
||||
file: "testdata/issue10968.tar",
|
||||
err: ErrHeader,
|
||||
@@ -624,32 +621,18 @@ func TestReader(t *testing.T) {
|
||||
},
|
||||
Format: FormatPAX,
|
||||
}},
|
||||
}, {
|
||||
// Small compressed file that uncompresses to
|
||||
// a file with a very large GNU 1.0 sparse map.
|
||||
file: "testdata/gnu-sparse-many-zeros.tar.bz2",
|
||||
err: errSparseTooLong,
|
||||
}}
|
||||
|
||||
for _, v := range vectors {
|
||||
t.Run(strings.TrimSuffix(path.Base(v.file), ".base64"), func(t *testing.T) {
|
||||
path := v.file
|
||||
if v.obscured {
|
||||
tf, err := obscuretestdata.DecodeToTempFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("obscuredtestdata.DecodeToTempFile(%s): %v", path, err)
|
||||
}
|
||||
path = tf
|
||||
}
|
||||
|
||||
f, err := os.Open(path)
|
||||
t.Run(path.Base(v.file), func(t *testing.T) {
|
||||
f, err := os.Open(v.file)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
var fr io.Reader = f
|
||||
if strings.HasSuffix(v.file, ".bz2") || strings.HasSuffix(v.file, ".bz2.base64") {
|
||||
if strings.HasSuffix(v.file, ".bz2") {
|
||||
fr = bzip2.NewReader(fr)
|
||||
}
|
||||
|
||||
@@ -787,7 +770,7 @@ type readBadSeeker struct{ io.ReadSeeker }
|
||||
|
||||
func (rbs *readBadSeeker) Seek(int64, int) (int64, error) { return 0, fmt.Errorf("illegal seek") }
|
||||
|
||||
// TestReadTruncation tests the ending condition on various truncated files and
|
||||
// TestReadTruncation test the ending condition on various truncated files and
|
||||
// that truncated files are still detected even if the underlying io.Reader
|
||||
// satisfies io.Seeker.
|
||||
func TestReadTruncation(t *testing.T) {
|
||||
|
||||
@@ -19,7 +19,7 @@ func init() {
|
||||
sysStat = statUnix
|
||||
}
|
||||
|
||||
// userMap and groupMap cache UID and GID lookups for performance reasons.
|
||||
// userMap and groupMap caches UID and GID lookups for performance reasons.
|
||||
// The downside is that renaming uname or gname by the OS never takes effect.
|
||||
var userMap, groupMap sync.Map // map[int]string
|
||||
|
||||
|
||||
@@ -213,17 +213,15 @@ func parsePAXTime(s string) (time.Time, error) {
|
||||
}
|
||||
|
||||
// Parse the nanoseconds.
|
||||
// Initialize an array with '0's to handle right padding automatically.
|
||||
nanoDigits := [maxNanoSecondDigits]byte{'0', '0', '0', '0', '0', '0', '0', '0', '0'}
|
||||
for i := range len(sn) {
|
||||
switch c := sn[i]; {
|
||||
case c < '0' || c > '9':
|
||||
return time.Time{}, ErrHeader
|
||||
case i < len(nanoDigits):
|
||||
nanoDigits[i] = c
|
||||
}
|
||||
if strings.Trim(sn, "0123456789") != "" {
|
||||
return time.Time{}, ErrHeader
|
||||
}
|
||||
nsecs, _ := strconv.ParseInt(string(nanoDigits[:]), 10, 64) // Must succeed after validation
|
||||
if len(sn) < maxNanoSecondDigits {
|
||||
sn += strings.Repeat("0", maxNanoSecondDigits-len(sn)) // Right pad
|
||||
} else {
|
||||
sn = sn[:maxNanoSecondDigits] // Right truncate
|
||||
}
|
||||
nsecs, _ := strconv.ParseInt(sn, 10, 64) // Must succeed
|
||||
if len(ss) > 0 && ss[0] == '-' {
|
||||
return time.Unix(secs, -1*nsecs), nil // Negative correction
|
||||
}
|
||||
@@ -312,7 +310,7 @@ func formatPAXRecord(k, v string) (string, error) {
|
||||
// "%d %s=%s\n" % (size, key, value)
|
||||
//
|
||||
// Keys and values should be UTF-8, but the number of bad writers out there
|
||||
// forces us to be more liberal.
|
||||
// forces us to be a more liberal.
|
||||
// Thus, we only reject all keys with NUL, and only reject NULs in values
|
||||
// for the PAX version of the USTAR string fields.
|
||||
// The key must not contain an '=' character.
|
||||
|
||||
@@ -439,66 +439,3 @@ func TestFormatPAXRecord(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkParsePAXTime(b *testing.B) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in string
|
||||
want time.Time
|
||||
ok bool
|
||||
}{
|
||||
{
|
||||
name: "NoNanos",
|
||||
in: "123456",
|
||||
want: time.Unix(123456, 0),
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
name: "ExactNanos",
|
||||
in: "1.123456789",
|
||||
want: time.Unix(1, 123456789),
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
name: "WithNanoPadding",
|
||||
in: "1.123",
|
||||
want: time.Unix(1, 123000000),
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
name: "WithNanoTruncate",
|
||||
in: "1.123456789123",
|
||||
want: time.Unix(1, 123456789),
|
||||
ok: true,
|
||||
},
|
||||
{
|
||||
name: "TrailingError",
|
||||
in: "1.123abc",
|
||||
want: time.Time{},
|
||||
ok: false,
|
||||
},
|
||||
{
|
||||
name: "LeadingError",
|
||||
in: "1.abc123",
|
||||
want: time.Time{},
|
||||
ok: false,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
b.Run(tt.name, func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for b.Loop() {
|
||||
ts, err := parsePAXTime(tt.in)
|
||||
if (err == nil) != tt.ok {
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
b.Fatal("expected error")
|
||||
}
|
||||
if !ts.Equal(tt.want) {
|
||||
b.Fatalf("time mismatch: got %v, want %v", ts, tt.want)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
BIN
src/archive/tar/testdata/gnu-sparse-big.tar
vendored
Normal file
BIN
src/archive/tar/testdata/gnu-sparse-big.tar
vendored
Normal file
Binary file not shown.
@@ -1,90 +0,0 @@
|
||||
Z251LXNwYXJzZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAAMDAwMDAw
|
||||
MAAwMDAwMDAwADAwMDAwMDA2MDAwADAwMDAwMDAwMDAwADAyMjIyNwAgUwAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhciAgAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwADAwMDAw
|
||||
MDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAlQL4gAw
|
||||
MDAwMDAwMTAwMACAAAAAAAAABKgXxgAwMDAwMDAwMTAwMACAAAAAAAAABvwjqgAwMDAwMDAwMTAw
|
||||
MACAAAAAAAAACVAvjgAwMDAwMDAwMTAwMAABgAAAAAAAAA34R1gAAAAAAAAAAAAAAAAAAAAAAACA
|
||||
AAAAAAAAC6Q7cgAwMDAwMDAwMTAwMACAAAAAAAAADfhHVgAwMDAwMDAwMTAwMAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1
|
||||
Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAADAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2
|
||||
Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3
|
||||
ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4
|
||||
OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5AAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAADAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5
|
||||
MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkw
|
||||
MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
|
||||
Binary file not shown.
BIN
src/archive/tar/testdata/neg-size.tar
vendored
Normal file
BIN
src/archive/tar/testdata/neg-size.tar
vendored
Normal file
Binary file not shown.
9
src/archive/tar/testdata/neg-size.tar.base64
vendored
9
src/archive/tar/testdata/neg-size.tar.base64
vendored
@@ -1,9 +0,0 @@
|
||||
EwMwMBMDLTgyMTk1MDI5NnQTE4NzfINzEzAwcXfhZrsDMDAwAAAAEDAxMRNz9DEwMTAwdBMTg3N8
|
||||
g3NzADATc3yDc3P0eFMTc/QxMDEwMHQTE4NzfINzc/QwE3N8g3Nz9HFTMNR0MBMwMHEw9DAAAAAQ
|
||||
MDGAABAwMTETc/QxMDH0MHQTMDBx1OFmuwMAAAD/gICAADExNTYyMQAgMBP///+AMTAwdHhTMDB0
|
||||
MBMwMHF3MDEwMTAwdBMTg3N8g3Nz9HhTMDB0MBMwMHF34Wa7AzAwMAAAABAwMTETc/QxMDEwMHQT
|
||||
E4NzfINzc/QwE3N8g3Nz9HhTE3P0MTAxMDB0ExODc3yDc3MwMBNzfINzczB4UzAwdDATMDBxMDAA
|
||||
gAAAEDAxc/QxMDEwMHQTAAAAIOFmuwMwNAAAABAwMTET////gDEwMHR4UzAwdDATMDBxd+FmuwMw
|
||||
MDAAAAAQMDExE3ODc3P0eFMTc/QxMDEwMHQTE4NzfINzc/QzMTEwMzM2MjQ4NDYxMjgzODBzfINz
|
||||
c/R4UzAwdDATMDBxMDAwAAAAEDAxAAAQMDExE3P0MTAxMDB0EzAwcdThZrsDMDQAAAAQg3N8g3Nz
|
||||
9DATc3yDc3P0eFMwMHQwEzAwcTAwMAAAABAwMQAAEDAxMRNz9DEwMTAwdBMwMHgw4Wa7AwAAEDA=
|
||||
BIN
src/archive/tar/testdata/pax-sparse-big.tar
vendored
Normal file
BIN
src/archive/tar/testdata/pax-sparse-big.tar
vendored
Normal file
Binary file not shown.
108
src/archive/tar/testdata/pax-sparse-big.tar.base64
vendored
108
src/archive/tar/testdata/pax-sparse-big.tar.base64
vendored
@@ -1,108 +0,0 @@
|
||||
UGF4SGVhZGVycy4wL3BheC1zcGFyc2UAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAwMDAwMDAAMDAwMDAw
|
||||
MAAwMDAwMDAwADAwMDAwMDAwMTcyADAwMDAwMDAwMDAwADAxMjIyNwAgeAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhcgAwMAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAy
|
||||
MiBHTlUuc3BhcnNlLm1ham9yPTEKMjIgR05VLnNwYXJzZS5taW5vcj0wCjMwIEdOVS5zcGFyc2Uu
|
||||
bmFtZT1wYXgtc3BhcnNlCjM1IEdOVS5zcGFyc2UucmVhbHNpemU9NjAwMDAwMDAwMDAKMTMgc2l6
|
||||
ZT0zNTg0CgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEdO
|
||||
VVNwYXJzZUZpbGUuMC9wYXgtc3BhcnNlAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwMDAwMDAwADAwMDAwMDAA
|
||||
MDAwMDAwMAAwMDAwMDAwNzAwMAAwMDAwMDAwMDAwMAAwMTM3MzcAIDAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdXN0YXIAMDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMAAwMDAwMDAw
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAANgo5
|
||||
OTk5OTk5NDg4CjUxMgoxOTk5OTk5OTQ4OAo1MTIKMjk5OTk5OTk0ODgKNTEyCjM5OTk5OTk5NDg4
|
||||
CjUxMgo0OTk5OTk5OTQ4OAo1MTIKNTk5OTk5OTk0ODgKNTEyCgAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3
|
||||
ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4
|
||||
OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5AAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAADAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5
|
||||
MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAMDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkw
|
||||
MTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OQAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAx
|
||||
MjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5AAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAADAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEy
|
||||
MzQ1Njc4OTAxMjM0NTY3ODkwMTIzNDU2Nzg5MDEyMzQ1Njc4OTAxMjM0NTY3ODkAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
BIN
src/archive/tar/testdata/writer-big-long.tar
vendored
Normal file
BIN
src/archive/tar/testdata/writer-big-long.tar
vendored
Normal file
Binary file not shown.
@@ -1,27 +0,0 @@
|
||||
bG9uZ25hbWUvbG9uZ25hbWUvbG9uZ25hbWUvbG9uZ25hbWUvbG9uZ25hbWUvbG9uZ25hbWUvbG9u
|
||||
Z25hbWUvbG9uZ25hbWUvbG9uZ25hbWUvbG9uZ25hbWUvbG9uZ25hbWUvbDAwMDAwMDAAMDAwMDAw
|
||||
MAAwMDAwMDAwADAwMDAwMDAwMjU2ADAwMDAwMDAwMDAwADAzMTQyMAAgeAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB1c3RhcgAwMAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAx
|
||||
NTQgcGF0aD1sb25nbmFtZS9sb25nbmFtZS9sb25nbmFtZS9sb25nbmFtZS9sb25nbmFtZS9sb25n
|
||||
bmFtZS9sb25nbmFtZS9sb25nbmFtZS9sb25nbmFtZS9sb25nbmFtZS9sb25nbmFtZS9sb25nbmFt
|
||||
ZS9sb25nbmFtZS9sb25nbmFtZS9sb25nbmFtZS8xNmdpZy50eHQKMjAgc2l6ZT0xNzE3OTg2OTE4
|
||||
NAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGxv
|
||||
bmduYW1lL2xvbmduYW1lL2xvbmduYW1lL2xvbmduYW1lL2xvbmduYW1lL2xvbmduYW1lL2xvbmdu
|
||||
YW1lL2xvbmduYW1lL2xvbmduYW1lL2xvbmduYW1lL2xvbmduYW1lL2wwMDAwNjQ0ADAwMDE3NTAA
|
||||
MDAwMTc1MAAwMDAwMDAwMDAwMAAxMjMzMjc3MDUwNwAwMzY0NjIAIDAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAdXN0YXIAMDBndWlsbGF1bWUAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAGd1aWxsYXVtZQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMDAwMDAwMAAwMDAwMDAw
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
@@ -415,17 +415,11 @@ func (tw *Writer) AddFS(fsys fs.FS) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
linkTarget := ""
|
||||
if typ := d.Type(); typ == fs.ModeSymlink {
|
||||
var err error
|
||||
linkTarget, err = fs.ReadLink(fsys, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else if !typ.IsRegular() && typ != fs.ModeDir {
|
||||
// TODO(#49580): Handle symlinks when fs.ReadLinkFS is available.
|
||||
if !d.IsDir() && !info.Mode().IsRegular() {
|
||||
return errors.New("tar: cannot add non-regular file")
|
||||
}
|
||||
h, err := FileInfoHeader(info, linkTarget)
|
||||
h, err := FileInfoHeader(info, "")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -436,7 +430,7 @@ func (tw *Writer) AddFS(fsys fs.FS) error {
|
||||
if err := tw.WriteHeader(h); err != nil {
|
||||
return err
|
||||
}
|
||||
if !d.Type().IsRegular() {
|
||||
if d.IsDir() {
|
||||
return nil
|
||||
}
|
||||
f, err := fsys.Open(name)
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"internal/obscuretestdata"
|
||||
"io"
|
||||
"io/fs"
|
||||
"maps"
|
||||
@@ -75,9 +74,8 @@ func TestWriter(t *testing.T) {
|
||||
)
|
||||
|
||||
vectors := []struct {
|
||||
file string // Optional filename of expected output
|
||||
obscured bool // Whether file is obscured
|
||||
tests []testFnc
|
||||
file string // Optional filename of expected output
|
||||
tests []testFnc
|
||||
}{{
|
||||
// The writer test file was produced with this command:
|
||||
// tar (GNU tar) 1.26
|
||||
@@ -153,8 +151,7 @@ func TestWriter(t *testing.T) {
|
||||
// bsdtar -xvf writer-big-long.tar
|
||||
//
|
||||
// This file is in PAX format.
|
||||
file: "testdata/writer-big-long.tar.base64",
|
||||
obscured: true,
|
||||
file: "testdata/writer-big-long.tar",
|
||||
tests: []testFnc{
|
||||
testHeader{Header{
|
||||
Typeflag: TypeReg,
|
||||
@@ -396,8 +393,7 @@ func TestWriter(t *testing.T) {
|
||||
testClose{},
|
||||
},
|
||||
}, {
|
||||
file: "testdata/gnu-sparse-big.tar.base64",
|
||||
obscured: true,
|
||||
file: "testdata/gnu-sparse-big.tar",
|
||||
tests: []testFnc{
|
||||
testHeader{Header{
|
||||
Typeflag: TypeGNUSparse,
|
||||
@@ -429,8 +425,7 @@ func TestWriter(t *testing.T) {
|
||||
testClose{nil},
|
||||
},
|
||||
}, {
|
||||
file: "testdata/pax-sparse-big.tar.base64",
|
||||
obscured: true,
|
||||
file: "testdata/pax-sparse-big.tar",
|
||||
tests: []testFnc{
|
||||
testHeader{Header{
|
||||
Typeflag: TypeReg,
|
||||
@@ -488,7 +483,7 @@ func TestWriter(t *testing.T) {
|
||||
return x == y
|
||||
}
|
||||
for _, v := range vectors {
|
||||
t.Run(strings.TrimSuffix(path.Base(v.file), ".base64"), func(t *testing.T) {
|
||||
t.Run(path.Base(v.file), func(t *testing.T) {
|
||||
const maxSize = 10 << 10 // 10KiB
|
||||
buf := new(bytes.Buffer)
|
||||
tw := NewWriter(iotest.TruncateWriter(buf, maxSize))
|
||||
@@ -527,16 +522,7 @@ func TestWriter(t *testing.T) {
|
||||
}
|
||||
|
||||
if v.file != "" {
|
||||
path := v.file
|
||||
if v.obscured {
|
||||
tf, err := obscuretestdata.DecodeToTempFile(path)
|
||||
if err != nil {
|
||||
t.Fatalf("obscuretestdata.DecodeToTempFile(%s): %v", path, err)
|
||||
}
|
||||
path = tf
|
||||
}
|
||||
|
||||
want, err := os.ReadFile(path)
|
||||
want, err := os.ReadFile(v.file)
|
||||
if err != nil {
|
||||
t.Fatalf("ReadFile() = %v, want nil", err)
|
||||
}
|
||||
@@ -1356,7 +1342,6 @@ func TestWriterAddFS(t *testing.T) {
|
||||
"emptyfolder": {Mode: 0o755 | os.ModeDir},
|
||||
"file.go": {Data: []byte("hello")},
|
||||
"subfolder/another.go": {Data: []byte("world")},
|
||||
"symlink.go": {Mode: 0o777 | os.ModeSymlink, Data: []byte("file.go")},
|
||||
// Notably missing here is the "subfolder" directory. This makes sure even
|
||||
// if we don't have a subfolder directory listed.
|
||||
}
|
||||
@@ -1385,7 +1370,7 @@ func TestWriterAddFS(t *testing.T) {
|
||||
for _, name := range names {
|
||||
entriesLeft--
|
||||
|
||||
entryInfo, err := fsys.Lstat(name)
|
||||
entryInfo, err := fsys.Stat(name)
|
||||
if err != nil {
|
||||
t.Fatalf("getting entry info error: %v", err)
|
||||
}
|
||||
@@ -1411,23 +1396,18 @@ func TestWriterAddFS(t *testing.T) {
|
||||
name, entryInfo.Mode(), hdr.FileInfo().Mode())
|
||||
}
|
||||
|
||||
switch entryInfo.Mode().Type() {
|
||||
case fs.ModeDir:
|
||||
// No additional checks necessary.
|
||||
case fs.ModeSymlink:
|
||||
origtarget := string(fsys[name].Data)
|
||||
if hdr.Linkname != origtarget {
|
||||
t.Fatalf("test fs has link content %s; archive header %v", origtarget, hdr.Linkname)
|
||||
}
|
||||
default:
|
||||
data, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
origdata := fsys[name].Data
|
||||
if string(data) != string(origdata) {
|
||||
t.Fatalf("test fs has file content %v; archive header has %v", origdata, data)
|
||||
}
|
||||
if entryInfo.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
data, err := io.ReadAll(tr)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
origdata := fsys[name].Data
|
||||
if string(data) != string(origdata) {
|
||||
t.Fatalf("test fs has file content %v; archive header has %v",
|
||||
data, origdata)
|
||||
}
|
||||
}
|
||||
if entriesLeft > 0 {
|
||||
|
||||
@@ -8,7 +8,6 @@ import (
|
||||
"bufio"
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"hash/crc32"
|
||||
"internal/godebug"
|
||||
@@ -805,9 +804,6 @@ func toValidName(name string) string {
|
||||
|
||||
func (r *Reader) initFileList() {
|
||||
r.fileListOnce.Do(func() {
|
||||
// Preallocate the minimum size of the index.
|
||||
// We may also synthesize additional directory entries.
|
||||
r.fileList = make([]fileListEntry, 0, len(r.File))
|
||||
// files and knownDirs map from a file/directory name
|
||||
// to an index into the r.fileList entry that we are
|
||||
// building. They are used to mark duplicate entries.
|
||||
@@ -834,16 +830,7 @@ func (r *Reader) initFileList() {
|
||||
continue
|
||||
}
|
||||
|
||||
dir := name
|
||||
for {
|
||||
if idx := strings.LastIndex(dir, "/"); idx < 0 {
|
||||
break
|
||||
} else {
|
||||
dir = dir[:idx]
|
||||
}
|
||||
if dirs[dir] {
|
||||
break
|
||||
}
|
||||
for dir := path.Dir(name); dir != "."; dir = path.Dir(dir) {
|
||||
dirs[dir] = true
|
||||
}
|
||||
|
||||
@@ -998,12 +985,6 @@ func (d *openDir) ReadDir(count int) ([]fs.DirEntry, error) {
|
||||
s, err := d.files[d.offset+i].stat()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
} else if s.Name() == "." || !fs.ValidPath(s.Name()) {
|
||||
return nil, &fs.PathError{
|
||||
Op: "readdir",
|
||||
Path: d.e.name,
|
||||
Err: fmt.Errorf("invalid file name: %v", d.files[d.offset+i].name),
|
||||
}
|
||||
}
|
||||
list[i] = s
|
||||
}
|
||||
|
||||
@@ -8,8 +8,6 @@ import (
|
||||
"bytes"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"internal/obscuretestdata"
|
||||
"io"
|
||||
"io/fs"
|
||||
@@ -1214,6 +1212,7 @@ func TestFS(t *testing.T) {
|
||||
[]string{"a/b/c"},
|
||||
},
|
||||
} {
|
||||
test := test
|
||||
t.Run(test.file, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
z, err := OpenReader(test.file)
|
||||
@@ -1247,6 +1246,7 @@ func TestFSWalk(t *testing.T) {
|
||||
wantErr: true,
|
||||
},
|
||||
} {
|
||||
test := test
|
||||
t.Run(test.file, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
z, err := OpenReader(test.file)
|
||||
@@ -1281,49 +1281,6 @@ func TestFSWalk(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSWalkBadFile(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var buf bytes.Buffer
|
||||
zw := NewWriter(&buf)
|
||||
hdr := &FileHeader{Name: "."}
|
||||
hdr.SetMode(fs.ModeDir | 0o755)
|
||||
w, err := zw.CreateHeader(hdr)
|
||||
if err != nil {
|
||||
t.Fatalf("create zip header: %v", err)
|
||||
}
|
||||
_, err = w.Write([]byte("some data"))
|
||||
if err != nil {
|
||||
t.Fatalf("write zip contents: %v", err)
|
||||
|
||||
}
|
||||
err = zw.Close()
|
||||
if err != nil {
|
||||
t.Fatalf("close zip writer: %v", err)
|
||||
|
||||
}
|
||||
|
||||
zr, err := NewReader(bytes.NewReader(buf.Bytes()), int64(buf.Len()))
|
||||
if err != nil {
|
||||
t.Fatalf("create zip reader: %v", err)
|
||||
|
||||
}
|
||||
var count int
|
||||
var errRepeat = errors.New("repeated call to path")
|
||||
err = fs.WalkDir(zr, ".", func(p string, d fs.DirEntry, err error) error {
|
||||
count++
|
||||
if count > 2 { // once for directory read, once for the error
|
||||
return errRepeat
|
||||
}
|
||||
return err
|
||||
})
|
||||
if err == nil {
|
||||
t.Fatalf("expected error from invalid file name")
|
||||
} else if errors.Is(err, errRepeat) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFSModTime(t *testing.T) {
|
||||
t.Parallel()
|
||||
z, err := OpenReader("testdata/subdir.zip")
|
||||
@@ -1875,83 +1832,3 @@ func TestBaseOffsetPlusOverflow(t *testing.T) {
|
||||
// as the section reader offset & size were < 0.
|
||||
NewReader(bytes.NewReader(data), int64(len(data))+1875)
|
||||
}
|
||||
|
||||
func BenchmarkReaderOneDeepDir(b *testing.B) {
|
||||
var buf bytes.Buffer
|
||||
zw := NewWriter(&buf)
|
||||
|
||||
for i := range 4000 {
|
||||
name := strings.Repeat("a/", i) + "data"
|
||||
zw.CreateHeader(&FileHeader{
|
||||
Name: name,
|
||||
Method: Store,
|
||||
})
|
||||
}
|
||||
|
||||
if err := zw.Close(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
data := buf.Bytes()
|
||||
|
||||
for b.Loop() {
|
||||
zr, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
zr.Open("does-not-exist")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReaderManyDeepDirs(b *testing.B) {
|
||||
var buf bytes.Buffer
|
||||
zw := NewWriter(&buf)
|
||||
|
||||
for i := range 2850 {
|
||||
name := fmt.Sprintf("%x", i)
|
||||
name = strings.Repeat("/"+name, i+1)[1:]
|
||||
|
||||
zw.CreateHeader(&FileHeader{
|
||||
Name: name,
|
||||
Method: Store,
|
||||
})
|
||||
}
|
||||
|
||||
if err := zw.Close(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
data := buf.Bytes()
|
||||
|
||||
for b.Loop() {
|
||||
zr, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
zr.Open("does-not-exist")
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReaderManyShallowFiles(b *testing.B) {
|
||||
var buf bytes.Buffer
|
||||
zw := NewWriter(&buf)
|
||||
|
||||
for i := range 310000 {
|
||||
name := fmt.Sprintf("%v", i)
|
||||
zw.CreateHeader(&FileHeader{
|
||||
Name: name,
|
||||
Method: Store,
|
||||
})
|
||||
}
|
||||
|
||||
if err := zw.Close(); err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
data := buf.Bytes()
|
||||
|
||||
for b.Loop() {
|
||||
zr, err := NewReader(bytes.NewReader(data), int64(len(data)))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
zr.Open("does-not-exist")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -311,7 +311,10 @@ func (b *Reader) ReadRune() (r rune, size int, err error) {
|
||||
if b.r == b.w {
|
||||
return 0, 0, b.readErr()
|
||||
}
|
||||
r, size = utf8.DecodeRune(b.buf[b.r:b.w])
|
||||
r, size = rune(b.buf[b.r]), 1
|
||||
if r >= utf8.RuneSelf {
|
||||
r, size = utf8.DecodeRune(b.buf[b.r:b.w])
|
||||
}
|
||||
b.r += size
|
||||
b.lastByte = int(b.buf[b.r-1])
|
||||
b.lastRuneSize = size
|
||||
@@ -516,11 +519,9 @@ func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
|
||||
b.lastByte = -1
|
||||
b.lastRuneSize = -1
|
||||
|
||||
if b.r < b.w {
|
||||
n, err = b.writeBuf(w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
n, err = b.writeBuf(w)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if r, ok := b.rd.(io.WriterTo); ok {
|
||||
|
||||
@@ -1149,7 +1149,7 @@ func (w errorWriterToTest) Write(p []byte) (int, error) {
|
||||
var errorWriterToTests = []errorWriterToTest{
|
||||
{1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe},
|
||||
{0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
|
||||
{0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrUnexpectedEOF},
|
||||
{0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrClosedPipe},
|
||||
{0, 1, io.EOF, nil, nil},
|
||||
}
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
// Copyright 2025 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build unix
|
||||
|
||||
package bufio_test
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"io"
|
||||
"net"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestCopyUnixpacket tests that we can use bufio when copying
|
||||
// across a unixpacket socket. This used to fail due to an unnecessary
|
||||
// empty Write call that was interpreted as an EOF.
|
||||
func TestCopyUnixpacket(t *testing.T) {
|
||||
tmpDir := t.TempDir()
|
||||
socket := filepath.Join(tmpDir, "unixsock")
|
||||
|
||||
// Start a unixpacket server.
|
||||
addr := &net.UnixAddr{
|
||||
Name: socket,
|
||||
Net: "unixpacket",
|
||||
}
|
||||
server, err := net.ListenUnix("unixpacket", addr)
|
||||
if err != nil {
|
||||
t.Skipf("skipping test because opening a unixpacket socket failed: %v", err)
|
||||
}
|
||||
|
||||
// Start a goroutine for the server to accept one connection
|
||||
// and read all the data sent on the connection,
|
||||
// reporting the number of bytes read on ch.
|
||||
ch := make(chan int, 1)
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
defer wg.Done()
|
||||
|
||||
tot := 0
|
||||
defer func() {
|
||||
ch <- tot
|
||||
}()
|
||||
|
||||
serverConn, err := server.Accept()
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
|
||||
buf := make([]byte, 1024)
|
||||
for {
|
||||
n, err := serverConn.Read(buf)
|
||||
tot += n
|
||||
if err == io.EOF {
|
||||
return
|
||||
}
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
}
|
||||
}()
|
||||
|
||||
clientConn, err := net.DialUnix("unixpacket", nil, addr)
|
||||
if err != nil {
|
||||
// Leaves the server goroutine hanging. Oh well.
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
defer wg.Wait()
|
||||
defer clientConn.Close()
|
||||
|
||||
const data = "data"
|
||||
r := bufio.NewReader(strings.NewReader(data))
|
||||
n, err := io.Copy(clientConn, r)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if n != int64(len(data)) {
|
||||
t.Errorf("io.Copy returned %d, want %d", n, len(data))
|
||||
}
|
||||
|
||||
clientConn.Close()
|
||||
tot := <-ch
|
||||
|
||||
if tot != len(data) {
|
||||
t.Errorf("server read %d, want %d", tot, len(data))
|
||||
}
|
||||
}
|
||||
@@ -260,11 +260,8 @@ func (s *Scanner) setErr(err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// Buffer controls memory allocation by the Scanner.
|
||||
// It sets the initial buffer to use when scanning
|
||||
// Buffer sets the initial buffer to use when scanning
|
||||
// and the maximum size of buffer that may be allocated during scanning.
|
||||
// The contents of the buffer are ignored.
|
||||
//
|
||||
// The maximum token size must be less than the larger of max and cap(buf).
|
||||
// If max <= cap(buf), [Scanner.Scan] will use this buffer only and do no allocation.
|
||||
//
|
||||
|
||||
@@ -21,12 +21,6 @@ type Buffer struct {
|
||||
buf []byte // contents are the bytes buf[off : len(buf)]
|
||||
off int // read at &buf[off], write at &buf[len(buf)]
|
||||
lastRead readOp // last read operation, so that Unread* can work correctly.
|
||||
|
||||
// Copying and modifying a non-zero Buffer is prone to error,
|
||||
// but we cannot employ the noCopy trick used by WaitGroup and Mutex,
|
||||
// which causes vet's copylocks checker to report misuse, as vet
|
||||
// cannot reliably distinguish the zero and non-zero cases.
|
||||
// See #26462, #25907, #47276, #48398 for history.
|
||||
}
|
||||
|
||||
// The readOp constants describe the last action performed on
|
||||
@@ -77,18 +71,6 @@ func (b *Buffer) String() string {
|
||||
return string(b.buf[b.off:])
|
||||
}
|
||||
|
||||
// Peek returns the next n bytes without advancing the buffer.
|
||||
// If Peek returns fewer than n bytes, it also returns [io.EOF].
|
||||
// The slice is only valid until the next call to a read or write method.
|
||||
// The slice aliases the buffer content at least until the next buffer modification,
|
||||
// so immediate changes to the slice will affect the result of future reads.
|
||||
func (b *Buffer) Peek(n int) ([]byte, error) {
|
||||
if b.Len() < n {
|
||||
return b.buf[b.off:], io.EOF
|
||||
}
|
||||
return b.buf[b.off : b.off+n], nil
|
||||
}
|
||||
|
||||
// empty reports whether the unread portion of the buffer is empty.
|
||||
func (b *Buffer) empty() bool { return len(b.buf) <= b.off }
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ func TestWriteAppend(t *testing.T) {
|
||||
got.Write(b)
|
||||
}
|
||||
if !Equal(got.Bytes(), want) {
|
||||
t.Fatalf("Bytes() = %q, want %q", &got, want)
|
||||
t.Fatalf("Bytes() = %q, want %q", got, want)
|
||||
}
|
||||
|
||||
// With a sufficiently sized buffer, there should be no allocations.
|
||||
@@ -531,40 +531,6 @@ func TestReadString(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
var peekTests = []struct {
|
||||
buffer string
|
||||
skip int
|
||||
n int
|
||||
expected string
|
||||
err error
|
||||
}{
|
||||
{"", 0, 0, "", nil},
|
||||
{"aaa", 0, 3, "aaa", nil},
|
||||
{"foobar", 0, 2, "fo", nil},
|
||||
{"a", 0, 2, "a", io.EOF},
|
||||
{"helloworld", 4, 3, "owo", nil},
|
||||
{"helloworld", 5, 5, "world", nil},
|
||||
{"helloworld", 5, 6, "world", io.EOF},
|
||||
{"helloworld", 10, 1, "", io.EOF},
|
||||
}
|
||||
|
||||
func TestPeek(t *testing.T) {
|
||||
for _, test := range peekTests {
|
||||
buf := NewBufferString(test.buffer)
|
||||
buf.Next(test.skip)
|
||||
bytes, err := buf.Peek(test.n)
|
||||
if string(bytes) != test.expected {
|
||||
t.Errorf("expected %q, got %q", test.expected, bytes)
|
||||
}
|
||||
if err != test.err {
|
||||
t.Errorf("expected error %v, got %v", test.err, err)
|
||||
}
|
||||
if buf.Len() != len(test.buffer)-test.skip {
|
||||
t.Errorf("bad length after peek: %d, want %d", buf.Len(), len(test.buffer)-test.skip)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkReadString(b *testing.B) {
|
||||
const n = 32 << 10
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ func IndexAny(s []byte, chars string) int {
|
||||
}
|
||||
return IndexRune(s, r)
|
||||
}
|
||||
if shouldUseASCIISet(len(s)) {
|
||||
if len(s) > 8 {
|
||||
if as, isASCII := makeASCIISet(chars); isASCII {
|
||||
for i, c := range s {
|
||||
if as.contains(c) {
|
||||
@@ -301,7 +301,7 @@ func LastIndexAny(s []byte, chars string) int {
|
||||
// Avoid scanning all of s.
|
||||
return -1
|
||||
}
|
||||
if shouldUseASCIISet(len(s)) {
|
||||
if len(s) > 8 {
|
||||
if as, isASCII := makeASCIISet(chars); isASCII {
|
||||
for i := len(s) - 1; i >= 0; i-- {
|
||||
if as.contains(s[i]) {
|
||||
@@ -451,9 +451,7 @@ var asciiSpace = [256]uint8{'\t': 1, '\n': 1, '\v': 1, '\f': 1, '\r': 1, ' ': 1}
|
||||
// Fields interprets s as a sequence of UTF-8-encoded code points.
|
||||
// It splits the slice s around each instance of one or more consecutive white space
|
||||
// characters, as defined by [unicode.IsSpace], returning a slice of subslices of s or an
|
||||
// empty slice if s contains only white space. Every element of the returned slice is
|
||||
// non-empty. Unlike [Split], leading and trailing runs of white space characters
|
||||
// are discarded.
|
||||
// empty slice if s contains only white space.
|
||||
func Fields(s []byte) [][]byte {
|
||||
// First count the fields.
|
||||
// This is an exact count if s is ASCII, otherwise it is an approximation.
|
||||
@@ -507,9 +505,7 @@ func Fields(s []byte) [][]byte {
|
||||
// FieldsFunc interprets s as a sequence of UTF-8-encoded code points.
|
||||
// It splits the slice s at each run of code points c satisfying f(c) and
|
||||
// returns a slice of subslices of s. If all code points in s satisfy f(c), or
|
||||
// len(s) == 0, an empty slice is returned. Every element of the returned slice is
|
||||
// non-empty. Unlike [Split], leading and trailing runs of code points
|
||||
// satisfying f(c) are discarded.
|
||||
// len(s) == 0, an empty slice is returned.
|
||||
//
|
||||
// FieldsFunc makes no guarantees about the order in which it calls f(c)
|
||||
// and assumes that f always returns the same value for a given c.
|
||||
@@ -528,7 +524,11 @@ func FieldsFunc(s []byte, f func(rune) bool) [][]byte {
|
||||
// more efficient, possibly due to cache effects.
|
||||
start := -1 // valid span start if >= 0
|
||||
for i := 0; i < len(s); {
|
||||
r, size := utf8.DecodeRune(s[i:])
|
||||
size := 1
|
||||
r := rune(s[i])
|
||||
if r >= utf8.RuneSelf {
|
||||
r, size = utf8.DecodeRune(s[i:])
|
||||
}
|
||||
if f(r) {
|
||||
if start >= 0 {
|
||||
spans = append(spans, span{start, i})
|
||||
@@ -610,7 +610,11 @@ func Map(mapping func(r rune) rune, s []byte) []byte {
|
||||
// fine. It could also shrink but that falls out naturally.
|
||||
b := make([]byte, 0, len(s))
|
||||
for i := 0; i < len(s); {
|
||||
r, wid := utf8.DecodeRune(s[i:])
|
||||
wid := 1
|
||||
r := rune(s[i])
|
||||
if r >= utf8.RuneSelf {
|
||||
r, wid = utf8.DecodeRune(s[i:])
|
||||
}
|
||||
r = mapping(r)
|
||||
if r >= 0 {
|
||||
b = utf8.AppendRune(b, r)
|
||||
@@ -909,7 +913,11 @@ func LastIndexFunc(s []byte, f func(r rune) bool) int {
|
||||
func indexFunc(s []byte, f func(r rune) bool, truth bool) int {
|
||||
start := 0
|
||||
for start < len(s) {
|
||||
r, wid := utf8.DecodeRune(s[start:])
|
||||
wid := 1
|
||||
r := rune(s[start])
|
||||
if r >= utf8.RuneSelf {
|
||||
r, wid = utf8.DecodeRune(s[start:])
|
||||
}
|
||||
if f(r) == truth {
|
||||
return start
|
||||
}
|
||||
@@ -935,22 +943,15 @@ func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
|
||||
return -1
|
||||
}
|
||||
|
||||
// asciiSet is a 256-byte lookup table for fast ASCII character membership testing.
|
||||
// Each element corresponds to an ASCII character value, with true indicating the
|
||||
// character is in the set. Using bool instead of byte allows the compiler to
|
||||
// eliminate the comparison instruction, as bool values are guaranteed to be 0 or 1.
|
||||
//
|
||||
// The full 256-element table is used rather than a 128-element table to avoid
|
||||
// additional operations in the lookup path. Alternative approaches were tested:
|
||||
// - [128]bool with explicit bounds check (if c >= 128): introduces branches
|
||||
// that cause pipeline stalls, resulting in ~70% slower performance
|
||||
// - [128]bool with masking (c&0x7f): eliminates bounds checks but the AND
|
||||
// operation still costs ~10% performance compared to direct indexing
|
||||
//
|
||||
// The 256-element array allows direct indexing with no bounds checks, no branches,
|
||||
// and no masking operations, providing optimal performance. The additional 128 bytes
|
||||
// of memory is a worthwhile tradeoff for the simpler, faster code.
|
||||
type asciiSet [256]bool
|
||||
// asciiSet is a 32-byte value, where each bit represents the presence of a
|
||||
// given ASCII character in the set. The 128-bits of the lower 16 bytes,
|
||||
// starting with the least-significant bit of the lowest word to the
|
||||
// most-significant bit of the highest word, map to the full range of all
|
||||
// 128 ASCII characters. The 128-bits of the upper 16 bytes will be zeroed,
|
||||
// ensuring that any non-ASCII character will be reported as not in the set.
|
||||
// This allocates a total of 32 bytes even though the upper half
|
||||
// is unused to avoid bounds checks in asciiSet.contains.
|
||||
type asciiSet [8]uint32
|
||||
|
||||
// makeASCIISet creates a set of ASCII characters and reports whether all
|
||||
// characters in chars are ASCII.
|
||||
@@ -960,24 +961,14 @@ func makeASCIISet(chars string) (as asciiSet, ok bool) {
|
||||
if c >= utf8.RuneSelf {
|
||||
return as, false
|
||||
}
|
||||
as[c] = true
|
||||
as[c/32] |= 1 << (c % 32)
|
||||
}
|
||||
return as, true
|
||||
}
|
||||
|
||||
// contains reports whether c is inside the set.
|
||||
func (as *asciiSet) contains(c byte) bool {
|
||||
return as[c]
|
||||
}
|
||||
|
||||
// shouldUseASCIISet returns whether to use the lookup table optimization.
|
||||
// The threshold of 8 bytes balances initialization cost against per-byte
|
||||
// search cost, performing well across all charset sizes.
|
||||
//
|
||||
// More complex heuristics (e.g., different thresholds per charset size)
|
||||
// add branching overhead that eats away any theoretical improvements.
|
||||
func shouldUseASCIISet(bufLen int) bool {
|
||||
return bufLen > 8
|
||||
return (as[c/32] & (1 << (c % 32))) != 0
|
||||
}
|
||||
|
||||
// containsRune is a simplified version of strings.ContainsRune
|
||||
@@ -1057,7 +1048,10 @@ func trimLeftASCII(s []byte, as *asciiSet) []byte {
|
||||
|
||||
func trimLeftUnicode(s []byte, cutset string) []byte {
|
||||
for len(s) > 0 {
|
||||
r, n := utf8.DecodeRune(s)
|
||||
r, n := rune(s[0]), 1
|
||||
if r >= utf8.RuneSelf {
|
||||
r, n = utf8.DecodeRune(s)
|
||||
}
|
||||
if !containsRune(cutset, r) {
|
||||
break
|
||||
}
|
||||
@@ -1119,34 +1113,41 @@ func trimRightUnicode(s []byte, cutset string) []byte {
|
||||
// TrimSpace returns a subslice of s by slicing off all leading and
|
||||
// trailing white space, as defined by Unicode.
|
||||
func TrimSpace(s []byte) []byte {
|
||||
// Fast path for ASCII: look for the first ASCII non-space byte.
|
||||
for lo, c := range s {
|
||||
// Fast path for ASCII: look for the first ASCII non-space byte
|
||||
start := 0
|
||||
for ; start < len(s); start++ {
|
||||
c := s[start]
|
||||
if c >= utf8.RuneSelf {
|
||||
// If we run into a non-ASCII byte, fall back to the
|
||||
// slower unicode-aware method on the remaining bytes.
|
||||
return TrimFunc(s[lo:], unicode.IsSpace)
|
||||
// slower unicode-aware method on the remaining bytes
|
||||
return TrimFunc(s[start:], unicode.IsSpace)
|
||||
}
|
||||
if asciiSpace[c] != 0 {
|
||||
continue
|
||||
}
|
||||
s = s[lo:]
|
||||
// Now look for the first ASCII non-space byte from the end.
|
||||
for hi := len(s) - 1; hi >= 0; hi-- {
|
||||
c := s[hi]
|
||||
if c >= utf8.RuneSelf {
|
||||
return TrimFunc(s[:hi+1], unicode.IsSpace)
|
||||
}
|
||||
if asciiSpace[c] == 0 {
|
||||
// At this point, s[:hi+1] starts and ends with ASCII
|
||||
// non-space bytes, so we're done. Non-ASCII cases have
|
||||
// already been handled above.
|
||||
return s[:hi+1]
|
||||
}
|
||||
if asciiSpace[c] == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
// Special case to preserve previous TrimLeftFunc behavior,
|
||||
// returning nil instead of empty slice if all spaces.
|
||||
return nil
|
||||
|
||||
// Now look for the first ASCII non-space byte from the end
|
||||
stop := len(s)
|
||||
for ; stop > start; stop-- {
|
||||
c := s[stop-1]
|
||||
if c >= utf8.RuneSelf {
|
||||
return TrimFunc(s[start:stop], unicode.IsSpace)
|
||||
}
|
||||
if asciiSpace[c] == 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// At this point s[start:stop] starts and ends with an ASCII
|
||||
// non-space bytes, so we're done. Non-ASCII cases have already
|
||||
// been handled above.
|
||||
if start == stop {
|
||||
// Special case to preserve previous TrimLeftFunc behavior,
|
||||
// returning nil instead of empty slice if all spaces.
|
||||
return nil
|
||||
}
|
||||
return s[start:stop]
|
||||
}
|
||||
|
||||
// Runes interprets s as a sequence of UTF-8-encoded code points.
|
||||
@@ -1187,22 +1188,19 @@ func Replace(s, old, new []byte, n int) []byte {
|
||||
t := make([]byte, len(s)+n*(len(new)-len(old)))
|
||||
w := 0
|
||||
start := 0
|
||||
if len(old) > 0 {
|
||||
for range n {
|
||||
j := start + Index(s[start:], old)
|
||||
w += copy(t[w:], s[start:j])
|
||||
w += copy(t[w:], new)
|
||||
start = j + len(old)
|
||||
for i := 0; i < n; i++ {
|
||||
j := start
|
||||
if len(old) == 0 {
|
||||
if i > 0 {
|
||||
_, wid := utf8.DecodeRune(s[start:])
|
||||
j += wid
|
||||
}
|
||||
} else {
|
||||
j += Index(s[start:], old)
|
||||
}
|
||||
} else { // len(old) == 0
|
||||
w += copy(t[w:], s[start:j])
|
||||
w += copy(t[w:], new)
|
||||
for range n - 1 {
|
||||
_, wid := utf8.DecodeRune(s[start:])
|
||||
j := start + wid
|
||||
w += copy(t[w:], s[start:j])
|
||||
w += copy(t[w:], new)
|
||||
start = j
|
||||
}
|
||||
start = j + len(old)
|
||||
}
|
||||
w += copy(t[w:], s[start:])
|
||||
return t[0:w]
|
||||
@@ -1223,7 +1221,7 @@ func ReplaceAll(s, old, new []byte) []byte {
|
||||
func EqualFold(s, t []byte) bool {
|
||||
// ASCII fast path
|
||||
i := 0
|
||||
for n := min(len(s), len(t)); i < n; i++ {
|
||||
for ; i < len(s) && i < len(t); i++ {
|
||||
sr := s[i]
|
||||
tr := t[i]
|
||||
if sr|tr >= utf8.RuneSelf {
|
||||
@@ -1253,10 +1251,19 @@ hasUnicode:
|
||||
t = t[i:]
|
||||
for len(s) != 0 && len(t) != 0 {
|
||||
// Extract first rune from each.
|
||||
sr, size := utf8.DecodeRune(s)
|
||||
s = s[size:]
|
||||
tr, size := utf8.DecodeRune(t)
|
||||
t = t[size:]
|
||||
var sr, tr rune
|
||||
if s[0] < utf8.RuneSelf {
|
||||
sr, s = rune(s[0]), s[1:]
|
||||
} else {
|
||||
r, size := utf8.DecodeRune(s)
|
||||
sr, s = r, s[size:]
|
||||
}
|
||||
if t[0] < utf8.RuneSelf {
|
||||
tr, t = rune(t[0]), t[1:]
|
||||
} else {
|
||||
r, size := utf8.DecodeRune(t)
|
||||
tr, t = r, t[size:]
|
||||
}
|
||||
|
||||
// If they match, keep going; if not, return false.
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ package bytes_test
|
||||
import (
|
||||
. "bytes"
|
||||
"fmt"
|
||||
"internal/asan"
|
||||
"internal/testenv"
|
||||
"iter"
|
||||
"math"
|
||||
@@ -693,14 +692,14 @@ func bmIndexRuneUnicode(rt *unicode.RangeTable, needle rune) func(b *testing.B,
|
||||
for _, r16 := range rt.R16 {
|
||||
for r := rune(r16.Lo); r <= rune(r16.Hi); r += rune(r16.Stride) {
|
||||
if r != needle {
|
||||
rs = append(rs, r)
|
||||
rs = append(rs, rune(r))
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, r32 := range rt.R32 {
|
||||
for r := rune(r32.Lo); r <= rune(r32.Hi); r += rune(r32.Stride) {
|
||||
if r != needle {
|
||||
rs = append(rs, r)
|
||||
rs = append(rs, rune(r))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -891,7 +890,9 @@ func BenchmarkCountSingle(b *testing.B) {
|
||||
b.Fatal("bad count", j, expect)
|
||||
}
|
||||
}
|
||||
clear(buf)
|
||||
for i := 0; i < len(buf); i++ {
|
||||
buf[i] = 0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -961,7 +962,7 @@ func TestSplit(t *testing.T) {
|
||||
if tt.n < 0 {
|
||||
b := sliceOfString(Split([]byte(tt.s), []byte(tt.sep)))
|
||||
if !slices.Equal(result, b) {
|
||||
t.Errorf("Split disagrees with SplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
|
||||
t.Errorf("Split disagrees withSplitN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
|
||||
}
|
||||
}
|
||||
if len(a) > 0 {
|
||||
@@ -1023,7 +1024,7 @@ func TestSplitAfter(t *testing.T) {
|
||||
if tt.n < 0 {
|
||||
b := sliceOfString(SplitAfter([]byte(tt.s), []byte(tt.sep)))
|
||||
if !slices.Equal(result, b) {
|
||||
t.Errorf("SplitAfter disagrees with SplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
|
||||
t.Errorf("SplitAfter disagrees withSplitAfterN(%q, %q, %d) = %v; want %v", tt.s, tt.sep, tt.n, b, a)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1224,7 +1225,7 @@ func TestMap(t *testing.T) {
|
||||
// Run a couple of awful growth/shrinkage tests
|
||||
a := tenRunes('a')
|
||||
|
||||
// 1. Grow. This triggers two reallocations in Map.
|
||||
// 1. Grow. This triggers two reallocations in Map.
|
||||
maxRune := func(r rune) rune { return unicode.MaxRune }
|
||||
m := Map(maxRune, []byte(a))
|
||||
expect := tenRunes(unicode.MaxRune)
|
||||
@@ -1785,20 +1786,9 @@ var ReplaceTests = []ReplaceTest{
|
||||
|
||||
func TestReplace(t *testing.T) {
|
||||
for _, tt := range ReplaceTests {
|
||||
var (
|
||||
in = []byte(tt.in)
|
||||
old = []byte(tt.old)
|
||||
new = []byte(tt.new)
|
||||
)
|
||||
if !asan.Enabled {
|
||||
allocs := testing.AllocsPerRun(10, func() { Replace(in, old, new, tt.n) })
|
||||
if allocs > 1 {
|
||||
t.Errorf("Replace(%q, %q, %q, %d) allocates %.2f objects", tt.in, tt.old, tt.new, tt.n, allocs)
|
||||
}
|
||||
}
|
||||
in = append(in, "<spare>"...)
|
||||
in := append([]byte(tt.in), "<spare>"...)
|
||||
in = in[:len(tt.in)]
|
||||
out := Replace(in, old, new, tt.n)
|
||||
out := Replace(in, []byte(tt.old), []byte(tt.new), tt.n)
|
||||
if s := string(out); s != tt.out {
|
||||
t.Errorf("Replace(%q, %q, %q, %d) = %q, want %q", tt.in, tt.old, tt.new, tt.n, s, tt.out)
|
||||
}
|
||||
@@ -1806,7 +1796,7 @@ func TestReplace(t *testing.T) {
|
||||
t.Errorf("Replace(%q, %q, %q, %d) didn't copy", tt.in, tt.old, tt.new, tt.n)
|
||||
}
|
||||
if tt.n == -1 {
|
||||
out := ReplaceAll(in, old, new)
|
||||
out := ReplaceAll(in, []byte(tt.old), []byte(tt.new))
|
||||
if s := string(out); s != tt.out {
|
||||
t.Errorf("ReplaceAll(%q, %q, %q) = %q, want %q", tt.in, tt.old, tt.new, s, tt.out)
|
||||
}
|
||||
@@ -1814,69 +1804,6 @@ func TestReplace(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func FuzzReplace(f *testing.F) {
|
||||
for _, tt := range ReplaceTests {
|
||||
f.Add([]byte(tt.in), []byte(tt.old), []byte(tt.new), tt.n)
|
||||
}
|
||||
f.Fuzz(func(t *testing.T, in, old, new []byte, n int) {
|
||||
differentImpl := func(in, old, new []byte, n int) []byte {
|
||||
var out Buffer
|
||||
if n < 0 {
|
||||
n = math.MaxInt
|
||||
}
|
||||
for i := 0; i < len(in); {
|
||||
if n == 0 {
|
||||
out.Write(in[i:])
|
||||
break
|
||||
}
|
||||
if HasPrefix(in[i:], old) {
|
||||
out.Write(new)
|
||||
i += len(old)
|
||||
n--
|
||||
if len(old) != 0 {
|
||||
continue
|
||||
}
|
||||
if i == len(in) {
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(old) == 0 {
|
||||
_, length := utf8.DecodeRune(in[i:])
|
||||
out.Write(in[i : i+length])
|
||||
i += length
|
||||
} else {
|
||||
out.WriteByte(in[i])
|
||||
i++
|
||||
}
|
||||
}
|
||||
if len(old) == 0 && n != 0 {
|
||||
out.Write(new)
|
||||
}
|
||||
return out.Bytes()
|
||||
}
|
||||
if simple, replace := differentImpl(in, old, new, n), Replace(in, old, new, n); !slices.Equal(simple, replace) {
|
||||
t.Errorf("The two implementations do not match %q != %q for Replace(%q, %q, %q, %d)", simple, replace, in, old, new, n)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func BenchmarkReplace(b *testing.B) {
|
||||
for _, tt := range ReplaceTests {
|
||||
desc := fmt.Sprintf("%q %q %q %d", tt.in, tt.old, tt.new, tt.n)
|
||||
var (
|
||||
in = []byte(tt.in)
|
||||
old = []byte(tt.old)
|
||||
new = []byte(tt.new)
|
||||
)
|
||||
b.Run(desc, func(b *testing.B) {
|
||||
b.ReportAllocs()
|
||||
for b.Loop() {
|
||||
Replace(in, old, new, tt.n)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type TitleTest struct {
|
||||
in, out string
|
||||
}
|
||||
@@ -2126,9 +2053,8 @@ func TestContainsFunc(t *testing.T) {
|
||||
var makeFieldsInput = func() []byte {
|
||||
x := make([]byte, 1<<20)
|
||||
// Input is ~10% space, ~10% 2-byte UTF-8, rest ASCII non-space.
|
||||
r := rand.New(rand.NewSource(99))
|
||||
for i := range x {
|
||||
switch r.Intn(10) {
|
||||
switch rand.Intn(10) {
|
||||
case 0:
|
||||
x[i] = ' '
|
||||
case 1:
|
||||
@@ -2147,9 +2073,8 @@ var makeFieldsInput = func() []byte {
|
||||
var makeFieldsInputASCII = func() []byte {
|
||||
x := make([]byte, 1<<20)
|
||||
// Input is ~10% space, rest ASCII non-space.
|
||||
r := rand.New(rand.NewSource(99))
|
||||
for i := range x {
|
||||
if r.Intn(10) == 0 {
|
||||
if rand.Intn(10) == 0 {
|
||||
x[i] = ' '
|
||||
} else {
|
||||
x[i] = 'x'
|
||||
@@ -2246,9 +2171,8 @@ func makeBenchInputHard() []byte {
|
||||
"hello", "world",
|
||||
}
|
||||
x := make([]byte, 0, 1<<20)
|
||||
r := rand.New(rand.NewSource(99))
|
||||
for {
|
||||
i := r.Intn(len(tokens))
|
||||
i := rand.Intn(len(tokens))
|
||||
if len(x)+len(tokens[i]) >= 1<<20 {
|
||||
break
|
||||
}
|
||||
|
||||
@@ -245,9 +245,9 @@ func ExampleCut() {
|
||||
}
|
||||
|
||||
func ExampleCutPrefix() {
|
||||
show := func(s, prefix string) {
|
||||
after, found := bytes.CutPrefix([]byte(s), []byte(prefix))
|
||||
fmt.Printf("CutPrefix(%q, %q) = %q, %v\n", s, prefix, after, found)
|
||||
show := func(s, sep string) {
|
||||
after, found := bytes.CutPrefix([]byte(s), []byte(sep))
|
||||
fmt.Printf("CutPrefix(%q, %q) = %q, %v\n", s, sep, after, found)
|
||||
}
|
||||
show("Gopher", "Go")
|
||||
show("Gopher", "ph")
|
||||
@@ -257,9 +257,9 @@ func ExampleCutPrefix() {
|
||||
}
|
||||
|
||||
func ExampleCutSuffix() {
|
||||
show := func(s, suffix string) {
|
||||
before, found := bytes.CutSuffix([]byte(s), []byte(suffix))
|
||||
fmt.Printf("CutSuffix(%q, %q) = %q, %v\n", s, suffix, before, found)
|
||||
show := func(s, sep string) {
|
||||
before, found := bytes.CutSuffix([]byte(s), []byte(sep))
|
||||
fmt.Printf("CutSuffix(%q, %q) = %q, %v\n", s, sep, before, found)
|
||||
}
|
||||
show("Gopher", "Go")
|
||||
show("Gopher", "er")
|
||||
@@ -628,93 +628,3 @@ func ExampleToUpperSpecial() {
|
||||
// Original : ahoj vývojári golang
|
||||
// ToUpper : AHOJ VÝVOJÁRİ GOLANG
|
||||
}
|
||||
|
||||
func ExampleLines() {
|
||||
text := []byte("Hello\nWorld\nGo Programming\n")
|
||||
for line := range bytes.Lines(text) {
|
||||
fmt.Printf("%q\n", line)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// "Hello\n"
|
||||
// "World\n"
|
||||
// "Go Programming\n"
|
||||
}
|
||||
|
||||
func ExampleSplitSeq() {
|
||||
s := []byte("a,b,c,d")
|
||||
for part := range bytes.SplitSeq(s, []byte(",")) {
|
||||
fmt.Printf("%q\n", part)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// "a"
|
||||
// "b"
|
||||
// "c"
|
||||
// "d"
|
||||
}
|
||||
|
||||
func ExampleSplitAfterSeq() {
|
||||
s := []byte("a,b,c,d")
|
||||
for part := range bytes.SplitAfterSeq(s, []byte(",")) {
|
||||
fmt.Printf("%q\n", part)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// "a,"
|
||||
// "b,"
|
||||
// "c,"
|
||||
// "d"
|
||||
}
|
||||
|
||||
func ExampleFieldsSeq() {
|
||||
text := []byte("The quick brown fox")
|
||||
fmt.Println("Split byte slice into fields:")
|
||||
for word := range bytes.FieldsSeq(text) {
|
||||
fmt.Printf("%q\n", word)
|
||||
}
|
||||
|
||||
textWithSpaces := []byte(" lots of spaces ")
|
||||
fmt.Println("\nSplit byte slice with multiple spaces:")
|
||||
for word := range bytes.FieldsSeq(textWithSpaces) {
|
||||
fmt.Printf("%q\n", word)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Split byte slice into fields:
|
||||
// "The"
|
||||
// "quick"
|
||||
// "brown"
|
||||
// "fox"
|
||||
//
|
||||
// Split byte slice with multiple spaces:
|
||||
// "lots"
|
||||
// "of"
|
||||
// "spaces"
|
||||
}
|
||||
|
||||
func ExampleFieldsFuncSeq() {
|
||||
text := []byte("The quick brown fox")
|
||||
fmt.Println("Split on whitespace(similar to FieldsSeq):")
|
||||
for word := range bytes.FieldsFuncSeq(text, unicode.IsSpace) {
|
||||
fmt.Printf("%q\n", word)
|
||||
}
|
||||
|
||||
mixedText := []byte("abc123def456ghi")
|
||||
fmt.Println("\nSplit on digits:")
|
||||
for word := range bytes.FieldsFuncSeq(mixedText, unicode.IsDigit) {
|
||||
fmt.Printf("%q\n", word)
|
||||
}
|
||||
|
||||
// Output:
|
||||
// Split on whitespace(similar to FieldsSeq):
|
||||
// "The"
|
||||
// "quick"
|
||||
// "brown"
|
||||
// "fox"
|
||||
//
|
||||
// Split on digits:
|
||||
// "abc"
|
||||
// "def"
|
||||
// "ghi"
|
||||
}
|
||||
|
||||
@@ -28,23 +28,30 @@ func Lines(s []byte) iter.Seq[[]byte] {
|
||||
return
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// explodeSeq returns an iterator over the runes in s.
|
||||
func explodeSeq(s []byte) iter.Seq[[]byte] {
|
||||
return func(yield func([]byte) bool) {
|
||||
for len(s) > 0 {
|
||||
_, size := utf8.DecodeRune(s)
|
||||
if !yield(s[:size:size]) {
|
||||
return
|
||||
}
|
||||
s = s[size:]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// splitSeq is SplitSeq or SplitAfterSeq, configured by how many
|
||||
// bytes of sep to include in the results (none or all).
|
||||
func splitSeq(s, sep []byte, sepSave int) iter.Seq[[]byte] {
|
||||
if len(sep) == 0 {
|
||||
return explodeSeq(s)
|
||||
}
|
||||
return func(yield func([]byte) bool) {
|
||||
if len(sep) == 0 {
|
||||
for len(s) > 0 {
|
||||
_, size := utf8.DecodeRune(s)
|
||||
if !yield(s[:size:size]) {
|
||||
return
|
||||
}
|
||||
s = s[size:]
|
||||
}
|
||||
return
|
||||
}
|
||||
for {
|
||||
i := Index(s, sep)
|
||||
if i < 0 {
|
||||
@@ -117,7 +124,11 @@ func FieldsFuncSeq(s []byte, f func(rune) bool) iter.Seq[[]byte] {
|
||||
return func(yield func([]byte) bool) {
|
||||
start := -1
|
||||
for i := 0; i < len(s); {
|
||||
r, size := utf8.DecodeRune(s[i:])
|
||||
size := 1
|
||||
r := rune(s[i])
|
||||
if r >= utf8.RuneSelf {
|
||||
r, size = utf8.DecodeRune(s[i:])
|
||||
}
|
||||
if f(r) {
|
||||
if start >= 0 {
|
||||
if !yield(s[start:i:i]) {
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
// Copyright 2024 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 bytes_test
|
||||
|
||||
import (
|
||||
. "bytes"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func BenchmarkSplitSeqEmptySeparator(b *testing.B) {
|
||||
for range b.N {
|
||||
for range SplitSeq(benchInputHard, nil) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSplitSeqSingleByteSeparator(b *testing.B) {
|
||||
sep := []byte("/")
|
||||
for range b.N {
|
||||
for range SplitSeq(benchInputHard, sep) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSplitSeqMultiByteSeparator(b *testing.B) {
|
||||
sep := []byte("hello")
|
||||
for range b.N {
|
||||
for range SplitSeq(benchInputHard, sep) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSplitAfterSeqEmptySeparator(b *testing.B) {
|
||||
for range b.N {
|
||||
for range SplitAfterSeq(benchInputHard, nil) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSplitAfterSeqSingleByteSeparator(b *testing.B) {
|
||||
sep := []byte("/")
|
||||
for range b.N {
|
||||
for range SplitAfterSeq(benchInputHard, sep) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkSplitAfterSeqMultiByteSeparator(b *testing.B) {
|
||||
sep := []byte("hello")
|
||||
for range b.N {
|
||||
for range SplitAfterSeq(benchInputHard, sep) {
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,16 +6,27 @@
|
||||
|
||||
setlocal
|
||||
|
||||
go tool dist env -w -p >env.bat || exit /b 1
|
||||
set GOBUILDFAIL=0
|
||||
|
||||
go tool dist env -w -p >env.bat
|
||||
if errorlevel 1 goto fail
|
||||
call .\env.bat
|
||||
del env.bat
|
||||
echo.
|
||||
|
||||
if not exist %GOTOOLDIR%\dist.exe (
|
||||
echo cannot find %GOTOOLDIR%\dist.exe; nothing to clean
|
||||
exit /b 1
|
||||
)
|
||||
if exist %GOTOOLDIR%\dist.exe goto distok
|
||||
echo cannot find %GOTOOLDIR%\dist; nothing to clean
|
||||
goto fail
|
||||
:distok
|
||||
|
||||
"%GOBIN%\go" clean -i std
|
||||
"%GOBIN%\go" tool dist clean
|
||||
"%GOBIN%\go" clean -i cmd
|
||||
|
||||
goto end
|
||||
|
||||
:fail
|
||||
set GOBUILDFAIL=1
|
||||
|
||||
:end
|
||||
if x%GOBUILDEXIT%==x1 exit %GOBUILDFAIL%
|
||||
|
||||
@@ -99,11 +99,6 @@ func TestGolden(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCompareAPI(t *testing.T) {
|
||||
if *flagCheck {
|
||||
// not worth repeating in -check
|
||||
t.Skip("skipping with -check set")
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
features, required, exception []string
|
||||
@@ -185,11 +180,6 @@ func TestCompareAPI(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestSkipInternal(t *testing.T) {
|
||||
if *flagCheck {
|
||||
// not worth repeating in -check
|
||||
t.Skip("skipping with -check set")
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
pkg string
|
||||
want bool
|
||||
@@ -304,20 +294,14 @@ func TestIssue41358(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestIssue64958(t *testing.T) {
|
||||
if testing.Short() {
|
||||
t.Skip("skipping with -short")
|
||||
}
|
||||
if *flagCheck {
|
||||
// slow, not worth repeating in -check
|
||||
t.Skip("skipping with -check set")
|
||||
}
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
defer func() {
|
||||
if x := recover(); x != nil {
|
||||
t.Errorf("expected no panic; recovered %v", x)
|
||||
}
|
||||
}()
|
||||
|
||||
testenv.MustHaveGoBuild(t)
|
||||
|
||||
for _, context := range contexts {
|
||||
w := NewWalker(context, "testdata/src/issue64958")
|
||||
pkg, err := w.importFrom("p", "", 0)
|
||||
|
||||
@@ -1058,7 +1058,7 @@ func (w *Walker) emitIfaceType(name string, typ *types.Interface) {
|
||||
if w.isDeprecated(m) {
|
||||
w.emitf("%s //deprecated", m.Name())
|
||||
}
|
||||
w.emitf("%s%s", m.Name(), w.signatureString(m.Signature()))
|
||||
w.emitf("%s%s", m.Name(), w.signatureString(m.Type().(*types.Signature)))
|
||||
}
|
||||
|
||||
if !complete {
|
||||
@@ -1088,7 +1088,7 @@ func (w *Walker) emitIfaceType(name string, typ *types.Interface) {
|
||||
}
|
||||
|
||||
func (w *Walker) emitFunc(f *types.Func) {
|
||||
sig := f.Signature()
|
||||
sig := f.Type().(*types.Signature)
|
||||
if sig.Recv() != nil {
|
||||
panic("method considered a regular function: " + f.String())
|
||||
}
|
||||
|
||||
12
src/cmd/api/testdata/src/pkg/p1/golden.txt
vendored
12
src/cmd/api/testdata/src/pkg/p1/golden.txt
vendored
@@ -1,6 +1,6 @@
|
||||
pkg p1, const A //deprecated
|
||||
pkg p1, const A = 1
|
||||
pkg p1, const A ideal-int
|
||||
pkg p1, const A //deprecated
|
||||
pkg p1, const A64 = 1
|
||||
pkg p1, const A64 int64
|
||||
pkg p1, const AIsLowerA = 11
|
||||
@@ -25,8 +25,8 @@ pkg p1, func TakesFunc(func(int) int)
|
||||
pkg p1, method (*B) JustOnB()
|
||||
pkg p1, method (*B) OnBothTandBPtr()
|
||||
pkg p1, method (*Embedded) OnEmbedded()
|
||||
pkg p1, method (*S2) SMethod //deprecated
|
||||
pkg p1, method (*S2) SMethod(int8, int16, int64)
|
||||
pkg p1, method (*S2) SMethod //deprecated
|
||||
pkg p1, method (*T) JustOnT()
|
||||
pkg p1, method (*T) OnBothTandBPtr()
|
||||
pkg p1, method (B) OnBothTandBVal()
|
||||
@@ -53,8 +53,8 @@ pkg p1, type Error interface { Error, Temporary }
|
||||
pkg p1, type Error interface, Error() string
|
||||
pkg p1, type Error interface, Temporary() bool
|
||||
pkg p1, type FuncType func(int, int, string) (*B, error)
|
||||
pkg p1, type I interface, Get //deprecated
|
||||
pkg p1, type I interface, Get(string) int64
|
||||
pkg p1, type I interface, Get //deprecated
|
||||
pkg p1, type I interface, GetNamed(string) int64
|
||||
pkg p1, type I interface, Name() string
|
||||
pkg p1, type I interface, PackageTwoMeth()
|
||||
@@ -63,9 +63,9 @@ pkg p1, type I interface, unexported methods
|
||||
pkg p1, type MyInt int
|
||||
pkg p1, type Namer interface { Name }
|
||||
pkg p1, type Namer interface, Name() string
|
||||
pkg p1, type Private //deprecated
|
||||
pkg p1, type Private interface, X()
|
||||
pkg p1, type Private interface, unexported methods
|
||||
pkg p1, type Private //deprecated
|
||||
pkg p1, type Public interface { X, Y }
|
||||
pkg p1, type Public interface, X()
|
||||
pkg p1, type Public interface, Y()
|
||||
@@ -84,8 +84,8 @@ pkg p1, type TPtrExported struct
|
||||
pkg p1, type TPtrExported struct, embedded *Embedded
|
||||
pkg p1, type TPtrUnexported struct
|
||||
pkg p1, type Time struct
|
||||
pkg p1, type URL //deprecated
|
||||
pkg p1, type URL struct
|
||||
pkg p1, type URL //deprecated
|
||||
pkg p1, var Byte uint8
|
||||
pkg p1, var ByteConv []uint8
|
||||
pkg p1, var ByteFunc func(uint8) int32
|
||||
@@ -97,8 +97,8 @@ pkg p1, var StrConv string
|
||||
pkg p1, var V string
|
||||
pkg p1, var V1 uint64
|
||||
pkg p1, var V2 p2.Twoer
|
||||
pkg p1, var VError //deprecated
|
||||
pkg p1, var VError Error
|
||||
pkg p1, var VError //deprecated
|
||||
pkg p1, var X I
|
||||
pkg p1, var X0 int64
|
||||
pkg p1, var Y int
|
||||
|
||||
5
src/cmd/api/testdata/src/pkg/p2/golden.txt
vendored
5
src/cmd/api/testdata/src/pkg/p2/golden.txt
vendored
@@ -1,7 +1,8 @@
|
||||
pkg p2, func F //deprecated
|
||||
pkg p2, func F() string
|
||||
pkg p2, func F //deprecated
|
||||
pkg p2, func G() Twoer
|
||||
pkg p2, func NewError(string) error
|
||||
pkg p2, type Twoer interface { PackageTwoMeth }
|
||||
pkg p2, type Twoer interface, PackageTwoMeth //deprecated
|
||||
pkg p2, type Twoer interface, PackageTwoMeth()
|
||||
pkg p2, type Twoer interface, PackageTwoMeth //deprecated
|
||||
|
||||
|
||||
6
src/cmd/api/testdata/src/pkg/p4/golden.txt
vendored
6
src/cmd/api/testdata/src/pkg/p4/golden.txt
vendored
@@ -1,6 +1,6 @@
|
||||
pkg p4, func Clone //deprecated
|
||||
pkg p4, func Clone[$0 interface{ ~[]$1 }, $1 interface{}]($0) $0
|
||||
pkg p4, func NewPair[$0 interface{ M }, $1 interface{ ~int }]($0, $1) Pair[$0, $1]
|
||||
pkg p4, method (Pair[$0, $1]) First() $0
|
||||
pkg p4, method (Pair[$0, $1]) Second() $1
|
||||
pkg p4, method (Pair[$0, $1]) First() $0
|
||||
pkg p4, type Pair[$0 interface{ M }, $1 interface{ ~int }] struct
|
||||
pkg p4, func Clone[$0 interface{ ~[]$1 }, $1 interface{}]($0) $0
|
||||
pkg p4, func Clone //deprecated
|
||||
|
||||
@@ -92,8 +92,7 @@ func jumpX86(word string) bool {
|
||||
func jumpRISCV(word string) bool {
|
||||
switch word {
|
||||
case "BEQ", "BEQZ", "BGE", "BGEU", "BGEZ", "BGT", "BGTU", "BGTZ", "BLE", "BLEU", "BLEZ",
|
||||
"BLT", "BLTU", "BLTZ", "BNE", "BNEZ", "CALL", "CBEQZ", "CBNEZ", "CJ", "CJALR", "CJR",
|
||||
"JAL", "JALR", "JMP":
|
||||
"BLT", "BLTU", "BLTZ", "BNE", "BNEZ", "CALL", "JAL", "JALR", "JMP":
|
||||
return true
|
||||
}
|
||||
return false
|
||||
|
||||
@@ -59,10 +59,10 @@ func jumpArm64(word string) bool {
|
||||
|
||||
var arm64SpecialOperand map[string]arm64.SpecialOperand
|
||||
|
||||
// ARM64SpecialOperand returns the internal representation of a special operand.
|
||||
func ARM64SpecialOperand(name string) arm64.SpecialOperand {
|
||||
// GetARM64SpecialOperand returns the internal representation of a special operand.
|
||||
func GetARM64SpecialOperand(name string) arm64.SpecialOperand {
|
||||
if arm64SpecialOperand == nil {
|
||||
// Generate mapping when function is first called.
|
||||
// Generate the mapping automatically when the first time the function is called.
|
||||
arm64SpecialOperand = map[string]arm64.SpecialOperand{}
|
||||
for opd := arm64.SPOP_BEGIN; opd < arm64.SPOP_END; opd++ {
|
||||
arm64SpecialOperand[opd.String()] = opd
|
||||
@@ -195,6 +195,149 @@ func ARM64RegisterShift(reg, op, count int16) (int64, error) {
|
||||
return int64(reg&31)<<16 | int64(op)<<22 | int64(uint16(count)), nil
|
||||
}
|
||||
|
||||
// ARM64RegisterExtension constructs an ARM64 register with extension or arrangement.
|
||||
func ARM64RegisterExtension(a *obj.Addr, ext string, reg, num int16, isAmount, isIndex bool) error {
|
||||
Rnum := (reg & 31) + int16(num<<5)
|
||||
if isAmount {
|
||||
if num < 0 || num > 7 {
|
||||
return errors.New("index shift amount is out of range")
|
||||
}
|
||||
}
|
||||
if reg <= arm64.REG_R31 && reg >= arm64.REG_R0 {
|
||||
if !isAmount {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
switch ext {
|
||||
case "UXTB":
|
||||
if a.Type == obj.TYPE_MEM {
|
||||
return errors.New("invalid shift for the register offset addressing mode")
|
||||
}
|
||||
a.Reg = arm64.REG_UXTB + Rnum
|
||||
case "UXTH":
|
||||
if a.Type == obj.TYPE_MEM {
|
||||
return errors.New("invalid shift for the register offset addressing mode")
|
||||
}
|
||||
a.Reg = arm64.REG_UXTH + Rnum
|
||||
case "UXTW":
|
||||
// effective address of memory is a base register value and an offset register value.
|
||||
if a.Type == obj.TYPE_MEM {
|
||||
a.Index = arm64.REG_UXTW + Rnum
|
||||
} else {
|
||||
a.Reg = arm64.REG_UXTW + Rnum
|
||||
}
|
||||
case "UXTX":
|
||||
if a.Type == obj.TYPE_MEM {
|
||||
return errors.New("invalid shift for the register offset addressing mode")
|
||||
}
|
||||
a.Reg = arm64.REG_UXTX + Rnum
|
||||
case "SXTB":
|
||||
if a.Type == obj.TYPE_MEM {
|
||||
return errors.New("invalid shift for the register offset addressing mode")
|
||||
}
|
||||
a.Reg = arm64.REG_SXTB + Rnum
|
||||
case "SXTH":
|
||||
if a.Type == obj.TYPE_MEM {
|
||||
return errors.New("invalid shift for the register offset addressing mode")
|
||||
}
|
||||
a.Reg = arm64.REG_SXTH + Rnum
|
||||
case "SXTW":
|
||||
if a.Type == obj.TYPE_MEM {
|
||||
a.Index = arm64.REG_SXTW + Rnum
|
||||
} else {
|
||||
a.Reg = arm64.REG_SXTW + Rnum
|
||||
}
|
||||
case "SXTX":
|
||||
if a.Type == obj.TYPE_MEM {
|
||||
a.Index = arm64.REG_SXTX + Rnum
|
||||
} else {
|
||||
a.Reg = arm64.REG_SXTX + Rnum
|
||||
}
|
||||
case "LSL":
|
||||
a.Index = arm64.REG_LSL + Rnum
|
||||
default:
|
||||
return errors.New("unsupported general register extension type: " + ext)
|
||||
|
||||
}
|
||||
} else if reg <= arm64.REG_V31 && reg >= arm64.REG_V0 {
|
||||
switch ext {
|
||||
case "B8":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8B & 15) << 5)
|
||||
case "B16":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_16B & 15) << 5)
|
||||
case "H4":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4H & 15) << 5)
|
||||
case "H8":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_8H & 15) << 5)
|
||||
case "S2":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2S & 15) << 5)
|
||||
case "S4":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_4S & 15) << 5)
|
||||
case "D1":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1D & 15) << 5)
|
||||
case "D2":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_2D & 15) << 5)
|
||||
case "Q1":
|
||||
if isIndex {
|
||||
return errors.New("invalid register extension")
|
||||
}
|
||||
a.Reg = arm64.REG_ARNG + (reg & 31) + ((arm64.ARNG_1Q & 15) << 5)
|
||||
case "B":
|
||||
if !isIndex {
|
||||
return nil
|
||||
}
|
||||
a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_B & 15) << 5)
|
||||
a.Index = num
|
||||
case "H":
|
||||
if !isIndex {
|
||||
return nil
|
||||
}
|
||||
a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_H & 15) << 5)
|
||||
a.Index = num
|
||||
case "S":
|
||||
if !isIndex {
|
||||
return nil
|
||||
}
|
||||
a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_S & 15) << 5)
|
||||
a.Index = num
|
||||
case "D":
|
||||
if !isIndex {
|
||||
return nil
|
||||
}
|
||||
a.Reg = arm64.REG_ELEM + (reg & 31) + ((arm64.ARNG_D & 15) << 5)
|
||||
a.Index = num
|
||||
default:
|
||||
return errors.New("unsupported simd register extension type: " + ext)
|
||||
}
|
||||
} else {
|
||||
return errors.New("invalid register and extension combination")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ARM64RegisterArrangement constructs an ARM64 vector register arrangement.
|
||||
func ARM64RegisterArrangement(reg int16, name, arng string) (int64, error) {
|
||||
var curQ, curSize uint16
|
||||
|
||||
@@ -23,6 +23,18 @@ func jumpLoong64(word string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// IsLoong64MUL reports whether the op (as defined by an loong64.A* constant) is
|
||||
// one of the MUL/DIV/REM instructions that require special handling.
|
||||
func IsLoong64MUL(op obj.As) bool {
|
||||
switch op {
|
||||
case loong64.AMUL, loong64.AMULU, loong64.AMULV, loong64.AMULVU,
|
||||
loong64.ADIV, loong64.ADIVU, loong64.ADIVV, loong64.ADIVVU,
|
||||
loong64.AREM, loong64.AREMU, loong64.AREMV, loong64.AREMVU:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsLoong64RDTIME reports whether the op (as defined by an loong64.A*
|
||||
// constant) is one of the RDTIMELW/RDTIMEHW/RDTIMED instructions that
|
||||
// require special handling.
|
||||
@@ -34,14 +46,6 @@ func IsLoong64RDTIME(op obj.As) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func IsLoong64PRELD(op obj.As) bool {
|
||||
switch op {
|
||||
case loong64.APRELD, loong64.APRELDX:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsLoong64AMO(op obj.As) bool {
|
||||
return loong64.IsAtomicInst(op)
|
||||
}
|
||||
|
||||
@@ -11,11 +11,11 @@ package arch
|
||||
import (
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/riscv"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
// IsRISCV64AMO reports whether op is an AMO instruction that requires
|
||||
// special handling.
|
||||
// IsRISCV64AMO reports whether the op (as defined by a riscv.A*
|
||||
// constant) is one of the AMO instructions that requires special
|
||||
// handling.
|
||||
func IsRISCV64AMO(op obj.As) bool {
|
||||
switch op {
|
||||
case riscv.ASCW, riscv.ASCD, riscv.AAMOSWAPW, riscv.AAMOSWAPD, riscv.AAMOADDW, riscv.AAMOADDD,
|
||||
@@ -26,59 +26,3 @@ func IsRISCV64AMO(op obj.As) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// IsRISCV64VTypeI reports whether op is a vtype immediate instruction that
|
||||
// requires special handling.
|
||||
func IsRISCV64VTypeI(op obj.As) bool {
|
||||
return op == riscv.AVSETVLI || op == riscv.AVSETIVLI
|
||||
}
|
||||
|
||||
// IsRISCV64CSRO reports whether the op is an instruction that uses
|
||||
// CSR symbolic names and whether that instruction expects a register
|
||||
// or an immediate source operand.
|
||||
func IsRISCV64CSRO(op obj.As) (imm bool, ok bool) {
|
||||
switch op {
|
||||
case riscv.ACSRRCI, riscv.ACSRRSI, riscv.ACSRRWI:
|
||||
imm = true
|
||||
fallthrough
|
||||
case riscv.ACSRRC, riscv.ACSRRS, riscv.ACSRRW:
|
||||
ok = true
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
var riscv64SpecialOperand map[string]riscv.SpecialOperand
|
||||
|
||||
// RISCV64SpecialOperand returns the internal representation of a special operand.
|
||||
func RISCV64SpecialOperand(name string) riscv.SpecialOperand {
|
||||
if riscv64SpecialOperand == nil {
|
||||
// Generate mapping when function is first called.
|
||||
riscv64SpecialOperand = map[string]riscv.SpecialOperand{}
|
||||
for opd := riscv.SPOP_RVV_BEGIN; opd < riscv.SPOP_RVV_END; opd++ {
|
||||
riscv64SpecialOperand[opd.String()] = opd
|
||||
}
|
||||
// Add the CSRs
|
||||
for csrCode, csrName := range riscv.CSRs {
|
||||
// The set of RVV special operand names and the set of CSR special operands
|
||||
// names are disjoint and so can safely share a single namespace. However,
|
||||
// it's possible that a future update to the CSRs in inst.go could introduce
|
||||
// a conflict. This check ensures that such a conflict does not go
|
||||
// unnoticed.
|
||||
if _, ok := riscv64SpecialOperand[csrName]; ok {
|
||||
panic(fmt.Sprintf("riscv64 special operand %q redefined", csrName))
|
||||
}
|
||||
riscv64SpecialOperand[csrName] = riscv.SpecialOperand(int(csrCode) + int(riscv.SPOP_CSR_BEGIN))
|
||||
}
|
||||
}
|
||||
if opd, ok := riscv64SpecialOperand[name]; ok {
|
||||
return opd
|
||||
}
|
||||
return riscv.SPOP_END
|
||||
}
|
||||
|
||||
// RISCV64ValidateVectorType reports whether the given configuration is a
|
||||
// valid vector type.
|
||||
func RISCV64ValidateVectorType(vsew, vlmul, vtail, vmask int64) error {
|
||||
_, err := riscv.EncodeVectorType(vsew, vlmul, vtail, vmask)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -248,7 +248,7 @@ func (p *Parser) asmData(operands [][]lex.Token) {
|
||||
case obj.TYPE_CONST:
|
||||
switch sz {
|
||||
case 1, 2, 4, 8:
|
||||
nameAddr.Sym.WriteInt(p.ctxt, nameAddr.Offset, sz, valueAddr.Offset)
|
||||
nameAddr.Sym.WriteInt(p.ctxt, nameAddr.Offset, int(sz), valueAddr.Offset)
|
||||
default:
|
||||
p.errorf("bad int size for DATA argument: %d", sz)
|
||||
}
|
||||
@@ -262,10 +262,10 @@ func (p *Parser) asmData(operands [][]lex.Token) {
|
||||
p.errorf("bad float size for DATA argument: %d", sz)
|
||||
}
|
||||
case obj.TYPE_SCONST:
|
||||
nameAddr.Sym.WriteString(p.ctxt, nameAddr.Offset, sz, valueAddr.Val.(string))
|
||||
nameAddr.Sym.WriteString(p.ctxt, nameAddr.Offset, int(sz), valueAddr.Val.(string))
|
||||
case obj.TYPE_ADDR:
|
||||
if sz == p.arch.PtrSize {
|
||||
nameAddr.Sym.WriteAddr(p.ctxt, nameAddr.Offset, sz, valueAddr.Sym, valueAddr.Offset)
|
||||
nameAddr.Sym.WriteAddr(p.ctxt, nameAddr.Offset, int(sz), valueAddr.Sym, valueAddr.Offset)
|
||||
} else {
|
||||
p.errorf("bad addr size for DATA argument: %d", sz)
|
||||
}
|
||||
@@ -654,12 +654,6 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||
prog.RegTo2 = a[1].Reg
|
||||
break
|
||||
}
|
||||
|
||||
if arch.IsLoong64PRELD(op) {
|
||||
prog.From = a[0]
|
||||
prog.AddRestSource(a[1])
|
||||
break
|
||||
}
|
||||
}
|
||||
prog.From = a[0]
|
||||
prog.To = a[1]
|
||||
@@ -676,11 +670,6 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||
prog.From = a[0]
|
||||
prog.To = a[1]
|
||||
prog.RegTo2 = a[2].Reg
|
||||
|
||||
case arch.IsLoong64PRELD(op):
|
||||
prog.From = a[0]
|
||||
prog.AddRestSourceArgs([]obj.Addr{a[1], a[2]})
|
||||
|
||||
default:
|
||||
prog.From = a[0]
|
||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||
@@ -782,21 +771,6 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||
prog.RegTo2 = a[2].Reg
|
||||
break
|
||||
}
|
||||
// RISCV64 instructions that reference CSRs with symbolic names.
|
||||
if isImm, ok := arch.IsRISCV64CSRO(op); ok {
|
||||
if a[0].Type != obj.TYPE_CONST && isImm {
|
||||
p.errorf("invalid value for first operand to %s instruction, must be a 5 bit unsigned immediate", op)
|
||||
return
|
||||
}
|
||||
if a[1].Type != obj.TYPE_SPECIAL {
|
||||
p.errorf("invalid value for second operand to %s instruction, must be a CSR name", op)
|
||||
return
|
||||
}
|
||||
prog.AddRestSourceArgs([]obj.Addr{a[1]})
|
||||
prog.From = a[0]
|
||||
prog.To = a[2]
|
||||
break
|
||||
}
|
||||
prog.From = a[0]
|
||||
prog.Reg = p.getRegister(prog, op, &a[1])
|
||||
prog.To = a[2]
|
||||
@@ -941,19 +915,6 @@ func (p *Parser) asmInstruction(op obj.As, cond string, a []obj.Addr) {
|
||||
prog.To = a[5]
|
||||
break
|
||||
}
|
||||
if p.arch.Family == sys.RISCV64 && arch.IsRISCV64VTypeI(op) {
|
||||
prog.From = a[0]
|
||||
vsew := p.getSpecial(prog, op, &a[1])
|
||||
vlmul := p.getSpecial(prog, op, &a[2])
|
||||
vtail := p.getSpecial(prog, op, &a[3])
|
||||
vmask := p.getSpecial(prog, op, &a[4])
|
||||
if err := arch.RISCV64ValidateVectorType(vsew, vlmul, vtail, vmask); err != nil {
|
||||
p.errorf("invalid vtype: %v", err)
|
||||
}
|
||||
prog.AddRestSourceArgs([]obj.Addr{a[1], a[2], a[3], a[4]})
|
||||
prog.To = a[5]
|
||||
break
|
||||
}
|
||||
fallthrough
|
||||
default:
|
||||
p.errorf("can't handle %s instruction with %d operands", op, len(a))
|
||||
@@ -989,6 +950,14 @@ func (p *Parser) getConstant(prog *obj.Prog, op obj.As, addr *obj.Addr) int64 {
|
||||
return addr.Offset
|
||||
}
|
||||
|
||||
// getImmediate checks that addr represents an immediate constant and returns its value.
|
||||
func (p *Parser) getImmediate(prog *obj.Prog, op obj.As, addr *obj.Addr) int64 {
|
||||
if addr.Type != obj.TYPE_CONST || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 {
|
||||
p.errorf("%s: expected immediate constant; found %s", op, obj.Dconv(prog, addr))
|
||||
}
|
||||
return addr.Offset
|
||||
}
|
||||
|
||||
// getRegister checks that addr represents a register and returns its value.
|
||||
func (p *Parser) getRegister(prog *obj.Prog, op obj.As, addr *obj.Addr) int16 {
|
||||
if addr.Type != obj.TYPE_REG || addr.Offset != 0 || addr.Name != 0 || addr.Index != 0 {
|
||||
@@ -996,11 +965,3 @@ func (p *Parser) getRegister(prog *obj.Prog, op obj.As, addr *obj.Addr) int16 {
|
||||
}
|
||||
return addr.Reg
|
||||
}
|
||||
|
||||
// getSpecial checks that addr represents a special operand and returns its value.
|
||||
func (p *Parser) getSpecial(prog *obj.Prog, op obj.As, addr *obj.Addr) int64 {
|
||||
if addr.Type != obj.TYPE_SPECIAL || addr.Name != 0 || addr.Reg != 0 || addr.Index != 0 {
|
||||
p.errorf("%s: expected special operand; found %s", op, obj.Dconv(prog, addr))
|
||||
}
|
||||
return addr.Offset
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ func testEndToEnd(t *testing.T, goarch, file string) {
|
||||
ctxt.IsAsm = true
|
||||
defer ctxt.Bso.Flush()
|
||||
failed := false
|
||||
ctxt.DiagFunc = func(format string, args ...any) {
|
||||
ctxt.DiagFunc = func(format string, args ...interface{}) {
|
||||
failed = true
|
||||
t.Errorf(format, args...)
|
||||
}
|
||||
@@ -193,17 +193,12 @@ Diff:
|
||||
top := pList.Firstpc
|
||||
var text *obj.LSym
|
||||
ok = true
|
||||
ctxt.DiagFunc = func(format string, args ...any) {
|
||||
ctxt.DiagFunc = func(format string, args ...interface{}) {
|
||||
t.Errorf(format, args...)
|
||||
ok = false
|
||||
}
|
||||
obj.Flushplist(ctxt, pList, nil)
|
||||
|
||||
if !ok {
|
||||
// If we've encountered errors, the output is unlikely to be sane.
|
||||
t.FailNow()
|
||||
}
|
||||
|
||||
for p := top; p != nil; p = p.Link {
|
||||
if p.As == obj.ATEXT {
|
||||
text = p.From.Sym
|
||||
@@ -299,7 +294,7 @@ func testErrors(t *testing.T, goarch, file string, flags ...string) {
|
||||
failed := false
|
||||
var errBuf bytes.Buffer
|
||||
parser.errorWriter = &errBuf
|
||||
ctxt.DiagFunc = func(format string, args ...any) {
|
||||
ctxt.DiagFunc = func(format string, args ...interface{}) {
|
||||
failed = true
|
||||
s := fmt.Sprintf(format, args...)
|
||||
if !strings.HasSuffix(s, "\n") {
|
||||
@@ -470,16 +465,9 @@ func TestLOONG64Encoder(t *testing.T) {
|
||||
testEndToEnd(t, "loong64", "loong64enc1")
|
||||
testEndToEnd(t, "loong64", "loong64enc2")
|
||||
testEndToEnd(t, "loong64", "loong64enc3")
|
||||
testEndToEnd(t, "loong64", "loong64enc4")
|
||||
testEndToEnd(t, "loong64", "loong64enc5")
|
||||
testEndToEnd(t, "loong64", "loong64enc6")
|
||||
testEndToEnd(t, "loong64", "loong64")
|
||||
}
|
||||
|
||||
func TestLOONG64Errors(t *testing.T) {
|
||||
testErrors(t, "loong64", "loong64error")
|
||||
}
|
||||
|
||||
func TestPPC64EndToEnd(t *testing.T) {
|
||||
defer func(old int) { buildcfg.GOPPC64 = old }(buildcfg.GOPPC64)
|
||||
for _, goppc64 := range []int{8, 9, 10} {
|
||||
@@ -491,35 +479,12 @@ func TestPPC64EndToEnd(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func testRISCV64AllProfiles(t *testing.T, testFn func(t *testing.T)) {
|
||||
t.Helper()
|
||||
|
||||
defer func(orig int) { buildcfg.GORISCV64 = orig }(buildcfg.GORISCV64)
|
||||
|
||||
for _, goriscv64 := range []int{20, 22, 23} {
|
||||
t.Run(fmt.Sprintf("rva%vu64", goriscv64), func(t *testing.T) {
|
||||
buildcfg.GORISCV64 = goriscv64
|
||||
testFn(t)
|
||||
})
|
||||
}
|
||||
func TestRISCVEndToEnd(t *testing.T) {
|
||||
testEndToEnd(t, "riscv64", "riscv64")
|
||||
}
|
||||
|
||||
func TestRISCV64EndToEnd(t *testing.T) {
|
||||
testRISCV64AllProfiles(t, func(t *testing.T) {
|
||||
testEndToEnd(t, "riscv64", "riscv64")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRISCV64Errors(t *testing.T) {
|
||||
testRISCV64AllProfiles(t, func(t *testing.T) {
|
||||
testErrors(t, "riscv64", "riscv64error")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRISCV64Validation(t *testing.T) {
|
||||
testRISCV64AllProfiles(t, func(t *testing.T) {
|
||||
testErrors(t, "riscv64", "riscv64validation")
|
||||
})
|
||||
func TestRISCVErrors(t *testing.T) {
|
||||
testErrors(t, "riscv64", "riscv64error")
|
||||
}
|
||||
|
||||
func TestS390XEndToEnd(t *testing.T) {
|
||||
|
||||
@@ -21,7 +21,6 @@ import (
|
||||
"cmd/asm/internal/lex"
|
||||
"cmd/internal/obj"
|
||||
"cmd/internal/obj/arm64"
|
||||
"cmd/internal/obj/riscv"
|
||||
"cmd/internal/obj/x86"
|
||||
"cmd/internal/objabi"
|
||||
"cmd/internal/src"
|
||||
@@ -78,7 +77,7 @@ func NewParser(ctxt *obj.Link, ar *arch.Arch, lexer lex.TokenReader) *Parser {
|
||||
// and turn it into a recoverable panic.
|
||||
var panicOnError bool
|
||||
|
||||
func (p *Parser) errorf(format string, args ...any) {
|
||||
func (p *Parser) errorf(format string, args ...interface{}) {
|
||||
if panicOnError {
|
||||
panic(fmt.Errorf(format, args...))
|
||||
}
|
||||
@@ -90,7 +89,7 @@ func (p *Parser) errorf(format string, args ...any) {
|
||||
if p.lex != nil {
|
||||
// Put file and line information on head of message.
|
||||
format = "%s:%d: " + format + "\n"
|
||||
args = append([]any{p.lex.File(), p.lineNum}, args...)
|
||||
args = append([]interface{}{p.lex.File(), p.lineNum}, args...)
|
||||
}
|
||||
fmt.Fprintf(p.errorWriter, format, args...)
|
||||
p.errorCount++
|
||||
@@ -399,21 +398,16 @@ func (p *Parser) operand(a *obj.Addr) {
|
||||
tok := p.next()
|
||||
name := tok.String()
|
||||
if tok.ScanToken == scanner.Ident && !p.atStartOfRegister(name) {
|
||||
// See if this is an architecture specific special operand.
|
||||
switch p.arch.Family {
|
||||
case sys.ARM64:
|
||||
if opd := arch.ARM64SpecialOperand(name); opd != arm64.SPOP_END {
|
||||
// arm64 special operands.
|
||||
if opd := arch.GetARM64SpecialOperand(name); opd != arm64.SPOP_END {
|
||||
a.Type = obj.TYPE_SPECIAL
|
||||
a.Offset = int64(opd)
|
||||
break
|
||||
}
|
||||
case sys.RISCV64:
|
||||
if opd := arch.RISCV64SpecialOperand(name); opd != riscv.SPOP_END {
|
||||
a.Type = obj.TYPE_SPECIAL
|
||||
a.Offset = int64(opd)
|
||||
}
|
||||
}
|
||||
|
||||
if a.Type != obj.TYPE_SPECIAL {
|
||||
fallthrough
|
||||
default:
|
||||
// We have a symbol. Parse $sym±offset(symkind)
|
||||
p.symbolReference(a, p.qualifySymbol(name), prefix)
|
||||
}
|
||||
@@ -775,7 +769,7 @@ func (p *Parser) registerExtension(a *obj.Addr, name string, prefix rune) {
|
||||
|
||||
switch p.arch.Family {
|
||||
case sys.ARM64:
|
||||
err := arm64.ARM64RegisterExtension(a, ext, reg, num, isAmount, isIndex)
|
||||
err := arch.ARM64RegisterExtension(a, ext, reg, num, isAmount, isIndex)
|
||||
if err != nil {
|
||||
p.errorf("%v", err)
|
||||
}
|
||||
|
||||
@@ -169,8 +169,3 @@ TEXT ·a34(SB), 0, $0-0
|
||||
SHLXQ AX, CX, R15
|
||||
ADDQ $1, R15
|
||||
RET
|
||||
|
||||
// Ensure from3 get GOT-rewritten without errors.
|
||||
TEXT ·a35(SB), 0, $0-0
|
||||
VGF2P8AFFINEQB $0, runtime·writeBarrier(SB), Z1, Z1
|
||||
RET
|
||||
|
||||
@@ -1059,7 +1059,5 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
RDPID DX // f30fc7fa
|
||||
RDPID R11 // f3410fc7fb
|
||||
|
||||
ENDBR64 // f30f1efa
|
||||
|
||||
// End of tests.
|
||||
RET
|
||||
|
||||
20
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
20
src/cmd/asm/internal/asm/testdata/arm64.s
vendored
@@ -400,8 +400,6 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
||||
MOVD $0x11110000, R1 // MOVD $286326784, R1 // 2122a2d2
|
||||
MOVD $0xaaaa0000aaaa1111, R1 // MOVD $-6149102338357718767, R1 // 212282d24155b5f24155f5f2
|
||||
MOVD $0x1111ffff1111aaaa, R1 // MOVD $1230045644216969898, R1 // a1aa8a922122a2f22122e2f2
|
||||
MOVD $0xaaaaaaaaaaaaaaab, R1 // MOVD $-6148914691236517205, R1 // e1f301b2615595f2
|
||||
MOVD $0x0ff019940ff00ff0, R1 // MOVD $1148446028692721648, R1 // e19f0cb28132c3f2
|
||||
MOVD $0, R1 // e1031faa
|
||||
MOVD $-1, R1 // 01008092
|
||||
MOVD $0x210000, R0 // MOVD $2162688, R0 // 2004a0d2
|
||||
@@ -632,8 +630,6 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
||||
FMOVS F1, 0x44332211(R2) // FMOVS F1, 1144201745(R2)
|
||||
FMOVD F1, 0x1007000(R2) // FMOVD F1, 16805888(R2)
|
||||
FMOVD F1, 0x44332211(R2) // FMOVD F1, 1144201745(R2)
|
||||
FMOVQ F1, 0x1003000(R2) // FMOVQ F1, 16789504(R2)
|
||||
FMOVQ F1, 0x44332211(R2) // FMOVQ F1, 1144201745(R2)
|
||||
|
||||
MOVB 0x1000000(R1), R2 // MOVB 16777216(R1), R2
|
||||
MOVB 0x44332211(R1), R2 // MOVB 1144201745(R1), R2
|
||||
@@ -647,8 +643,6 @@ TEXT foo(SB), DUPOK|NOSPLIT, $-8
|
||||
FMOVS 0x44332211(R1), F2 // FMOVS 1144201745(R1), F2
|
||||
FMOVD 0x1000000(R1), F2 // FMOVD 16777216(R1), F2
|
||||
FMOVD 0x44332211(R1), F2 // FMOVD 1144201745(R1), F2
|
||||
FMOVQ 0x1000000(R1), F2 // FMOVQ 16777216(R1), F2
|
||||
FMOVQ 0x44332211(R1), F2 // FMOVQ 1144201745(R1), F2
|
||||
|
||||
// shifted or extended register offset.
|
||||
MOVD (R2)(R6.SXTW), R4 // 44c866f8
|
||||
@@ -1894,18 +1888,4 @@ next:
|
||||
DC CIGDVAC, R25 // b97e0bd5
|
||||
DC CVAP, R26 // 3a7c0bd5
|
||||
DC CVADP, R27 // 3b7d0bd5
|
||||
|
||||
// Branch Target Identification
|
||||
BTI C // 5f2403d5
|
||||
BTI J // 9f2403d5
|
||||
BTI JC // df2403d5
|
||||
|
||||
// Pointer Authentication Codes (PAC)
|
||||
PACIASP // 3f2303d5
|
||||
AUTIASP // bf2303d5
|
||||
PACIBSP // 7f2303d5
|
||||
AUTIBSP // ff2303d5
|
||||
AUTIA1716 // 9f2103d5
|
||||
AUTIB1716 // df2103d5
|
||||
|
||||
END
|
||||
|
||||
@@ -420,12 +420,4 @@ TEXT errors(SB),$0
|
||||
AESE V1.B16, V2.B8 // ERROR "invalid arrangement"
|
||||
SHA256SU1 V1.S4, V2.B16, V3.S4 // ERROR "invalid arrangement"
|
||||
SHA1H V1.B16, V2.B16 // ERROR "invalid operands"
|
||||
BTI // ERROR "missing operand"
|
||||
BTI PLDL1KEEP // ERROR "illegal argument"
|
||||
PACIASP C // ERROR "illegal combination"
|
||||
AUTIASP R2 // ERROR "illegal combination"
|
||||
PACIBSP R0 // ERROR "illegal combination"
|
||||
AUTIBSP C // ERROR "illegal combination"
|
||||
AUTIA1716 $45 // ERROR "illegal combination"
|
||||
AUTIB1716 R0 // ERROR "illegal combination"
|
||||
RET
|
||||
|
||||
923
src/cmd/asm/internal/asm/testdata/loong64enc1.s
vendored
923
src/cmd/asm/internal/asm/testdata/loong64enc1.s
vendored
File diff suppressed because it is too large
Load Diff
56
src/cmd/asm/internal/asm/testdata/loong64enc2.s
vendored
56
src/cmd/asm/internal/asm/testdata/loong64enc2.s
vendored
@@ -12,7 +12,7 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
AND $-1, R4, R5 // 1efcbf0285f81400
|
||||
AND $-1, R4 // 1efcbf0284f81400
|
||||
MOVW $-1, F4 // 1efcbf02c4a71401
|
||||
MOVW $1, F4 // 1e048003c4a71401
|
||||
MOVW $1, F4 // 1e048002c4a71401
|
||||
TEQ $4, R4, R5 // 8508005c04002a00
|
||||
TEQ $4, R4 // 0408005c04002a00
|
||||
TNE $4, R4, R5 // 8508005804002a00
|
||||
@@ -21,10 +21,6 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
ADD $4096, R4, R5 // 3e00001485781000
|
||||
ADD $65536, R4 // 1e02001484781000
|
||||
ADD $4096, R4 // 3e00001484781000
|
||||
ADDW $65536, R4, R5 // 1e02001485781000
|
||||
ADDW $4096, R4, R5 // 3e00001485781000
|
||||
ADDW $65536, R4 // 1e02001484781000
|
||||
ADDW $4096, R4 // 3e00001484781000
|
||||
ADDV $65536, R4, R5 // 1e02001485f81000
|
||||
ADDV $4096, R4, R5 // 3e00001485f81000
|
||||
ADDV $65536, R4 // 1e02001484f81000
|
||||
@@ -41,6 +37,10 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
SGTU $4096, R4, R5 // 3e00001485f81200
|
||||
SGTU $65536, R4 // 1e02001484f81200
|
||||
SGTU $4096, R4 // 3e00001484f81200
|
||||
ADDU $65536, R4, R5 // 1e02001485781000
|
||||
ADDU $4096, R4, R5 // 3e00001485781000
|
||||
ADDU $65536, R4 // 1e02001484781000
|
||||
ADDU $4096, R4 // 3e00001484781000
|
||||
ADDVU $65536, R4, R5 // 1e02001485f81000
|
||||
ADDVU $4096, R4, R5 // 3e00001485f81000
|
||||
ADDVU $65536, R4 // 1e02001484f81000
|
||||
@@ -77,49 +77,3 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
MOVH name(SB), R4 // 1e00001ac4034028
|
||||
MOVHU R4, name(SB) // 1e00001ac4034029
|
||||
MOVHU name(SB), R4 // 1e00001ac403402a
|
||||
|
||||
// MOVV C_DCON12_20S, r
|
||||
MOVV $0x273fffff80000000, R4 // MOVV $2828260563841187840, R4 // 0400001584cc0903
|
||||
MOVV $0xf73fffff80000000, R4 // MOVV $-630503949979353088, R4 // 0400001584cc3d03
|
||||
|
||||
// MOVV C_DCON20S_20, r
|
||||
MOVV $0xfff800000f000000, R4 // MOVV $-2251799562027008, R4 // 04001e1404000017
|
||||
|
||||
// MOVV C_DCON12_12S, r
|
||||
MOVV $0x273ffffffffff800, R4 // MOVV $2828260565988669440, R4 // 0400e00284cc0903
|
||||
MOVV $0xf73ffffffffff800, R4 // MOVV $-630503947831871488, R4 // 0400e00284cc3d03
|
||||
|
||||
// MOVV C_DCON20S_12S, r
|
||||
MOVV $0xfff80000fffff800, R4 // MOVV $-2251795518720000, R4 // 0400a00204000017
|
||||
MOVV $0xfff8000000000000, R4 // MOVV $-2251799813685248, R4 // 0400800204000017
|
||||
|
||||
// MOVV C_DCON12_12U, r
|
||||
MOVV $0x2730000000000800, R4 // MOVV $2823756966361303040, R4 // 0400a00384cc0903
|
||||
MOVV $0xf730000000000800, R4 // MOVV $-635007547459237888, R4 // 0400a00384cc3d03
|
||||
|
||||
// MOVV C_DCON20S_12U, r
|
||||
MOVV $0xfff8000000000800, R4 // MOVV $-2251799813683200, R4 // 0400a00304000017
|
||||
|
||||
// ADDV/AND C_DCON12_0, [r1], r2
|
||||
ADDV $0x3210000000000000, R4 // ADDV $3607383301523767296, R4 // 1e840c0384f81000
|
||||
ADDV $0x3210000000000000, R5, R4 // ADDV $3607383301523767296, R5, R4 // 1e840c03a4f81000
|
||||
ADDV $0xc210000000000000, R4 // ADDV $-4463067230724161536, R4 // 1e84300384f81000
|
||||
ADDV $0xc210000000000000, R5, R4 // ADDV $-4463067230724161536, R5, R4 // 1e843003a4f81000
|
||||
AND $0x3210000000000000, R4 // AND $3607383301523767296, R4 // 1e840c0384f81400
|
||||
AND $0x3210000000000000, R5, R4 // AND $3607383301523767296, R5, R4 // 1e840c03a4f81400
|
||||
AND $0xc210000000000000, R4 // AND $-4463067230724161536, R4 // 1e84300384f81400
|
||||
AND $0xc210000000000000, R5, R4 // AND $-4463067230724161536, R5, R4 // 1e843003a4f81400
|
||||
|
||||
// ADDV/AND C_UCON, [r1], r2
|
||||
ADDV $0x43210000, R4 // ADDV $1126236160, R4 // 1e42861484f81000
|
||||
ADDV $0x43210000, R5, R4 // ADDV $1126236160, R5, R4 // 1e428614a4f81000
|
||||
ADDV $0xffffffffc3210000, R4 // ADDV $-1021247488, R4 // 1e42861584f81000
|
||||
ADDV $0xffffffffc3210000, R5, R4 // ADDV $-1021247488, R5, R4 // 1e428615a4f81000
|
||||
AND $0x43210000, R4 // AND $1126236160, R4 // 1e42861484f81400
|
||||
AND $0x43210000, R5, R4 // AND $1126236160, R5, R4 // 1e428614a4f81400
|
||||
AND $0xffffffffc3210000, R4 // AND $-1021247488, R4 // 1e42861584f81400
|
||||
AND $0xffffffffc3210000, R5, R4 // AND $-1021247488, R5, R4 // 1e428615a4f81400
|
||||
|
||||
// AND C_ADDCON, [r1], r2
|
||||
AND $0xfffffffffffffc21, R4 // AND $-991, R4 // 1e84b00284f81400
|
||||
AND $0xfffffffffffffc21, R5, R4 // AND $-991, R5, R4 // 1e84b002a4f81400
|
||||
|
||||
94
src/cmd/asm/internal/asm/testdata/loong64enc3.s
vendored
94
src/cmd/asm/internal/asm/testdata/loong64enc3.s
vendored
@@ -11,16 +11,12 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
MOVV $4096(R4), R5 // 3e000014de03800385f81000
|
||||
ADD $74565, R4 // 5e020014de178d0384781000
|
||||
ADD $4097, R4 // 3e000014de07800384781000
|
||||
ADDW $74565, R4 // 5e020014de178d0384781000
|
||||
ADDW $4097, R4 // 3e000014de07800384781000
|
||||
ADDV $74565, R4 // 5e020014de178d0384f81000
|
||||
ADDV $4097, R4 // 3e000014de07800384f81000
|
||||
AND $74565, R4 // 5e020014de178d0384f81400
|
||||
AND $4097, R4 // 3e000014de07800384f81400
|
||||
ADD $74565, R4, R5 // 5e020014de178d0385781000
|
||||
ADD $4097, R4, R5 // 3e000014de07800385781000
|
||||
ADDW $74565, R4, R5 // 5e020014de178d0385781000
|
||||
ADDW $4097, R4, R5 // 3e000014de07800385781000
|
||||
ADDV $74565, R4, R5 // 5e020014de178d0385f81000
|
||||
ADDV $4097, R4, R5 // 3e000014de07800385f81000
|
||||
AND $74565, R4, R5 // 5e020014de178d0385f81400
|
||||
@@ -46,10 +42,8 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
MOVB R4, 4096(R5) // 3e000014de971000c4030029
|
||||
MOVBU R4, 65536(R5) // 1e020014de971000c4030029
|
||||
MOVBU R4, 4096(R5) // 3e000014de971000c4030029
|
||||
SC R4, 65536(R5) // 1e040010de971000c4030021
|
||||
SCV R4, 65536(R5) // 1e040010de971000c4030023
|
||||
LL 65536(R5), R4 // 1e040010de971000c4030020
|
||||
LLV 65536(R5), R4 // 1e040010de971000c4030022
|
||||
SC R4, 65536(R5) // 1e020014de971000c4030021
|
||||
SC R4, 4096(R5) // 3e000014de971000c4030021
|
||||
MOVW y+65540(FP), R4 // 1e020014de8f1000c4338028
|
||||
MOVWU y+65540(FP), R4 // 1e020014de8f1000c433802a
|
||||
MOVV y+65540(FP), R4 // 1e020014de8f1000c433c028
|
||||
@@ -111,6 +105,10 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
SGTU $74565, R4, R5 // 5e020014de178d0385f81200
|
||||
SGTU $4097, R4 // 3e000014de07800384f81200
|
||||
SGTU $4097, R4, R5 // 3e000014de07800385f81200
|
||||
ADDU $74565, R4 // 5e020014de178d0384781000
|
||||
ADDU $74565, R4, R5 // 5e020014de178d0385781000
|
||||
ADDU $4097, R4 // 3e000014de07800384781000
|
||||
ADDU $4097, R4, R5 // 3e000014de07800385781000
|
||||
ADDVU $4097, R4 // 3e000014de07800384f81000
|
||||
ADDVU $4097, R4, R5 // 3e000014de07800385f81000
|
||||
ADDVU $74565, R4 // 5e020014de178d0384f81000
|
||||
@@ -123,83 +121,3 @@ TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
XOR $74565, R4, R5 // 5e020014de178d0385f81500
|
||||
XOR $4097, R4 // 3e000014de07800384f81500
|
||||
XOR $4097, R4, R5 // 3e000014de07800385f81500
|
||||
|
||||
MOVWP R5, -32768(R4) // 1efcff13de931000c5038025
|
||||
MOVWP R5, 32768(R4) // 1e000010de931000c5038025
|
||||
MOVWP R5, 65536(R4) // 1e040010de931000c5030025
|
||||
MOVWP R5, 1048576(R4) // 1e400010de931000c5030025
|
||||
MOVVP R5, -32768(R4) // 1efcff13de931000c5038027
|
||||
MOVVP R5, 65536(R4) // 1e040010de931000c5030027
|
||||
MOVVP R5, 1048576(R4) // 1e400010de931000c5030027
|
||||
MOVWP -32768(R5), R4 // 1efcff13de971000c4038024
|
||||
MOVWP 2229248(R5), R4 // 1e880010de971000c4030424
|
||||
MOVWP -2145518592(R5), R4 // 1e740012de971000c403fc24
|
||||
MOVVP -32768(R5), R4 // 1efcff13de971000c4038026
|
||||
MOVVP 2229248(R5), R4 // 1e880010de971000c4030426
|
||||
MOVVP -2145518592(R5), R4 // 1e740012de971000c403fc26
|
||||
|
||||
|
||||
// MOVV C_DCON32_12S, r
|
||||
MOVV $0x27312345fffff800, R4 // MOVV $2824077224892692480, R4 // 0400a002a468241684cc0903
|
||||
MOVV $0xf7312345fffff800, R4 // MOVV $-634687288927848448, R4 // 0400a002a468241684cc3d03
|
||||
|
||||
// MOVV C_DCON32_0, r
|
||||
MOVV $0x2731234500000000, R4 // MOVV $2824077220597727232, R4 // 04008002a468241684cc0903
|
||||
MOVV $0xf731234500000000, R4 // MOVV $-634687293222813696, R4 // 04008002a468241684cc3d03
|
||||
|
||||
// MOVV C_DCON32_20, r
|
||||
MOVV $0x2731234512345000, R4 // MOVV $2824077220903145472, R4 // a4682414a468241684cc0903
|
||||
MOVV $0xf731234512345000, R4 // MOVV $-634687292917395456, R4 // a4682414a468241684cc3d03
|
||||
|
||||
// MOVV C_DCON12_32S, r
|
||||
MOVV $0x273fffff80000800, R4 // MOVV $2828260563841189888, R4 // 040000158400a00384cc0903
|
||||
MOVV $0xf73fffff80000800, R4 // MOVV $-630503949979351040, R4 // 040000158400a00384cc3d03
|
||||
|
||||
// MOVV C_DCON20S_32, r
|
||||
MOVV $0xfff8000080000800, R4 // MOVV $-2251797666199552, R4 // 040000158400a00304000017
|
||||
|
||||
// MOVV C_DCON32_12U, r
|
||||
MOVV $0x2731234500000800, R4 // MOVV $2824077220597729280, R4 // 0400a003a468241684cc0903
|
||||
MOVV $0xf731234500000800, R4 // MOVV $-634687293222811648, R4 // 0400a003a468241684cc3d03
|
||||
|
||||
// ADDV/AND C_DCON12_20S, [r1], r2
|
||||
ADDV $0x273fffff80000000, R4 // ADDV $2828260563841187840, R4 // 1e000015decf090384f81000
|
||||
ADDV $0x273fffff80000000, R4, R5 // ADDV $2828260563841187840, R4, R5 // 1e000015decf090385f81000
|
||||
AND $0x273fffff80000000, R4 // AND $2828260563841187840, R4 // 1e000015decf090384f81400
|
||||
AND $0x273fffff80000000, R4, R5 // AND $2828260563841187840, R4, R5 // 1e000015decf090385f81400
|
||||
|
||||
// ADDV/AND C_DCON20S_20, [r1], r2
|
||||
ADDV $0xfff800000f000000, R4 // ADDV $-2251799562027008, R4 // 1e001e141e00001784f81000
|
||||
ADDV $0xfff800000f000000, R4, R5 // ADDV $-2251799562027008, R4, R5 // 1e001e141e00001785f81000
|
||||
AND $0xfff800000f000000, R4 // AND $-2251799562027008, R4 // 1e001e141e00001784f81400
|
||||
AND $0xfff800000f000000, R4, R5 // AND $-2251799562027008, R4, R5 // 1e001e141e00001785f81400
|
||||
|
||||
// ADDV/AND C_DCON12_12S, [r1], r2
|
||||
ADDV $0x273ffffffffff800, R4 // ADDV $2828260565988669440, R4 // 1e00e002decf090384f81000
|
||||
ADDV $0x273ffffffffff800, R4, R5 // ADDV $2828260565988669440, R4, R5 // 1e00e002decf090385f81000
|
||||
AND $0x273ffffffffff800, R4 // AND $2828260565988669440, R4 // 1e00e002decf090384f81400
|
||||
AND $0x273ffffffffff800, R4, R5 // AND $2828260565988669440, R4, R5 // 1e00e002decf090385f81400
|
||||
|
||||
// ADDV/AND C_DCON20S_12S, [r1], r2
|
||||
ADDV $0xfff80000fffff800, R4 // ADDV $-2251795518720000, R4 // 1e00a0021e00001784f81000
|
||||
ADDV $0xfff80000fffff800, R4, R5 // ADDV $-2251795518720000, R4, R5 // 1e00a0021e00001785f81000
|
||||
AND $0xfff80000fffff800, R4 // AND $-2251795518720000, R4 // 1e00a0021e00001784f81400
|
||||
AND $0xfff80000fffff800, R4, R5 // AND $-2251795518720000, R4, R5 // 1e00a0021e00001785f81400
|
||||
|
||||
// ADDV/AND C_DCON20S_0, [r1], r2
|
||||
ADDV $0xfff8000000000000, R4 // ADDV $-2251799813685248, R4 // 1e0080021e00001784f81000
|
||||
ADDV $0xfff8000000000000, R4, R5 // ADDV $-2251799813685248, R4, R5 // 1e0080021e00001785f81000
|
||||
AND $0xfff8000000000000, R4 // AND $-2251799813685248, R4 // 1e0080021e00001784f81400
|
||||
AND $0xfff8000000000000, R4, R5 // AND $-2251799813685248, R4, R5 // 1e0080021e00001785f81400
|
||||
|
||||
// ADDV/AND C_DCON12_12U, [r1], r2
|
||||
ADDV $0x2730000000000800, R4 // ADDV $2823756966361303040, R4 // 1e00a003decf090384f81000
|
||||
ADDV $0x2730000000000800, R4, R5 // ADDV $2823756966361303040, R4, R5 // 1e00a003decf090385f81000
|
||||
AND $0x2730000000000800, R4 // AND $2823756966361303040, R4 // 1e00a003decf090384f81400
|
||||
AND $0x2730000000000800, R4, R5 // AND $2823756966361303040, R4, R5 // 1e00a003decf090385f81400
|
||||
|
||||
// ADDV/AND C_DCON20S_12U, [r1], r2
|
||||
ADDV $0xfff8000000000800, R4 // ADDV $-2251799813683200, R4 // 1e00a0031e00001784f81000
|
||||
ADDV $0xfff8000000000800, R4, R5 // ADDV $-2251799813683200, R4, R5 // 1e00a0031e00001785f81000
|
||||
AND $0xfff8000000000800, R4 // AND $-2251799813683200, R4 // 1e00a0031e00001784f81400
|
||||
AND $0xfff8000000000800, R4, R5 // AND $-2251799813683200, R4, R5 // 1e00a0031e00001785f81400
|
||||
|
||||
42
src/cmd/asm/internal/asm/testdata/loong64enc4.s
vendored
42
src/cmd/asm/internal/asm/testdata/loong64enc4.s
vendored
@@ -1,42 +0,0 @@
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
// ADDV/AND C_DCON32_12S, [r1], r2
|
||||
ADDV $0x27312345fffff800, R4 // ADDV $2824077224892692480, R4 // 1e00a002be682416decf090384f81000
|
||||
ADDV $0x27312345fffff800, R4, R5 // ADDV $2824077224892692480, R4, R5 // 1e00a002be682416decf090385f81000
|
||||
AND $0x27312345fffff800, R4 // AND $2824077224892692480, R4 // 1e00a002be682416decf090384f81400
|
||||
AND $0x27312345fffff800, R4, R5 // AND $2824077224892692480, R4, R5 // 1e00a002be682416decf090385f81400
|
||||
|
||||
// ADDV/AND C_DCON32_0, [r1], r2
|
||||
ADDV $0x2731234500000000, R4 // ADDV $2824077220597727232, R4 // 1e008002be682416decf090384f81000
|
||||
ADDV $0x2731234500000000, R4, R5 // ADDV $2824077220597727232, R4, R5 // 1e008002be682416decf090385f81000
|
||||
AND $0x2731234500000000, R4 // AND $2824077220597727232, R4 // 1e008002be682416decf090384f81400
|
||||
AND $0x2731234500000000, R4, R5 // AND $2824077220597727232, R4, R5 // 1e008002be682416decf090385f81400
|
||||
|
||||
// ADDV/AND C_DCON32_20, [r1], r2
|
||||
ADDV $0x2731234512345000, R4 // ADDV $2824077220903145472, R4 // be682414be682416decf090384f81000
|
||||
ADDV $0x2731234512345000, R4, R5 // ADDV $2824077220903145472, R4, R5 // be682414be682416decf090385f81000
|
||||
AND $0x2731234512345000, R4 // AND $2824077220903145472, R4 // be682414be682416decf090384f81400
|
||||
AND $0x2731234512345000, R4, R5 // AND $2824077220903145472, R4, R5 // be682414be682416decf090385f81400
|
||||
|
||||
// ADDV/AND C_DCON12_32S, [r1], r2
|
||||
ADDV $0x273fffff80000800, R4 // ADDV $2828260563841189888, R4 // 1e000015de03a003decf090384f81000
|
||||
ADDV $0x273fffff80000800, R4, R5 // ADDV $2828260563841189888, R4, R5 // 1e000015de03a003decf090385f81000
|
||||
AND $0x273fffff80000800, R4 // AND $2828260563841189888, R4 // 1e000015de03a003decf090384f81400
|
||||
AND $0x273fffff80000800, R4, R5 // AND $2828260563841189888, R4, R5 // 1e000015de03a003decf090385f81400
|
||||
|
||||
// ADDV/AND C_DCON20S_32, [r1], r2
|
||||
ADDV $0xfff8000080000800, R4 // ADDV $-2251797666199552, R4 // 1e000015de03a0031e00001784f81000
|
||||
ADDV $0xfff8000080000800, R4, R5 // ADDV $-2251797666199552, R4, R5 // 1e000015de03a0031e00001785f81000
|
||||
AND $0xfff8000080000800, R4 // AND $-2251797666199552, R4 // 1e000015de03a0031e00001784f81400
|
||||
AND $0xfff8000080000800, R4, R5 // AND $-2251797666199552, R4, R5 // 1e000015de03a0031e00001785f81400
|
||||
|
||||
// ADDV/AND C_DCON32_12U, [r1], r2
|
||||
ADDV $0x2731234500000800, R4 // ADDV $2824077220597729280, R4 // 1e00a003be682416decf090384f81000
|
||||
ADDV $0x2731234500000800, R4, R5 // ADDV $2824077220597729280, R4, R5 // 1e00a003be682416decf090385f81000
|
||||
AND $0x2731234500000800, R4 // AND $2824077220597729280, R4 // 1e00a003be682416decf090384f81400
|
||||
AND $0x2731234500000800, R4, R5 // AND $2824077220597729280, R4, R5 // 1e00a003be682416decf090385f81400
|
||||
22
src/cmd/asm/internal/asm/testdata/loong64enc5.s
vendored
22
src/cmd/asm/internal/asm/testdata/loong64enc5.s
vendored
@@ -1,22 +0,0 @@
|
||||
// Copyright 2024 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
// ADDV/AND C_DCON, [r1], r2
|
||||
ADDV $0xfedcba9876543210, R4 // ADDV $-81985529216486896, R4 // 7ea8ec14de4388031e539717deb73f0384f81000
|
||||
ADDV $0xfedcba9876543210, R5, R4 // ADDV $-81985529216486896, R5, R4 // 7ea8ec14de4388031e539717deb73f03a4f81000
|
||||
ADDV $0x4edcba9876543210, R4 // ADDV $5682621993817747984, R4 // 7ea8ec14de4388031e539717deb7130384f81000
|
||||
ADDV $0x4edcba9876543210, R5, R4 // ADDV $5682621993817747984, R5, R4 // 7ea8ec14de4388031e539717deb71303a4f81000
|
||||
AND $0x4edcba9876543210, R4 // AND $5682621993817747984, R4 // 7ea8ec14de4388031e539717deb7130384f81400
|
||||
AND $0x4edcba9876543210, R5, R4 // AND $5682621993817747984, R5, R4 // 7ea8ec14de4388031e539717deb71303a4f81400
|
||||
AND $0xfedcba9876543210, R4 // AND $-81985529216486896, R4 // 7ea8ec14de4388031e539717deb73f0384f81400
|
||||
AND $0xfedcba9876543210, R5, R4 // AND $-81985529216486896, R5, R4 // 7ea8ec14de4388031e539717deb73f03a4f81400
|
||||
|
||||
PRELDX 0(R7), $0x80001021, $0 // PRELDX (R7), $2147487777, $0 // 1e020014de0380031e000016de130003e0782c38
|
||||
PRELDX -1(R7), $0x1021, $2 // PRELDX -1(R7), $4129, $2 // fe030014deffbf031e000016de030003e2782c38
|
||||
PRELDX 8(R7), $0x80100800, $31 // PRELDX 8(R7), $2148534272, $31 // 1ee00714de238003fe1f0016de130003ff782c38
|
||||
PRELDX 16(R7), $0x202040, $1 // PRELDX 16(R7), $2105408, $1 // 1e200014de4380033e000216de030003e1782c38
|
||||
|
||||
12
src/cmd/asm/internal/asm/testdata/loong64enc6.s
vendored
12
src/cmd/asm/internal/asm/testdata/loong64enc6.s
vendored
@@ -1,12 +0,0 @@
|
||||
// Copyright 2025 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
#include "../../../../../runtime/textflag.h"
|
||||
|
||||
TEXT asmtest(SB),DUPOK|NOSPLIT,$0
|
||||
// MOVWP LOREG_64(Rx), Ry
|
||||
MOVWP 81985529216486896(R4), R5 // 9e571315dec3b703feac6816de4b000384f8100085000025
|
||||
MOVWP -81985529216486896(R4), R5 // 7ea8ec14de4388031e539717deb73f0384f8100085000025
|
||||
MOVWP R4, 81985529216486896(R5) // 9e571315dec3b703feac6816de4b0003a5f81000a4000025
|
||||
MOVWP R4, -81985529216486896(R5) // 7ea8ec14de4388031e539717deb73f03a5f81000a4000025
|
||||
14
src/cmd/asm/internal/asm/testdata/loong64error.s
vendored
14
src/cmd/asm/internal/asm/testdata/loong64error.s
vendored
@@ -1,14 +0,0 @@
|
||||
// Copyright 2025 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.
|
||||
|
||||
TEXT errors(SB),$0
|
||||
VSHUF4IV $16, V1, V2 // ERROR "operand out of range 0 to 15"
|
||||
XVSHUF4IV $16, X1, X2 // ERROR "operand out of range 0 to 15"
|
||||
ADDV16 $1, R4, R5 // ERROR "the constant must be a multiple of 65536."
|
||||
ADDV16 $65535, R4, R5 // ERROR "the constant must be a multiple of 65536."
|
||||
SC R4, 1(R5) // ERROR "offset must be a multiple of 4."
|
||||
SCV R4, 1(R5) // ERROR "offset must be a multiple of 4."
|
||||
LL 1(R5), R4 // ERROR "offset must be a multiple of 4."
|
||||
LLV 1(R5), R4 // ERROR "offset must be a multiple of 4."
|
||||
|
||||
1615
src/cmd/asm/internal/asm/testdata/riscv64.s
vendored
1615
src/cmd/asm/internal/asm/testdata/riscv64.s
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user