Skip to content

Commit 9e3714c

Browse files
committed
fix: char parsing for 1.9 compat
1 parent 6f30615 commit 9e3714c

File tree

5 files changed

+156
-110
lines changed

5 files changed

+156
-110
lines changed

src/conversion.jl

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,11 @@ function Expr_float(x)
121121
end
122122
function Expr_char(x)
123123
val = _unescape_string(valof(x)[2:prevind(valof(x), lastindex(valof(x)))])
124-
# one byte e.g. '\xff' maybe not valid UTF-8
125-
# but we want to use the raw value as a codepoint in this case
126-
sizeof(val) == 1 && return Char(codeunit(val, 1))
124+
if VERSION < v"1.9-"
125+
# one byte e.g. '\xff' maybe not valid UTF-8
126+
# but we want to use the raw value as a codepoint in this case
127+
sizeof(val) == 1 && return Char(codeunit(val, 1))
128+
end
127129
length(val) == 1 || error("Invalid character literal: $(Vector{UInt8}(valof(x)))")
128130
val[1]
129131
end

src/spec.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,6 @@ end
144144
end
145145
end
146146

147-
148-
149147
span(x::EXPR) = x.span
150148

151149
function update_span!(x::EXPR)

src/utils.jl

Lines changed: 73 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -506,41 +506,83 @@ function _unescape_string(io, s::AbstractString)
506506
end
507507
end
508508
end
509-
510-
function valid_escaped_seq(s::AbstractString)
511-
l = length(s)
512-
l == 0 && return false # zero length chars are always invalid
513-
l == 1 && return true # length-one chars are always valid to Julia's parser
514-
a = Iterators.Stateful(s)
515-
if popfirst!(a) == '\\'
516-
c = popfirst!(a)
517-
if c === 'x' || c === 'u' || c === 'U'
518-
maxiter = c === 'x' ? 2 : c === 'u' ? 4 : 8
519-
0 < length(a) <= maxiter || return false
520-
n = 0
521-
while !isempty(a)
522-
nc = popfirst!(a)
523-
n = '0' <= nc <= '9' ? n << 4 + (nc - '0') :
524-
'a' <= nc <= 'f' ? n << 4 + (nc - 'a' + 10) :
525-
'A' <= nc <= 'F' ? n << 4 + (nc - 'A' + 10) : return false
526-
end
527-
return n <= 0x10ffff
528-
elseif '0' <= c <= '7'
529-
length(a) <= 3 || return false
530-
n = c - '0'
531-
while !isempty(a)
532-
nc = popfirst!(a)
533-
n = ('0' <= c <= '7') ? n << 3 + nc - '0' : return false
509+
@static if VERSION < v"1.9-"
510+
function valid_escaped_seq(s::AbstractString)
511+
l = length(s)
512+
l == 0 && return false # zero length chars are always invalid
513+
l == 1 && return true # length-one chars are always valid to Julia's parser
514+
a = Iterators.Stateful(s)
515+
if popfirst!(a) == '\\'
516+
c = popfirst!(a)
517+
if c === 'x' || c === 'u' || c === 'U'
518+
maxiter = c === 'x' ? 2 : c === 'u' ? 4 : 8
519+
0 < length(a) <= maxiter || return false
520+
n = 0
521+
while !isempty(a)
522+
nc = popfirst!(a)
523+
n = '0' <= nc <= '9' ? n << 4 + (nc - '0') :
524+
'a' <= nc <= 'f' ? n << 4 + (nc - 'a' + 10) :
525+
'A' <= nc <= 'F' ? n << 4 + (nc - 'A' + 10) : return false
526+
end
527+
return n <= 0x10ffff
528+
elseif '0' <= c <= '7'
529+
length(a) <= 3 || return false
530+
n = c - '0'
531+
while !isempty(a)
532+
nc = popfirst!(a)
533+
n = ('0' <= c <= '7') ? n << 3 + nc - '0' : return false
534+
end
535+
return n < 128
536+
else
537+
@static if VERSION < v"1.1.0"
538+
c = string(c)
539+
end
540+
return ncodeunits(c) == 1 && isempty(a)
534541
end
535-
return n < 128
536-
else
537-
@static if VERSION < v"1.1.0"
538-
c = string(c)
542+
end
543+
return false
544+
end
545+
else
546+
function valid_escaped_seq(s::AbstractString)
547+
l = length(s)
548+
l == 0 && return false # zero length chars are always invalid
549+
l == 1 && return true # length-one chars are always valid to Julia's parser
550+
a = Iterators.Stateful(s)
551+
ok = false
552+
while !isempty(a)
553+
if popfirst!(a) == '\\'
554+
c = popfirst!(a)
555+
if c === 'x' || c === 'u' || c === 'U'
556+
maxiter = c === 'x' ? 2 : c === 'u' ? 4 : 8
557+
n = 0
558+
for _ in 1:min(length(a), maxiter)
559+
nc = popfirst!(a)
560+
n = '0' <= nc <= '9' ? n << 4 + (nc - '0') :
561+
'a' <= nc <= 'f' ? n << 4 + (nc - 'a' + 10) :
562+
'A' <= nc <= 'F' ? n << 4 + (nc - 'A' + 10) : return false
563+
end
564+
ok = n <= 0x10ffff
565+
elseif '0' <= c <= '7'
566+
n = c - '0'
567+
for _ in 1:min(length(a), 3)
568+
nc = popfirst!(a)
569+
n = ('0' <= c <= '7') ? n << 3 + nc - '0' : return false
570+
end
571+
ok = n < 128
572+
else
573+
@static if VERSION < v"1.1.0"
574+
c = string(c)
575+
end
576+
ok = ncodeunits(c) == 1 && isempty(a)
577+
end
578+
else
579+
return false
539580
end
540-
return ncodeunits(c) == 1 && isempty(a)
581+
582+
!ok && return false
541583
end
584+
return ok
542585
end
543-
return false
544586
end
545587

546588
"""

0 commit comments

Comments
 (0)