github.com/golang/dep@v0.5.4/gps/strings.go (about) 1 // Copyright 2017 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package gps 6 7 import ( 8 "bytes" 9 "unicode" 10 "unicode/utf8" 11 ) 12 13 // toFold returns a string with the property that strings.EqualFold(s, t) iff 14 // ToFold(s) == ToFold(t) This lets us test a large set of strings for 15 // fold-equivalent duplicates without making a quadratic number of calls to 16 // EqualFold. Note that strings.ToUpper and strings.ToLower do not have the 17 // desired property in some corner cases. 18 // 19 // This is hoisted from toolchain internals: src/cmd/go/internal/str/str.go 20 func toFold(s string) string { 21 // Fast path: all ASCII, no upper case. 22 // Most paths look like this already. 23 for i := 0; i < len(s); i++ { 24 c := s[i] 25 if c >= utf8.RuneSelf || 'A' <= c && c <= 'Z' { 26 goto Slow 27 } 28 } 29 return s 30 31 Slow: 32 var buf bytes.Buffer 33 for _, r := range s { 34 // SimpleFold(x) cycles to the next equivalent rune > x 35 // or wraps around to smaller values. Iterate until it wraps, 36 // and we've found the minimum value. 37 for { 38 r0 := r 39 r = unicode.SimpleFold(r0) 40 if r <= r0 { 41 break 42 } 43 } 44 // Exception to allow fast path above: A-Z => a-z 45 if 'A' <= r && r <= 'Z' { 46 r += 'a' - 'A' 47 } 48 buf.WriteRune(r) 49 } 50 return buf.String() 51 }