Skip to content

Commit 0b8bc56

Browse files
authored
Merge pull request #65 from CodaFi/dont-write-filechecks-your-mouth-cant-cash
A Bit More FileCheck Cleanup
2 parents 7dfc371 + 0b47abd commit 0b8bc56

File tree

1 file changed

+51
-56
lines changed

1 file changed

+51
-56
lines changed

Tests/LLVMTests/FileCheck.swift

Lines changed: 51 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -422,10 +422,10 @@ private final class BoxedTable {
422422
}
423423
}
424424

425-
/// Check the input to FileCheck provided in the \p Buffer against the \p
426-
/// CheckStrings read from the check file.
425+
/// Check the input to FileCheck provided in the buffer against the check
426+
/// strings read from the check file.
427427
///
428-
/// Returns false if the input fails to satisfy the checks.
428+
/// Returns `false` if the input fails to satisfy the checks.
429429
private func check(input b : String, against checkStrings : [CheckString]) -> Bool {
430430
var buffer = b
431431
var failedChecks = false
@@ -448,13 +448,14 @@ private func check(input b : String, against checkStrings : [CheckString]) -> Bo
448448
}
449449

450450
// Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
451-
guard let (matchLabelPos, matchLabelLen) = checkStr.check(buffer, true, variableTable) else {
451+
guard let range = checkStr.check(buffer, true, variableTable) else {
452452
// Immediately bail of CHECK-LABEL fails, nothing else we can do.
453453
return false
454454
}
455455

456-
checkRegion = buffer.substring(to: buffer.index(buffer.startIndex, offsetBy: matchLabelPos + matchLabelLen))
457-
buffer = buffer.substring(from: buffer.index(buffer.startIndex, offsetBy: matchLabelPos + matchLabelLen))
456+
457+
checkRegion = buffer.substring(to: buffer.index(buffer.startIndex, offsetBy: NSMaxRange(range)))
458+
buffer = buffer.substring(from: buffer.index(buffer.startIndex, offsetBy: NSMaxRange(range)))
458459
j += 1
459460
}
460461

@@ -463,13 +464,13 @@ private func check(input b : String, against checkStrings : [CheckString]) -> Bo
463464

464465
// Check each string within the scanned region, including a second check
465466
// of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
466-
guard let (matchPos, matchLen) = checkStrings[i].check(checkRegion, false, variableTable) else {
467+
guard let range = checkStrings[i].check(checkRegion, false, variableTable) else {
467468
failedChecks = true
468469
i = j
469470
break
470471
}
471472

472-
checkRegion = checkRegion.substring(from: checkRegion.index(checkRegion.startIndex, offsetBy: matchPos + matchLen))
473+
checkRegion = checkRegion.substring(from: checkRegion.index(checkRegion.startIndex, offsetBy: NSMaxRange(range)))
473474
}
474475

