@@ -163,25 +163,29 @@ func validateCheckPrefixes(_ prefixes : [String]) -> [String]? {
163
163
164
164
extension CChar {
165
165
fileprivate var isPartOfWord : Bool {
166
- return isalnum ( Int32 ( self ) ) != 0 || UInt8 ( self ) == " - " . utf8 . first! || UInt8 ( self ) == " _ " . utf8 . first!
166
+ return isalnum ( Int32 ( self ) ) != 0 || self == ( " - " as Character ) . utf8CodePoint || self == ( " _ " as Character ) . utf8CodePoint
167
167
}
168
168
}
169
169
170
170
extension Character {
171
+ var utf8CodePoint : CChar {
172
+ return String ( self ) . cString ( using: . utf8) !. first!
173
+ }
174
+
171
175
fileprivate var isPartOfWord : Bool {
172
- let utf8Value = String ( self ) . utf8 . first!
173
- return isalnum ( Int32 ( utf8Value) ) != 0 || utf8Value == " - " . utf8 . first! || utf8Value == " _ " . utf8 . first!
176
+ let utf8Value = self . utf8CodePoint
177
+ return isalnum ( Int32 ( utf8Value) ) != 0 || self == " - " || self == " _ "
174
178
}
175
179
}
176
180
177
181
private func findCheckType( in buf : UnsafeBufferPointer < CChar > , with prefix : String ) -> CheckType {
178
- let nextChar = UInt8 ( buf [ prefix. utf8. count] )
182
+ let nextChar = buf [ prefix. utf8. count]
179
183
180
184
// Verify that the : is present after the prefix.
181
- if nextChar == " : " . utf8 . first! {
185
+ if nextChar == ( " : " as Character ) . utf8CodePoint {
182
186
return . plain
183
187
}
184
- if nextChar != " - " . utf8 . first! {
188
+ if nextChar != ( " - " as Character ) . utf8CodePoint {
185
189
return . none
186
190
}
187
191
@@ -192,7 +196,7 @@ private func findCheckType(in buf : UnsafeBufferPointer<CChar>, with prefix : St
192
196
length: buf. count - ( prefix. utf8. count + 1 ) ,
193
197
encoding: . utf8,
194
198
freeWhenDone: false
195
- ) !
199
+ ) !
196
200
if rest. hasPrefix ( " NEXT: " ) {
197
201
return . next
198
202
}
@@ -221,7 +225,7 @@ private func findCheckType(in buf : UnsafeBufferPointer<CChar>, with prefix : St
221
225
" NOT-NEXT: " ,
222
226
" SAME-NOT: " ,
223
227
" NOT-SAME: " ,
224
- ]
228
+ ]
225
229
if badNotPrefixes. reduce ( false , { ( acc, s) in acc || rest. hasPrefix ( s) } ) {
226
230
return . badNot
227
231
}
@@ -230,8 +234,8 @@ private func findCheckType(in buf : UnsafeBufferPointer<CChar>, with prefix : St
230
234
}
231
235
232
236
extension UnsafeBufferPointer {
233
- fileprivate func substr( _ Start : Int , _ Size : Int ) -> UnsafeBufferPointer < Element > {
234
- return UnsafeBufferPointer < Element > ( start: self . baseAddress!. advanced ( by: Start ) , count: Size )
237
+ fileprivate func substr( _ start : Int , _ size : Int ) -> UnsafeBufferPointer < Element > {
238
+ return UnsafeBufferPointer < Element > ( start: self . baseAddress!. advanced ( by: start ) , count: size )
235
239
}
236
240
237
241
fileprivate func dropFront( _ n : Int ) -> UnsafeBufferPointer < Element > {
@@ -282,12 +286,12 @@ private func findFirstMatch(in inbuffer : UnsafeBufferPointer<CChar>, among pref
282
286
// intentional and unintentional uses of this feature.
283
287
if skippedPrefix. isEmpty || !skippedPrefix. characters. last!. isPartOfWord {
284
288
// Now extract the type.
285
- let CheckTy = findCheckType ( in: buffer, with: prefixStr)
289
+ let checkTy = findCheckType ( in: buffer, with: prefixStr)
286
290
287
291
288
292
// If we've found a valid check type for this prefix, we're done.
289
- if CheckTy != . none {
290
- return ( prefixStr, CheckTy , lineNumber, buffer)
293
+ if checkTy != . none {
294
+ return ( prefixStr, checkTy , lineNumber, buffer)
291
295
}
292
296
}
293
297
// If we didn't successfully find a prefix, we need to skip this invalid
@@ -334,14 +338,14 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
334
338
// Okay, we found the prefix, yay. Remember the rest of the line, but
335
339
// ignore leading whitespace.
336
340
if !options. contains ( . strictWhitespace) || !options. contains ( . matchFullLines) {
337
- guard let idx = buffer. index ( where: { c in UInt8 ( c ) != " " . utf8 . first! && UInt8 ( c ) != " \t " . utf8 . first! } ) else {
341
+ guard let idx = buffer. index ( where: { c in c != ( " " as Character ) . utf8CodePoint && c != ( " \t " as Character ) . utf8CodePoint } ) else {
338
342
return [ ]
339
343
}
340
344
buffer = buffer. dropFront ( idx)
341
345
}
342
346
343
347
// Scan ahead to the end of line.
344
- let EOL : Int = buffer. index ( of: CChar ( " \n " . utf8 . first! ) ) ?? buffer. index ( of: CChar ( " \r " . utf8 . first! ) ) !
348
+ let EOL : Int = buffer. index ( of: ( " \n " as Character ) . utf8CodePoint ) ?? buffer. index ( of: ( " \r " as Character ) . utf8CodePoint ) !
345
349
346
350
// Remember the location of the start of the pattern, for diagnostics.
347
351
let patternLoc = CheckLoc . inBuffer ( buffer. baseAddress!, buf)
@@ -471,12 +475,12 @@ private enum CheckLoc {
471
475
switch self {
472
476
case let . inBuffer( ptr, buf) :
473
477
var startPtr = ptr
474
- while startPtr != buf. baseAddress! && startPtr. predecessor ( ) . pointee != CChar ( " \n " . utf8 . first! ) {
478
+ while startPtr != buf. baseAddress! && startPtr. predecessor ( ) . pointee != ( " \n " as Character ) . utf8CodePoint {
475
479
startPtr = startPtr. predecessor ( )
476
480
}
477
481
478
482
var endPtr = ptr
479
- while endPtr != buf. baseAddress!. advanced ( by: buf. endIndex) && endPtr. successor ( ) . pointee != CChar ( " \n " . utf8 . first! ) {
483
+ while endPtr != buf. baseAddress!. advanced ( by: buf. endIndex) && endPtr. successor ( ) . pointee != ( " \n " as Character ) . utf8CodePoint {
480
484
endPtr = endPtr. successor ( )
481
485
}
482
486
// One more for good measure.
@@ -576,13 +580,13 @@ private class Pattern {
576
580
return nil
577
581
}
578
582
expr = expr. substring ( from: expr. index ( expr. startIndex, offsetBy: " @LINE " . utf8. count) )
579
- guard let firstC = expr. utf8 . first else {
583
+ guard let firstC = expr. characters . first else {
580
584
return " \( self . lineNumber) "
581
585
}
582
586
583
- if firstC == " + " . utf8 . first! {
587
+ if firstC == " + " {
584
588
expr = expr. substring ( from: expr. index ( after: expr. startIndex) )
585
- } else if firstC != " - " . utf8 . first! {
589
+ } else if firstC != " - " {
586
590
return nil
587
591
}
588
592
@@ -627,7 +631,7 @@ private class Pattern {
627
631
for (v, offset) in variableUses {
628
632
var value : String = " "
629
633
630
- if v . utf8 . first! == " @ " . utf8 . first! {
634
+ if let c = v . characters . first, c == " @ " {
631
635
guard let v = self . evaluateExpression ( v) else {
632
636
return nil
633
637
}
@@ -654,8 +658,9 @@ private class Pattern {
654
658
let matchInfo = r. matches ( in: buffer, options: [ ] , range: NSRange ( location: 0 , length: buffer. utf8. count) )
655
659
656
660
// Successful regex match.
657
- assert ( !matchInfo. isEmpty, " Didn't get any match " )
658
- let fullMatch = matchInfo. first!
661
+ guard let fullMatch = matchInfo. first else {
662
+ fatalError ( " Didn't get any matches! " )
663
+ }
659
664
660
665
// If this defines any variables, remember their values.
661
666
for (_, index) in self . variableDefs {
@@ -679,16 +684,16 @@ private class Pattern {
679
684
// [...] Nesting depth
680
685
var bracketDepth = 0
681
686
682
- while ! string. isEmpty {
687
+ while let firstChar = string. characters . first {
683
688
if string. hasPrefix ( " ]] " ) && bracketDepth == 0 {
684
689
return offset
685
690
}
686
- if string . utf8 . first! == " \\ " . utf8 . first! {
691
+ if firstChar == " \\ " {
687
692
// Backslash escapes the next char within regexes, so skip them both.
688
693
string = string. substring ( from: string. index ( string. startIndex, offsetBy: 2 ) )
689
694
offset = regVar. index ( offset, offsetBy: 2 )
690
695
} else {
691
- switch string . characters . first! {
696
+ switch firstChar {
692
697
case " [ " :
693
698
bracketDepth += 1
694
699
case " ] " :
@@ -838,17 +843,16 @@ private class Pattern {
838
843
// is relaxed, more strict check is performed in \c EvaluateExpression.
839
844
var isExpression = false
840
845
let diagLoc = CheckLoc . inBuffer ( pattern. baseAddress!, buf)
841
- for (i, c) in name. utf8 . enumerated ( ) {
842
- if i == 0 && c == " @ " . utf8 . first! {
846
+ for (i, c) in name. characters . enumerated ( ) {
847
+ if i == 0 && c == " @ " {
843
848
if nameEnd == nil {
844
849
diagnose ( . error, diagLoc, " invalid name in named regex definition " )
845
850
return true
846
851
}
847
852
isExpression = true
848
853
continue
849
854
}
850
- if ( c != " _ " . utf8. first! && isalnum ( Int32 ( c) ) == 0 &&
851
- ( !isExpression || ( c != " + " . utf8. first! && c != " - " . utf8. first!) ) ) {
855
+ if c != " _ " && isalnum ( Int32 ( c. utf8CodePoint) ) == 0 && ( !isExpression || ( c != " + " && c != " - " ) ) {
852
856
diagnose ( . error, diagLoc, " invalid name in named regex " )
853
857
return true
854
858
}
0 commit comments