@@ -163,25 +163,29 @@ func validateCheckPrefixes(_ prefixes : [String]) -> [String]? {
163163
164164extension CChar {
165165 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
167167 }
168168}
169169
170170extension Character {
171+ var utf8CodePoint : CChar {
172+ return String ( self ) . cString ( using: . utf8) !. first!
173+ }
174+
171175 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 == " _ "
174178 }
175179}
176180
177181private 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]
179183
180184 // Verify that the : is present after the prefix.
181- if nextChar == " : " . utf8 . first! {
185+ if nextChar == ( " : " as Character ) . utf8CodePoint {
182186 return . plain
183187 }
184- if nextChar != " - " . utf8 . first! {
188+ if nextChar != ( " - " as Character ) . utf8CodePoint {
185189 return . none
186190 }
187191
@@ -192,7 +196,7 @@ private func findCheckType(in buf : UnsafeBufferPointer<CChar>, with prefix : St
192196 length: buf. count - ( prefix. utf8. count + 1 ) ,
193197 encoding: . utf8,
194198 freeWhenDone: false
195- ) !
199+ ) !
196200 if rest. hasPrefix ( " NEXT: " ) {
197201 return . next
198202 }
@@ -221,7 +225,7 @@ private func findCheckType(in buf : UnsafeBufferPointer<CChar>, with prefix : St
221225 " NOT-NEXT: " ,
222226 " SAME-NOT: " ,
223227 " NOT-SAME: " ,
224- ]
228+ ]
225229 if badNotPrefixes. reduce ( false , { ( acc, s) in acc || rest. hasPrefix ( s) } ) {
226230 return . badNot
227231 }
@@ -230,8 +234,8 @@ private func findCheckType(in buf : UnsafeBufferPointer<CChar>, with prefix : St
230234}
231235
232236extension 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 )
235239 }
236240
237241 fileprivate func dropFront( _ n : Int ) -> UnsafeBufferPointer < Element > {
@@ -282,12 +286,12 @@ private func findFirstMatch(in inbuffer : UnsafeBufferPointer<CChar>, among pref
282286 // intentional and unintentional uses of this feature.
283287 if skippedPrefix. isEmpty || !skippedPrefix. characters. last!. isPartOfWord {
284288 // Now extract the type.
285- let CheckTy = findCheckType ( in: buffer, with: prefixStr)
289+ let checkTy = findCheckType ( in: buffer, with: prefixStr)
286290
287291
288292 // 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)
291295 }
292296 }
293297 // 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
334338 // Okay, we found the prefix, yay. Remember the rest of the line, but
335339 // ignore leading whitespace.
336340 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 {
338342 return [ ]
339343 }
340344 buffer = buffer. dropFront ( idx)
341345 }
342346
343347 // 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 ) !
345349
346350 // Remember the location of the start of the pattern, for diagnostics.
347351 let patternLoc = CheckLoc . inBuffer ( buffer. baseAddress!, buf)
@@ -471,12 +475,12 @@ private enum CheckLoc {
471475 switch self {
472476 case let . inBuffer( ptr, buf) :
473477 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 {
475479 startPtr = startPtr. predecessor ( )
476480 }
477481
478482 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 {
480484 endPtr = endPtr. successor ( )
481485 }
482486 // One more for good measure.
@@ -576,13 +580,13 @@ private class Pattern {
576580 return nil
577581 }
578582 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 {
580584 return " \( self . lineNumber) "
581585 }
582586
583- if firstC == " + " . utf8 . first! {
587+ if firstC == " + " {
584588 expr = expr. substring ( from: expr. index ( after: expr. startIndex) )
585- } else if firstC != " - " . utf8 . first! {
589+ } else if firstC != " - " {
586590 return nil
587591 }
588592
@@ -627,7 +631,7 @@ private class Pattern {
627631 for (v, offset) in variableUses {
628632 var value : String = " "
629633
630- if v . utf8 . first! == " @ " . utf8 . first! {
634+ if let c = v . characters . first, c == " @ " {
631635 guard let v = self . evaluateExpression ( v) else {
632636 return nil
633637 }
@@ -654,8 +658,9 @@ private class Pattern {
654658 let matchInfo = r. matches ( in: buffer, options: [ ] , range: NSRange ( location: 0 , length: buffer. utf8. count) )
655659
656660 // 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+ }
659664
660665 // If this defines any variables, remember their values.
661666 for (_, index) in self . variableDefs {
@@ -679,16 +684,16 @@ private class Pattern {
679684 // [...] Nesting depth
680685 var bracketDepth = 0
681686
682- while ! string. isEmpty {
687+ while let firstChar = string. characters . first {
683688 if string. hasPrefix ( " ]] " ) && bracketDepth == 0 {
684689 return offset
685690 }
686- if string . utf8 . first! == " \\ " . utf8 . first! {
691+ if firstChar == " \\ " {
687692 // Backslash escapes the next char within regexes, so skip them both.
688693 string = string. substring ( from: string. index ( string. startIndex, offsetBy: 2 ) )
689694 offset = regVar. index ( offset, offsetBy: 2 )
690695 } else {
691- switch string . characters . first! {
696+ switch firstChar {
692697 case " [ " :
693698 bracketDepth += 1
694699 case " ] " :
@@ -838,17 +843,16 @@ private class Pattern {
838843 // is relaxed, more strict check is performed in \c EvaluateExpression.
839844 var isExpression = false
840845 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 == " @ " {
843848 if nameEnd == nil {
844849 diagnose ( . error, diagLoc, " invalid name in named regex definition " )
845850 return true
846851 }
847852 isExpression = true
848853 continue
849854 }
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 != " - " ) ) {
852856 diagnose ( . error, diagLoc, " invalid name in named regex " )
853857 return true
854858 }
0 commit comments