Skip to content

Commit 0ec6397

Browse files
authored
Merge pull request swiftlang#71224 from glessard/rdar121395821
[stdlib] Improve documentation for the various "String from C-string" initializers
2 parents ada2e40 + e10899e commit 0ec6397

File tree

2 files changed

+119
-40
lines changed

2 files changed

+119
-40
lines changed

stdlib/public/core/CString.swift

Lines changed: 113 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ extension String {
4242
/// }
4343
/// // Prints "Caf�"
4444
///
45-
/// - Parameter nullTerminatedUTF8: A pointer to a null-terminated UTF-8 code sequence.
45+
/// - Parameter nullTerminatedUTF8:
46+
/// A pointer to a null-terminated sequence of UTF-8 code units.
4647
public init(cString nullTerminatedUTF8: UnsafePointer<CChar>) {
4748
let len = UTF8._nullCodeUnitOffset(in: nullTerminatedUTF8)
4849
let buffer = UnsafeBufferPointer(start: nullTerminatedUTF8, count: len)
@@ -51,8 +52,24 @@ extension String {
5152
}
5253
}
5354

55+
/// Creates a new string by copying the null-terminated UTF-8 data referenced
56+
/// by the given array.
57+
///
58+
/// If `cString` contains ill-formed UTF-8 code unit sequences, this
59+
/// initializer replaces them with the Unicode replacement character
60+
/// (`"\u{FFFD}"`).
61+
///
62+
/// - Note: This initializer is deprecated. Use the initializer
63+
/// `String.init(decoding: array, as: UTF8.self)` instead,
64+
/// remembering that "\0" is a valid character in Swift.
65+
///
66+
/// - Parameter nullTerminatedUTF8:
67+
/// An array containing a null-terminated sequence of UTF-8 code units.
5468
@inlinable
5569
@_alwaysEmitIntoClient
70+
@available(swift, deprecated: 6, message:
71+
"Use String(decoding: array, as: UTF8.self) instead, after truncating the null termination."
72+
)
5673
public init(cString nullTerminatedUTF8: [CChar]) {
5774
self = nullTerminatedUTF8.withUnsafeBufferPointer {
5875
$0.withMemoryRebound(to: UInt8.self, String.init(_checkingCString:))
@@ -91,14 +108,32 @@ extension String {
91108
///
92109
/// This is identical to `init(cString: UnsafePointer<CChar>)` but operates on
93110
/// an unsigned sequence of bytes.
111+
///
112+
/// - Parameter nullTerminatedUTF8:
113+
/// A pointer to a null-terminated sequence of UTF-8 code units.
94114
public init(cString nullTerminatedUTF8: UnsafePointer<UInt8>) {
95115
let len = UTF8._nullCodeUnitOffset(in: nullTerminatedUTF8)
96116
self = String._fromUTF8Repairing(
97117
UnsafeBufferPointer(start: nullTerminatedUTF8, count: len)).0
98118
}
99119

120+
/// Creates a new string by copying the null-terminated UTF-8 data referenced
121+
/// by the given array.
122+
///
123+
/// This is identical to `init(cString: [CChar])` but operates on
124+
/// an unsigned sequence of bytes.
125+
///
126+
/// - Note: This initializer is deprecated. Use the initializer
127+
/// `String.init(decoding: array, as: UTF8.self)` instead,
128+
/// remembering that "\0" is a valid character in Swift.
129+
///
130+
/// - Parameter nullTerminatedUTF8:
131+
/// An array containing a null-terminated UTF-8 code unit sequence.
100132
@inlinable
101133
@_alwaysEmitIntoClient
134+
@available(swift, deprecated: 6, message:
135+
"Use String(decoding: array, as: UTF8.self) instead, after truncating the null termination."
136+
)
102137
public init(cString nullTerminatedUTF8: [UInt8]) {
103138
self = nullTerminatedUTF8.withUnsafeBufferPointer {
104139
String(_checkingCString: $0)
@@ -150,7 +185,7 @@ extension String {
150185
/// // Prints "nil"
151186
///
152187
/// - Parameter nullTerminatedUTF8:
153-
/// A pointer to a null-terminated UTF-8 code sequence.
188+
/// A pointer to a null-terminated sequence of UTF-8 code units.
154189
@inlinable
155190
@_alwaysEmitIntoClient
156191
public init?(validatingCString nullTerminatedUTF8: UnsafePointer<CChar>) {
@@ -183,10 +218,11 @@ extension String {
183218
/// }
184219
/// // Prints "nil"
185220
///
186-
/// Note: This initializer is deprecated. Use
187-
/// `String.init?(validatingCString:)` instead.
221+
/// - Note: This initializer has been renamed. Use
222+
/// `String.init?(validatingCString:)` instead.
188223
///
189-
/// - Parameter cString: A pointer to a null-terminated UTF-8 code sequence.
224+
/// - Parameter cString:
225+
/// A pointer to a null-terminated sequence of UTF-8 code units.
190226
@available(swift, deprecated: 6, renamed: "String.init(validatingCString:)")
191227
public init?(validatingUTF8 cString: UnsafePointer<CChar>) {
192228
let len = UTF8._nullCodeUnitOffset(in: cString)
@@ -198,8 +234,23 @@ extension String {
198234
self = str
199235
}
200236

237+
/// Creates a new string by copying and validating the null-terminated UTF-8
238+
/// data referenced by the given array.
239+
///
240+
/// This initializer does not try to repair ill-formed UTF-8 code unit
241+
/// sequences. If any are found, the result of the initializer is `nil`.
242+
///
243+
/// - Note: This initializer is deprecated. Use the initializer
244+
/// `String.init?(validating: array, as: UTF8.self)` instead,
245+
/// remembering that "\0" is a valid character in Swift.
246+
///
247+
/// - Parameter nullTerminatedUTF8:
248+
/// An array containing a null-terminated sequence of UTF-8 code units.
201249
@inlinable
202250
@_alwaysEmitIntoClient
251+
@available(swift, deprecated: 6, message:
252+
"Use String(validating: array, as: UTF8.self) instead, after truncating the null termination."
253+
)
203254
public init?(validatingCString nullTerminatedUTF8: [CChar]) {
204255
guard let length = nullTerminatedUTF8.firstIndex(of: 0) else {
205256
_preconditionFailure(
@@ -213,9 +264,23 @@ extension String {
213264
self = string
214265
}
215266

267+
/// Creates a new string by copying and validating the null-terminated UTF-8
268+
/// data referenced by the given array.
269+
///
270+
/// This initializer does not try to repair ill-formed UTF-8 code unit
271+
/// sequences. If any are found, the result of the initializer is `nil`.
272+
///
273+
/// - Note: This initializer is deprecated. Use the initializer
274+
/// `String.init?(validating: array, as: UTF8.self)` instead,
275+
/// remembering that "\0" is a valid character in Swift.
276+
///
277+
/// - Parameter cString:
278+
/// An array containing a null-terminated sequence of UTF-8 code units.
216279
@inlinable
217280
@_alwaysEmitIntoClient
218-
@available(swift, deprecated: 6, renamed: "String.init(validatingCString:)")
281+
@available(swift, deprecated: 6, message:
282+
"Use String(validating: array, as: UTF8.self) instead, after truncating the null termination."
283+
)
219284
public init?(validatingUTF8 cString: [CChar]) {
220285
self.init(validatingCString: cString)
221286
}
@@ -240,7 +305,7 @@ extension String {
240305
public init?(validatingCString nullTerminatedUTF8: inout CChar) {
241306
guard nullTerminatedUTF8 == 0 else {
242307
_preconditionFailure(
243-
"input of String.init(validatingUTF8:) must be null-terminated"
308+
"input of String.init(validatingCString:) must be null-terminated"
244309
)
245310
}
246311
self = ""
@@ -284,8 +349,8 @@ extension String {
284349
/// // Prints "Optional((result: "Caf�", repairsMade: true))"
285350
///
286351
/// - Parameters:
287-
/// - cString: A pointer to a null-terminated code sequence encoded in
288-
/// `encoding`.
352+
/// - cString: A pointer to a null-terminated sequence of
353+
/// code units encoded in `encoding`.
289354
/// - encoding: The Unicode encoding of the data referenced by `cString`.
290355
/// - isRepairing: Pass `true` to create a new string, even when the data
291356
/// referenced by `cString` contains ill-formed sequences. Ill-formed
@@ -329,9 +394,7 @@ extension String {
329394
codeUnits, encoding: encoding, repair: isRepairing)
330395
}
331396

332-
@_specialize(where Encoding == Unicode.UTF8)
333-
@_specialize(where Encoding == Unicode.UTF16)
334-
@inlinable // Fold away specializations
397+
@inlinable
335398
@_alwaysEmitIntoClient
336399
public static func decodeCString<Encoding: _UnicodeEncoding>(
337400
_ cString: [Encoding.CodeUnit],
@@ -365,8 +428,6 @@ extension String {
365428
}
366429
}
367430

368-
@_specialize(where Encoding == Unicode.UTF8)
369-
@_specialize(where Encoding == Unicode.UTF16)
370431
@inlinable
371432
@_alwaysEmitIntoClient
372433
@available(*, deprecated, message: "Use a copy of the String argument")
@@ -382,8 +443,6 @@ extension String {
382443
}
383444
}
384445

385-
@_specialize(where Encoding == Unicode.UTF8)
386-
@_specialize(where Encoding == Unicode.UTF16)
387446
@inlinable
388447
@_alwaysEmitIntoClient
389448
@available(*, deprecated, message: "Use String(_ scalar: Unicode.Scalar)")
@@ -400,58 +459,74 @@ extension String {
400459
return ("", false)
401460
}
402461

403-
/// Creates a string from the null-terminated sequence of bytes at the given
404-
/// pointer.
462+
/// Creates a new string by copying the null-terminated sequence of code units
463+
/// referenced by the given pointer.
464+
///
465+
/// If `nullTerminatedCodeUnits` contains ill-formed code unit sequences, this
466+
/// initializer replaces them with the Unicode replacement character
467+
/// (`"\u{FFFD}"`).
405468
///
406469
/// - Parameters:
407-
/// - nullTerminatedCodeUnits: A pointer to a sequence of contiguous code
408-
/// units in the encoding specified in `sourceEncoding`, ending just
409-
/// before the first zero code unit.
410-
/// - sourceEncoding: The encoding in which the code units should be
470+
/// - nullTerminatedCodeUnits: A pointer to a null-terminated sequence of
471+
/// code units encoded in `encoding`.
472+
/// - encoding: The encoding in which the code units should be
411473
/// interpreted.
412474
@_specialize(where Encoding == Unicode.UTF8)
413475
@_specialize(where Encoding == Unicode.UTF16)
414476
@inlinable // Fold away specializations
415477
public init<Encoding: Unicode.Encoding>(
416478
decodingCString nullTerminatedCodeUnits: UnsafePointer<Encoding.CodeUnit>,
417-
as sourceEncoding: Encoding.Type
479+
as encoding: Encoding.Type
418480
) {
419-
self = String.decodeCString(nullTerminatedCodeUnits, as: sourceEncoding)!.0
481+
self = String.decodeCString(nullTerminatedCodeUnits, as: encoding)!.0
420482
}
421483

422-
@_specialize(where Encoding == Unicode.UTF8)
423-
@_specialize(where Encoding == Unicode.UTF16)
424-
@inlinable // Fold away specializations
484+
/// Creates a new string by copying the null-terminated sequence of code units
485+
/// referenced by the given array.
486+
///
487+
/// If `nullTerminatedCodeUnits` contains ill-formed code unit sequences, this
488+
/// initializer replaces them with the Unicode replacement character
489+
/// (`"\u{FFFD}"`).
490+
///
491+
/// - Note: This initializer is deprecated. Use the initializer
492+
/// `String.init(decoding: array, as: Encoding.self)` instead,
493+
/// remembering that "\0" is a valid character in Swift.
494+
///
495+
/// - Parameters:
496+
/// - nullTerminatedCodeUnits: An array containing a null-terminated
497+
/// sequence of code units encoded in `encoding`.
498+
/// - encoding: The encoding in which the code units should be
499+
/// interpreted.
500+
@inlinable
425501
@_alwaysEmitIntoClient
502+
@available(swift, deprecated: 6, message:
503+
"Use String(decoding: array, as: Encoding.self) instead, after truncating the null termination."
504+
)
426505
public init<Encoding: Unicode.Encoding>(
427506
decodingCString nullTerminatedCodeUnits: [Encoding.CodeUnit],
428-
as sourceEncoding: Encoding.Type
507+
as encoding: Encoding.Type
429508
) {
430-
self = String.decodeCString(nullTerminatedCodeUnits, as: sourceEncoding)!.0
509+
self = String.decodeCString(nullTerminatedCodeUnits, as: encoding)!.0
431510
}
432511

433-
@_specialize(where Encoding == Unicode.UTF8)
434-
@_specialize(where Encoding == Unicode.UTF16)
435512
@inlinable
436513
@_alwaysEmitIntoClient
437514
@available(*, deprecated, message: "Use a copy of the String argument")
438515
public init<Encoding: _UnicodeEncoding>(
439516
decodingCString nullTerminatedCodeUnits: String,
440-
as sourceEncoding: Encoding.Type
517+
as encoding: Encoding.Type
441518
) {
442-
self = nullTerminatedCodeUnits.withCString(encodedAs: sourceEncoding) {
443-
String(decodingCString: $0, as: sourceEncoding.self)
519+
self = nullTerminatedCodeUnits.withCString(encodedAs: encoding) {
520+
String(decodingCString: $0, as: encoding.self)
444521
}
445522
}
446523

447-
@_specialize(where Encoding == Unicode.UTF8)
448-
@_specialize(where Encoding == Unicode.UTF16)
449-
@inlinable // Fold away specializations
524+
@inlinable
450525
@_alwaysEmitIntoClient
451526
@available(*, deprecated, message: "Use String(_ scalar: Unicode.Scalar)")
452527
public init<Encoding: Unicode.Encoding>(
453528
decodingCString nullTerminatedCodeUnits: inout Encoding.CodeUnit,
454-
as sourceEncoding: Encoding.Type
529+
as encoding: Encoding.Type
455530
) {
456531
guard nullTerminatedCodeUnits == 0 else {
457532
_preconditionFailure(

test/stdlib/StringAPICStringDiagnostics.swift

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ func checkStringOverloadCompilationDiagnostics() {
66

77
_ = String(cString: "string") // expected-warning {{'init(cString:)' is deprecated: Use a copy of the String argument}}
88

9-
_ = String(validatingCString: "string") // expected-warning {{init(validatingCString:)' is deprecated: Use a copy of the String argument}}
9+
_ = String(validatingUTF8: "string") // expected-warning {{init(validatingUTF8:)' is deprecated: Use a copy of the String argument}}
10+
11+
_ = String(validatingCString: "string") // expected-warning {{'init(validatingCString:)' is deprecated: Use a copy of the String argument}}
1012

1113
_ = String.decodeCString("string", as: Unicode.UTF8.self) // expected-warning {{'decodeCString(_:as:repairingInvalidCodeUnits:)' is deprecated: Use a copy of the String argument}}
1214

@@ -23,7 +25,9 @@ func checkInoutConversionOverloadCompilationDiagnostics() {
2325

2426
_ = String(cString: &c) // expected-warning {{'init(cString:)' is deprecated: Use String(_ scalar: Unicode.Scalar)}}
2527

26-
_ = String(validatingCString: &c) // expected-warning {{init(validatingCString:)' is deprecated: Use String(_ scalar: Unicode.Scalar)}}
28+
_ = String(validatingUTF8: &c) // expected-warning {{init(validatingUTF8:)' is deprecated: Use String(_ scalar: Unicode.Scalar)}}
29+
30+
_ = String(validatingCString: &c) // expected-warning {{'init(validatingCString:)' is deprecated: Use String(_ scalar: Unicode.Scalar)}}
2731

2832
var u = Unicode.UTF8.CodeUnit.zero
2933

0 commit comments

Comments
 (0)