@@ -407,6 +407,21 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
407407 return contents
408408}
409409
410+ private final class BoxedTable {
411+ var table : [ String : String ] = [ : ]
412+
413+ init ( ) { }
414+
415+ subscript( _ i : String ) -> String ? {
416+ set {
417+ self . table [ i] = newValue!
418+ }
419+ get {
420+ return self . table [ i]
421+ }
422+ }
423+ }
424+
410425/// Check the input to FileCheck provided in the \p Buffer against the \p
411426/// CheckStrings read from the check file.
412427///
@@ -416,7 +431,7 @@ private func check(input b : String, against checkStrings : [CheckString]) -> Bo
416431 var failedChecks = false
417432
418433 // This holds all the current filecheck variables.
419- var variableTable = [ String : String ] ( )
434+ var variableTable = BoxedTable ( )
420435
421436 var i = 0
422437 var j = 0
@@ -604,7 +619,7 @@ private class Pattern {
604619 ///
605620 /// The \p VariableTable StringMap provides the current values of filecheck
606621 /// variables and is updated if this match defines new values.
607- func match( _ buffer : String , _ variableTable : [ String : String ] ) -> ( Int , Int ) ? {
622+ func match( _ buffer : String , _ variableTable : BoxedTable ) -> ( Int , Int ) ? {
608623 var matchLen : Int = 0
609624 // If this is the EOF pattern, match it immediately.
610625 if self . type == . EOF {
@@ -626,9 +641,9 @@ private class Pattern {
626641 // If there are variable uses, we need to create a temporary string with the
627642 // actual value.
628643 var regExToMatch = self . regExPattern
629- if !variableUses. isEmpty {
644+ if !self . variableUses. isEmpty {
630645 var insertOffset = 0
631- for (v, offset) in variableUses {
646+ for (v, offset) in self . variableUses {
632647 var value : String = " "
633648
634649 if let c = v. characters. first, c == " @ " {
@@ -663,9 +678,21 @@ private class Pattern {
663678 }
664679
665680 // If this defines any variables, remember their values.
666- for (_, index) in self . variableDefs {
667- assert ( index < matchInfo. count, " Internal paren error " )
668- // VariableTable[VariableDef.0] = MatchInfo[VariableDef.second]
681+ for (v, index) in self . variableDefs {
682+ assert ( index < fullMatch. numberOfRanges, " Internal paren error " )
683+ #if os(macOS)
684+ let r = fullMatch. rangeAt ( index)
685+ #else
686+ let r = fullMatch. range ( at: index)
687+ #endif
688+ variableTable [ v] = buffer. substring (
689+ with: Range < String . Index > (
690+ uncheckedBounds: (
691+ buffer. index ( buffer. startIndex, offsetBy: r. location) ,
692+ buffer. index ( buffer. startIndex, offsetBy: NSMaxRange ( r) )
693+ )
694+ )
695+ )
669696 }
670697
671698 matchLen = fullMatch. range. length
@@ -829,7 +856,7 @@ private class Pattern {
829856 if let end = nameEnd? . lowerBound {
830857 name = matchStr. substring ( to: end)
831858 } else {
832- name = " "
859+ name = matchStr
833860 }
834861
835862 if name. isEmpty {
@@ -868,14 +895,14 @@ private class Pattern {
868895 guard let ne = nameEnd else {
869896 // Handle variables that were defined earlier on the same line by
870897 // emitting a backreference.
871- if let VarParenNum = self . variableDefs [ name] {
872- if VarParenNum < 1 || VarParenNum > 9 {
898+ if let varParenNum = self . variableDefs [ name] {
899+ if varParenNum < 1 || varParenNum > 9 {
873900 diagnose ( . error, diagLoc, " Can't back-reference more than 9 variables " )
874901 return true
875902 }
876- self . addBackrefToRegEx ( VarParenNum )
903+ self . addBackrefToRegEx ( varParenNum )
877904 } else {
878- variableUses. append ( ( name, regExPattern. utf8 . count) )
905+ variableUses. append ( ( name, regExPattern. characters . count) )
879906 }
880907 continue
881908 }
@@ -899,6 +926,9 @@ private class Pattern {
899926 if let fixedMatchEnd = mino ( patternStr. range ( of: " {{ " ) ? . lowerBound, patternStr. range ( of: " [[ " ) ? . lowerBound) {
900927 self . regExPattern += NSRegularExpression . escapedPattern ( for: patternStr. substring ( to: fixedMatchEnd) )
901928 patternStr = patternStr. substring ( from: fixedMatchEnd)
929+ } else {
930+ // No more matches, time to quit.
931+ break
902932 }
903933 }
904934
@@ -958,7 +988,7 @@ private struct CheckString {
958988 let dagNotStrings : Array < Pattern > = [ ]
959989
960990 /// Match check string and its "not strings" and/or "dag strings".
961- func check( _ buffer : String , _ isLabelScanMode : Bool , _ variableTable : [ String : String ] ) -> ( Int , Int ) ? {
991+ func check( _ buffer : String , _ isLabelScanMode : Bool , _ variableTable : BoxedTable ) -> ( Int , Int ) ? {
962992 var lastPos = 0
963993
964994 // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
@@ -1092,11 +1122,11 @@ private struct CheckString {
10921122 }
10931123
10941124 /// Verify there's no "not strings" in the given buffer.
1095- private func checkNot( _ buffer : String , _ notStrings : [ Pattern ] , _ VariableTable : [ String : String ] ) -> Bool {
1125+ private func checkNot( _ buffer : String , _ notStrings : [ Pattern ] , _ variableTable : BoxedTable ) -> Bool {
10961126 for pat in notStrings {
10971127 assert ( pat. type == . not, " Expect CHECK-NOT! " )
10981128
1099- guard let ( Pos, _) /*(Pos, MatchLen)*/ = pat. match ( buffer, VariableTable ) else {
1129+ guard let ( Pos, _) /*(Pos, MatchLen)*/ = pat. match ( buffer, variableTable ) else {
11001130 continue
11011131 }
11021132 buffer. cString ( using: . utf8) ? . withUnsafeBufferPointer { buf in
@@ -1111,7 +1141,7 @@ private struct CheckString {
11111141 }
11121142
11131143 /// Match "dag strings" and their mixed "not strings".
1114- func checkDAG( _ buffer : String , _ variableTable : [ String : String ] ) -> Int ? {
1144+ func checkDAG( _ buffer : String , _ variableTable : BoxedTable ) -> Int ? {
11151145 var notStrings = [ Pattern] ( )
11161146 if dagNotStrings. isEmpty {
11171147 return 0
0 commit comments