475476
if j == e {
@@ -614,24 +615,23 @@ private class Pattern {
614615
/// Matches the pattern string against the input buffer.
615616
///
616617
/// This returns the position that is matched or npos if there is no match. If
617-
/// there is a match, the size of the matched string is returned in \p
618-
/// MatchLen.
618+
/// there is a match, the range of the match is returned.
619619
///
620-
/// The \p VariableTable StringMap provides the current values of filecheck
621-
/// variables and is updated if this match defines new values.
622-
func match(_ buffer : String, _ variableTable : BoxedTable) -> (Int, Int)? {
620+
/// The variable table provides the current values of filecheck variables and
621+
/// is updated if this match defines new values.
622+
func match(_ buffer : String, _ variableTable : BoxedTable) -> NSRange? {
623623
var matchLen : Int = 0
624624
// If this is the EOF pattern, match it immediately.
625625
if self.type == .EOF {
626626
matchLen = 0
627-
return (buffer.utf8.count, matchLen)
627+
return NSRange(location: buffer.utf8.count, length: matchLen)
628628
}
629629

630630
// If this is a fixed string pattern, just match it now.
631631
if !self.fixedString.isEmpty {
632632
matchLen = self.fixedString.utf8.count
633633
if let b = buffer.range(of: self.fixedString)?.lowerBound {
634-
return (buffer.distance(from: buffer.startIndex, to: b), matchLen)
634+
return NSRange(location: buffer.distance(from: buffer.startIndex, to: b), length: matchLen)
635635
}
636636
return nil
637637
}
@@ -674,7 +674,7 @@ private class Pattern {
674674

675675
// Successful regex match.
676676
guard let fullMatch = matchInfo.first else {
677-
fatalError("Didn't get any matches!")
677+
return nil
678678
}
679679

680680
// If this defines any variables, remember their values.
@@ -696,23 +696,23 @@ private class Pattern {
696696
}
697697

698698
matchLen = fullMatch.range.length
699-
return (fullMatch.range.location, matchLen)
699+
return NSRange(location: fullMatch.range.location, length: matchLen)
700700
}
701701

702702
/// Finds the closing sequence of a regex variable usage or definition.
703703
///
704-
/// \p Str has to point in the beginning of the definition (right after the
705-
/// opening sequence). Returns the offset of the closing sequence within Str,
706-
/// or npos if it was not found.
707-
private func findRegexVarEnd(_ regVar : String) -> String.Index? {
704+
/// The given string has to start in the beginning of the definition
705+
/// (right after the opening sequence). Returns the offset of the closing
706+
/// sequence within the string, or nil if it was not found.
707+
private func findRegexVarEnd(_ regVar : String, brackets: (open: Character, close: Character), terminator: String) -> String.Index? {
708708
var string = regVar
709709
// Offset keeps track of the current offset within the input Str
710710
var offset = regVar.startIndex
711711
// [...] Nesting depth
712712
var bracketDepth = 0
713713

714714
while let firstChar = string.characters.first {
715-
if string.hasPrefix("]]") && bracketDepth == 0 {
715+
if string.hasPrefix(terminator) && bracketDepth == 0 {
716716
return offset
717717
}
718718
if firstChar == "\\" {
@@ -721,11 +721,11 @@ private class Pattern {
721721
offset = regVar.index(offset, offsetBy: 2)
722722
} else {
723723
switch firstChar {
724-
case "[":
724+
case brackets.open:
725725
bracketDepth += 1
726-
case "]":
726+
case brackets.close:
727727
if bracketDepth == 0 {
728-
diagnose(.error, .string(regVar), "missing closing \"]\" for regex variable")
728+
diagnose(.error, .string(regVar), "missing closing \"\(brackets.close)\" for regex variable")
729729
return nil
730730
}
731731
bracketDepth -= 1
@@ -752,11 +752,6 @@ private class Pattern {
752752
}
753753

754754
/// Parses the given string into the Pattern.
755-
///
756-
/// \p Prefix provides which prefix is being matched, \p SM provides the
757-
/// SourceMgr used for error reports, and \p LineNumber is the line number in
758-
/// the input file from which the pattern string was read. Returns true in
759-
/// case of an error, false otherwise.
760755
func parse(in buf : UnsafeBufferPointer<CChar>, pattern : UnsafeBufferPointer<CChar>, withPrefix prefix : String, at lineNumber : Int, options: FileCheckOptions) -> Bool {
761756
func mino(_ l : String.Index?, _ r : String.Index?) -> String.Index? {
762757
if l == nil && r == nil {
@@ -808,7 +803,8 @@ private class Pattern {
808803
// RegEx matches.
809804
if patternStr.range(of: "{{")?.lowerBound == patternStr.startIndex {
810805
// This is the start of a regex match. Scan for the }}.
811-
guard let End = patternStr.range(of: "}}") else {
806+
patternStr = patternStr.substring(from: patternStr.index(patternStr.startIndex, offsetBy: 2))
807+
guard let end = self.findRegexVarEnd(patternStr, brackets: (open: "{", close: "}"), terminator: "}}") else {
812808
let loc = CheckLoc.inBuffer(pattern.baseAddress!, buf)
813809
diagnose(.error, loc, "found start of regex string with no end '}}'")
814810
return true
@@ -821,22 +817,15 @@ private class Pattern {
821817
regExPattern += "("
822818
curParen += 1
823819

824-
let substr = patternStr.substring(
825-
with: Range<String.Index>(
826-
uncheckedBounds: (
827-
patternStr.index(patternStr.startIndex, offsetBy: 2),
828-
End.lowerBound
829-
)
830-
)
831-
)
820+
let substr = patternStr.substring(to: end)
832821
let (res, paren) = self.addRegExToRegEx(substr, curParen)
833822
curParen = paren
834823
if res {
835824
return true
836825
}
837826
regExPattern += ")"
838827

839-
patternStr = patternStr.substring(from: patternStr.index(End.lowerBound, offsetBy: 2))
828+
patternStr = patternStr.substring(from: patternStr.index(end, offsetBy: 2))
840829
continue
841830
}
842831

@@ -849,7 +838,7 @@ private class Pattern {
849838
// Find the closing bracket pair ending the match. End is going to be an
850839
// offset relative to the beginning of the match string.
851840
let regVar = patternStr.substring(from: patternStr.index(patternStr.startIndex, offsetBy: 2))
852-
guard let end = self.findRegexVarEnd(regVar) else {
841+
guard let end = self.findRegexVarEnd(regVar, brackets: (open: "[", close: "]"), terminator: "]]") else {
853842
let loc = CheckLoc.inBuffer(pattern.baseAddress!, buf)
854843
diagnose(.error, loc, "invalid named regex reference, no ]] found")
855844
return true
@@ -981,22 +970,21 @@ func countNumNewlinesBetween(_ r : String) -> (Int, String.Index?) {
981970

982971
/// CheckString - This is a check that we found in the input file.
983972
private struct CheckString {
984-
/// Pat - The pattern to match.
973+
/// The pattern to match.
985974
let pattern : Pattern
986975

987-
/// Prefix - Which prefix name this check matched.
976+
/// Which prefix name this check matched.
988977
let prefix : String
989978

990-
/// Loc - The location in the match file that the check string was specified.
979+
/// The location in the match file that the check string was specified.
991980
let loc : CheckLoc
992981

993-
/// DagNotStrings - These are all of the strings that are disallowed from
994-
/// occurring between this match string and the previous one (or start of
995-
/// file).
982+
/// These are all of the strings that are disallowed from occurring between
983+
/// this match string and the previous one (or start of file).
996984
let dagNotStrings : Array<Pattern> = []
997985

998986
/// Match check string and its "not strings" and/or "dag strings".
999-
func check(_ buffer : String, _ isLabelScanMode : Bool, _ variableTable : BoxedTable) -> (Int, Int)? {
987+
func check(_ buffer : String, _ isLabelScanMode : Bool, _ variableTable : BoxedTable) -> NSRange? {
1000988
var lastPos = 0
1001989

1002990
// IsLabelScanMode is true when we are scanning forward to find CHECK-LABEL
@@ -1013,10 +1001,17 @@ private struct CheckString {
10131001

10141002
// Match itself from the last position after matching CHECK-DAG.
10151003
let matchBuffer = buffer.substring(from: buffer.index(buffer.startIndex, offsetBy: lastPos))
1016-
guard let (matchPos, matchLen) = self.pattern.match(matchBuffer, variableTable) else {
1017-
diagnose(.error, self.loc, self.prefix + ": could not find '\(self.pattern.fixedString)' in input")
1004+
guard let range = self.pattern.match(matchBuffer, variableTable) else {
1005+
if self.pattern.fixedString.isEmpty {
1006+
diagnose(.error, self.loc, self.prefix + ": could not find a match for regex '\(self.pattern.regExPattern)' in input")
1007+
} else if self.pattern.regExPattern.isEmpty {
1008+
diagnose(.error, self.loc, self.prefix + ": could not find '\(self.pattern.fixedString)' in input")
1009+
} else {
1010+
diagnose(.error, self.loc, self.prefix + ": could not find '\(self.pattern.fixedString)' (with regex '\(self.pattern.regExPattern)') in input")
1011+
}
10181012
return nil
10191013
}
1014+
let (matchPos, matchLen) = (range.location, range.length)
10201015

10211016
// Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
10221017
// or CHECK-NOT
@@ -1050,7 +1045,7 @@ private struct CheckString {
10501045
}
10511046
}
10521047

1053-
return (lastPos + matchPos, matchLen)
1048+
return NSRange(location: lastPos + matchPos, length: matchLen)
10541049
}
10551050

10561051
/// Verify there is no newline in the given buffer.
@@ -1134,11 +1129,11 @@ private struct CheckString {
11341129
for pat in notStrings {
11351130
assert(pat.type == .not, "Expect CHECK-NOT!")
11361131

1137-
guard let (Pos, _)/*(Pos, MatchLen)*/ = pat.match(buffer, variableTable) else {
1132+
guard let range = pat.match(buffer, variableTable) else {
11381133
continue
11391134
}
11401135
buffer.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
1141-
let loc = CheckLoc.inBuffer(buf.baseAddress!.advanced(by: Pos), buf)
1136+
let loc = CheckLoc.inBuffer(buf.baseAddress!.advanced(by: range.location), buf)
11421137
diagnose(.error, loc, self.prefix + "-NOT: string occurred!")
11431138
}
11441139
diagnose(.note, pat.patternLoc, self.prefix + "-NOT: pattern specified here")
@@ -1172,12 +1167,12 @@ private struct CheckString {
11721167
let matchBuffer = buffer.substring(from: buffer.index(buffer.startIndex, offsetBy: startPos))
11731168
// With a group of CHECK-DAGs, a single mismatching means the match on
11741169
// that group of CHECK-DAGs fails immediately.
1175-
guard let t = pattern.match(matchBuffer, variableTable) else {
1170+
guard let range = pattern.match(matchBuffer, variableTable) else {
11761171
// PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable)
11771172
return nil
11781173
}
1179-
var matchPos = t.0
1180-
let matchLen = t.1
1174+
var matchPos = range.location
1175+
let matchLen = range.length
11811176

11821177
// Re-calc it as the offset relative to the start of the original string.
11831178
matchPos += startPos

0 commit comments

Comments
 (0)