Skip to content

Commit

Permalink
allow non-ascii characters in printf format strings (#23899)
Browse files Browse the repository at this point in the history
fixes issue #23880
  • Loading branch information
KlausC authored and JeffBezanson committed Sep 29, 2017
1 parent 5da628f commit 49cbf5a
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 7 deletions.
15 changes: 8 additions & 7 deletions base/printf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,24 @@ end
### printf format string parsing ###

function parse(s::AbstractString)
# parse format string in to stings and format tuples
# parse format string into strings and format tuples
list = []
i = j = start(s)
j1 = 0 # invariant: j1 == prevind(s, j)
while !done(s,j)
c, k = next(s,j)
if c == '%'
isempty(s[i:j-1]) || push!(list, s[i:j-1])
i > j1 || push!(list, s[i:j1])
flags, width, precision, conversion, k = parse1(s,k)
'\'' in flags && error("printf format flag ' not yet supported")
conversion == 'n' && error("printf feature %n not supported")
push!(list, conversion == '%' ? "%" : (flags,width,precision,conversion))
i = j = k
else
j = k
i = k
end
j1 = j
j = k
end
isempty(s[i:end]) || push!(list, s[i:end])
i > endof(s) || push!(list, s[i:end])
# coalesce adjacent strings
i = 1
while i < length(list)
Expand Down Expand Up @@ -98,7 +99,7 @@ function parse1(s::AbstractString, k::Integer)
while c in "#0- + '"
c, k = next_or_die(s,k)
end
flags = String(s[j:k-2])
flags = String(s[j:prevind(s,k)-1]) # exploiting that all flags are one-byte.
# parse width
while '0' <= c <= '9'
width = 10*width + c-'0'
Expand Down
15 changes: 15 additions & 0 deletions test/printf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -272,3 +272,18 @@ end

# Check bug with trailing nul printing BigFloat
@test (@sprintf("%.330f", BigFloat(1)))[end] != '\0'

# Check utf8 strings #23880
@test (@sprintf("X%d", 2)) == "X2"
@test (@sprintf("\u00d0%d", 2)) == "\u00d02"
@test (@sprintf("\u0f00%d", 2)) == "\u0f002"
@test (@sprintf("\U0001ffff%d", 2)) == "\U0001ffff2"
@test (@sprintf("%dX%d", 1, 2)) == "1X2"
@test (@sprintf("%d\u00d0%d", 1, 2)) == "1\u00d02"
@test (@sprintf("%d\u0f00%d", 1, 2)) == "1\u0f002"
@test (@sprintf("%d\U0001ffff%d", 1, 2)) == "1\U0001ffff2"
@test (@sprintf("%d\u2203%d\u0203", 1, 2)) == "1\u22032\u0203"
@test_throws ArgumentError @macroexpand(@sprintf("%y%d", 1, 2))
@test_throws ArgumentError @macroexpand(@sprintf("%\u00d0%d", 1, 2))
@test_throws ArgumentError @macroexpand(@sprintf("%\u0f00%d", 1, 2))
@test_throws ArgumentError @macroexpand(@sprintf("%\U0001ffff%d", 1, 2))

0 comments on commit 49cbf5a

Please sign in to comment.