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.
5 // Package str provides string manipulation utilities.
15 // StringList flattens its arguments into a single []string.
16 // Each argument in args must have type string or []string.
17 func StringList(args
...interface{}) []string {
19 for _
, arg
:= range args
{
20 switch arg
:= arg
.(type) {
26 panic("stringList: invalid argument of type " + fmt
.Sprintf("%T", arg
))
32 // ToFold returns a string with the property that
33 // strings.EqualFold(s, t) iff ToFold(s) == ToFold(t)
34 // This lets us test a large set of strings for fold-equivalent
35 // duplicates without making a quadratic number of calls
36 // to EqualFold. Note that strings.ToUpper and strings.ToLower
37 // do not have the desired property in some corner cases.
38 func ToFold(s
string) string {
39 // Fast path: all ASCII, no upper case.
40 // Most paths look like this already.
41 for i
:= 0; i
< len(s
); i
++ {
43 if c
>= utf8
.RuneSelf ||
'A' <= c
&& c
<= 'Z' {
52 // SimpleFold(x) cycles to the next equivalent rune > x
53 // or wraps around to smaller values. Iterate until it wraps,
54 // and we've found the minimum value.
57 r
= unicode
.SimpleFold(r0
)
62 // Exception to allow fast path above: A-Z => a-z
63 if 'A' <= r
&& r
<= 'Z' {
71 // FoldDup reports a pair of strings from the list that are
72 // equal according to strings.EqualFold.
73 // It returns "", "" if there are no such strings.
74 func FoldDup(list
[]string) (string, string) {
75 clash
:= map[string]string{}
76 for _
, s
:= range list
{
78 if t
:= clash
[fold
]; t
!= "" {
89 // Contains reports whether x contains s.
90 func Contains(x
[]string, s
string) bool {
99 func isSpaceByte(c
byte) bool {
100 return c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r'
103 // SplitQuotedFields splits s into a list of fields,
104 // allowing single or double quotes around elements.
105 // There is no unescaping or other processing within
107 func SplitQuotedFields(s
string) ([]string, error
) {
108 // Split fields allowing '' or "" around elements.
109 // Quotes further inside the string do not count.
112 for len(s
) > 0 && isSpaceByte(s
[0]) {
118 // Accepted quoted string. No unescaping inside.
119 if s
[0] == '"' || s
[0] == '\'' {
123 for i
< len(s
) && s
[i
] != quote
{
127 return nil, fmt
.Errorf("unterminated %c string", quote
)
134 for i
< len(s
) && !isSpaceByte(s
[i
]) {