Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 11 additions & 32 deletions base/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,38 +38,16 @@ julia> parse(Complex{Float64}, "3.2e-1 + 4.5im")
parse(T::Type, str; base = Int)
parse(::Type{Union{}}, slurp...; kwargs...) = error("cannot parse a value as Union{}")

@noinline function _invalid_base(base)
throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base"))
end

@noinline _invalid_digit(base, char) = throw(ArgumentError("invalid base $base digit $(repr(char))"))

function parse_char(::Type{T}, c::AbstractChar, base::Integer, throw::Bool) where T
a::UInt8 = (base <= 36 ? 10 : 36)
(2 <= base <= 62) || _invalid_base(base)
base = base % UInt8
cp = codepoint(c)
cp = cp > 0x7a ? 0xff : cp % UInt8
d = UInt8('0') cp UInt8('9') ? cp - UInt8('0') :
UInt8('A') cp UInt8('Z') ? cp - UInt8('A') + UInt8(10) :
UInt8('a') cp UInt8('z') ? cp - UInt8('a') + a :
0xff
d < base || (throw ? _invalid_digit(base, c) : return nothing)
convert(T, d)::T
end

function parse(::Type{T}, c::AbstractChar; base::Integer=10) where {T <: Integer}
@inline parse_char(T, c, base, true)
function parse(::Type{T}, c::AbstractChar; base::Integer = 10) where T<:Integer
a::Int = (base <= 36 ? 10 : 36)
2 <= base <= 62 || throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base"))
d = '0' <= c <= '9' ? c-'0' :
'A' <= c <= 'Z' ? c-'A'+10 :
'a' <= c <= 'z' ? c-'a'+a : throw(ArgumentError("invalid digit: $(repr(c))"))
d < base || throw(ArgumentError("invalid base $base digit $(repr(c))"))
convert(T, d)
end

function tryparse(::Type{T}, c::AbstractChar; base::Integer=10) where {T <: Integer}
@inline parse_char(T, c, base, false)
end

# For consistency with parse(t, AbstractString), support a `base` argument only when T<:Integer
parse(::Type{T}, c::AbstractChar) where T = @inline parse_char(T, c, 10, true)
tryparse(::Type{T}, c::AbstractChar) where T = @inline parse_char(T, c, 10, false)

function parseint_iterate(s::AbstractString, startpos::Int, endpos::Int)
(0 < startpos <= endpos) || (return Char(0), 0, 0)
j = startpos
Expand Down Expand Up @@ -138,7 +116,8 @@ function tryparse_internal(::Type{T}, s::AbstractString, startpos::Int, endpos::
return nothing
end
if !(2 <= base <= 62)
raise ? _invalid_base(base) : return nothing
raise && throw(ArgumentError(LazyString("invalid base: base must be 2 ≤ base ≤ 62, got ", base)))
return nothing
end
if i == 0
raise && throw(ArgumentError("premature end of integer: $(repr(SubString(s,startpos,endpos)))"))
Expand Down Expand Up @@ -257,7 +236,7 @@ end
if 2 <= base <= 62
return base
end
_invalid_base(base)
throw(ArgumentError("invalid base: base must be 2 ≤ base ≤ 62, got $base"))
end

"""
Expand Down
1 change: 0 additions & 1 deletion base/public.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

public
# Modules
Cartesian,
Checked,
Filesystem,
Order,
Expand Down
7 changes: 0 additions & 7 deletions test/parse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,6 @@
@test parse(Int, 'a', base=16) == 10
@test_throws ArgumentError parse(Int, 'a')
@test_throws ArgumentError parse(Int,typemax(Char))

@test tryparse(Int, '8') === 8
@test tryparse(Int, 'a') === nothing
@test tryparse(Int, 'a'; base=11) === 10
@test tryparse(Int32, 'a'; base=11) === Int32(10)
@test tryparse(UInt8, 'f'; base=16) === 0x0f
@test tryparse(UInt8, 'f'; base=15) === nothing
end

# Issue 29451
Expand Down
Loading