diff options
author | Ian Lance Taylor <iant@golang.org> | 2019-01-18 19:04:36 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2019-01-18 19:04:36 +0000 |
commit | 4f4a855d82a889cebcfca150a7a43909bcb6a346 (patch) | |
tree | f12bae0781920fa34669fe30b6f4615a86d9fb80 /libgo/go/bytes | |
parent | 225220d668dafb8262db7012bced688acbe63b33 (diff) | |
download | gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.zip gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.tar.gz gcc-4f4a855d82a889cebcfca150a7a43909bcb6a346.tar.bz2 |
libgo: update to Go1.12beta2
Reviewed-on: https://go-review.googlesource.com/c/158019
gotools/:
* Makefile.am (go_cmd_vet_files): Update for Go1.12beta2 release.
(GOTOOLS_TEST_TIMEOUT): Increase to 600.
(check-runtime): Export LD_LIBRARY_PATH before computing GOARCH
and GOOS.
(check-vet): Copy golang.org/x/tools into check-vet-dir.
* Makefile.in: Regenerate.
gcc/testsuite/:
* go.go-torture/execute/names-1.go: Stop using debug/xcoff, which
is no longer externally visible.
From-SVN: r268084
Diffstat (limited to 'libgo/go/bytes')
-rw-r--r-- | libgo/go/bytes/buffer.go | 23 | ||||
-rw-r--r-- | libgo/go/bytes/buffer_test.go | 2 | ||||
-rw-r--r-- | libgo/go/bytes/bytes.go | 62 | ||||
-rw-r--r-- | libgo/go/bytes/bytes_decl.go | 24 | ||||
-rw-r--r-- | libgo/go/bytes/bytes_test.go | 6 | ||||
-rw-r--r-- | libgo/go/bytes/compare_test.go | 13 | ||||
-rw-r--r-- | libgo/go/bytes/example_test.go | 14 | ||||
-rw-r--r-- | libgo/go/bytes/indexbyte.c | 73 | ||||
-rw-r--r-- | libgo/go/bytes/reader.go | 6 | ||||
-rw-r--r-- | libgo/go/bytes/reader_test.go | 42 |
10 files changed, 136 insertions, 129 deletions
diff --git a/libgo/go/bytes/buffer.go b/libgo/go/bytes/buffer.go index a2eca2e..aff2db5 100644 --- a/libgo/go/bytes/buffer.go +++ b/libgo/go/bytes/buffer.go @@ -12,13 +12,15 @@ import ( "unicode/utf8" ) +// smallBufferSize is an initial allocation minimal capacity. +const smallBufferSize = 64 + // A Buffer is a variable-sized buffer of bytes with Read and Write methods. // The zero value for Buffer is an empty buffer ready to use. type Buffer struct { - buf []byte // contents are the bytes buf[off : len(buf)] - off int // read at &buf[off], write at &buf[len(buf)] - bootstrap [64]byte // memory to hold first slice; helps small buffers avoid allocation. - lastRead readOp // last read operation, so that Unread* can work correctly. + 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. // FIXME: it would be advisable to align Buffer to cachelines to avoid false // sharing. @@ -66,7 +68,7 @@ func (b *Buffer) String() string { return string(b.buf[b.off:]) } -// empty returns whether the unread portion of the buffer is empty. +// empty reports whether the unread portion of the buffer is empty. func (b *Buffer) empty() bool { return len(b.buf) <= b.off } // Len returns the number of bytes of the unread portion of the buffer; @@ -125,9 +127,8 @@ func (b *Buffer) grow(n int) int { if i, ok := b.tryGrowByReslice(n); ok { return i } - // Check if we can make use of bootstrap array. - if b.buf == nil && n <= len(b.bootstrap) { - b.buf = b.bootstrap[:n] + if b.buf == nil && n <= smallBufferSize { + b.buf = make([]byte, n, smallBufferSize) return 0 } c := cap(b.buf) @@ -441,9 +442,9 @@ func (b *Buffer) ReadString(delim byte) (line string, err error) { // NewBuffer creates and initializes a new Buffer using buf as its // initial contents. The new Buffer takes ownership of buf, and the // caller should not use buf after this call. NewBuffer is intended to -// prepare a Buffer to read existing data. It can also be used to size -// the internal buffer for writing. To do that, buf should have the -// desired capacity but a length of zero. +// prepare a Buffer to read existing data. It can also be used to set +// the initial size of the internal buffer for writing. To do that, +// buf should have the desired capacity but a length of zero. // // In most cases, new(Buffer) (or just declaring a Buffer variable) is // sufficient to initialize a Buffer. diff --git a/libgo/go/bytes/buffer_test.go b/libgo/go/bytes/buffer_test.go index acbe5ca..6e9d695 100644 --- a/libgo/go/bytes/buffer_test.go +++ b/libgo/go/bytes/buffer_test.go @@ -293,7 +293,7 @@ func TestReadFromPanicReader(t *testing.T) { } check(t, "TestReadFromPanicReader (1)", &buf, "") - // Confirm that when Reader panics, the emtpy buffer remains empty + // Confirm that when Reader panics, the empty buffer remains empty var buf2 Buffer defer func() { recover() diff --git a/libgo/go/bytes/bytes.go b/libgo/go/bytes/bytes.go index 437a6e1..daf4a32 100644 --- a/libgo/go/bytes/bytes.go +++ b/libgo/go/bytes/bytes.go @@ -12,6 +12,13 @@ import ( "unicode/utf8" ) +// Equal returns a boolean reporting whether a and b +// are the same length and contain the same bytes. +// A nil argument is equivalent to an empty slice. +func Equal(a, b []byte) bool { + return bytealg.Equal(a, b) +} + func equalPortable(a, b []byte) bool { if len(a) != len(b) { return false @@ -24,6 +31,13 @@ func equalPortable(a, b []byte) bool { return true } +// Compare returns an integer comparing two byte slices lexicographically. +// The result will be 0 if a==b, -1 if a < b, and +1 if a > b. +// A nil argument is equivalent to an empty slice. +func Compare(a, b []byte) int { + return bytealg.Compare(a, b) +} + // explode splits s into a slice of UTF-8 sequences, one per Unicode code point (still slices of bytes), // up to a maximum of n byte slices. Invalid UTF-8 sequences are chopped into individual bytes. func explode(s []byte, n int) [][]byte { @@ -83,6 +97,11 @@ func ContainsRune(b []byte, r rune) bool { return IndexRune(b, r) >= 0 } +// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b. +func IndexByte(b []byte, c byte) int { + return bytealg.IndexByte(b, c) +} + func indexBytePortable(s []byte, c byte) int { for i, b := range s { if b == c { @@ -489,19 +508,19 @@ func ToTitle(s []byte) []byte { return Map(unicode.ToTitle, s) } // ToUpperSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their // upper case, giving priority to the special casing rules. func ToUpperSpecial(c unicode.SpecialCase, s []byte) []byte { - return Map(func(r rune) rune { return c.ToUpper(r) }, s) + return Map(c.ToUpper, s) } // ToLowerSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their // lower case, giving priority to the special casing rules. func ToLowerSpecial(c unicode.SpecialCase, s []byte) []byte { - return Map(func(r rune) rune { return c.ToLower(r) }, s) + return Map(c.ToLower, s) } // ToTitleSpecial treats s as UTF-8-encoded bytes and returns a copy with all the Unicode letters mapped to their // title case, giving priority to the special casing rules. func ToTitleSpecial(c unicode.SpecialCase, s []byte) []byte { - return Map(func(r rune) rune { return c.ToTitle(r) }, s) + return Map(c.ToTitle, s) } // isSeparator reports whether the rune could mark a word boundary. @@ -774,6 +793,15 @@ func Replace(s, old, new []byte, n int) []byte { return t[0:w] } +// ReplaceAll returns a copy of the slice s with all +// non-overlapping instances of old replaced by new. +// If old is empty, it matches at the beginning of the slice +// and after each UTF-8 sequence, yielding up to k+1 replacements +// for a k-rune slice. +func ReplaceAll(s, old, new []byte) []byte { + return Replace(s, old, new, -1) +} + // EqualFold reports whether s and t, interpreted as UTF-8 strings, // are equal under Unicode case-folding. func EqualFold(s, t []byte) bool { @@ -849,21 +877,22 @@ func Index(s, sep []byte) int { if len(s) <= bytealg.MaxBruteForce { return bytealg.Index(s, sep) } - c := sep[0] + c0 := sep[0] + c1 := sep[1] i := 0 - t := s[:len(s)-n+1] + t := len(s) - n + 1 fails := 0 - for i < len(t) { - if t[i] != c { + for i < t { + if s[i] != c0 { // IndexByte is faster than bytealg.Index, so use it as long as // we're not getting lots of false positives. - o := IndexByte(t[i:], c) + o := IndexByte(s[i:t], c0) if o < 0 { return -1 } i += o } - if Equal(s[i:i+n], sep) { + if s[i+1] == c1 && Equal(s[i:i+n], sep) { return i } fails++ @@ -879,24 +908,25 @@ func Index(s, sep []byte) int { } return -1 } - c := sep[0] + c0 := sep[0] + c1 := sep[1] i := 0 fails := 0 - t := s[:len(s)-n+1] - for i < len(t) { - if t[i] != c { - o := IndexByte(t[i:], c) + t := len(s) - n + 1 + for i < t { + if s[i] != c0 { + o := IndexByte(s[i:t], c0) if o < 0 { break } i += o } - if Equal(s[i:i+n], sep) { + if s[i+1] == c1 && Equal(s[i:i+n], sep) { return i } i++ fails++ - if fails >= 4+i>>4 && i < len(t) { + if fails >= 4+i>>4 && i < t { // Give up on IndexByte, it isn't skipping ahead // far enough to be better than Rabin-Karp. // Experiments (using IndexPeriodic) suggest diff --git a/libgo/go/bytes/bytes_decl.go b/libgo/go/bytes/bytes_decl.go deleted file mode 100644 index af0f8b1..0000000 --- a/libgo/go/bytes/bytes_decl.go +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2010 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package bytes - -//go:noescape - -// IndexByte returns the index of the first instance of c in b, or -1 if c is not present in b. -func IndexByte(b []byte, c byte) int // in internal/bytealg - -//go:noescape - -// Equal returns a boolean reporting whether a and b -// are the same length and contain the same bytes. -// A nil argument is equivalent to an empty slice. -func Equal(a, b []byte) bool // in internal/bytealg - -//go:noescape - -// Compare returns an integer comparing two byte slices lexicographically. -// The result will be 0 if a==b, -1 if a < b, and +1 if a > b. -// A nil argument is equivalent to an empty slice. -func Compare(a, b []byte) int // in internal/bytealg diff --git a/libgo/go/bytes/bytes_test.go b/libgo/go/bytes/bytes_test.go index 11c5ef9..ec4ecf3 100644 --- a/libgo/go/bytes/bytes_test.go +++ b/libgo/go/bytes/bytes_test.go @@ -1367,6 +1367,12 @@ func TestReplace(t *testing.T) { if cap(in) == cap(out) && &in[:1][0] == &out[:1][0] { 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, []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) + } + } } } diff --git a/libgo/go/bytes/compare_test.go b/libgo/go/bytes/compare_test.go index 3e33c27..a321f2e 100644 --- a/libgo/go/bytes/compare_test.go +++ b/libgo/go/bytes/compare_test.go @@ -41,9 +41,16 @@ var compareTests = []struct { func TestCompare(t *testing.T) { for _, tt := range compareTests { - cmp := Compare(tt.a, tt.b) - if cmp != tt.i { - t.Errorf(`Compare(%q, %q) = %v`, tt.a, tt.b, cmp) + numShifts := 16 + buffer := make([]byte, len(tt.b)+numShifts) + // vary the input alignment of tt.b + for offset := 0; offset <= numShifts; offset++ { + shiftedB := buffer[offset : len(tt.b)+offset] + copy(shiftedB, tt.b) + cmp := Compare(tt.a, shiftedB) + if cmp != tt.i { + t.Errorf(`Compare(%q, %q), offset %d = %v; want %v`, tt.a, tt.b, offset, cmp, tt.i) + } } } } diff --git a/libgo/go/bytes/example_test.go b/libgo/go/bytes/example_test.go index 5b7a460..6d32837 100644 --- a/libgo/go/bytes/example_test.go +++ b/libgo/go/bytes/example_test.go @@ -39,6 +39,14 @@ func ExampleBuffer_Grow() { // Output: "64 bytes or fewer" } +func ExampleBuffer_Len() { + var b bytes.Buffer + b.Grow(64) + b.Write([]byte("abcde")) + fmt.Printf("%d", b.Len()) + // Output: 5 +} + func ExampleCompare() { // Interpret Compare's result by comparing it to zero. var a, b []byte @@ -290,6 +298,12 @@ func ExampleReplace() { // moo moo moo } +func ExampleReplaceAll() { + fmt.Printf("%s\n", bytes.ReplaceAll([]byte("oink oink oink"), []byte("oink"), []byte("moo"))) + // Output: + // moo moo moo +} + func ExampleRunes() { rs := bytes.Runes([]byte("go gopher")) for _, r := range rs { diff --git a/libgo/go/bytes/indexbyte.c b/libgo/go/bytes/indexbyte.c deleted file mode 100644 index b248108..0000000 --- a/libgo/go/bytes/indexbyte.c +++ /dev/null @@ -1,73 +0,0 @@ -/* indexbyte.c -- implement bytes.IndexByte for Go. - - Copyright 2009 The Go Authors. All rights reserved. - Use of this source code is governed by a BSD-style - license that can be found in the LICENSE file. */ - -#include <stddef.h> - -#include "runtime.h" -#include "array.h" - -/* This is in C so that the compiler can optimize it appropriately. - We deliberately don't split the stack in case it does call the - library function, which shouldn't need much stack space. */ - -intgo IndexByte (struct __go_open_array, char) - __asm__ (GOSYM_PREFIX "bytes.IndexByte") - __attribute__ ((no_split_stack)); - -intgo -IndexByte (struct __go_open_array s, char b) -{ - char *p; - - p = __builtin_memchr (s.__values, b, s.__count); - if (p == NULL) - return -1; - return p - (char *) s.__values; -} - -/* Comparison. */ - -_Bool Equal (struct __go_open_array a, struct __go_open_array b) - __asm__ (GOSYM_PREFIX "bytes.Equal") - __attribute__ ((no_split_stack)); - -_Bool -Equal (struct __go_open_array a, struct __go_open_array b) -{ - if (a.__count != b.__count) - return 0; - return __builtin_memcmp (a.__values, b.__values, a.__count) == 0; -} - -intgo Compare (struct __go_open_array a, struct __go_open_array b) - __asm__ (GOSYM_PREFIX "bytes.Compare") - __attribute__ ((no_split_stack)); - -intgo -Compare (struct __go_open_array a, struct __go_open_array b) -{ - intgo len; - - len = a.__count; - if (len > b.__count) - len = b.__count; - if (len > 0) - { - intgo ret; - - ret = __builtin_memcmp (a.__values, b.__values, len); - if (ret < 0) - return -1; - else if (ret > 0) - return 1; - } - if (a.__count < b.__count) - return -1; - else if (a.__count > b.__count) - return 1; - else - return 0; -} diff --git a/libgo/go/bytes/reader.go b/libgo/go/bytes/reader.go index 08464c2..5946cf9 100644 --- a/libgo/go/bytes/reader.go +++ b/libgo/go/bytes/reader.go @@ -14,6 +14,7 @@ import ( // io.ByteScanner, and io.RuneScanner interfaces by reading from // a byte slice. // Unlike a Buffer, a Reader is read-only and supports seeking. +// The zero value for Reader operates like a Reader of an empty slice. type Reader struct { s []byte i int64 // current reading index @@ -75,10 +76,10 @@ func (r *Reader) ReadByte() (byte, error) { // UnreadByte complements ReadByte in implementing the io.ByteScanner interface. func (r *Reader) UnreadByte() error { - r.prevRune = -1 if r.i <= 0 { return errors.New("bytes.Reader.UnreadByte: at beginning of slice") } + r.prevRune = -1 r.i-- return nil } @@ -101,6 +102,9 @@ func (r *Reader) ReadRune() (ch rune, size int, err error) { // UnreadRune complements ReadRune in implementing the io.RuneScanner interface. func (r *Reader) UnreadRune() error { + if r.i <= 0 { + return errors.New("bytes.Reader.UnreadRune: at beginning of slice") + } if r.prevRune < 0 { return errors.New("bytes.Reader.UnreadRune: previous operation was not ReadRune") } diff --git a/libgo/go/bytes/reader_test.go b/libgo/go/bytes/reader_test.go index 8806876..d799e03 100644 --- a/libgo/go/bytes/reader_test.go +++ b/libgo/go/bytes/reader_test.go @@ -276,3 +276,45 @@ func TestReaderReset(t *testing.T) { t.Errorf("ReadAll: got %q, want %q", got, want) } } + +func TestReaderZero(t *testing.T) { + if l := (&Reader{}).Len(); l != 0 { + t.Errorf("Len: got %d, want 0", l) + } + + if n, err := (&Reader{}).Read(nil); n != 0 || err != io.EOF { + t.Errorf("Read: got %d, %v; want 0, io.EOF", n, err) + } + + if n, err := (&Reader{}).ReadAt(nil, 11); n != 0 || err != io.EOF { + t.Errorf("ReadAt: got %d, %v; want 0, io.EOF", n, err) + } + + if b, err := (&Reader{}).ReadByte(); b != 0 || err != io.EOF { + t.Errorf("ReadByte: got %d, %v; want 0, io.EOF", b, err) + } + + if ch, size, err := (&Reader{}).ReadRune(); ch != 0 || size != 0 || err != io.EOF { + t.Errorf("ReadRune: got %d, %d, %v; want 0, 0, io.EOF", ch, size, err) + } + + if offset, err := (&Reader{}).Seek(11, io.SeekStart); offset != 11 || err != nil { + t.Errorf("Seek: got %d, %v; want 11, nil", offset, err) + } + + if s := (&Reader{}).Size(); s != 0 { + t.Errorf("Size: got %d, want 0", s) + } + + if (&Reader{}).UnreadByte() == nil { + t.Errorf("UnreadByte: got nil, want error") + } + + if (&Reader{}).UnreadRune() == nil { + t.Errorf("UnreadRune: got nil, want error") + } + + if n, err := (&Reader{}).WriteTo(ioutil.Discard); n != 0 || err != nil { + t.Errorf("WriteTo: got %d, %v; want 0, nil", n, err) + } +} |