Skip to content

Commit f4214ef

Browse files
authored
Merge pull request #2552 from spevans/pr_sr_11687
2 parents facf571 + dd0c273 commit f4214ef

File tree

2 files changed

+21
-2
lines changed

2 files changed

+21
-2
lines changed

Foundation/Scanner.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -381,10 +381,11 @@ extension String {
381381
private func _scan<T: BinaryFloatingPoint>(buffer buf: inout _NSStringBuffer, locale: Locale?, neg: Bool, to: (T) -> Void, base: UInt,
382382
numericValue: ((_: unichar) -> Int?)) -> Bool {
383383
let ds = (locale ?? Locale.current).decimalSeparator?.first ?? Character(".")
384-
var localResult: T = T(0)
384+
var localResult: T! = nil
385385
var neg = neg
386386

387387
while let numeral = numericValue(buf.currentCharacter) {
388+
localResult = localResult ?? T(0)
388389
// if (localResult >= T.greatestFiniteMagnitude / T(10)) && ((localResult > T.greatestFiniteMagnitude / T(10)) || T(numericValue(buf.currentCharacter) - (neg ? 1 : 0)) >= T.greatestFiniteMagnitude - localResult * T(10)) is evidently too complex; so break it down to more "edible chunks"
389390
let limit1 = localResult >= T.greatestFiniteMagnitude / T(base)
390391
let limit2 = localResult > T.greatestFiniteMagnitude / T(base)
@@ -407,12 +408,17 @@ extension String {
407408
var factor = 1 / T(base)
408409
buf.advance()
409410
while let numeral = numericValue(buf.currentCharacter) {
411+
localResult = localResult ?? T(0)
410412
localResult = localResult + T(numeral) * factor
411413
factor = factor / T(base)
412414
buf.advance()
413415
}
414416
}
415417

418+
guard localResult != nil else {
419+
return false
420+
}
421+
416422
// If this is used to parse a number in Hexadecimal, this will never be true as the 'e' or 'E' will be caught by the previous loop.
417423
if buf.currentCharacter == unichar(unicodeScalarLiteral: "e") || buf.currentCharacter == unichar(unicodeScalarLiteral: "E") {
418424
var exponent = Double(0)
@@ -435,7 +441,7 @@ extension String {
435441
}
436442
}
437443
}
438-
444+
439445
to(neg ? T(-1) * localResult : localResult)
440446
return true
441447
}

TestFoundation/TestScanner.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,19 @@ class TestScanner : XCTestCase {
7575
expectEqual($0.scanDouble(), atof("3.14"), "Roundtrip: 1")
7676
expectEqual($0.scanDouble(), atof("-100"), "Roundtrip: 2")
7777
}
78+
79+
withScanner(for: "0.5 bla 0. .1 1e2 e+3 e4") {
80+
expectEqual($0.scanDouble(), 0.5, "Parse '0.5' as Double")
81+
expectEqual($0.scanDouble(), nil, "Dont parse 'bla' as a Double") // "bla" doesnt parse as Double
82+
expectEqual($0.scanString("bla"), "bla", "Consume the 'bla'")
83+
expectEqual($0.scanDouble(), 0, "Parse '0.' as a Double")
84+
expectEqual($0.scanDouble(), 0.1, "Parse '.1' as a Double")
85+
expectEqual($0.scanDouble(), 100, "Parse '1e2' as a Double")
86+
expectEqual($0.scanDouble(), nil, "Dont parse 'e+3' as a Double") // "e+3" doesnt parse as Double
87+
expectEqual($0.scanString("e+3"), "e+3", "Consume the 'e+3'")
88+
expectEqual($0.scanDouble(), nil, "Dont parse 'e4' as a Double'") // "e3" doesnt parse as Double
89+
expectEqual($0.scanString("e4"), "e4", "Consume the 'e4'")
90+
}
7891
}
7992

8093
func testHexRepresentation() {

0 commit comments

Comments
 (0)