Skip to content

Commit 00945ab

Browse files
committed
Declare a FileCheck Tool
1 parent bd9cb30 commit 00945ab

File tree

4 files changed

+113
-11
lines changed

4 files changed

+113
-11
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ playground.xcworkspace
4040
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
4141
# Packages/
4242
.build/
43+
.swiftpm/
4344

4445
# CocoaPods
4546
#

Package.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,22 @@ import PackageDescription
55
let package = Package(
66
name: "FileCheck",
77
products: [
8+
.executable(name: "filecheck",
9+
targets: ["filecheck-tool"]),
810
.library(
911
name: "FileCheck",
1012
targets: ["FileCheck"]),
1113
],
14+
dependencies: [
15+
.package(url: "https://github.com/apple/swift-package-manager.git", from: "0.1.0"),
16+
.package(url: "https://github.com/onevcat/Rainbow.git", from: "3.0.0"),
17+
],
1218
targets: [
1319
.target(
1420
name: "FileCheck"),
21+
.target(
22+
name: "filecheck-tool",
23+
dependencies: ["FileCheck", "SPMUtility", "Rainbow"]),
1524
.testTarget(
1625
name: "FileCheckTests",
1726
dependencies: ["FileCheck"]),

Sources/FileCheck/CheckString.swift

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -133,12 +133,6 @@ struct CheckString {
133133
}
134134

135135
// Count the number of newlines between the previous match and this one.
136-
// assert(Buffer.data() !=
137-
// SM.getMemoryBuffer(SM.FindBufferContainingLoc(
138-
// SMLoc::getFromPointer(Buffer.data())))
139-
// ->getBufferStart() &&
140-
// "CHECK-SAME can't be the first check in a file")
141-
142136
if countNewlines(in: buffer).count != 0 {
143137
diagnose(.error,
144138
at: self.location,
@@ -166,11 +160,6 @@ struct CheckString {
166160
}
167161

168162
// Count the number of newlines between the previous match and this one.
169-
// assert(Buffer.data() !=
170-
// SM.getMemoryBuffer(SM.FindBufferContainingLoc(
171-
// SMLoc::getFromPointer(Buffer.data())))
172-
// ->getBufferStart(), "CHECK-NEXT can't be the first check in a file")
173-
174163
let (numNewLines, firstNewLine) = countNewlines(in: buffer)
175164
if numNewLines == 0 {
176165
diagnose(.error, at: self.location, with: prefix + "-NEXT: is on the same line as previous match", options: options)

Sources/filecheck-tool/main.swift

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
import Foundation
2+
import Basic
3+
import SPMUtility
4+
import FileCheck
5+
import Rainbow
6+
7+
func run() -> Int {
8+
let cli = ArgumentParser(usage: "FileCheck", overview: "")
9+
let binder = ArgumentBinder<FileCheckOptions>()
10+
//swiftlint:disable statement_position
11+
binder.bind(option:
12+
cli.add(option: "--disable-colors", kind: Bool.self,
13+
usage: "Disable colorized diagnostics"),
14+
to: { if $1 { $0.insert(.disableColors) }
15+
else { $0.remove(.disableColors) } })
16+
binder.bind(option:
17+
cli.add(option: "--use-strict-whitespace",
18+
kind: Bool.self,
19+
usage: "Do not treat all horizontal whitespace as equivalent"),
20+
to: { if $1 { $0.insert(.strictWhitespace) }
21+
else { $0.remove(.strictWhitespace) } })
22+
binder.bind(option:
23+
cli.add(option: "--allow-empty-input", shortName: "-e",
24+
kind: Bool.self,
25+
usage: """
26+
Allow the input file to be empty. This is useful when \
27+
making checks that some error message does not occur, \
28+
for example.
29+
"""),
30+
to: { if $1 { $0.insert(.allowEmptyInput) }
31+
else { $0.remove(.allowEmptyInput) } })
32+
binder.bind(option:
33+
cli.add(option: "--match-full-lines",
34+
kind: Bool.self,
35+
usage: """
36+
Require all positive matches to cover an entire input line. \
37+
Allows leading and trailing whitespace if \
38+
--strict-whitespace is not also used.
39+
"""),
40+
to: { if $1 { $0.insert(.matchFullLines) }
41+
else { $0.remove(.matchFullLines) } })
42+
let prefixes =
43+
cli.add(option: "--prefixes", kind: [String].self,
44+
usage: """
45+
Specifies one or more prefixes to match. By default these \
46+
patterns are prefixed with “CHECK”.
47+
""")
48+
49+
let inputFile =
50+
cli.add(option: "--input-file", shortName: "-i",
51+
kind: String.self,
52+
usage: "The file to use for checked input. Defaults to stdin.")
53+
54+
let file =
55+
cli.add(positional: "", kind: String.self,
56+
usage: "")
57+
58+
let args = Array(CommandLine.arguments.dropFirst())
59+
guard let results = try? cli.parse(args) else {
60+
cli.printUsage(on: stderrStream)
61+
return -1
62+
}
63+
64+
guard let filePath = results.get(file) else {
65+
print("FileCheck error: No input file was provided.")
66+
return -1
67+
}
68+
69+
var options = FileCheckOptions()
70+
do {
71+
try binder.fill(parseResult: results, into: &options)
72+
} catch {
73+
cli.printUsage(on: stderrStream)
74+
return -1
75+
}
76+
Rainbow.enabled = !options.contains(.disableColors)
77+
78+
let fileHandle: FileHandle
79+
if let input = results.get(inputFile) {
80+
guard let handle = FileHandle(forReadingAtPath: input) else {
81+
print("FileCheck error: unable to open check file at path \(inputFile).")
82+
return -1
83+
}
84+
fileHandle = handle
85+
} else {
86+
fileHandle = .standardInput
87+
}
88+
var checkPrefixes = results.get(prefixes) ?? []
89+
checkPrefixes.append("CHECK")
90+
91+
let matchedAll = fileCheckOutput(of: .stdout,
92+
withPrefixes: checkPrefixes,
93+
checkNot: [],
94+
against: .filePath(filePath),
95+
options: options) {
96+
// FIXME: Better way to stream this data?
97+
FileHandle.standardOutput.write(fileHandle.readDataToEndOfFile())
98+
}
99+
100+
return matchedAll ? 0 : -1
101+
}
102+
103+
exit(Int32(run()))

0 commit comments

Comments
 (0)