mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
stdlib/NSString APIs on String: add more tests and fix a crash in
_countFormatSpecifiers() that was triggered by non-BMP characters in the format string Swift SVN r21014
This commit is contained in:
@@ -259,6 +259,7 @@ public struct _StringCore {
|
||||
let p = UnsafeMutablePointer<UInt8>(_pointerToNth(position).value)
|
||||
// Always dereference two bytes, but when elements are 8 bits we
|
||||
// multiply the high byte by 0.
|
||||
// FIXME(performance): use masking instead of multiplication.
|
||||
return UTF16.CodeUnit(p.memory)
|
||||
+ UTF16.CodeUnit((p + 1).memory) * _highByteMultiplier
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ extension String {
|
||||
}
|
||||
res = res * 10
|
||||
|
||||
var d = Int(c.value - _asUnicodeScalar("0").value)
|
||||
var d = Int(c.value - UnicodeScalar("0").value)
|
||||
// Underflow occurs if res - d < Int.min.
|
||||
if res < Int.min + d {
|
||||
return .None
|
||||
|
||||
@@ -233,16 +233,6 @@ public func <(lhs: UnicodeScalar, rhs: UnicodeScalar) -> Bool {
|
||||
return lhs.value < rhs.value
|
||||
}
|
||||
|
||||
/// Helper to provide type context to guide type inference in code like::
|
||||
///
|
||||
/// var value = digit - _asUnicodeScalar("0")
|
||||
public func _asUnicodeScalar(us: UnicodeScalar) -> UnicodeScalar {
|
||||
return us
|
||||
}
|
||||
public func _asUTF16CodeUnit(us: UnicodeScalar) -> UTF16.CodeUnit {
|
||||
return UTF16.CodeUnit(us.value)
|
||||
}
|
||||
|
||||
extension UnicodeScalar {
|
||||
struct UTF16View {
|
||||
var value: UnicodeScalar
|
||||
|
||||
@@ -35,21 +35,27 @@ func _toNSRange(r: Range<String.Index>) -> NSRange {
|
||||
}
|
||||
|
||||
func _countFormatSpecifiers(a: String) -> Int {
|
||||
var lastChar = _asUTF16CodeUnit(".") // anything other than % would work here
|
||||
// The implementation takes advantage of the fact that internal
|
||||
// representation of String is UTF-16. Because we only care about the ASCII
|
||||
// percent character, we don't need to decode UTF-16.
|
||||
|
||||
let percentUTF16 = UTF16.CodeUnit(("%" as UnicodeScalar).value)
|
||||
let notPercentUTF16: UTF16.CodeUnit = 0
|
||||
var lastChar = notPercentUTF16 // anything other than % would work here
|
||||
var count = 0
|
||||
|
||||
for c in a.unicodeScalars {
|
||||
if lastChar == _asUTF16CodeUnit("%") {
|
||||
if c == "%" {
|
||||
for c in a.utf16 {
|
||||
if lastChar == percentUTF16 {
|
||||
if c == percentUTF16 {
|
||||
// a "%" following this one should not be taken as literal
|
||||
lastChar = _asUTF16CodeUnit(".")
|
||||
lastChar = notPercentUTF16
|
||||
}
|
||||
else {
|
||||
++count
|
||||
lastChar = _asUTF16CodeUnit(c)
|
||||
lastChar = c
|
||||
}
|
||||
} else {
|
||||
lastChar = _asUTF16CodeUnit(c)
|
||||
lastChar = c
|
||||
}
|
||||
}
|
||||
return count
|
||||
|
||||
@@ -717,12 +717,21 @@ NSStringAPIs.test("init(utf16CodeUnitsNoCopy:count:freeWhenDone:)") {
|
||||
}
|
||||
|
||||
NSStringAPIs.test("init(format:_:...)") {
|
||||
expectEqual("", String(format: ""))
|
||||
expectEqual(
|
||||
"abc абв \u{0001F60A}", String(format: "abc абв \u{0001F60A}"))
|
||||
|
||||
let world: NSString = "world"
|
||||
expectEqual("Hello, world!%42",
|
||||
String(format: "Hello, %@!%%%ld", world, 42))
|
||||
}
|
||||
|
||||
NSStringAPIs.test("init(format:arguments:)") {
|
||||
expectEqual("", String(format: "", arguments: []))
|
||||
expectEqual(
|
||||
"abc абв \u{0001F60A}",
|
||||
String(format: "abc абв \u{0001F60A}", arguments: []))
|
||||
|
||||
let world: NSString = "world"
|
||||
let args: [CVarArgType] = [ world, 42 ]
|
||||
expectEqual("Hello, world!%42",
|
||||
@@ -1079,6 +1088,17 @@ NSStringAPIs.test("stringByAddingPercentEscapesUsingEncoding(_:)") {
|
||||
}
|
||||
|
||||
NSStringAPIs.test("stringByAppendingFormat(_:_:...)") {
|
||||
expectEqual("", "".stringByAppendingFormat(""))
|
||||
expectEqual("a", "a".stringByAppendingFormat(""))
|
||||
expectEqual(
|
||||
"abc абв \u{0001F60A}",
|
||||
"abc абв \u{0001F60A}".stringByAppendingFormat(""))
|
||||
|
||||
let formatArg: NSString = "привет мир \u{0001F60A}"
|
||||
expectEqual(
|
||||
"abc абв \u{0001F60A}def привет мир \u{0001F60A} 42",
|
||||
"abc абв \u{0001F60A}"
|
||||
.stringByAppendingFormat("def %@ %ld", formatArg, 42))
|
||||
// FIXME
|
||||
}
|
||||
|
||||
@@ -1091,7 +1111,10 @@ NSStringAPIs.test("stringByAppendingPathExtension(_:)") {
|
||||
}
|
||||
|
||||
NSStringAPIs.test("stringByAppendingString(_:)") {
|
||||
// FIXME
|
||||
expectEqual("", "".stringByAppendingString(""))
|
||||
expectEqual("a", "a".stringByAppendingString(""))
|
||||
expectEqual("a", "".stringByAppendingString("a"))
|
||||
expectEqual("さ\u{3099}", "さ".stringByAppendingString("\u{3099}"))
|
||||
}
|
||||
|
||||
NSStringAPIs.test("stringByDeletingLastPathComponent") {
|
||||
|
||||
Reference in New Issue
Block a user