Skip to content

Commit 30665d6

Browse files
committed
rename to tryparse. call tryparse for floatNN_isvalid methods
1 parent 7f8b140 commit 30665d6

File tree

5 files changed

+80
-122
lines changed

5 files changed

+80
-122
lines changed

base/exports.jl

+1-3
Original file line numberDiff line numberDiff line change
@@ -355,9 +355,7 @@ export
355355
fldmod,
356356
flipsign,
357357
float,
358-
maybefloat32,
359-
maybefloat64,
360-
maybeint,
358+
tryparse,
361359
floor,
362360
fma,
363361
frexp,

base/gmp.jl

+6-9
Original file line numberDiff line numberDiff line change
@@ -76,28 +76,25 @@ signed(x::BigInt) = x
7676
BigInt(x::BigInt) = x
7777
BigInt(s::AbstractString) = parseint(BigInt,s)
7878

79-
function parse_bigint(s::AbstractString, base::Int, nothrow::Bool)
79+
function Base.tryparse_internal(::Type{BigInt}, s::AbstractString, base::Int, raise::Bool=false)
8080
_n = Nullable{BigInt}()
8181
s = bytestring(s)
8282
sgn, base, i = Base.parseint_preamble(true,s,base)
8383
if i == 0
84-
nothrow && return _n
85-
throw(ArgumentError("premature end of integer: $(repr(s))"))
84+
raise && throw(ArgumentError("premature end of integer: $(repr(s))"))
85+
return _n
8686
end
8787
z = BigInt()
8888
err = ccall((:__gmpz_set_str, :libgmp),
8989
Int32, (Ptr{BigInt}, Ptr{UInt8}, Int32),
9090
&z, SubString(s,i), base)
9191
if err != 0
92-
nothrow && return _n
93-
throw(ArgumentError("invalid BigInt: $(repr(s))"))
92+
raise && throw(ArgumentError("invalid BigInt: $(repr(s))"))
93+
return _n
9494
end
9595
Nullable(sgn < 0 ? -z : z)
9696
end
9797

98-
Base.maybeint_internal(::Type{BigInt}, s::AbstractString, base::Int) = parse_bigint(s, base, true)
99-
Base.parseint_nocheck(::Type{BigInt}, s::AbstractString, base::Int) = get(parse_bigint(s, base, false))
100-
10198
function BigInt(x::Union(Clong,Int32))
10299
z = BigInt()
103100
ccall((:__gmpz_set_si, :libgmp), Void, (Ptr{BigInt}, Clong), &z, x)
@@ -228,7 +225,7 @@ function serialize(s, n::BigInt)
228225
serialize(s, base(62,n))
229226
end
230227

231-
deserialize(s, ::Type{BigInt}) = Base.parseint_nocheck(BigInt, deserialize(s), 62)
228+
deserialize(s, ::Type{BigInt}) = (Base.tryparse_internal(BigInt, deserialize(s), 62, true)).value
232229

