@@ -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,17 @@ 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+ let r = fullMatch. rangeAt ( index)
684+ variableTable [ v] = buffer. substring (
685+ with: Range < String . Index > (
686+ uncheckedBounds: (
687+ buffer. index ( buffer. startIndex, offsetBy: r. location) ,
688+ buffer. index ( buffer. startIndex, offsetBy: NSMaxRange ( r) )
689+ )
690+ )
691+ )
669692 }
670693
671694 matchLen = fullMatch. range. length
@@ -829,7 +852,7 @@ private class Pattern {
829852 if let end = nameEnd? . lowerBound {
830853 name = matchStr. substring ( to: end)
831854 } else {
832- name = " "
855+ name = matchStr
833856 }
834857
835858 if name. isEmpty {
@@ -868,14 +891,14 @@ private class Pattern {
868891 guard let ne = nameEnd else {
869892 // Handle variables that were defined earlier on the same line by
870893 // emitting a backreference.
871- if let VarParenNum = self . variableDefs [ name] {
872- if VarParenNum < 1 || VarParenNum > 9 {
894+ if let varParenNum = self . variableDefs [ name] {
895+ if varParenNum < 1 || varParenNum > 9 {
873896 diagnose ( . error, diagLoc, " Can't back-reference more than 9 variables " )
874897 return true
875898 }
876- self . addBackrefToRegEx ( VarParenNum )
899+ self . addBackrefToRegEx ( varParenNum )
877900 } else {
878- variableUses. append ( ( name, regExPattern. utf8 . count) )
901+ variableUses. append ( ( name, regExPattern. characters . count) )
879902 }
880903 continue
881904 }
@@ -899,6 +922,9 @@ private class Pattern {
899922 if let fixedMatchEnd = mino ( patternStr. range ( of: " {{ " ) ? . lowerBound, patternStr. range ( of: " [[ " ) ? . lowerBound) {
900923 self . regExPattern += NSRegularExpression . escapedPattern ( for: patternStr. substring ( to: fixedMatchEnd) )
901924 patternStr = patternStr. substring ( from: fixedMatchEnd)
925+ } else {
926+ // No more matches, time to quit.
927+ break
902928 }
903929 }
904930
@@ -958,7 +984,7 @@ private struct CheckString {
958984 let dagNotStrings : Array < Pattern > = [ ]
959985
960986 /// Match check string and its "not strings" and/or "dag strings".
961- func check( _ buffer : String , _ isLabelScanMode : Bool , _ variableTable : [ String : String ] ) -> ( Int , Int ) ? {
987+ func check( _ buffer : String , _ isLabelScanMode : Bool , _ variableTable : BoxedTable ) -> ( Int , Int ) ? {
962988 var lastPos = 0
963989
964990 // IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
@@ -1092,11 +1118,11 @@ private struct CheckString {
10921118 }
10931119
10941120 /// Verify there's no "not strings" in the given buffer.
1095- private func checkNot( _ buffer : String , _ notStrings : [ Pattern ] , _ VariableTable : [ String : String ] ) -> Bool {
1121+ private func checkNot( _ buffer : String , _ notStrings : [ Pattern ] , _ variableTable : BoxedTable ) -> Bool {
10961122 for pat in notStrings {
10971123 assert ( pat. type == . not, " Expect CHECK-NOT! " )
10981124
1099- guard let ( Pos, _) /*(Pos, MatchLen)*/ = pat. match ( buffer, VariableTable ) else {
1125+ guard let ( Pos, _) /*(Pos, MatchLen)*/ = pat. match ( buffer, variableTable ) else {
11001126 continue
11011127 }
11021128 buffer. cString ( using: . utf8) ? . withUnsafeBufferPointer { buf in
@@ -1111,7 +1137,7 @@ private struct CheckString {
11111137 }
11121138
11131139 /// Match "dag strings" and their mixed "not strings".
1114- func checkDAG( _ buffer : String , _ variableTable : [ String : String ] ) -> Int ? {
1140+ func checkDAG( _ buffer : String , _ variableTable : BoxedTable ) -> Int ? {
11151141 var notStrings = [ Pattern] ( )
11161142 if dagNotStrings. isEmpty {
11171143 return 0
0 commit comments