Skip to content

Commit cb5ac26

Browse files
committed
Remove the boxed table abstraction
1 parent 8534fe6 commit cb5ac26

File tree

4 files changed

+43
-49
lines changed

4 files changed

+43
-49
lines changed

Sources/FileCheck/BoxedTable.swift

Lines changed: 0 additions & 22 deletions
This file was deleted.

Sources/FileCheck/CheckString.swift

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -63,28 +63,31 @@ struct CheckString {
6363
var dagNotStrings : Array<Pattern>
6464

6565
/// Match check string and its "not strings" and/or "dag strings".
66-
func check(_ buffer : String, _ isLabelScanMode : Bool, _ variableTable : BoxedTable, _ options: FileCheckOptions) -> NSRange? {
66+
func check(_ buffer : String, _ isLabelScanMode : Bool, _ variableTable : [String:String], _ options: FileCheckOptions) -> (NSRange, [String:String])? {
6767
// This condition is true when we are scanning forward to find CHECK-LABEL
6868
// bounds we have not processed variable definitions within the bounded block
6969
// yet so cannot handle any final CHECK-DAG yet this is handled when going
7070
// over the block again (including the last CHECK-LABEL) in normal mode.
7171
let lastPos : Int
7272
let notStrings : [Pattern]
73+
let initialTable : [String:String]
7374
if !isLabelScanMode {
7475
// Match "dag strings" (with mixed "not strings" if any).
75-
guard let (lp, ns) = self.checkDAG(buffer, variableTable, options) else {
76+
guard let (lp, ns, vt) = self.checkDAG(buffer, variableTable, options) else {
7677
return nil
7778
}
7879
lastPos = lp
7980
notStrings = ns
81+
initialTable = vt
8082
} else {
8183
lastPos = 0
8284
notStrings = []
85+
initialTable = variableTable
8386
}
8487

8588
// Match itself from the last position after matching CHECK-DAG.
8689
let matchBuffer = buffer.substring(from: buffer.index(buffer.startIndex, offsetBy: lastPos))
87-
guard let range = self.pattern.match(matchBuffer, variableTable) else {
90+
guard let (range, mutVariableTable) = self.pattern.match(matchBuffer, initialTable) else {
8891
if let rtm = self.pattern.computeRegexToMatch(variableTable) {
8992
if !self.pattern.fixedString.isEmpty {
9093
diagnose(.error,
@@ -112,12 +115,14 @@ struct CheckString {
112115

113116
// Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT
114117
// or CHECK-NOT
118+
let finalTable : [String:String]
115119
if !isLabelScanMode {
120+
let startIdx = buffer.index(buffer.startIndex, offsetBy: lastPos)
116121
let skippedRegion = buffer.substring(
117122
with: Range<String.Index>(
118123
uncheckedBounds: (
119-
buffer.index(buffer.startIndex, offsetBy: lastPos),
120-
buffer.index(buffer.startIndex, offsetBy: matchPos)
124+
startIdx,
125+
buffer.index(startIdx, offsetBy: matchPos)
121126
)
122127
)
123128
)
@@ -137,12 +142,16 @@ struct CheckString {
137142

138143
// If this match had "not strings", verify that they don't exist in the
139144
// skipped region.
140-
if self.checkNot(skippedRegion, notStrings, variableTable, options) {
145+
let (cond, variableTable) = self.checkNot(skippedRegion, notStrings, mutVariableTable, options)
146+
finalTable = variableTable
147+
if cond {
141148
return nil
142149
}
150+
} else {
151+
finalTable = mutVariableTable
143152
}
144153

145-
return NSRange(location: lastPos + matchPos, length: matchLen)
154+
return (NSRange(location: lastPos + matchPos, length: matchLen), finalTable)
146155
}
147156

148157
/// Verify there is no newline in the given buffer.
@@ -226,34 +235,35 @@ struct CheckString {
226235
}
227236

228237
/// Verify there's no "not strings" in the given buffer.
229-
private func checkNot(_ buffer : String, _ notStrings : [Pattern], _ variableTable : BoxedTable, _ options: FileCheckOptions) -> Bool {
238+
private func checkNot(_ buffer : String, _ notStrings : [Pattern], _ variableTable : [String:String], _ options: FileCheckOptions) -> (Bool, [String:String]) {
230239
for pat in notStrings {
231240
assert(pat.type == .not, "Expect CHECK-NOT!")
232241

233-
guard let range = pat.match(buffer, variableTable) else {
242+
guard let (range, variableTable) = pat.match(buffer, variableTable) else {
234243
continue
235244
}
236245
buffer.cString(using: .utf8)?.withUnsafeBufferPointer { buf in
237246
let loc = CheckLoc.inBuffer(buf.baseAddress!.advanced(by: range.location), buf)
238247
diagnose(.error, at: loc, with: self.prefix + "-NOT: string occurred!", options: options)
239248
}
240249
diagnose(.note, at: pat.patternLoc, with: self.prefix + "-NOT: pattern specified here", options: options)
241-
return true
250+
return (true, variableTable)
242251
}
243252

244-
return false
253+
return (false, variableTable)
245254
}
246255

247256
/// Match "dag strings" and their mixed "not strings".
248-
func checkDAG(_ buffer : String, _ variableTable : BoxedTable, _ options: FileCheckOptions) -> (Int, [Pattern])? {
257+
func checkDAG(_ buffer : String, _ variableTable : [String:String], _ options: FileCheckOptions) -> (Int, [Pattern], [String:String])? {
249258
var notStrings = [Pattern]()
250-
if dagNotStrings.isEmpty {
251-
return (0, notStrings)
259+
if self.dagNotStrings.isEmpty {
260+
return (0, notStrings, variableTable)
252261
}
253262

254263
var lastPos = 0
255264
var startPos = lastPos
256265

266+
var finalTable : [String:String] = variableTable
257267
for pattern in self.dagNotStrings {
258268
assert((pattern.type == .dag || pattern.type == .not), "Invalid CHECK-DAG or CHECK-NOT!")
259269

@@ -268,10 +278,11 @@ struct CheckString {
268278
let matchBuffer = buffer.substring(from: buffer.index(buffer.startIndex, offsetBy: startPos))
269279
// With a group of CHECK-DAGs, a single mismatching means the match on
270280
// that group of CHECK-DAGs fails immediately.
271-
guard let range = pattern.match(matchBuffer, variableTable) else {
281+
guard let (range, variableTable) = pattern.match(matchBuffer, finalTable) else {
272282
// PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable)
273283
return nil
274284
}
285+
finalTable = variableTable
275286

276287
// Re-calc it as the offset relative to the start of the original string.
277288
let matchPos = range.location + startPos
@@ -302,9 +313,11 @@ struct CheckString {
302313
)
303314
)
304315
)
305-
if self.checkNot(skippedRegion, notStrings, variableTable, options) {
316+
let (cond, mutVarTable) = self.checkNot(skippedRegion, notStrings, finalTable, options)
317+
if cond {
306318
return nil
307319
}
320+
finalTable = mutVarTable
308321
// Clear "not strings".
309322
notStrings.removeAll()
310323
}
@@ -313,6 +326,6 @@ struct CheckString {
313326
lastPos = max(matchPos + range.length, lastPos)
314327
}
315328

316-
return (lastPos, notStrings)
329+
return (lastPos, notStrings, finalTable)
317330
}
318331
}

Sources/FileCheck/FileCheck.swift

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -456,7 +456,7 @@ private func check(input b : String, against checkStrings : [CheckString], optio
456456
var failedChecks = false
457457

458458
// This holds all the current filecheck variables.
459-
var variableTable = BoxedTable()
459+
var variableTable = [String:String]()
460460

461461
var i = 0
462462
var j = 0
@@ -472,11 +472,12 @@ private func check(input b : String, against checkStrings : [CheckString], optio
472472
}
473473

474474
// Scan to next CHECK-LABEL match, ignoring CHECK-NOT and CHECK-DAG
475-
guard let range = checkStr.check(buffer, true, variableTable, options) else {
475+
guard let (range, mutVariableTable) = checkStr.check(buffer, true, variableTable, options) else {
476476
// Immediately bail of CHECK-LABEL fails, nothing else we can do.
477477
return false
478478
}
479479

480+
variableTable = mutVariableTable
480481
checkRegion = buffer.substring(to: buffer.index(buffer.startIndex, offsetBy: NSMaxRange(range)))
481482
buffer = buffer.substring(from: buffer.index(buffer.startIndex, offsetBy: NSMaxRange(range)))
482483
j += 1
@@ -487,12 +488,12 @@ private func check(input b : String, against checkStrings : [CheckString], optio
487488

488489
// Check each string within the scanned region, including a second check
489490
// of any final CHECK-LABEL (to verify CHECK-NOT and CHECK-DAG)
490-
guard let range = checkStrings[i].check(checkRegion, false, variableTable, options) else {
491+
guard let (range, mutVarTable) = checkStrings[i].check(checkRegion, false, variableTable, options) else {
491492
failedChecks = true
492493
i = j
493494
break
494495
}
495-
496+
variableTable = mutVarTable
496497
checkRegion = checkRegion.substring(from: checkRegion.index(checkRegion.startIndex, offsetBy: NSMaxRange(range)))
497498
}
498499

Sources/FileCheck/Pattern.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,6 +234,7 @@ final class Pattern {
234234
patternStr = patternStr.substring(from: fixedMatchEnd)
235235
} else {
236236
// No more matches, time to quit.
237+
self.regExPattern += NSRegularExpression.escapedPattern(for: patternStr)
237238
break
238239
}
239240
}
@@ -276,7 +277,7 @@ final class Pattern {
276277
return "\(self.lineNumber + offset)"
277278
}
278279

279-
func computeRegexToMatch(_ variableTable : BoxedTable) -> String? {
280+
func computeRegexToMatch(_ variableTable : [String:String]) -> String? {
280281
// If there are variable uses, we need to create a temporary string with the
281282
// actual value.
282283
var regExToMatch = self.regExPattern
@@ -314,16 +315,16 @@ final class Pattern {
314315
///
315316
/// The variable table provides the current values of filecheck variables and
316317
/// is updated if this match defines new values.
317-
func match(_ buffer : String, _ variableTable : BoxedTable) -> NSRange? {
318+
func match(_ buffer : String, _ variableTable : [String:String]) -> (NSRange, [String:String])? {
318319
// If this is the EOF pattern, match it immediately.
319320
if self.type == .EOF {
320-
return NSRange(location: buffer.utf8.count, length: 0)
321+
return (NSRange(location: buffer.utf8.count, length: 0), variableTable)
321322
}
322323

323324
// If this is a fixed string pattern, just match it now.
324325
if !self.fixedString.isEmpty {
325326
if let b = buffer.range(of: self.fixedString)?.lowerBound {
326-
return NSRange(location: buffer.distance(from: buffer.startIndex, to: b), length: self.fixedString.utf8.count)
327+
return (NSRange(location: buffer.distance(from: buffer.startIndex, to: b), length: self.fixedString.utf8.count), variableTable)
327328
}
328329
return nil
329330
}
@@ -346,14 +347,15 @@ final class Pattern {
346347
}
347348

348349
// If this defines any variables, remember their values.
350+
var mutTable = variableTable
349351
for (v, index) in self.variableDefs {
350352
assert(index < fullMatch.numberOfRanges, "Internal paren error")
351353
#if os(macOS)
352354
let r = fullMatch.rangeAt(index)
353355
#else
354356
let r = fullMatch.range(at: index)
355357
#endif
356-
variableTable[v] = buffer.substring(
358+
mutTable[v] = buffer.substring(
357359
with: Range<String.Index>(
358360
uncheckedBounds: (
359361
buffer.index(buffer.startIndex, offsetBy: r.location),
@@ -363,7 +365,7 @@ final class Pattern {
363365
)
364366
}
365367

366-
return fullMatch.range
368+
return (fullMatch.range, mutTable)
367369
}
368370

369371
/// Finds the closing sequence of a regex variable usage or definition.

0 commit comments

Comments
 (0)