Skip to content

Commit b5cb540

Browse files
committed
Golf
1 parent 4ff161a commit b5cb540

File tree

4 files changed

+106
-94
lines changed

4 files changed

+106
-94
lines changed

Sources/FileCheck/CheckString.swift

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,10 @@ enum CheckType {
1212

1313
/// MatchEOF - When set, this pattern only matches the end of file. This is
1414
/// used for trailing CHECK-NOTs.
15-
case EOF
15+
case endOfFile
1616

17-
// Get the size of the prefix extension.
18-
var size : Int {
17+
// Get the count of utf8 bytes of the prefix extension.
18+
var prefixSize : Int {
1919
switch (self) {
2020
case .none:
2121
return 0
@@ -33,8 +33,8 @@ enum CheckType {
3333
return "-DAG:".utf8.count
3434
case .label:
3535
return "-LABEL:".utf8.count
36-
case .EOF:
37-
fatalError("Should not be using EOF size")
36+
case .endOfFile:
37+
fatalError("Should not be using endOfFile prefix size")
3838
}
3939
}
4040
}
@@ -48,14 +48,14 @@ struct CheckString {
4848
let prefix : String
4949

5050
/// The location in the match file that the check string was specified.
51-
let loc : CheckLoc
51+
let location : CheckLocation
5252

5353
/// These are all of the strings that are disallowed from occurring between
5454
/// this match string and the previous one (or start of file).
55-
var dagNotStrings : Array<Pattern>
55+
let dagNotStrings : Array<Pattern>
5656

5757
/// Match check string and its "not strings" and/or "dag strings".
58-
func check(_ buffer : String, _ isLabelScanMode : Bool, _ variableTable : [String:String], _ options: FileCheckOptions) -> (NSRange, [String:String])? {
58+
func check(_ buffer : String, _ isLabelScanMode : Bool, _ variableTable : [String:String], _ options : FileCheckOptions) -> (NSRange, [String:String])? {
5959
// This condition is true when we are scanning forward to find CHECK-LABEL
6060
// bounds we have not processed variable definitions within the bounded block
6161
// yet so cannot handle any final CHECK-DAG yet this is handled when going
@@ -80,7 +80,7 @@ struct CheckString {
8080
// Match itself from the last position after matching CHECK-DAG.
8181
let matchBuffer = String(buffer[buffer.index(buffer.startIndex, offsetBy: lastPos)...])
8282
guard let (range, mutVariableTable) = self.pattern.match(matchBuffer, initialTable) else {
83-
diagnoseFailedCheck(self.pattern, self.loc, self.prefix, variableTable, options, buffer)
83+
diagnoseFailedCheck(self.pattern, self.location, self.prefix, variableTable, options, buffer)
8484
return nil
8585
}
8686
let (matchPos, matchLen) = (range.location, range.length)
@@ -139,19 +139,18 @@ struct CheckString {
139139
// ->getBufferStart() &&
140140
// "CHECK-SAME can't be the first check in a file")
141141

142-
let (numNewLines, _ /*firstNewLine*/) = countNumNewlinesBetween(buffer)
143-
if numNewLines != 0 {
142+
if countNewlines(in: buffer).count != 0 {
144143
diagnose(.error,
145-
at: self.loc,
144+
at: self.location,
146145
with: self.prefix + "-SAME: is not on the same line as the previous match",
147146
options: options
148147
)
149148
rest.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
150-
let loc = CheckLoc.inBuffer(buf.baseAddress!, buf)
149+
let loc = CheckLocation.inBuffer(buf.baseAddress!, buf)
151150
diagnose(.note, at: loc, with: "'next' match was here", options: options)
152151
}
153152
buffer.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
154-
let loc = CheckLoc.inBuffer(buf.baseAddress!, buf)
153+
let loc = CheckLocation.inBuffer(buf.baseAddress!, buf)
155154
diagnose(.note, at: loc, with: "previous match ended here", options: options)
156155
}
157156
return true
@@ -172,31 +171,31 @@ struct CheckString {
172171
// SMLoc::getFromPointer(Buffer.data())))
173172
// ->getBufferStart(), "CHECK-NEXT can't be the first check in a file")
174173

175-
let (numNewLines, firstNewLine) = countNumNewlinesBetween(buffer)
174+
let (numNewLines, firstNewLine) = countNewlines(in: buffer)
176175
if numNewLines == 0 {
177-
diagnose(.error, at: self.loc, with: prefix + "-NEXT: is on the same line as previous match", options: options)
176+
diagnose(.error, at: self.location, with: prefix + "-NEXT: is on the same line as previous match", options: options)
178177
rest.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
179-
let loc = CheckLoc.inBuffer(buf.baseAddress!, buf)
178+
let loc = CheckLocation.inBuffer(buf.baseAddress!, buf)
180179
diagnose(.note, at: loc, with: "'next' match was here", options: options)
181180
}
182181
buffer.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
183-
let loc = CheckLoc.inBuffer(buf.baseAddress!, buf)
182+
let loc = CheckLocation.inBuffer(buf.baseAddress!, buf)
184183
diagnose(.note, at: loc, with: "previous match ended here", options: options)
185184
}
186185
return true
187186
}
188187

189188
if numNewLines != 1 {
190-
diagnose(.error, at: self.loc, with: prefix + "-NEXT: is not on the line after the previous match", options: options)
189+
diagnose(.error, at: self.location, with: prefix + "-NEXT: is not on the line after the previous match", options: options)
191190
rest.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
192-
let loc = CheckLoc.inBuffer(buf.baseAddress!, buf)
191+
let loc = CheckLocation.inBuffer(buf.baseAddress!, buf)
193192
diagnose(.note, at: loc, with: "'next' match was here", options: options)
194193
}
195194
buffer.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
196-
let loc = CheckLoc.inBuffer(buf.baseAddress!, buf)
195+
let loc = CheckLocation.inBuffer(buf.baseAddress!, buf)
197196
diagnose(.note, at: loc, with: "previous match ended here", options: options)
198197
if let fnl = firstNewLine {
199-
let noteLoc = CheckLoc.inBuffer(buf.baseAddress!.advanced(by: buffer.distance(from: buffer.startIndex, to: fnl)), buf)
198+
let noteLoc = CheckLocation.inBuffer(buf.baseAddress!.advanced(by: buffer.distance(from: buffer.startIndex, to: fnl)), buf)
200199
diagnose(.note, at: noteLoc, with: "non-matching line after previous match is here", options: options)
201200
}
202201
}
@@ -215,7 +214,7 @@ struct CheckString {
215214
continue
216215
}
217216
buffer.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
218-
let loc = CheckLoc.inBuffer(buf.baseAddress!.advanced(by: range.location), buf)
217+
let loc = CheckLocation.inBuffer(buf.baseAddress!.advanced(by: range.location), buf)
219218
diagnose(.error, at: loc, with: self.prefix + "-NOT: string occurred!", options: options)
220219
}
221220
diagnose(.note, at: pat.patternLoc, with: self.prefix + "-NOT: pattern specified here", options: options)
@@ -226,7 +225,7 @@ struct CheckString {
226225
}
227226

228227
/// Match "dag strings" and their mixed "not strings".
229-
func checkDAG(_ buffer : String, _ variableTable : [String:String], _ options: FileCheckOptions) -> (Int, [Pattern], [String:String])? {
228+
private func checkDAG(_ buffer : String, _ variableTable : [String:String], _ options: FileCheckOptions) -> (Int, [Pattern], [String:String])? {
230229
var notStrings = [Pattern]()
231230
if self.dagNotStrings.isEmpty {
232231
return (0, notStrings, variableTable)
@@ -262,9 +261,9 @@ struct CheckString {
262261
if matchPos < lastPos {
263262
// Reordered?
264263
buffer.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
265-
let loc1 = CheckLoc.inBuffer(buf.baseAddress!.advanced(by: matchPos), buf)
264+
let loc1 = CheckLocation.inBuffer(buf.baseAddress!.advanced(by: matchPos), buf)
266265
diagnose(.error, at: loc1, with: prefix + "-DAG: found a match of CHECK-DAG reordering across a CHECK-NOT", options: options)
267-
let loc2 = CheckLoc.inBuffer(buf.baseAddress!.advanced(by: lastPos), buf)
266+
let loc2 = CheckLocation.inBuffer(buf.baseAddress!.advanced(by: lastPos), buf)
268267
diagnose(.note, at: loc2, with: prefix + "-DAG: the farthest match of CHECK-DAG is found here", options: options)
269268
}
270269
diagnose(.note, at: notStrings[0].patternLoc, with: prefix + "-NOT: the crossed pattern specified here", options: options)
@@ -303,7 +302,7 @@ struct CheckString {
303302
}
304303

305304
private func diagnoseFailedCheck(
306-
_ pattern: Pattern, _ loc: CheckLoc, _ prefix: String,
305+
_ pattern: Pattern, _ loc: CheckLocation, _ prefix: String,
307306
_ variableTable: [String : String], _ options: FileCheckOptions,
308307
_ buffer: String
309308
) {
@@ -405,7 +404,7 @@ private func diagnoseFailedCheck(
405404

406405
if let Best = BestLine, BestQuality < 50 {
407406
buffer.utf8CString.withUnsafeBufferPointer { buf in
408-
let otherPatternLoc = CheckLoc.inBuffer(
407+
let otherPatternLoc = CheckLocation.inBuffer(
409408
buf.baseAddress!.advanced(by: Best),
410409
UnsafeBufferPointer(start: buf.baseAddress?.advanced(by: Best), count: buf.count - Best)
411410
)

Sources/FileCheck/Diagnostics.swift

Lines changed: 2 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import Foundation
22

3-
func diagnose(_ kind : DiagnosticKind, at loc : CheckLoc, with message : String, options: FileCheckOptions) {
3+
func diagnose(_ kind : DiagnosticKind, at loc : CheckLocation, with message : String, options: FileCheckOptions) {
44
let disableColors = options.contains(.disableColors)
55
if disableColors {
66
print("\(kind): \(message)")
@@ -42,29 +42,7 @@ struct StdOutStream: TextOutputStream {
4242
var stdoutStream = StdOutStream()
4343
var diagnosticStream = ColoredANSIStream(&stdoutStream)
4444

45-
enum CheckLoc {
45+
enum CheckLocation {
4646
case inBuffer(UnsafePointer<CChar>, UnsafeBufferPointer<CChar>)
4747
case string(String)
48-
49-
var message : String {
50-
switch self {
51-
case let .inBuffer(ptr, buf):
52-
var startPtr = ptr
53-
while startPtr != buf.baseAddress! && startPtr.predecessor().pointee != ("\n" as Character).utf8CodePoint {
54-
startPtr = startPtr.predecessor()
55-
}
56-
57-
var endPtr = ptr
58-
while endPtr != buf.baseAddress!.advanced(by: buf.endIndex) && endPtr.successor().pointee != ("\n" as Character).utf8CodePoint {
59-
endPtr = endPtr.successor()
60-
}
61-
// One more for good measure.
62-
if endPtr != buf.baseAddress!.advanced(by: buf.endIndex) {
63-
endPtr = endPtr.successor()
64-
}
65-
return substring(in: buf, with: NSMakeRange(buf.baseAddress!.distance(to: startPtr), startPtr.distance(to: endPtr)))
66-
case let .string(s):
67-
return s
68-
}
69-
}
7048
}

Sources/FileCheck/FileCheck.swift

Lines changed: 46 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import Foundation
66
import Darwin
77
#endif
88

9+
/// `FileCheckOptions` enumerates supported FileCheck options that can be used
10+
/// to modify the behavior of the checking routine.
911
public struct FileCheckOptions: OptionSet {
1012
public let rawValue: UInt64
1113

@@ -97,7 +99,7 @@ public func fileCheckOutput(of FD : FileCheckFD = .stdout, withPrefixes prefixes
9799
"hyphens and underscores")
98100
return false
99101
}
100-
guard let prefixRE = try? NSRegularExpression(pattern: validPrefixes.sorted(by: >).joined(separator: "|"), options: []) else {
102+
guard let prefixRE = try? NSRegularExpression(pattern: validPrefixes.sorted(by: >).joined(separator: "|")) else {
101103
print("Unable to combine check-prefix strings into a prefix regular ",
102104
"expression! This is likely a bug in FileCheck's verification of ",
103105
"the check-prefix strings. Regular expression parsing failed.")
@@ -162,7 +164,7 @@ private func overrideFDAndCollectOutput(file : FileCheckFD, of block : () -> ())
162164
}
163165

164166
private func validateCheckPrefixes(_ prefixes : [String]) -> [String]? {
165-
let validator = try! NSRegularExpression(pattern: "^[a-zA-Z0-9_-]*$", options: [])
167+
let validator = try! NSRegularExpression(pattern: "^[a-zA-Z0-9_-]*$")
166168

167169
for prefix in prefixes {
168170
// Reject empty prefixes.
@@ -174,7 +176,7 @@ private func validateCheckPrefixes(_ prefixes : [String]) -> [String]? {
174176
location: 0,
175177
length: prefix.distance(from: prefix.startIndex, to: prefix.endIndex)
176178
)
177-
if validator.matches(in: prefix, options: [], range: range).isEmpty {
179+
if validator.matches(in: prefix, range: range).isEmpty {
178180
return nil
179181
}
180182
}
@@ -266,7 +268,31 @@ extension UnsafeBufferPointer {
266268
}
267269
}
268270

269-
func substring(in buffer : UnsafeBufferPointer<CChar>, with range : NSRange) -> String {
271+
extension CheckLocation {
272+
var message : String {
273+
switch self {
274+
case let .inBuffer(ptr, buf):
275+
var startPtr = ptr
276+
while startPtr != buf.baseAddress! && startPtr.predecessor().pointee != ("\n" as Character).utf8CodePoint {
277+
startPtr = startPtr.predecessor()
278+
}
279+
280+
var endPtr = ptr
281+
while endPtr != buf.baseAddress!.advanced(by: buf.endIndex) && endPtr.successor().pointee != ("\n" as Character).utf8CodePoint {
282+
endPtr = endPtr.successor()
283+
}
284+
// One more for good measure.
285+
if endPtr != buf.baseAddress!.advanced(by: buf.endIndex) {
286+
endPtr = endPtr.successor()
287+
}
288+
return substring(in: buf, with: NSMakeRange(buf.baseAddress!.distance(to: startPtr), startPtr.distance(to: endPtr)))
289+
case let .string(s):
290+
return s
291+
}
292+
}
293+
}
294+
295+
private func substring(in buffer : UnsafeBufferPointer<CChar>, with range : NSRange) -> String {
270296
precondition(range.location + range.length <= buffer.count)
271297
let ptr = buffer.substr(range.location, range.length)
272298
return String(bytesNoCopy: UnsafeMutableRawPointer(mutating: ptr.baseAddress!), length: range.length, encoding: .utf8, freeWhenDone: false) ?? ""
@@ -278,7 +304,7 @@ private func findFirstMatch(in inbuffer : UnsafeBufferPointer<CChar>, among pref
278304

279305
while !buffer.isEmpty {
280306
let str = String(bytesNoCopy: UnsafeMutableRawPointer(mutating: buffer.baseAddress!), length: buffer.count, encoding: .utf8, freeWhenDone: false)!
281-
let match = RE.firstMatch(in: str, options: [], range: NSRange(location: 0, length: str.distance(from: str.startIndex, to: str.endIndex)))
307+
let match = RE.firstMatch(in: str, range: NSRange(location: 0, length: str.distance(from: str.startIndex, to: str.endIndex)))
282308
guard let prefix = match else {
283309
return ("", .none, lineNumber, buffer)
284310
}
@@ -343,7 +369,7 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
343369
let patBuf = UnsafeBufferPointer<CChar>(start: buf.baseAddress, count: buf.count - 1)
344370
let pat = Pattern(checking: .not, in: buf, pattern: patBuf, withPrefix: "IMPLICIT-CHECK", at: 0, options: options)!
345371
// Compute the message from this buffer now for diagnostics later.
346-
let msg = CheckLoc.inBuffer(buf.baseAddress!, buf).message
372+
let msg = CheckLocation.inBuffer(buf.baseAddress!, buf).message
347373
implicitNegativeChecks.append(Pattern(copying: pat, at: .string("IMPLICIT-CHECK-NOT: " + msg)))
348374
}
349375
}
@@ -360,11 +386,11 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
360386
lineNumber = ln
361387

362388
// Skip the buffer to the end.
363-
buffer = newBuffer.dropFront(usedPrefix.utf8.count + checkTy.size)
389+
buffer = newBuffer.dropFront(usedPrefix.utf8.count + checkTy.prefixSize)
364390

365391
// Complain about useful-looking but unsupported suffixes.
366392
if checkTy == .badNot {
367-
let loc = CheckLoc.inBuffer(buffer.baseAddress!, buf)
393+
let loc = CheckLocation.inBuffer(buffer.baseAddress!, buf)
368394
diagnose(.error, at: loc, with: "unsupported -NOT combo on prefix '\(usedPrefix)'", options: options)
369395
return []
370396
}
@@ -382,7 +408,7 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
382408
let EOL : Int = buffer.index(of: ("\n" as Character).utf8CodePoint) ?? buffer.index(of: ("\r" as Character).utf8CodePoint)!
383409

384410
// Remember the location of the start of the pattern, for diagnostics.
385-
let patternLoc = CheckLoc.inBuffer(buffer.baseAddress!, buf)
411+
let patternLoc = CheckLocation.inBuffer(buffer.baseAddress!, buf)
386412

387413
// Parse the pattern.
388414
let subBuffer = UnsafeBufferPointer<CChar>(start: buffer.baseAddress, count: EOL)
@@ -399,7 +425,7 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
399425
// Verify that CHECK-NEXT lines have at least one CHECK line before them.
400426
if (checkTy == .next || checkTy == .same) && contents.isEmpty {
401427
let type = (checkTy == .next) ? "NEXT" : "SAME"
402-
let loc = CheckLoc.inBuffer(buffer.baseAddress!, buf)
428+
let loc = CheckLocation.inBuffer(buffer.baseAddress!, buf)
403429
diagnose(.error, at: loc, with: "found '\(usedPrefix)-\(type)' without previous '\(usedPrefix): line", options: options)
404430
return []
405431
}
@@ -419,7 +445,7 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
419445
let cs = CheckString(
420446
pattern: pat,
421447
prefix: usedPrefix,
422-
loc: .string(patternLoc.message),
448+
location: .string(patternLoc.message),
423449
dagNotStrings: dagNotMatches
424450
)
425451
contents.append(cs)
@@ -430,9 +456,9 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
430456
// prefix as a filler for the error message.
431457
if !dagNotMatches.isEmpty {
432458
let cs = CheckString(
433-
pattern: Pattern(withType: .EOF),
459+
pattern: Pattern(withType: .endOfFile),
434460
prefix: prefixes.first!,
435-
loc: dagNotMatches.last!.patternLoc,
461+
location: dagNotMatches.last!.patternLoc,
436462
dagNotStrings: dagNotMatches
437463
)
438464
contents.append(cs)
@@ -454,7 +480,7 @@ private func readCheckStrings(in buf : UnsafeBufferPointer<CChar>, withPrefixes
454480
///
455481
/// Returns `false` if the input fails to satisfy the checks.
456482
private func check(input b : String, against checkStrings : [CheckString], options: FileCheckOptions) -> Bool {
457-
var buffer = b
483+
var buffer = Substring(b)
458484
var failedChecks = false
459485

460486
// This holds all the current filecheck variables.
@@ -463,7 +489,7 @@ private func check(input b : String, against checkStrings : [CheckString], optio
463489
var i = 0
464490
var j = 0
465491
while true {
466-
var checkRegion : String
492+
var checkRegion : Substring
467493
if j == checkStrings.count {
468494
checkRegion = buffer
469495
} else {
@@ -474,14 +500,14 @@ private func check(input b : String, against checkStrings : [CheckString], optio
474500
}
475501

476502
// Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
477-
guard let (range, mutVariableTable) = checkStr.check(buffer, true, variableTable, options) else {
503+
guard let (range, mutVariableTable) = checkStr.check(String(buffer), true, variableTable, options) else {
478504
// Immediately bail if CHECK-LABEL fails, nothing else we can do.
479505
return false
480506
}
481507

482508
variableTable = mutVariableTable
483-
checkRegion = String(buffer[..<buffer.index(buffer.startIndex, offsetBy: NSMaxRange(range))])
484-
buffer = String(buffer[buffer.index(buffer.startIndex, offsetBy: NSMaxRange(range))...])
509+
checkRegion = buffer[..<buffer.index(buffer.startIndex, offsetBy: NSMaxRange(range))]
510+
buffer = buffer[buffer.index(buffer.startIndex, offsetBy: NSMaxRange(range))...]
485511
j += 1
486512
}
487513

@@ -490,13 +516,13 @@ private func check(input b : String, against checkStrings : [CheckString], optio
490516

491517
// Check each string within the scanned region, including a second check
492518
// of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
493-
guard let (range, mutVarTable) = checkStrings[i].check(checkRegion, false, variableTable, options) else {
519+
guard let (range, mutVarTable) = checkStrings[i].check(String(checkRegion), false, variableTable, options) else {
494520
failedChecks = true
495521
i = j-1
496522
break
497523
}
498524
variableTable = mutVarTable
499-
checkRegion = String(checkRegion[checkRegion.index(checkRegion.startIndex, offsetBy: NSMaxRange(range))...])
525+
checkRegion = checkRegion[checkRegion.index(checkRegion.startIndex, offsetBy: NSMaxRange(range))...]
500526
}
501527

502528
if j == checkStrings.count {

0 commit comments

Comments
 (0)