aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/bytes
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2022-02-11 14:53:56 -0800
committerIan Lance Taylor <iant@golang.org>2022-02-11 15:01:19 -0800
commit8dc2499aa62f768c6395c9754b8cabc1ce25c494 (patch)
tree43d7fd2bbfd7ad8c9625a718a5e8718889351994 /libgo/go/bytes
parent9a56779dbc4e2d9c15be8d31e36f2f59be7331a8 (diff)
downloadgcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.zip
gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.tar.gz
gcc-8dc2499aa62f768c6395c9754b8cabc1ce25c494.tar.bz2
libgo: update to Go1.18beta2
gotools/ * Makefile.am (go_cmd_cgo_files): Add ast_go118.go (check-go-tool): Copy golang.org/x/tools directories. * Makefile.in: Regenerate. Reviewed-on: https://go-review.googlesource.com/c/gofrontend/+/384695
Diffstat (limited to 'libgo/go/bytes')
-rw-r--r--libgo/go/bytes/boundary_test.go19
-rw-r--r--libgo/go/bytes/bytes.go146
-rw-r--r--libgo/go/bytes/bytes_test.go32
-rw-r--r--libgo/go/bytes/example_test.go194
-rw-r--r--libgo/go/bytes/reader_test.go2
5 files changed, 297 insertions, 96 deletions
diff --git a/libgo/go/bytes/boundary_test.go b/libgo/go/bytes/boundary_test.go
index 5a47526..f9855fc 100644
--- a/libgo/go/bytes/boundary_test.go
+++ b/libgo/go/bytes/boundary_test.go
@@ -3,7 +3,6 @@
// license that can be found in the LICENSE file.
//
//go:build linux
-// +build linux
package bytes_test
@@ -66,7 +65,11 @@ func TestIndexByteNearPageBoundary(t *testing.T) {
func TestIndexNearPageBoundary(t *testing.T) {
t.Parallel()
- var q [64]byte
+ q := dangerousSlice(t)
+ if len(q) > 64 {
+ // Only worry about when we're near the end of a page.
+ q = q[len(q)-64:]
+ }
b := dangerousSlice(t)
if len(b) > 256 {
// Only worry about when we're near the end of a page.
@@ -82,4 +85,16 @@ func TestIndexNearPageBoundary(t *testing.T) {
}
q[j-1] = 0
}
+
+ // Test differing alignments and sizes of q which always end on a page boundary.
+ q[len(q)-1] = 1 // difference is only found on the last byte
+ for j := 0; j < len(q); j++ {
+ for i := range b {
+ idx := Index(b[i:], q[j:])
+ if idx != -1 {
+ t.Fatalf("Index(b[%d:], q[%d:])=%d, want -1\n", i, j, idx)
+ }
+ }
+ }
+ q[len(q)-1] = 0
}
diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go
index ce52649f1..6fdaa49 100644
--- a/libgo/go/bytes/bytes.go
+++ b/libgo/go/bytes/bytes.go
@@ -21,7 +21,7 @@ func Equal(a, b []byte) bool {
}
// Compare returns an integer comparing two byte slices lexicographically.
-// The result will be 0 if a==b, -1 if a < b, and +1 if a > b.
+// The result will be 0 if a == b, -1 if a < b, and +1 if a > b.
// A nil argument is equivalent to an empty slice.
func Compare(a, b []byte) int {
return bytealg.Compare(a, b)
@@ -699,7 +699,7 @@ func ToValidUTF8(s, replacement []byte) []byte {
if c < utf8.RuneSelf {
i++
invalid = false
- b = append(b, byte(c))
+ b = append(b, c)
continue
}
_, wid := utf8.DecodeRune(s[i:])
@@ -746,7 +746,8 @@ func isSeparator(r rune) bool {
// Title treats s as UTF-8-encoded bytes and returns a copy with all Unicode letters that begin
// words mapped to their title case.
//
-// BUG(rsc): The rule Title uses for word boundaries does not handle Unicode punctuation properly.
+// Deprecated: The rule Title uses for word boundaries does not handle Unicode
+// punctuation properly. Use golang.org/x/text/cases instead.
func Title(s []byte) []byte {
// Use a closure here to remember state.
// Hackish but effective. Depends on Map scanning in order and calling
@@ -867,6 +868,8 @@ func lastIndexFunc(s []byte, f func(r rune) bool, truth bool) int {
// 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
@@ -877,53 +880,133 @@ func makeASCIISet(chars string) (as asciiSet, ok bool) {
if c >= utf8.RuneSelf {
return as, false
}
- as[c>>5] |= 1 << uint(c&31)
+ 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>>5] & (1 << uint(c&31))) != 0
+ return (as[c/32] & (1 << (c % 32))) != 0
}
-func makeCutsetFunc(cutset string) func(r rune) bool {
- if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
- return func(r rune) bool {
- return r == rune(cutset[0])
- }
- }
- if as, isASCII := makeASCIISet(cutset); isASCII {
- return func(r rune) bool {
- return r < utf8.RuneSelf && as.contains(byte(r))
- }
- }
- return func(r rune) bool {
- for _, c := range cutset {
- if c == r {
- return true
- }
+// containsRune is a simplified version of strings.ContainsRune
+// to avoid importing the strings package.
+// We avoid bytes.ContainsRune to avoid allocating a temporary copy of s.
+func containsRune(s string, r rune) bool {
+ for _, c := range s {
+ if c == r {
+ return true
}
- return false
}
+ return false
}
// Trim returns a subslice of s by slicing off all leading and
// trailing UTF-8-encoded code points contained in cutset.
func Trim(s []byte, cutset string) []byte {
- return TrimFunc(s, makeCutsetFunc(cutset))
+ if len(s) == 0 || cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimLeftByte(trimRightByte(s, cutset[0]), cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimLeftASCII(trimRightASCII(s, &as), &as)
+ }
+ return trimLeftUnicode(trimRightUnicode(s, cutset), cutset)
}
// TrimLeft returns a subslice of s by slicing off all leading
// UTF-8-encoded code points contained in cutset.
func TrimLeft(s []byte, cutset string) []byte {
- return TrimLeftFunc(s, makeCutsetFunc(cutset))
+ if len(s) == 0 || cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimLeftByte(s, cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimLeftASCII(s, &as)
+ }
+ return trimLeftUnicode(s, cutset)
+}
+
+func trimLeftByte(s []byte, c byte) []byte {
+ for len(s) > 0 && s[0] == c {
+ s = s[1:]
+ }
+ return s
+}
+
+func trimLeftASCII(s []byte, as *asciiSet) []byte {
+ for len(s) > 0 {
+ if !as.contains(s[0]) {
+ break
+ }
+ s = s[1:]
+ }
+ return s
+}
+
+func trimLeftUnicode(s []byte, cutset string) []byte {
+ for len(s) > 0 {
+ r, n := rune(s[0]), 1
+ if r >= utf8.RuneSelf {
+ r, n = utf8.DecodeRune(s)
+ }
+ if !containsRune(cutset, r) {
+ break
+ }
+ s = s[n:]
+ }
+ return s
}
// TrimRight returns a subslice of s by slicing off all trailing
// UTF-8-encoded code points that are contained in cutset.
func TrimRight(s []byte, cutset string) []byte {
- return TrimRightFunc(s, makeCutsetFunc(cutset))
+ if len(s) == 0 || cutset == "" {
+ return s
+ }
+ if len(cutset) == 1 && cutset[0] < utf8.RuneSelf {
+ return trimRightByte(s, cutset[0])
+ }
+ if as, ok := makeASCIISet(cutset); ok {
+ return trimRightASCII(s, &as)
+ }
+ return trimRightUnicode(s, cutset)
+}
+
+func trimRightByte(s []byte, c byte) []byte {
+ for len(s) > 0 && s[len(s)-1] == c {
+ s = s[:len(s)-1]
+ }
+ return s
+}
+
+func trimRightASCII(s []byte, as *asciiSet) []byte {
+ for len(s) > 0 {
+ if !as.contains(s[len(s)-1]) {
+ break
+ }
+ s = s[:len(s)-1]
+ }
+ return s
+}
+
+func trimRightUnicode(s []byte, cutset string) []byte {
+ for len(s) > 0 {
+ r, n := rune(s[len(s)-1]), 1
+ if r >= utf8.RuneSelf {
+ r, n = utf8.DecodeLastRune(s)
+ }
+ if !containsRune(cutset, r) {
+ break
+ }
+ s = s[:len(s)-n]
+ }
+ return s
}
// TrimSpace returns a subslice of s by slicing off all leading and
@@ -1174,3 +1257,16 @@ func Index(s, sep []byte) int {
}
return -1
}
+
+// Cut slices s around the first instance of sep,
+// returning the text before and after sep.
+// The found result reports whether sep appears in s.
+// If sep does not appear in s, cut returns s, nil, false.
+//
+// Cut returns slices of the original slice s, not copies.
+func Cut(s, sep []byte) (before, after []byte, found bool) {
+ if i := Index(s, sep); i >= 0 {
+ return s[:i], s[i+len(sep):], true
+ }
+ return s, nil, false
+}
diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go
index 0111d31..2e6d27c 100644
--- a/libgo/go/bytes/bytes_test.go
+++ b/libgo/go/bytes/bytes_test.go
@@ -1256,7 +1256,9 @@ var trimTests = []TrimTest{
{"TrimLeft", "abba", "ab", ""},
{"TrimRight", "abba", "ab", ""},
{"TrimLeft", "abba", "a", "bba"},
+ {"TrimLeft", "abba", "b", "abba"},
{"TrimRight", "abba", "a", "abb"},
+ {"TrimRight", "abba", "b", "abba"},
{"Trim", "<tag>", "<>", "tag"},
{"Trim", "* listitem", " *", "listitem"},
{"Trim", `"quote"`, `"`, "quote"},
@@ -1570,6 +1572,29 @@ func TestEqualFold(t *testing.T) {
}
}
+var cutTests = []struct {
+ s, sep string
+ before, after string
+ found bool
+}{
+ {"abc", "b", "a", "c", true},
+ {"abc", "a", "", "bc", true},
+ {"abc", "c", "ab", "", true},
+ {"abc", "abc", "", "", true},
+ {"abc", "", "", "abc", true},
+ {"abc", "d", "abc", "", false},
+ {"", "d", "", "", false},
+ {"", "", "", "", true},
+}
+
+func TestCut(t *testing.T) {
+ for _, tt := range cutTests {
+ if before, after, found := Cut([]byte(tt.s), []byte(tt.sep)); string(before) != tt.before || string(after) != tt.after || found != tt.found {
+ t.Errorf("Cut(%q, %q) = %q, %q, %v, want %q, %q, %v", tt.s, tt.sep, before, after, found, tt.before, tt.after, tt.found)
+ }
+ }
+}
+
func TestBufferGrowNegative(t *testing.T) {
defer func() {
if err := recover(); err == nil {
@@ -1968,6 +1993,13 @@ func BenchmarkTrimASCII(b *testing.B) {
}
}
+func BenchmarkTrimByte(b *testing.B) {
+ x := []byte(" the quick brown fox ")
+ for i := 0; i < b.N; i++ {
+ Trim(x, " ")
+ }
+}
+
func BenchmarkIndexPeriodic(b *testing.B) {
key := []byte{1, 1}
for _, skip := range [...]int{2, 4, 8, 16, 32, 64} {
diff --git a/libgo/go/bytes/example_test.go b/libgo/go/bytes/example_test.go
index ae93202..54a7aa6 100644
--- a/libgo/go/bytes/example_test.go
+++ b/libgo/go/bytes/example_test.go
@@ -37,6 +37,16 @@ func ExampleBuffer_Bytes() {
// Output: hello world
}
+func ExampleBuffer_Cap() {
+ buf1 := bytes.NewBuffer(make([]byte, 10))
+ buf2 := bytes.NewBuffer(make([]byte, 0, 10))
+ fmt.Println(buf1.Cap())
+ fmt.Println(buf2.Cap())
+ // Output:
+ // 10
+ // 10
+}
+
func ExampleBuffer_Grow() {
var b bytes.Buffer
b.Grow(64)
@@ -54,6 +64,52 @@ func ExampleBuffer_Len() {
// Output: 5
}
+func ExampleBuffer_Next() {
+ var b bytes.Buffer
+ b.Grow(64)
+ b.Write([]byte("abcde"))
+ fmt.Printf("%s\n", string(b.Next(2)))
+ fmt.Printf("%s\n", string(b.Next(2)))
+ fmt.Printf("%s", string(b.Next(2)))
+ // Output:
+ // ab
+ // cd
+ // e
+}
+
+func ExampleBuffer_Read() {
+ var b bytes.Buffer
+ b.Grow(64)
+ b.Write([]byte("abcde"))
+ rdbuf := make([]byte, 1)
+ n, err := b.Read(rdbuf)
+ if err != nil {
+ panic(err)
+ }
+ fmt.Println(n)
+ fmt.Println(b.String())
+ fmt.Println(string(rdbuf))
+ // Output
+ // 1
+ // bcde
+ // a
+}
+
+func ExampleBuffer_ReadByte() {
+ var b bytes.Buffer
+ b.Grow(64)
+ b.Write([]byte("abcde"))
+ c, err := b.ReadByte()
+ if err != nil {
+ panic(err)
+ }
+ fmt.Println(c)
+ fmt.Println(b.String())
+ // Output
+ // 97
+ // bcde
+}
+
func ExampleCompare() {
// Interpret Compare's result by comparing it to zero.
var a, b []byte
@@ -92,36 +148,6 @@ func ExampleCompare_search() {
}
}
-func ExampleTrimSuffix() {
- var b = []byte("Hello, goodbye, etc!")
- b = bytes.TrimSuffix(b, []byte("goodbye, etc!"))
- b = bytes.TrimSuffix(b, []byte("gopher"))
- b = append(b, bytes.TrimSuffix([]byte("world!"), []byte("x!"))...)
- os.Stdout.Write(b)
- // Output: Hello, world!
-}
-
-func ExampleTrimPrefix() {
- var b = []byte("Goodbye,, world!")
- b = bytes.TrimPrefix(b, []byte("Goodbye,"))
- b = bytes.TrimPrefix(b, []byte("See ya,"))
- fmt.Printf("Hello%s", b)
- // Output: Hello, world!
-}
-
-func ExampleFields() {
- fmt.Printf("Fields are: %q", bytes.Fields([]byte(" foo bar baz ")))
- // Output: Fields are: ["foo" "bar" "baz"]
-}
-
-func ExampleFieldsFunc() {
- f := func(c rune) bool {
- return !unicode.IsLetter(c) && !unicode.IsNumber(c)
- }
- fmt.Printf("Fields are: %q", bytes.FieldsFunc([]byte(" foo1;bar2,baz3..."), f))
- // Output: Fields are: ["foo1" "bar2" "baz3"]
-}
-
func ExampleContains() {
fmt.Println(bytes.Contains([]byte("seafood"), []byte("foo")))
fmt.Println(bytes.Contains([]byte("seafood"), []byte("bar")))
@@ -168,6 +194,22 @@ func ExampleCount() {
// 5
}
+func ExampleCut() {
+ show := func(s, sep string) {
+ before, after, found := bytes.Cut([]byte(s), []byte(sep))
+ fmt.Printf("Cut(%q, %q) = %q, %q, %v\n", s, sep, before, after, found)
+ }
+ show("Gopher", "Go")
+ show("Gopher", "ph")
+ show("Gopher", "er")
+ show("Gopher", "Badger")
+ // Output:
+ // Cut("Gopher", "Go") = "", "pher", true
+ // Cut("Gopher", "ph") = "Go", "er", true
+ // Cut("Gopher", "er") = "Goph", "", true
+ // Cut("Gopher", "Badger") = "Gopher", "", false
+}
+
func ExampleEqual() {
fmt.Println(bytes.Equal([]byte("Go"), []byte("Go")))
fmt.Println(bytes.Equal([]byte("Go"), []byte("C++")))
@@ -181,6 +223,19 @@ func ExampleEqualFold() {
// Output: true
}
+func ExampleFields() {
+ fmt.Printf("Fields are: %q", bytes.Fields([]byte(" foo bar baz ")))
+ // Output: Fields are: ["foo" "bar" "baz"]
+}
+
+func ExampleFieldsFunc() {
+ f := func(c rune) bool {
+ return !unicode.IsLetter(c) && !unicode.IsNumber(c)
+ }
+ fmt.Printf("Fields are: %q", bytes.FieldsFunc([]byte(" foo1;bar2,baz3..."), f))
+ // Output: Fields are: ["foo1" "bar2" "baz3"]
+}
+
func ExampleHasPrefix() {
fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("Go")))
fmt.Println(bytes.HasPrefix([]byte("Gopher"), []byte("C")))
@@ -246,6 +301,12 @@ func ExampleIndexRune() {
// -1
}
+func ExampleJoin() {
+ s := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}
+ fmt.Printf("%s", bytes.Join(s, []byte(", ")))
+ // Output: foo, bar, baz
+}
+
func ExampleLastIndex() {
fmt.Println(bytes.Index([]byte("go gopher"), []byte("go")))
fmt.Println(bytes.LastIndex([]byte("go gopher"), []byte("go")))
@@ -286,10 +347,12 @@ func ExampleLastIndexFunc() {
// -1
}
-func ExampleJoin() {
- s := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}
- fmt.Printf("%s", bytes.Join(s, []byte(", ")))
- // Output: foo, bar, baz
+func ExampleReader_Len() {
+ fmt.Println(bytes.NewReader([]byte("Hi!")).Len())
+ fmt.Println(bytes.NewReader([]byte("こんにちは!")).Len())
+ // Output:
+ // 3
+ // 16
}
func ExampleRepeat() {
@@ -399,20 +462,6 @@ func ExampleTrimFunc() {
// go-gopher!
}
-func ExampleMap() {
- rot13 := func(r rune) rune {
- switch {
- case r >= 'A' && r <= 'Z':
- return 'A' + (r-'A'+13)%26
- case r >= 'a' && r <= 'z':
- return 'a' + (r-'a'+13)%26
- }
- return r
- }
- fmt.Printf("%s", bytes.Map(rot13, []byte("'Twas brillig and the slithy gopher...")))
- // Output: 'Gjnf oevyyvt naq gur fyvgul tbcure...
-}
-
func ExampleTrimLeft() {
fmt.Print(string(bytes.TrimLeft([]byte("453gopher8257"), "0123456789")))
// Output:
@@ -429,11 +478,28 @@ func ExampleTrimLeftFunc() {
// go-gopher!567
}
+func ExampleTrimPrefix() {
+ var b = []byte("Goodbye,, world!")
+ b = bytes.TrimPrefix(b, []byte("Goodbye,"))
+ b = bytes.TrimPrefix(b, []byte("See ya,"))
+ fmt.Printf("Hello%s", b)
+ // Output: Hello, world!
+}
+
func ExampleTrimSpace() {
fmt.Printf("%s", bytes.TrimSpace([]byte(" \t\n a lone gopher \n\t\r\n")))
// Output: a lone gopher
}
+func ExampleTrimSuffix() {
+ var b = []byte("Hello, goodbye, etc!")
+ b = bytes.TrimSuffix(b, []byte("goodbye, etc!"))
+ b = bytes.TrimSuffix(b, []byte("gopher"))
+ b = append(b, bytes.TrimSuffix([]byte("world!"), []byte("x!"))...)
+ os.Stdout.Write(b)
+ // Output: Hello, world!
+}
+
func ExampleTrimRight() {
fmt.Print(string(bytes.TrimRight([]byte("453gopher8257"), "0123456789")))
// Output:
@@ -450,21 +516,6 @@ func ExampleTrimRightFunc() {
// 1234go-gopher!
}
-func ExampleToUpper() {
- fmt.Printf("%s", bytes.ToUpper([]byte("Gopher")))
- // Output: GOPHER
-}
-
-func ExampleToUpperSpecial() {
- str := []byte("ahoj vývojári golang")
- totitle := bytes.ToUpperSpecial(unicode.AzeriCase, str)
- fmt.Println("Original : " + string(str))
- fmt.Println("ToUpper : " + string(totitle))
- // Output:
- // Original : ahoj vývojári golang
- // ToUpper : AHOJ VÝVOJÁRİ GOLANG
-}
-
func ExampleToLower() {
fmt.Printf("%s", bytes.ToLower([]byte("Gopher")))
// Output: gopher
@@ -480,10 +531,17 @@ func ExampleToLowerSpecial() {
// ToLower : ahoj vývojári golang
}
-func ExampleReader_Len() {
- fmt.Println(bytes.NewReader([]byte("Hi!")).Len())
- fmt.Println(bytes.NewReader([]byte("こんにちは!")).Len())
+func ExampleToUpper() {
+ fmt.Printf("%s", bytes.ToUpper([]byte("Gopher")))
+ // Output: GOPHER
+}
+
+func ExampleToUpperSpecial() {
+ str := []byte("ahoj vývojári golang")
+ totitle := bytes.ToUpperSpecial(unicode.AzeriCase, str)
+ fmt.Println("Original : " + string(str))
+ fmt.Println("ToUpper : " + string(totitle))
// Output:
- // 3
- // 16
+ // Original : ahoj vývojári golang
+ // ToUpper : AHOJ VÝVOJÁRİ GOLANG
}
diff --git a/libgo/go/bytes/reader_test.go b/libgo/go/bytes/reader_test.go
index 8baac50..9119c94 100644
--- a/libgo/go/bytes/reader_test.go
+++ b/libgo/go/bytes/reader_test.go
@@ -76,7 +76,7 @@ func TestReaderAt(t *testing.T) {
off int64
n int
want string
- wanterr interface{}
+ wanterr any
}{
{0, 10, "0123456789", nil},
{1, 10, "123456789", io.EOF},