@@ -20,6 +20,49 @@ extension FilePath {
2020 self . init ( _platformString: platformString)
2121 }
2222
23+ /// Creates a file path by copying bytes from a null-terminated platform
24+ /// string.
25+ ///
26+ /// - Note It is a precondition that `platformString` must be null-terminated.
27+ /// The absence of a null byte will trigger a runtime error.
28+ ///
29+ /// - Parameter platformString: A null-terminated platform string.
30+ @inlinable
31+ @_alwaysEmitIntoClient
32+ public init ( platformString: [ CInterop . PlatformChar ] ) {
33+ guard let _ = platformString. firstIndex ( of: 0 ) else {
34+ fatalError (
35+ " input of FilePath.init(platformString:) must be null-terminated "
36+ )
37+ }
38+ self = platformString. withUnsafeBufferPointer {
39+ FilePath ( platformString: $0. baseAddress!)
40+ }
41+ }
42+
43+ @inlinable
44+ @_alwaysEmitIntoClient
45+ @available ( * , deprecated, message: " Use FilePath.init(_ scalar: Unicode.Scalar) " )
46+ public init ( platformString: inout CInterop . PlatformChar ) {
47+ guard platformString == 0 else {
48+ fatalError (
49+ " input of FilePath.init(platformString:) must be null-terminated "
50+ )
51+ }
52+ self = FilePath ( )
53+ }
54+
55+ @inlinable
56+ @_alwaysEmitIntoClient
57+ @available ( * , deprecated, message: " Use FilePath(_: String) to create a path from a String " )
58+ public init ( platformString: String ) {
59+ if let nullLoc = platformString. firstIndex ( of: " \0 " ) {
60+ self = FilePath ( String ( platformString [ ..< nullLoc] ) )
61+ } else {
62+ self = FilePath ( platformString)
63+ }
64+ }
65+
2366 /// Calls the given closure with a pointer to the contents of the file path,
2467 /// represented as a null-terminated platform string.
2568 ///
@@ -60,6 +103,59 @@ extension FilePath.Component {
60103 self . init ( _platformString: platformString)
61104 }
62105
106+ /// Creates a file path component by copying bytes from a null-terminated
107+ /// platform string. It is a precondition that a null byte indicates the end of
108+ /// the string. The absence of a null byte will trigger a runtime error.
109+ ///
110+ /// Returns `nil` if `platformString` is empty, is a root, or has more than
111+ /// one component in it.
112+ ///
113+ /// - Note It is a precondition that `platformString` must be null-terminated.
114+ /// The absence of a null byte will trigger a runtime error.
115+ ///
116+ /// - Parameter platformString: A null-terminated platform string.
117+ @inlinable
118+ @_alwaysEmitIntoClient
119+ public init ? ( platformString: [ CInterop . PlatformChar ] ) {
120+ guard let _ = platformString. firstIndex ( of: 0 ) else {
121+ fatalError (
122+ " input of FilePath.Component.init?(platformString:) must be null-terminated "
123+ )
124+ }
125+ guard let component = platformString. withUnsafeBufferPointer ( {
126+ FilePath . Component ( platformString: $0. baseAddress!)
127+ } ) else {
128+ return nil
129+ }
130+ self = component
131+ }
132+
133+ @inlinable
134+ @_alwaysEmitIntoClient
135+ @available ( * , deprecated, message: " Use FilePath.Component.init(_ scalar: Unicode.Scalar) " )
136+ public init ? ( platformString: inout CInterop . PlatformChar ) {
137+ guard platformString == 0 else {
138+ fatalError (
139+ " input of FilePath.Component.init?(platformString:) must be null-terminated "
140+ )
141+ }
142+ return nil
143+ }
144+
145+ @inlinable
146+ @_alwaysEmitIntoClient
147+ @available ( * , deprecated, message: " Use FilePath.Component.init(_: String) " )
148+ public init ? ( platformString: String ) {
149+ let string : String
150+ if let nullLoc = platformString. firstIndex ( of: " \0 " ) {
151+ string = String ( platformString [ ..< nullLoc] )
152+ } else {
153+ string = platformString
154+ }
155+ guard let component = FilePath . Component ( string) else { return nil }
156+ self = component
157+ }
158+
63159 /// Calls the given closure with a pointer to the contents of the file path
64160 /// component, represented as a null-terminated platform string.
65161 ///
@@ -96,6 +192,58 @@ extension FilePath.Root {
96192 self . init ( _platformString: platformString)
97193 }
98194
195+ /// Creates a file path root by copying bytes from a null-terminated platform
196+ /// string. It is a precondition that a null byte indicates the end of
197+ /// the string. The absence of a null byte will trigger a runtime error.
198+ ///
199+ /// Returns `nil` if `platformString` is empty or is not a root.
200+ ///
201+ /// - Note It is a precondition that `platformString` must be null-terminated.
202+ /// The absence of a null byte will trigger a runtime error.
203+ ///
204+ /// - Parameter platformString: A null-terminated platform string.
205+ @inlinable
206+ @_alwaysEmitIntoClient
207+ public init ? ( platformString: [ CInterop . PlatformChar ] ) {
208+ guard let _ = platformString. firstIndex ( of: 0 ) else {
209+ fatalError (
210+ " input of FilePath.Root.init?(platformString:) must be null-terminated "
211+ )
212+ }
213+ guard let component = platformString. withUnsafeBufferPointer ( {
214+ FilePath . Root ( platformString: $0. baseAddress!)
215+ } ) else {
216+ return nil
217+ }
218+ self = component
219+ }
220+
221+ @inlinable
222+ @_alwaysEmitIntoClient
223+ @available ( * , deprecated, message: " Use FilePath.Root.init(_ scalar: Unicode.Scalar) " )
224+ public init ? ( platformString: inout CInterop . PlatformChar ) {
225+ guard platformString == 0 else {
226+ fatalError (
227+ " input of FilePath.Root.init?(platformString:) must be null-terminated "
228+ )
229+ }
230+ return nil
231+ }
232+
233+ @inlinable
234+ @_alwaysEmitIntoClient
235+ @available ( * , deprecated, message: " Use FilePath.Root.init(_: String) " )
236+ public init ? ( platformString: String ) {
237+ let string : String
238+ if let nullLoc = platformString. firstIndex ( of: " \0 " ) {
239+ string = String ( platformString [ ..< nullLoc] )
240+ } else {
241+ string = platformString
242+ }
243+ guard let root = FilePath . Root ( string) else { return nil }
244+ self = root
245+ }
246+
99247 /// Calls the given closure with a pointer to the contents of the file path
100248 /// root, represented as a null-terminated platform string.
101249 ///
@@ -148,7 +296,7 @@ extension FilePath.Component: ExpressibleByStringLiteral {
148296 public init ( stringLiteral: String ) {
149297 guard let s = FilePath . Component ( stringLiteral) else {
150298 // TODO: static assert
151- preconditionFailure ( """
299+ fatalError ( """
152300 FilePath.Component must be created from exactly one non-root component
153301 """ )
154302 }
@@ -172,7 +320,7 @@ extension FilePath.Root: ExpressibleByStringLiteral {
172320 public init ( stringLiteral: String ) {
173321 guard let s = FilePath . Root ( stringLiteral) else {
174322 // TODO: static assert
175- preconditionFailure ( """
323+ fatalError ( """
176324 FilePath.Root must be created from a root
177325 """ )
178326 }
@@ -405,10 +553,26 @@ extension String {
405553extension FilePath {
406554 /// For backwards compatibility only. This initializer is equivalent to
407555 /// the preferred `FilePath(platformString:)`.
556+ @available ( * , deprecated, renamed: " init(platformString:) " )
408557 public init ( cString: UnsafePointer < CChar > ) {
409558 self . init ( platformString: cString)
410559 }
411560
561+ @available ( * , deprecated, renamed: " init(platformString:) " )
562+ public init ( cString: [ CChar ] ) {
563+ self . init ( platformString: cString)
564+ }
565+
566+ @available ( * , deprecated, renamed: " init(platformString:) " )
567+ public init ( cString: inout CChar ) {
568+ self . init ( platformString: & cString)
569+ }
570+
571+ @available ( * , deprecated, renamed: " init(platformString:) " )
572+ public init ( cString: String ) {
573+ self . init ( platformString: cString)
574+ }
575+
412576 /// For backwards compatibility only. This function is equivalent to
413577 /// the preferred `withPlatformString`.
414578 public func withCString< Result> (
0 commit comments