Skip to content

Commit 97ec3b5

Browse files
authored
Merge pull request #49 from gmittert/MakeSpaceForAnEscapeRoute
Handle Spaces in Makefile Parsing
2 parents 13882c7 + f016af0 commit 97ec3b5

File tree

4 files changed

+110
-17
lines changed

4 files changed

+110
-17
lines changed

Sources/ISDBTibs/Makefile.swift

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2019 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
import Foundation
13+
14+
public struct Makefile {
15+
public let outputs: [(target: Substring, deps: [Substring])]
16+
17+
public init?(contents: String) {
18+
var makeOutputs: [(target: Substring, deps: [Substring])] = []
19+
20+
let lines = contents.split(whereSeparator: { $0.isNewline })
21+
for line in lines {
22+
var deps: [Substring] = []
23+
let split = line.split(separator: ":", maxSplits: 1)
24+
25+
guard let output = split.first, let depStr = split.last else {
26+
return nil
27+
}
28+
29+
var prev: Character = "."
30+
var it = depStr.startIndex
31+
var strStart = it
32+
33+
while it != depStr.endIndex {
34+
let curr = depStr[it]
35+
if curr == " " && prev != "\\" {
36+
let dep = depStr[strStart..<it]
37+
if !dep.isEmpty {
38+
deps.append(dep)
39+
}
40+
strStart = depStr.index(after: it)
41+
}
42+
prev = curr
43+
it = depStr.index(after: it)
44+
}
45+
46+
let dep = depStr[strStart..<it]
47+
if !dep.isEmpty {
48+
deps.append(dep)
49+
}
50+
makeOutputs.append((target: output, deps: deps))
51+
}
52+
outputs = makeOutputs
53+
}
54+
55+
public init?(path: URL) {
56+
guard let contents = try? String(contentsOf: path) else {
57+
return nil
58+
}
59+
self.init(contents: contents)
60+
}
61+
62+
}

Sources/tibs/main.swift

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -26,27 +26,15 @@ var stderr = FileHandle.standardError
2626

2727
func swiftDepsMerge(output: String, _ files: [String]) {
2828
var allDeps: Set<Substring> = []
29+
2930
for file in files {
30-
let content: String
31-
do {
32-
content = try String(contentsOf: URL(fileURLWithPath: file))
33-
} catch {
34-
print("error: could not read dep file '\(file)': \(error)", to: &stderr)
31+
guard let makefile = Makefile(path: URL(fileURLWithPath: file)) else {
32+
print("error: could not read dep file '\(file)'", to: &stderr)
3533
exit(1)
3634
}
3735

38-
let lines = content.split(whereSeparator: { $0.isNewline })
39-
for line in lines {
40-
guard let depStr = line.split(separator: ":", maxSplits: 1).last else {
41-
print("error: malformed dep file '\(file)': expected :", to: &stderr)
42-
exit(1)
43-
}
44-
45-
let deps = depStr.split(whereSeparator: { $0.isWhitespace })
46-
for dep in deps {
47-
allDeps.insert(dep)
48-
}
49-
}
36+
let allOutputs = makefile.outputs.flatMap { $0.deps }
37+
allDeps.formUnion(allOutputs)
5038
}
5139

5240
print("\(output) : \(allDeps.sorted().joined(separator: " "))")

Tests/ISDBTibsTests/MiscTests.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,46 @@ final class MiscTests: XCTestCase {
2929
XCTAssertFalse(try data2.writeIfChanged(to: url))
3030
try FileManager.default.removeItem(at: url)
3131
}
32+
33+
func testMakefile() throws {
34+
typealias Outputs = [(target: Substring, deps: [Substring])]
35+
func outputsEqual(actual: Outputs, expected: Outputs) -> Bool {
36+
return actual.count == expected.count && zip(actual, expected).allSatisfy(==)
37+
}
38+
39+
let makefiles: [String: Outputs] = [
40+
/*simple*/
41+
"target: dep1 dep2 dep3": [
42+
(target: "target", deps: ["dep1", "dep2", "dep3"])
43+
],
44+
/*newlines*/
45+
"target1: dep1 \ntarget2: dep1 dep2 dep3": [
46+
(target: "target1", deps: ["dep1"]),
47+
(target: "target2", deps: ["dep1", "dep2", "dep3"])
48+
],
49+
/*nodeps*/
50+
"target: ": [
51+
(target: "target", deps: [])
52+
],
53+
/*spaces*/
54+
"target: Dep\\ with\\ spaces" : [
55+
(target: "target", deps: ["Dep\\ with\\ spaces"])
56+
],
57+
"target\\ with\\ spaces: Dep" : [
58+
(target: "target\\ with\\ spaces", deps: ["Dep"])
59+
],
60+
/*paths*/
61+
"target: Dep/with\\slashes" : [
62+
(target: "target", deps: ["Dep/with\\slashes"])
63+
],
64+
]
65+
66+
for (makefile, exp) in makefiles {
67+
guard let parsed = Makefile(contents: makefile) else {
68+
XCTFail("Could not parse: \(makefile)")
69+
return
70+
}
71+
XCTAssertTrue(outputsEqual(actual: parsed.outputs, expected: exp), "Makefile parse did not match!\nExpected: \(exp)\nAcutal: \(parsed.outputs)")
72+
}
73+
}
3274
}

Tests/ISDBTibsTests/XCTestManifests.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ extension MiscTests {
77
// to regenerate.
88
static let __allTests__MiscTests = [
99
("testDataWriteIfChanged", testDataWriteIfChanged),
10+
("testMakefile", testMakefile),
1011
]
1112
}
1213

0 commit comments

Comments
 (0)