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  }