aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/strings/strings.go
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@golang.org>2018-09-24 21:46:21 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-09-24 21:46:21 +0000
commitdd931d9b48647e898dc80927c532ae93cc09e192 (patch)
tree71be2295cd79b8a182f6130611658db8628772d5 /libgo/go/strings/strings.go
parent779d8a5ad09b01428726ea5a0e6c87bd9ac3c0e4 (diff)
downloadgcc-dd931d9b48647e898dc80927c532ae93cc09e192.zip
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.gz
gcc-dd931d9b48647e898dc80927c532ae93cc09e192.tar.bz2
libgo: update to Go 1.11
Reviewed-on: https://go-review.googlesource.com/136435 gotools/: * Makefile.am (mostlyclean-local): Run chmod on check-go-dir to make sure it is writable. (check-go-tools): Likewise. (check-vet): Copy internal/objabi to check-vet-dir. * Makefile.in: Rebuild. From-SVN: r264546
Diffstat (limited to 'libgo/go/strings/strings.go')
-rw-r--r--libgo/go/strings/strings.go98
1 files changed, 93 insertions, 5 deletions
diff --git a/libgo/go/strings/strings.go b/libgo/go/strings/strings.go
index 05e8243..20868be 100644
--- a/libgo/go/strings/strings.go
+++ b/libgo/go/strings/strings.go
@@ -8,6 +8,7 @@
package strings
import (
+ "internal/bytealg"
"unicode"
"unicode/utf8"
)
@@ -72,12 +73,16 @@ func hashStrRev(sep string) (uint32, uint32) {
return hash, pow
}
-// countGeneric implements Count.
-func countGeneric(s, substr string) int {
+// Count counts the number of non-overlapping instances of substr in s.
+// If substr is an empty string, Count returns 1 + the number of Unicode code points in s.
+func Count(s, substr string) int {
// special case
if len(substr) == 0 {
return utf8.RuneCountInString(s) + 1
}
+ if len(substr) == 1 {
+ return bytealg.CountString(s, substr[0])
+ }
n := 0
for {
i := Index(s, substr)
@@ -792,6 +797,8 @@ func Trim(s string, cutset string) string {
// TrimLeft returns a slice of the string s with all leading
// Unicode code points contained in cutset removed.
+//
+// To remove a prefix, use TrimPrefix instead.
func TrimLeft(s string, cutset string) string {
if s == "" || cutset == "" {
return s
@@ -801,6 +808,8 @@ func TrimLeft(s string, cutset string) string {
// TrimRight returns a slice of the string s, with all trailing
// Unicode code points contained in cutset removed.
+//
+// To remove a suffix, use TrimSuffix instead.
func TrimRight(s string, cutset string) string {
if s == "" || cutset == "" {
return s
@@ -903,9 +912,9 @@ func EqualFold(s, t string) bool {
tr, sr = sr, tr
}
// Fast check for ASCII.
- if tr < utf8.RuneSelf && 'A' <= sr && sr <= 'Z' {
- // ASCII, and sr is upper case. tr must be lower case.
- if tr == sr+'a'-'A' {
+ if tr < utf8.RuneSelf {
+ // ASCII only, sr/tr must be upper/lower case
+ if 'A' <= sr && sr <= 'Z' && tr == sr+'a'-'A' {
continue
}
return false
@@ -927,6 +936,85 @@ func EqualFold(s, t string) bool {
return s == t
}
+// Index returns the index of the first instance of substr in s, or -1 if substr is not present in s.
+func Index(s, substr string) int {
+ n := len(substr)
+ switch {
+ case n == 0:
+ return 0
+ case n == 1:
+ return IndexByte(s, substr[0])
+ case n == len(s):
+ if substr == s {
+ return 0
+ }
+ return -1
+ case n > len(s):
+ return -1
+ case n <= bytealg.MaxLen:
+ // Use brute force when s and substr both are small
+ if len(s) <= bytealg.MaxBruteForce {
+ return bytealg.IndexString(s, substr)
+ }
+ c := substr[0]
+ i := 0
+ t := s[:len(s)-n+1]
+ fails := 0
+ for i < len(t) {
+ if t[i] != c {
+ // IndexByte is faster than bytealg.IndexString, so use it as long as
+ // we're not getting lots of false positives.
+ o := IndexByte(t[i:], c)
+ if o < 0 {
+ return -1
+ }
+ i += o
+ }
+ if s[i:i+n] == substr {
+ return i
+ }
+ fails++
+ i++
+ // Switch to bytealg.IndexString when IndexByte produces too many false positives.
+ if fails > bytealg.Cutover(i) {
+ r := bytealg.IndexString(s[i:], substr)
+ if r >= 0 {
+ return r + i
+ }
+ return -1
+ }
+ }
+ return -1
+ }
+ c := substr[0]
+ i := 0
+ t := s[:len(s)-n+1]
+ fails := 0
+ for i < len(t) {
+ if t[i] != c {
+ o := IndexByte(t[i:], c)
+ if o < 0 {
+ return -1
+ }
+ i += o
+ }
+ if s[i:i+n] == substr {
+ return i
+ }
+ i++
+ fails++
+ if fails >= 4+i>>4 && i < len(t) {
+ // See comment in ../bytes/bytes_generic.go.
+ j := indexRabinKarp(s[i:], substr)
+ if j < 0 {
+ return -1
+ }
+ return i + j
+ }
+ }
+ return -1
+}
+
func indexRabinKarp(s, substr string) int {
// Rabin-Karp search
hashss, pow := hashStr(substr)