233230
# Binary ops
234231
for (fJ, fC) in ((:+, :add), (:-,:sub), (:*, :mul),

base/string.jl

+57-94
Original file line numberDiff line numberDiff line change
@@ -1537,12 +1537,18 @@ safe_mul{T<:Integer}(n1::T, n2::T) = ((n2 > 0) ? ((n1 > div(typemax(T),n2)) ||
15371537
#safe_div{T<:Integer}(n1::T, n2::T) = ((n1 == typemin(T)) && (n2 == T(-1))) ? Nullable{T}() : Nullable{T}(div(n1, n2))
15381538
#safe_abs{T<:Integer}(n::T) = (n == typemin(T)) ? Nullable{T}() : abs(n)
15391539

1540-
function maybeint_internal{T<:Integer}(::Type{T}, s::AbstractString, base::Int, a::Int)
1540+
function tryparse_internal{T<:Integer}(::Type{T}, s::AbstractString, base::Int, a::Int, raise::Bool=false)
15411541
_n = Nullable{T}()
15421542
sgn, base, i = parseint_preamble(T<:Signed,s,base)
1543-
(i == 0) && return _n
1543+
if i == 0
1544+
raise && throw(ArgumentError("premature end of integer: $(repr(s))"))
1545+
return _n
1546+
end
15441547
c, i = parseint_next(s,i)
1545-
(i == 0) && return _n
1548+
if i == 0
1549+
raise && throw(ArgumentError("premature end of integer: $(repr(s))"))
1550+
return _n
1551+
end
15461552

15471553
base = convert(T,base)
15481554
m::T = div(typemax(T)-base+1,base)
@@ -1551,7 +1557,10 @@ function maybeint_internal{T<:Integer}(::Type{T}, s::AbstractString, base::Int,
15511557
d::T = '0' <= c <= '9' ? c-'0' :
15521558
'A' <= c <= 'Z' ? c-'A'+10 :
15531559
'a' <= c <= 'z' ? c-'a'+a : base
1554-
d < base || return _n
1560+
if d >= base
1561+
raise && throw(ArgumentError("invalid base $base digit $(repr(c)) in $(repr(s))"))
1562+
return _n
1563+
end
15551564
n *= base
15561565
n += d
15571566
if done(s,i)
@@ -1566,124 +1575,78 @@ function maybeint_internal{T<:Integer}(::Type{T}, s::AbstractString, base::Int,
15661575
d::T = '0' <= c <= '9' ? c-'0' :
15671576
'A' <= c <= 'Z' ? c-'A'+10 :
15681577
'a' <= c <= 'z' ? c-'a'+a : base
1569-
d < base || return _n
1578+
if d >= base
1579+
raise && throw(ArgumentError("invalid base $base digit $(repr(c)) in $(repr(s))"))
1580+
return _n
1581+
end
15701582
(T <: Signed) && (d *= sgn)
15711583

15721584
safe_n = safe_mul(n, base)
1573-
isnull(safe_n) || (safe_n = safe_add(get(safe_n), d))
1574-
isnull(safe_n) && return Nullable{T}()
1575-
n = get(safe_n)
1585+
safe_n.isnull || (safe_n = safe_add(safe_n.value, d))
1586+
if safe_n.isnull
1587+
raise && throw(OverflowError())
1588+
return _n
1589+
end
1590+
n = safe_n.value
15761591
done(s,i) && return Nullable{T}(n)
15771592
c, i = next(s,i)
15781593
end
15791594
while !done(s,i)
15801595
c, i = next(s,i)
1581-
isspace(c) || return _n
1596+
if !isspace(c)
1597+
raise && throw(ArgumentError("extra characters after whitespace in $(repr(s))"))
1598+
return _n
1599+
end
15821600
end
15831601
return Nullable{T}(n)
15841602
end
1585-
maybeint_internal{T<:Integer}(::Type{T}, s::AbstractString, base::Int) =
1586-
maybeint_internal(T, s, base, base <= 36 ? 10 : 36)
1587-
maybeint{T<:Integer}(::Type{T}, s::AbstractString) = maybeint_internal(T,s,0)
1603+
tryparse_internal{T<:Integer}(::Type{T}, s::AbstractString, base::Int, raise::Bool=false) =
1604+
tryparse_internal(T, s, base, base <= 36 ? 10 : 36, raise)
1605+
tryparse{T<:Integer}(::Type{T}, s::AbstractString, base::Int) =
1606+
2 <= base <= 62 ? tryparse_internal(T,s,Int(base)) : throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base"))
1607+
tryparse{T<:Integer}(::Type{T}, s::AbstractString) = tryparse_internal(T,s,0)
15881608

1589-
function parseint_nocheck{T<:Integer}(::Type{T}, s::AbstractString, base::Int, a::Int)
1590-
sgn, base, i = parseint_preamble(T<:Signed,s,base)
1591-
(i == 0) && throw(ArgumentError("premature end of integer: $(repr(s))"))
1592-
1593-
c, i = parseint_next(s,i)
1594-
(i == 0) && throw(ArgumentError("premature end of integer: $(repr(s))"))
1595-
1596-
base = convert(T,base)
1597-
## FIXME: remove 128-bit specific code once 128-bit div doesn't rely on BigInt
1598-
m::T = T===UInt128 || T===Int128 ? typemax(T) : div(typemax(T)-base+1,base)
1599-
n::T = 0
1600-
while n <= m
1601-
d::T = '0' <= c <= '9' ? c-'0' :
1602-
'A' <= c <= 'Z' ? c-'A'+10 :
1603-
'a' <= c <= 'z' ? c-'a'+a : base
1604-
d < base || throw(ArgumentError("invalid base $base digit $(repr(c)) in $(repr(s))"))
1605-
n *= base
1606-
n += d
1607-
if done(s,i)
1608-
n *= sgn
1609-
return n
1610-
end
1611-
c, i = next(s,i)
1612-
isspace(c) && break
1613-
end
1614-
(T <: Signed) && (n *= sgn)
1615-
while !isspace(c)
1616-
d::T = '0' <= c <= '9' ? c-'0' :
1617-
'A' <= c <= 'Z' ? c-'A'+10 :
1618-
'a' <= c <= 'z' ? c-'a'+a : base
1619-
d < base || throw(ArgumentError("invalid base $base digit $(repr(c)) in $(repr(s))"))
1620-
(T <: Signed) && (d *= sgn)
1621-
n = checked_mul(n,base)
1622-
n = checked_add(n,d)
1623-
done(s,i) && return n
1624-
c, i = next(s,i)
1625-
end
1626-
while !done(s,i)
1627-
c, i = next(s,i)
1628-
isspace(c) || throw(ArgumentError("extra characters after whitespace in $(repr(s))"))
1629-
end
1630-
return n
1609+
function parseint{T<:Integer}(::Type{T}, s::AbstractString, base::Integer)
1610+
(2 <= base <= 62) || throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base"))
1611+
(tryparse_internal(T, s, base, true)).value
16311612
end
1632-
parseint_nocheck{T<:Integer}(::Type{T}, s::AbstractString, base::Int) =
1633-
parseint_nocheck(T, s, base, base <= 36 ? 10 : 36)
1634-
1635-
parseint{T<:Integer}(::Type{T}, s::AbstractString, base::Integer) =
1636-
2 <= base <= 62 ? parseint_nocheck(T,s,Int(base)) : throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base"))
1637-
parseint{T<:Integer}(::Type{T}, s::AbstractString) = parseint_nocheck(T,s,0)
1613+
parseint{T<:Integer}(::Type{T}, s::AbstractString) = (tryparse_internal(T, s, 0, true)).value
16381614
parseint(s::AbstractString, base::Integer) = parseint(Int,s,base)
1639-
parseint(s::AbstractString) = parseint_nocheck(Int,s,0)
1615+
parseint(s::AbstractString) = parseint(Int,s)
16401616

16411617
## stringifying integers more efficiently ##
16421618

16431619
string(x::Union(Int8,Int16,Int32,Int64,Int128)) = dec(x)
16441620

16451621
## string to float functions ##
16461622

1647-
float64_isvalid(s::AbstractString, out::Array{Float64,1}) =
1648-
ccall(:jl_strtod, Int32, (Ptr{UInt8},Ptr{Float64}), s, out) == 0
1649-
float32_isvalid(s::AbstractString, out::Array{Float32,1}) =
1650-
ccall(:jl_strtof, Int32, (Ptr{UInt8},Ptr{Float32}), s, out) == 0
1651-
1652-
float64_isvalid(s::SubString, out::Array{Float64,1}) =
1653-
ccall(:jl_substrtod, Int32, (Ptr{UInt8},Csize_t,Cint,Ptr{Float64}), s.string, s.offset, s.endof, out) == 0
1654-
float32_isvalid(s::SubString, out::Array{Float32,1}) =
1655-
ccall(:jl_substrtof, Int32, (Ptr{UInt8},Csize_t,Cint,Ptr{Float32}), s.string, s.offset, s.endof, out) == 0
1656-
1657-
begin
1658-
local tmp::Array{Float64,1} = Array(Float64,1)
1659-
local tmpf::Array{Float32,1} = Array(Float32,1)
1660-
global parsefloat
1661-
function parsefloat(::Type{Float64}, s::AbstractString)
1662-
if !float64_isvalid(s, tmp)
1663-
throw(ArgumentError("parsefloat(Float64,::AbstractString): invalid number format $(repr(s))"))
1664-
end
1665-
return tmp[1]
1666-
end
1623+
tryparse(::Type{Float64}, s::AbstractString) = ccall(:jl_try_strtod, Nullable{Float64}, (Ptr{UInt8},), s)
1624+
tryparse(::Type{Float64}, s::SubString) = ccall(:jl_try_substrtod, Nullable{Float64}, (Ptr{UInt8},Csize_t,Cint), s.string, s.offset, s.endof)
16671625

1668-
function parsefloat(::Type{Float32}, s::AbstractString)
1669-
if !float32_isvalid(s, tmpf)
1670-
throw(ArgumentError("parsefloat(Float32,::AbstractString): invalid number format $(repr(s))"))
1671-
end
1672-
return tmpf[1]
1673-
end
1674-
end
1626+
tryparse(::Type{Float32}, s::AbstractString) = ccall(:jl_try_strtof, Nullable{Float32}, (Ptr{UInt8},), s)
1627+
tryparse(::Type{Float32}, s::SubString) = ccall(:jl_try_substrtof, Nullable{Float32}, (Ptr{UInt8},Csize_t,Cint), s.string, s.offset, s.endof)
16751628

1676-
float(x::AbstractString) = parsefloat(x)
1677-
parsefloat(x::AbstractString) = parsefloat(Float64,x)
1629+
function parse{T<:Union(Float32,Float64)}(::Type{T}, s::AbstractString)
1630+
nf = tryparse(T, s)
1631+
nf.isnull ? throw(ArgumentError("invalid number format $(repr(s)) for $T")) : nf.value
1632+
end
16781633

1679-
maybefloat64(s::AbstractString) = ccall(:jl_maybe_strtod, Nullable{Float64}, (Ptr{UInt8},), s)
1680-
maybefloat64(s::SubString) = ccall(:jl_maybe_substrtod, Nullable{Float64}, (Ptr{UInt8},Csize_t,Cint), s.string, s.offset, s.endof)
1634+
parsefloat{T<:Union(Float32,Float64)}(::Type{T}, s::AbstractString) = parse(T,s)
16811635

1682-
maybefloat32(s::AbstractString) = ccall(:jl_maybe_strtof, Nullable{Float32}, (Ptr{UInt8},), s)
1683-
maybefloat32(s::SubString) = ccall(:jl_maybe_substrtof, Nullable{Float32}, (Ptr{UInt8},Csize_t,Cint), s.string, s.offset, s.endof)
1636+
float(x::AbstractString) = parse(Float64,x)
1637+
parsefloat(x::AbstractString) = parse(Float64,x)
16841638

16851639
float{S<:AbstractString}(a::AbstractArray{S}) = map!(float, similar(a,typeof(float(0))), a)
16861640

1641+
function float_isvalid{T<:Union(Float32,Float64)}(s::AbstractString, out::Array{T,1})
1642+
tf = tryparse(T, s)
1643+
tf.isnull || (out[1] = tf.value)
1644+
!(tf.isnull)
1645+
end
1646+
1647+
float32_isvalid(s::AbstractString, out::Array{Float32,1}) = float_isvalid(s, out)
1648+
float64_isvalid(s::AbstractString, out::Array{Float64,1}) = float_isvalid(s, out)
1649+
16871650
# find the index of the first occurrence of a value in a byte array
16881651

16891652
typealias ByteArray Union(Array{UInt8,1},Array{Int8,1})

src/builtins.c

+8-8
Original file line numberDiff line numberDiff line change
@@ -757,7 +757,7 @@ int str_isspace(char *p) {
757757
return 1;
758758
}
759759

760-
DLLEXPORT jl_nullable_float64_t jl_maybe_substrtod(char *str, size_t offset, int len)
760+
DLLEXPORT jl_nullable_float64_t jl_try_substrtod(char *str, size_t offset, int len)
761761
{
762762
char *p;
763763
char *bstr = str+offset;
@@ -793,7 +793,7 @@ DLLEXPORT jl_nullable_float64_t jl_maybe_substrtod(char *str, size_t offset, int
793793
return (jl_nullable_float64_t){(uint8_t)err, out};
794794
}
795795

796-
DLLEXPORT jl_nullable_float64_t jl_maybe_strtod(char *str)
796+
DLLEXPORT jl_nullable_float64_t jl_try_strtod(char *str)
797797
{
798798
char *p;
799799
int err = 0;
@@ -816,7 +816,7 @@ DLLEXPORT jl_nullable_float64_t jl_maybe_strtod(char *str)
816816

817817
DLLEXPORT int jl_substrtod(char *str, size_t offset, int len, double *out)
818818
{
819-
jl_nullable_float64_t nd = jl_maybe_substrtod(str, offset, len);
819+
jl_nullable_float64_t nd = jl_try_substrtod(str, offset, len);
820820
if(0 == nd.isnull) {
821821
*out = nd.value;
822822
return 0;
@@ -826,7 +826,7 @@ DLLEXPORT int jl_substrtod(char *str, size_t offset, int len, double *out)
826826

827827
DLLEXPORT int jl_strtod(char *str, double *out)
828828
{
829-
jl_nullable_float64_t nd = jl_maybe_strtod(str);
829+
jl_nullable_float64_t nd = jl_try_strtod(str);
830830
if(0 == nd.isnull) {
831831
*out = nd.value;
832832
return 0;
@@ -839,7 +839,7 @@ DLLEXPORT int jl_strtod(char *str, double *out)
839839
#define HUGE_VALF (1e25f * 1e25f)
840840
#endif
841841

842-
DLLEXPORT jl_nullable_float32_t jl_maybe_substrtof(char *str, size_t offset, int len)
842+
DLLEXPORT jl_nullable_float32_t jl_try_substrtof(char *str, size_t offset, int len)
843843
{
844844
char *p;
845845
char *bstr = str+offset;
@@ -879,7 +879,7 @@ DLLEXPORT jl_nullable_float32_t jl_maybe_substrtof(char *str, size_t offset, int
879879
return (jl_nullable_float32_t){(uint8_t)err, out};
880880
}
881881

882-
DLLEXPORT jl_nullable_float32_t jl_maybe_strtof(char *str)
882+
DLLEXPORT jl_nullable_float32_t jl_try_strtof(char *str)
883883
{
884884
char *p;
885885
int err = 0;
@@ -905,7 +905,7 @@ DLLEXPORT jl_nullable_float32_t jl_maybe_strtof(char *str)
905905

906906
DLLEXPORT int jl_substrtof(char *str, int offset, int len, float *out)
907907
{
908-
jl_nullable_float32_t nf = jl_maybe_substrtof(str, offset, len);
908+
jl_nullable_float32_t nf = jl_try_substrtof(str, offset, len);
909909
if(0 == nf.isnull) {
910910
*out = nf.value;
911911
return 0;
@@ -915,7 +915,7 @@ DLLEXPORT int jl_substrtof(char *str, int offset, int len, float *out)
915915

916916
DLLEXPORT int jl_strtof(char *str, float *out)
917917
{
918-
jl_nullable_float32_t nf = jl_maybe_strtof(str);
918+
jl_nullable_float32_t nf = jl_try_strtof(str);
919919
if(0 == nf.isnull) {
920920
*out = nf.value;
921921
return 0;

test/strings.jl

+8-8
Original file line numberDiff line numberDiff line change
@@ -1409,21 +1409,21 @@ gstr = Base.GenericString("12");
14091409
for T in [Int8, UInt8, Int16, UInt16, Int32, UInt32, Int64, UInt64, Int128, UInt128]
14101410
for i in [typemax(T), typemin(T)]
14111411
s = "$i"
1412-
@test get(maybeint(T, s)) == i
1412+
@test get(tryparse(T, s)) == i
14131413
end
14141414
end
14151415

14161416
for T in [Int8, Int16, Int32, Int64, Int128]
14171417
for i in [typemax(T), typemin(T)]
14181418
f = "$(i)0"
1419-
@test isnull(maybeint(T, f))
1419+
@test isnull(tryparse(T, f))
14201420
end
14211421
end
14221422

1423-
@test get(maybeint(BigInt, "1234567890")) == BigInt(1234567890)
1424-
@test isnull(maybeint(BigInt, "1234567890-"))
1423+
@test get(tryparse(BigInt, "1234567890")) == BigInt(1234567890)
1424+
@test isnull(tryparse(BigInt, "1234567890-"))
14251425

1426-
@test get(maybefloat64("64")) == 64.0
1427-
@test isnull(maybefloat64("64o"))
1428-
@test get(maybefloat32("32")) == 32.0f0
1429-
@test isnull(maybefloat32("32o"))
1426+
@test get(tryparse(Float64, "64")) == 64.0
1427+
@test isnull(tryparse(Float64, "64o"))
1428+
@test get(tryparse(Float32, "32")) == 32.0f0
1429+
@test isnull(tryparse(Float32, "32o"))

0 commit comments

Comments
 (0)