Skip to content

Commit ce80641

Browse files
committed
Remove swift-function-caller-generator's dependency on Foundation
Building Foundation seems to be optional in the Linux build script, which makes it tricky to link against outside of Darwin platforms. This removes the dependency on Foundation and calls libc for I/O instead.
1 parent de49d68 commit ce80641

File tree

2 files changed

+54
-22
lines changed

2 files changed

+54
-22
lines changed

tools/swift-function-caller-generator/Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import PackageDescription
44

55
let package = Package(
66
name: "swift-function-caller-generator",
7-
platforms: [.macOS(.v11)],
7+
platforms: [.macOS(.v13)],
88
products: [
99
.executable(name: "swift-function-caller-generator", targets: ["swift-function-caller-generator"]),
1010
],

tools/swift-function-caller-generator/Sources/swift-function-caller-generator/swift-function-caller-generator.swift

Lines changed: 53 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,34 @@
1-
import Foundation
21
import SwiftParser
32
import SwiftSyntax
43
import SwiftSyntaxMacros
54

5+
#if canImport(Darwin)
6+
import Darwin
7+
#elseif canImport(Glibc)
8+
import Glibc
9+
#elseif canImport(Musl)
10+
import Musl
11+
#elseif canImport(Android)
12+
import Android
13+
#elseif os(WASI)
14+
import WASILibc
15+
#elseif os(Windows)
16+
import CRT
17+
import WinSDK
18+
#endif
19+
620
@main
721
class SwiftMacroTestGen: SyntaxVisitor {
822
static func main() {
923
if CommandLine.argc < 2 {
10-
print("error: missing module name (passed 1 argument, expected 2)")
24+
printError("missing module name (passed 0 arguments, expected 2)")
1125
exit(1)
1226
}
13-
let contents =
14-
if CommandLine.argc > 2 {
15-
read(file: CommandLine.arguments[2])
16-
} else {
17-
readStdin()
18-
}
27+
if CommandLine.argc < 3 {
28+
printError("missing module name (passed 1 argument, expected 2)")
29+
exit(1)
30+
}
31+
let contents = read(file: CommandLine.arguments[2])
1932
let syntaxTree = Parser.parse(source: contents)
2033
print("import \(CommandLine.arguments[1])\n")
2134
let visitor = SwiftMacroTestGen(viewMode: .all)
@@ -101,23 +114,27 @@ class TypeAliasReplacer: SyntaxRewriter {
101114
}
102115

103116
func read(file path: String) -> String {
104-
do {
105-
return try String(contentsOfFile: path, encoding: .utf8)
106-
} catch {
107-
print("Error reading file \(path): \(error.localizedDescription)")
117+
guard let f = fopen(path, "r") else {
118+
printError("could not open file \(path)")
108119
exit(1)
109120
}
110-
}
111-
112-
func readStdin() -> String {
113-
if let data = try? FileHandle.standardInput.readToEnd(),
114-
let input = String(data: data, encoding: .utf8)
115-
{
116-
return input
117-
} else {
118-
print("Error reading stdin)")
121+
if fseek(f, 0, SEEK_END) != 0 {
122+
printError("could not read file \(path)")
123+
exit(1)
124+
}
125+
let len = Int(ftell(f))
126+
if len < 0 {
127+
printError("could not read size of file \(path)")
119128
exit(1)
120129
}
130+
rewind(f)
131+
let contents = String(
132+
unsafeUninitializedCapacity: len,
133+
initializingUTF8With: { stringBuffer in
134+
fread(UnsafeMutableRawPointer(stringBuffer.baseAddress!), 1, len, f)
135+
})
136+
fclose(f)
137+
return contents
121138
}
122139

123140
func createBody(_ f: FunctionDeclSyntax, selfParam: TokenSyntax?) -> CodeBlockSyntax {
@@ -190,6 +207,17 @@ extension TypeSyntax {
190207
}
191208
}
192209

210+
// String.contains is not available without Foundation
211+
extension String {
212+
public func contains(_ other: String) -> Bool {
213+
return self.withCString({ this in
214+
return other.withCString({ that in
215+
return strstr(this, that) != nil
216+
})
217+
})
218+
}
219+
}
220+
193221
func addSelfParam(_ params: FunctionParameterListSyntax, _ type: TokenSyntax, _ name: TokenSyntax)
194222
-> FunctionParameterListSyntax
195223
{
@@ -282,3 +310,7 @@ extension AttributeListSyntax.Element {
282310
}
283311
}
284312
}
313+
314+
func printError(_ s: String) {
315+
fputs("error: \(s)\n", stderr)
316+
}

0 commit comments

Comments
 (0)