Skip to content

Commit 9151f80

Browse files
committed
Fix issue #27, world age problem on v0.6
Update tests for v0.6
1 parent 452aa89 commit 9151f80

File tree

2 files changed

+80
-13
lines changed

2 files changed

+80
-13
lines changed

src/cformat.jl

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,80 @@
11
formatters = Dict{ Compat.ASCIIString, Function }()
22

3-
function sprintf1( fmt::Compat.ASCIIString, x )
3+
@static if VERSION >= v"0.6-"
4+
5+
sprintf1( fmt::Compat.ASCIIString, x ) = eval(Expr(:call, generate_formatter( fmt ), x))
6+
7+
function checkfmt(fmt)
8+
test = Base.Printf.parse( fmt )
9+
(length( test ) == 1 && typeof( test[1] ) <: Tuple) ||
10+
error( "Only one AND undecorated format string is allowed")
11+
end
12+
13+
function generate_formatter( fmt::Compat.ASCIIString )
414
global formatters
5-
f = generate_formatter( fmt )
6-
f( x )
15+
16+
haskey( formatters, fmt ) && return formatters[fmt]
17+
18+
if !contains( fmt, "'" )
19+
checkfmt(fmt)
20+
return (formatters[ fmt ] = @eval(x->@sprintf( $fmt, x )))
21+
end
22+
23+
conversion = fmt[end]
24+
conversion in "sduifF" ||
25+
error( string("thousand separator not defined for ", conversion, " conversion") )
26+
27+
fmtactual = replace( fmt, "'", "", 1 )
28+
checkfmt( fmtactual )
29+
conversion in "sfF" ||
30+
return (formatters[ fmt ] = @eval(x->checkcommas(@sprintf( $fmtactual, x ))))
31+
32+
formatters[ fmt ] =
33+
if endswith( fmtactual, 's')
34+
@eval((x::Real)->((eltype(x) <: Rational)
35+
? addcommasrat(@sprintf( $fmtactual, x ))
36+
: addcommasreal(@sprintf( $fmtactual, x ))))
37+
else
38+
@eval((x::Real)->addcommasreal(@sprintf( $fmtactual, x )))
39+
end
740
end
841

42+
function addcommasreal(s)
43+
dpos = findfirst( s, '.' )
44+
dpos != 0 && return string(addcommas( s[1:dpos-1] ), s[ dpos:end ])
45+
# find the rightmost digit
46+
for i in length( s ):-1:1
47+
isdigit( s[i] ) && return string(addcommas( s[1:i] ), s[i+1:end])
48+
end
49+
s
50+
end
51+
52+
function addcommasrat(s)
53+
# commas are added to only the numerator
54+
spos = findfirst( s, '/' )
55+
string(addcommas( s[1:spos-1] ), s[spos:end])
56+
end
57+
58+
function checkcommas(s)
59+
for i in length( s ):-1:1
60+
if isdigit( s[i] )
61+
s = string(addcommas( s[1:i] ), s[i+1:end])
62+
break
63+
end
64+
end
65+
s
66+
end
67+
68+
else
69+
70+
sprintf1( fmt::Compat.ASCIIString, x ) = (generate_formatter( fmt ))(x)
71+
972
function generate_formatter( fmt::Compat.ASCIIString )
1073
global formatters
1174
if haskey( formatters, fmt )
1275
return formatters[fmt]
1376
end
77+
1478
func = @compat Symbol("sprintf_", replace(base64encode(fmt), "=", "!"))
1579

1680
if !contains( fmt, "'" )
@@ -77,6 +141,7 @@ function generate_formatter( fmt::Compat.ASCIIString )
77141
formatters[ fmt ] = f
78142
f
79143
end
144+
end
80145

81146
function addcommas( s::Compat.ASCIIString )
82147
len = length(s)

test/cformat.jl

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,13 @@ _erfinv(z) = sqrt(π) * Base.Math.@horner(z, 0, 1, 0, π/12, 0, 7π^2/480, 0, 12
88
function test_equality()
99
println( "test cformat equality...")
1010
srand(10)
11-
fmts = Compat.ASCIIString[ "%10.4f", "%f", "%e", "%10f", "%.3f", "%.3e" ]
12-
for fmt in fmts
13-
l = :( x-> x )
14-
l.args[2].args[2] = @compat Expr(:macrocall, Symbol("@sprintf"), fmt, :x)
15-
mfmtr = eval( l )
11+
fmts = [ (x->@sprintf("%10.4f",x), "%10.4f"),
12+
(x->@sprintf("%f", x), "%f"),
13+
(x->@sprintf("%e", x), "%e"),
14+
(x->@sprintf("%10f", x), "%10f"),
15+
(x->@sprintf("%.3f", x), "%.3f"),
16+
(x->@sprintf("%.3e", x), "%.3e")]
17+
for (mfmtr,fmt) in fmts
1618
for i in 1:10000
1719
n = _erfinv( rand() * 1.99 - 1.99/2.0 )
1820
expect = mfmtr( n )
@@ -21,11 +23,11 @@ function test_equality()
2123
end
2224
end
2325

24-
fmts = Compat.ASCIIString[ "%d", "%10d", "%010d", "%-10d" ]
25-
for fmt in fmts
26-
l = :( x-> x )
27-
l.args[2].args[2] = @compat Expr(:macrocall, Symbol("@sprintf"), fmt, :x)
28-
mfmtr = eval( l )
26+
fmts = [ (x->@sprintf("%d",x), "%d"),
27+
(x->@sprintf("%10d",x), "%10d"),
28+
(x->@sprintf("%010d",x), "%010d"),
29+
(x->@sprintf("%-10d",x), "%-10d")]
30+
for (mfmtr,fmt) in fmts
2931
for i in 1:10000
3032
j = round(Int, _erfinv( rand() * 1.99 - 1.99/2.0 ) * 100000 )
3133
expect = mfmtr( j )

0 commit comments

Comments
 (0)