Skip to content

Emit withPlatformString as an availability workaround for open #32

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 17, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ let targets: [PackageDescription.Target] = [
dependencies: ["CSystem"],
path: "Sources/System",
swiftSettings: [
.define("SYSTEM_PACKAGE"),
.define("ENABLE_MOCKING", .when(configuration: .debug))
]),
.target(
Expand Down
25 changes: 25 additions & 0 deletions Sources/System/FilePath/FilePathComponentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,30 @@ extension FilePath {
}
}

#if SYSTEM_PACKAGE
/// View the non-root components that make up this path.
public var components: ComponentView {
get { ComponentView(self) }
_modify {
// RRC's empty init means that we can't guarantee that the yielded
// view will restore our root. So copy it out first.
//
// TODO(perf): Small-form root (especially on Unix). Have Root
// always copy out (not worth ref counting). Make sure that we're
// not needlessly sliding values around or triggering a COW
let rootStr = self.root?._systemString ?? SystemString()
var comp = ComponentView(self)
self = FilePath()
defer {
self = comp._path
if root?._slice.elementsEqual(rootStr) != true {
self.root = Root(rootStr)
}
}
yield &comp
}
}
#else
/// View the non-root components that make up this path.
public var components: ComponentView {
__consuming get { ComponentView(self) }
Expand All @@ -62,6 +86,7 @@ extension FilePath {
yield &comp
}
}
#endif
}

// @available(macOS 9999, iOS 9999, watchOS 9999, tvOS 9999, *)
Expand Down
9 changes: 7 additions & 2 deletions Sources/System/FilePath/FilePathString.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ extension FilePath {
/// The pointer passed as an argument to `body` is valid
/// only during the execution of this method.
/// Don't try to store the pointer for later use.
@_alwaysEmitIntoClient
public func withPlatformString<Result>(
_ body: (UnsafePointer<CInterop.PlatformChar>) throws -> Result
) rethrows -> Result {
try _withPlatformString(body)
#if !os(Windows)
return try withCString(body)
#else
return try _withPlatformString(body)
#endif
}
}

Expand Down Expand Up @@ -412,7 +417,7 @@ extension FilePath {
#if os(Windows)
fatalError("FilePath.withCString() unsupported on Windows ")
#else
return try withPlatformString(body)
return try _withPlatformString(body)
#endif
}
}
22 changes: 14 additions & 8 deletions Sources/System/Internals/Mocking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -146,13 +146,20 @@ private func originalSyscallName(_ function: String) -> String {

private func mockImpl(
name: String,
path: UnsafePointer<CChar>?,
_ args: [AnyHashable]
) -> CInt {
precondition(mockingEnabled)
let origName = originalSyscallName(name)
guard let driver = currentMockingDriver else {
fatalError("Mocking requested from non-mocking context")
}
driver.trace.add(Trace.Entry(name: origName, args))
var mockArgs: Array<AnyHashable> = []
if let p = path {
mockArgs.append(String(_errorCorrectingPlatformString: p))
}
mockArgs.append(contentsOf: args)
driver.trace.add(Trace.Entry(name: origName, mockArgs))

switch driver.forceErrno {
case .none: break
Expand All @@ -170,21 +177,20 @@ private func mockImpl(
}

internal func _mock(
name: String = #function, _ args: AnyHashable...
name: String = #function, path: UnsafePointer<CChar>? = nil, _ args: AnyHashable...
) -> CInt {
precondition(mockingEnabled)
return mockImpl(name: name, args)
return mockImpl(name: name, path: path, args)
}
internal func _mockInt(
name: String = #function, _ args: AnyHashable...
name: String = #function, path: UnsafePointer<CChar>? = nil, _ args: AnyHashable...
) -> Int {
Int(mockImpl(name: name, args))
Int(mockImpl(name: name, path: path, args))
}

internal func _mockOffT(
name: String = #function, _ args: AnyHashable...
name: String = #function, path: UnsafePointer<CChar>? = nil, _ args: AnyHashable...
) -> _COffT {
_COffT(mockImpl(name: name, args))
_COffT(mockImpl(name: name, path: path, args))
}
#endif // ENABLE_MOCKING

Expand Down
4 changes: 2 additions & 2 deletions Sources/System/Internals/Syscalls.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ internal func system_open(
) -> CInt {
#if ENABLE_MOCKING
if mockingEnabled {
return _mock(String(_errorCorrectingPlatformString: path), oflag)
return _mock(path: path, oflag)
}
#endif
return open(path, oflag)
Expand All @@ -38,7 +38,7 @@ internal func system_open(
) -> CInt {
#if ENABLE_MOCKING
if mockingEnabled {
return _mock(String(_errorCorrectingPlatformString: path), oflag, mode)
return _mock(path: path, oflag, mode)
}
#endif
return open(path, oflag, mode)
Expand Down
3 changes: 2 additions & 1 deletion Tests/SystemTests/XCTestManifests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ extension FileDescriptorTest {
// to regenerate.
static let __allTests__FileDescriptorTest = [
("testConstants", testConstants),
("testStandardDescriptors", testStandardDescriptors),
]
}

Expand All @@ -26,6 +27,7 @@ extension FileOperationsTest {
// to regenerate.
static let __allTests__FileOperationsTest = [
("testAdHocOpen", testAdHocOpen),
("testGithubIssues", testGithubIssues),
("testHelpers", testHelpers),
("testSyscalls", testSyscalls),
]
Expand All @@ -38,7 +40,6 @@ extension FilePathComponentsTest {
static let __allTests__FilePathComponentsTest = [
("testAdHocRRC", testAdHocRRC),
("testCases", testCases),
("testConcatenation", testConcatenation),
("testSeparatorNormalization", testSeparatorNormalization),
]
}
Expand Down