9
9
package pattern
10
10
11
11
import (
12
- "bytes"
13
12
"fmt"
14
13
"regexp"
15
14
"strconv"
@@ -66,15 +65,15 @@ noopLoop:
66
65
return pat , nil
67
66
}
68
67
closingBraces := []int {}
69
- var buf bytes. Buffer
68
+ var sb strings. Builder
70
69
// Enable matching `\n` with the `.` metacharacter as globs match `\n`
71
- buf .WriteString ("(?s)" )
70
+ sb .WriteString ("(?s)" )
72
71
dotMeta := false
73
72
if mode & NoGlobCase != 0 {
74
- buf .WriteString ("(?i)" )
73
+ sb .WriteString ("(?i)" )
75
74
}
76
75
if mode & EntireString != 0 {
77
- buf .WriteString ("^" )
76
+ sb .WriteString ("^" )
78
77
}
79
78
writeLoop:
80
79
for i := 0 ; i < len (pat ); i ++ {
@@ -86,45 +85,45 @@ writeLoop:
86
85
if i ++ ; i < len (pat ) && pat [i ] == '*' {
87
86
singleAfter := i == len (pat )- 1 || pat [i + 1 ] == '/'
88
87
if mode & NoGlobStar != 0 || ! singleBefore || ! singleAfter {
89
- buf .WriteString ("[^/]*" )
88
+ sb .WriteString ("[^/]*" )
90
89
} else if i ++ ; i < len (pat ) && pat [i ] == '/' {
91
- buf .WriteString ("(.*/|)" )
90
+ sb .WriteString ("(.*/|)" )
92
91
dotMeta = true
93
92
} else {
94
- buf .WriteString (".*" )
93
+ sb .WriteString (".*" )
95
94
dotMeta = true
96
95
i --
97
96
}
98
97
} else {
99
- buf .WriteString ("[^/]*" )
98
+ sb .WriteString ("[^/]*" )
100
99
i --
101
100
}
102
101
} else {
103
- buf .WriteString (".*" )
102
+ sb .WriteString (".*" )
104
103
dotMeta = true
105
104
}
106
105
if mode & Shortest != 0 {
107
- buf .WriteByte ('?' )
106
+ sb .WriteByte ('?' )
108
107
}
109
108
case '?' :
110
109
if mode & Filenames != 0 {
111
- buf .WriteString ("[^/]" )
110
+ sb .WriteString ("[^/]" )
112
111
} else {
113
- buf .WriteByte ('.' )
112
+ sb .WriteByte ('.' )
114
113
dotMeta = true
115
114
}
116
115
case '\\' :
117
116
if i ++ ; i >= len (pat ) {
118
117
return "" , & SyntaxError {msg : `\ at end of pattern` }
119
118
}
120
- buf .WriteString (regexp .QuoteMeta (string (pat [i ])))
119
+ sb .WriteString (regexp .QuoteMeta (string (pat [i ])))
121
120
case '[' :
122
121
name , err := charClass (pat [i :])
123
122
if err != nil {
124
123
return "" , & SyntaxError {msg : "charClass invalid" , err : err }
125
124
}
126
125
if name != "" {
127
- buf .WriteString (name )
126
+ sb .WriteString (name )
128
127
i += len (name ) - 1
129
128
break
130
129
}
@@ -133,24 +132,24 @@ writeLoop:
133
132
if c == ']' {
134
133
break
135
134
} else if c == '/' {
136
- buf .WriteString ("\\ [" )
135
+ sb .WriteString ("\\ [" )
137
136
continue writeLoop
138
137
}
139
138
}
140
139
}
141
- buf .WriteByte (c )
140
+ sb .WriteByte (c )
142
141
if i ++ ; i >= len (pat ) {
143
142
return "" , & SyntaxError {msg : "[ was not matched with a closing ]" }
144
143
}
145
144
switch c = pat [i ]; c {
146
145
case '!' , '^' :
147
- buf .WriteByte ('^' )
146
+ sb .WriteByte ('^' )
148
147
if i ++ ; i >= len (pat ) {
149
148
return "" , & SyntaxError {msg : "[ was not matched with a closing ]" }
150
149
}
151
150
}
152
151
if c = pat [i ]; c == ']' {
153
- buf .WriteByte (']' )
152
+ sb .WriteByte (']' )
154
153
if i ++ ; i >= len (pat ) {
155
154
return "" , & SyntaxError {msg : "[ was not matched with a closing ]" }
156
155
}
@@ -159,11 +158,11 @@ writeLoop:
159
158
loopBracket:
160
159
for ; i < len (pat ); i ++ {
161
160
c = pat [i ]
162
- buf .WriteByte (c )
161
+ sb .WriteByte (c )
163
162
switch c {
164
163
case '\\' :
165
164
if i ++ ; i < len (pat ) {
166
- buf .WriteByte (pat [i ])
165
+ sb .WriteByte (pat [i ])
167
166
}
168
167
continue
169
168
case ']' :
@@ -183,7 +182,7 @@ writeLoop:
183
182
}
184
183
case '{' :
185
184
if mode & Braces == 0 {
186
- buf .WriteString (regexp .QuoteMeta (string (c )))
185
+ sb .WriteString (regexp .QuoteMeta (string (c )))
187
186
break
188
187
}
189
188
innerLevel := 1
@@ -205,7 +204,7 @@ writeLoop:
205
204
break peekBrace
206
205
}
207
206
closingBraces = append (closingBraces , j )
208
- buf .WriteString ("(?:" )
207
+ sb .WriteString ("(?:" )
209
208
continue writeLoop
210
209
}
211
210
}
@@ -216,47 +215,47 @@ writeLoop:
216
215
return "" , & SyntaxError {msg : fmt .Sprintf ("invalid range: %q" , match [0 ])}
217
216
}
218
217
// TODO: can we do better here?
219
- buf .WriteString ("(?:" )
218
+ sb .WriteString ("(?:" )
220
219
for n := start ; n <= end ; n ++ {
221
220
if n > start {
222
- buf .WriteByte ('|' )
221
+ sb .WriteByte ('|' )
223
222
}
224
- fmt .Fprintf (& buf , "%d" , n )
223
+ fmt .Fprintf (& sb , "%d" , n )
225
224
}
226
- buf .WriteByte (')' )
225
+ sb .WriteByte (')' )
227
226
i += len (match [0 ])
228
227
break
229
228
}
230
- buf .WriteString (regexp .QuoteMeta (string (c )))
229
+ sb .WriteString (regexp .QuoteMeta (string (c )))
231
230
case ',' :
232
231
if len (closingBraces ) == 0 {
233
- buf .WriteString (regexp .QuoteMeta (string (c )))
232
+ sb .WriteString (regexp .QuoteMeta (string (c )))
234
233
} else {
235
- buf .WriteByte ('|' )
234
+ sb .WriteByte ('|' )
236
235
}
237
236
case '}' :
238
237
if len (closingBraces ) > 0 && closingBraces [len (closingBraces )- 1 ] == i {
239
- buf .WriteByte (')' )
238
+ sb .WriteByte (')' )
240
239
closingBraces = closingBraces [:len (closingBraces )- 1 ]
241
240
} else {
242
- buf .WriteString (regexp .QuoteMeta (string (c )))
241
+ sb .WriteString (regexp .QuoteMeta (string (c )))
243
242
}
244
243
default :
245
244
if c > 128 {
246
- buf .WriteByte (c )
245
+ sb .WriteByte (c )
247
246
} else {
248
- buf .WriteString (regexp .QuoteMeta (string (c )))
247
+ sb .WriteString (regexp .QuoteMeta (string (c )))
249
248
}
250
249
}
251
250
}
252
251
if mode & EntireString != 0 {
253
- buf .WriteString ("$" )
252
+ sb .WriteString ("$" )
254
253
}
255
254
// No `.` metacharacters were used, so don't return the (?s) flag.
256
255
if ! dotMeta {
257
- return string ( buf . Bytes ()[4 :]) , nil
256
+ return sb . String ()[4 :], nil
258
257
}
259
- return buf .String (), nil
258
+ return sb .String (), nil
260
259
}
261
260
262
261
func charClass (s string ) (string , error ) {
0 commit comments