From 9151f8029101c9ea45eebb562877b0455d4f1721 Mon Sep 17 00:00:00 2001 From: ScottPJones Date: Sat, 28 Jan 2017 08:29:41 -0500 Subject: [PATCH 1/4] Fix issue #27, world age problem on v0.6 Update tests for v0.6 --- src/cformat.jl | 71 ++++++++++++++++++++++++++++++++++++++++++++++--- test/cformat.jl | 22 ++++++++------- 2 files changed, 80 insertions(+), 13 deletions(-) diff --git a/src/cformat.jl b/src/cformat.jl index 31fef5b..7307fab 100644 --- a/src/cformat.jl +++ b/src/cformat.jl @@ -1,16 +1,80 @@ formatters = Dict{ Compat.ASCIIString, Function }() -function sprintf1( fmt::Compat.ASCIIString, x ) +@static if VERSION >= v"0.6-" + +sprintf1( fmt::Compat.ASCIIString, x ) = eval(Expr(:call, generate_formatter( fmt ), x)) + +function checkfmt(fmt) + test = Base.Printf.parse( fmt ) + (length( test ) == 1 && typeof( test[1] ) <: Tuple) || + error( "Only one AND undecorated format string is allowed") +end + +function generate_formatter( fmt::Compat.ASCIIString ) global formatters - f = generate_formatter( fmt ) - f( x ) + + haskey( formatters, fmt ) && return formatters[fmt] + + if !contains( fmt, "'" ) + checkfmt(fmt) + return (formatters[ fmt ] = @eval(x->@sprintf( $fmt, x ))) + end + + conversion = fmt[end] + conversion in "sduifF" || + error( string("thousand separator not defined for ", conversion, " conversion") ) + + fmtactual = replace( fmt, "'", "", 1 ) + checkfmt( fmtactual ) + conversion in "sfF" || + return (formatters[ fmt ] = @eval(x->checkcommas(@sprintf( $fmtactual, x )))) + + formatters[ fmt ] = + if endswith( fmtactual, 's') + @eval((x::Real)->((eltype(x) <: Rational) + ? addcommasrat(@sprintf( $fmtactual, x )) + : addcommasreal(@sprintf( $fmtactual, x )))) + else + @eval((x::Real)->addcommasreal(@sprintf( $fmtactual, x ))) + end end +function addcommasreal(s) + dpos = findfirst( s, '.' ) + dpos != 0 && return string(addcommas( s[1:dpos-1] ), s[ dpos:end ]) + # find the rightmost digit + for i in length( s ):-1:1 + isdigit( s[i] ) && return string(addcommas( s[1:i] ), s[i+1:end]) + end + s +end + +function addcommasrat(s) + # commas are added to only the numerator + spos = findfirst( s, '/' ) + string(addcommas( s[1:spos-1] ), s[spos:end]) +end + +function checkcommas(s) + for i in length( s ):-1:1 + if isdigit( s[i] ) + s = string(addcommas( s[1:i] ), s[i+1:end]) + break + end + end + s +end + +else + +sprintf1( fmt::Compat.ASCIIString, x ) = (generate_formatter( fmt ))(x) + function generate_formatter( fmt::Compat.ASCIIString ) global formatters if haskey( formatters, fmt ) return formatters[fmt] end + func = @compat Symbol("sprintf_", replace(base64encode(fmt), "=", "!")) if !contains( fmt, "'" ) @@ -77,6 +141,7 @@ function generate_formatter( fmt::Compat.ASCIIString ) formatters[ fmt ] = f f end +end function addcommas( s::Compat.ASCIIString ) len = length(s) diff --git a/test/cformat.jl b/test/cformat.jl index d6f7932..15b396f 100644 --- a/test/cformat.jl +++ b/test/cformat.jl @@ -8,11 +8,13 @@ _erfinv(z) = sqrt(π) * Base.Math.@horner(z, 0, 1, 0, π/12, 0, 7π^2/480, 0, 12 function test_equality() println( "test cformat equality...") srand(10) - fmts = Compat.ASCIIString[ "%10.4f", "%f", "%e", "%10f", "%.3f", "%.3e" ] - for fmt in fmts - l = :( x-> x ) - l.args[2].args[2] = @compat Expr(:macrocall, Symbol("@sprintf"), fmt, :x) - mfmtr = eval( l ) + fmts = [ (x->@sprintf("%10.4f",x), "%10.4f"), + (x->@sprintf("%f", x), "%f"), + (x->@sprintf("%e", x), "%e"), + (x->@sprintf("%10f", x), "%10f"), + (x->@sprintf("%.3f", x), "%.3f"), + (x->@sprintf("%.3e", x), "%.3e")] + for (mfmtr,fmt) in fmts for i in 1:10000 n = _erfinv( rand() * 1.99 - 1.99/2.0 ) expect = mfmtr( n ) @@ -21,11 +23,11 @@ function test_equality() end end - fmts = Compat.ASCIIString[ "%d", "%10d", "%010d", "%-10d" ] - for fmt in fmts - l = :( x-> x ) - l.args[2].args[2] = @compat Expr(:macrocall, Symbol("@sprintf"), fmt, :x) - mfmtr = eval( l ) + fmts = [ (x->@sprintf("%d",x), "%d"), + (x->@sprintf("%10d",x), "%10d"), + (x->@sprintf("%010d",x), "%010d"), + (x->@sprintf("%-10d",x), "%-10d")] + for (mfmtr,fmt) in fmts for i in 1:10000 j = round(Int, _erfinv( rand() * 1.99 - 1.99/2.0 ) * 100000 ) expect = mfmtr( j ) From ea6c54b7ac5b85d77074246450a901e71544b127 Mon Sep 17 00:00:00 2001 From: ScottPJones Date: Tue, 25 Apr 2017 19:39:05 -0400 Subject: [PATCH 2/4] Use exact version number for when #265 fix was merged --- src/cformat.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cformat.jl b/src/cformat.jl index 7307fab..c7f9fa4 100644 --- a/src/cformat.jl +++ b/src/cformat.jl @@ -1,6 +1,6 @@ formatters = Dict{ Compat.ASCIIString, Function }() -@static if VERSION >= v"0.6-" +@static if VERSION >= v"0.6.0-dev.1671" sprintf1( fmt::Compat.ASCIIString, x ) = eval(Expr(:call, generate_formatter( fmt ), x)) From c94496c43c9051b09bf8e260f8034ecb74e1d4a1 Mon Sep 17 00:00:00 2001 From: ScottPJones Date: Sun, 30 Apr 2017 00:35:11 -0400 Subject: [PATCH 3/4] Removed use of at-static macro at top-level --- src/cformat.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cformat.jl b/src/cformat.jl index c7f9fa4..a1d8e2e 100644 --- a/src/cformat.jl +++ b/src/cformat.jl @@ -1,6 +1,6 @@ formatters = Dict{ Compat.ASCIIString, Function }() -@static if VERSION >= v"0.6.0-dev.1671" +if VERSION >= v"0.6.0-dev.1671" sprintf1( fmt::Compat.ASCIIString, x ) = eval(Expr(:call, generate_formatter( fmt ), x)) From 93b91e25d3da9b629d48dffec46e4d1b871773e4 Mon Sep 17 00:00:00 2001 From: Tony Kelman Date: Fri, 19 May 2017 08:24:06 -0400 Subject: [PATCH 4/4] make package 0.6-only remove Compat and duplicated code --- .travis.yml | 3 +- REQUIRE | 3 +- src/Formatting.jl | 2 -- src/cformat.jl | 91 ++++------------------------------------------- src/fmtcore.jl | 24 ++++++------- src/fmtspec.jl | 4 +-- src/formatexpr.jl | 24 ++++++------- test/cformat.jl | 1 - 8 files changed, 34 insertions(+), 118 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6508998..dd5a7e5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,7 @@ os: - linux - osx julia: - - 0.4 - - 0.5 + - 0.6 - nightly notifications: email: false diff --git a/REQUIRE b/REQUIRE index 959f8ca..e773e5c 100644 --- a/REQUIRE +++ b/REQUIRE @@ -1,2 +1 @@ -julia 0.4 -Compat 0.8.0 +julia 0.6-pre diff --git a/src/Formatting.jl b/src/Formatting.jl index 6fd420a..88f627a 100644 --- a/src/Formatting.jl +++ b/src/Formatting.jl @@ -9,8 +9,6 @@ module Formatting printfmt, printfmtln, fmt, format, sprintf1, generate_formatter - using Compat - include("cformat.jl" ) include("fmtspec.jl") include("fmtcore.jl") diff --git a/src/cformat.jl b/src/cformat.jl index a1d8e2e..e1d5bef 100644 --- a/src/cformat.jl +++ b/src/cformat.jl @@ -1,8 +1,6 @@ -formatters = Dict{ Compat.ASCIIString, Function }() +formatters = Dict{ String, Function }() -if VERSION >= v"0.6.0-dev.1671" - -sprintf1( fmt::Compat.ASCIIString, x ) = eval(Expr(:call, generate_formatter( fmt ), x)) +sprintf1( fmt::String, x ) = eval(Expr(:call, generate_formatter( fmt ), x)) function checkfmt(fmt) test = Base.Printf.parse( fmt ) @@ -10,7 +8,7 @@ function checkfmt(fmt) error( "Only one AND undecorated format string is allowed") end -function generate_formatter( fmt::Compat.ASCIIString ) +function generate_formatter( fmt::String ) global formatters haskey( formatters, fmt ) && return formatters[fmt] @@ -65,85 +63,8 @@ function checkcommas(s) s end -else - -sprintf1( fmt::Compat.ASCIIString, x ) = (generate_formatter( fmt ))(x) - -function generate_formatter( fmt::Compat.ASCIIString ) - global formatters - if haskey( formatters, fmt ) - return formatters[fmt] - end - - func = @compat Symbol("sprintf_", replace(base64encode(fmt), "=", "!")) - - if !contains( fmt, "'" ) - test = Base.Printf.parse( fmt ) - if length( test ) != 1 || !( typeof( test[1] ) <: Tuple ) - error( "Only one AND undecorated format string is allowed") - end - - code = quote - function $func( x ) - @sprintf( $fmt, x ) - end - end - else - conversion = fmt[end] - if !in( conversion, "sduifF" ) - error( "thousand separator not defined for " * string( conversion ) * " conversion") - end - fmtactual = replace( fmt, "'", "", 1 ) - test = Base.Printf.parse( fmtactual ) - if length( test ) != 1 || !( typeof( test[1] ) <: Tuple ) - error( "Only one AND undecorated format string is allowed") - end - if in( conversion, "sfF" ) - code = quote - function $func{T<:Real}( x::T ) - s = @sprintf( $fmtactual, x ) - # commas are added to only the numerator - if T <: Rational && endswith( $fmtactual, "s" ) - spos = findfirst( s, '/' ) - s = addcommas( s[1:spos-1] ) * s[spos:end] - else - dpos = findfirst( s, '.' ) - if dpos != 0 - s = addcommas( s[1:dpos-1] ) * s[ dpos:end ] - else # find the rightmost digit - for i in length( s ):-1:1 - if isdigit( s[i] ) - s = addcommas( s[1:i] ) * s[i+1:end] - break - end - end - end - end - s - end - end - else - code = quote - function $func( x ) - s = @sprintf( $fmtactual, x ) - for i in length( s ):-1:1 - if isdigit( s[i] ) - s = addcommas( s[1:i] ) * s[i+1:end] - break - end - end - s - end - end - end - end - f = eval( code ) - formatters[ fmt ] = f - f -end -end -function addcommas( s::Compat.ASCIIString ) +function addcommas( s::String ) len = length(s) t = "" for i in 1:3:len @@ -170,7 +91,7 @@ function generate_format_string(; signed::Bool=false, positivespace::Bool=false, alternative::Bool=false, - conversion::Compat.ASCIIString="f" #aAdecEfFiosxX + conversion::String="f" #aAdecEfFiosxX ) s = "%" if commas @@ -220,7 +141,7 @@ function format{T<:Real}( x::T; tryden::Int = 0, # if 2 or higher, try to use this denominator, without losing precision suffix::AbstractString="", # useful for units/% autoscale::Symbol=:none, # :metric, :binary or :finance - conversion::Compat.ASCIIString="" + conversion::String="" ) checkwidth = commas if conversion == "" diff --git a/src/fmtcore.jl b/src/fmtcore.jl index ea4b6d1..87a7ab4 100644 --- a/src/fmtcore.jl +++ b/src/fmtcore.jl @@ -12,7 +12,7 @@ end ### print string or char -@compat function _pfmt_s(out::IO, fs::FormatSpec, s::Union{AbstractString,Char}) +function _pfmt_s(out::IO, fs::FormatSpec, s::Union{AbstractString,Char}) wid = fs.width slen = length(s) if wid <= slen @@ -35,12 +35,12 @@ end _mul(x::Integer, ::_Dec) = x * 10 _mul(x::Integer, ::_Bin) = x << 1 _mul(x::Integer, ::_Oct) = x << 3 -@compat _mul(x::Integer, ::Union{_Hex, _HEX}) = x << 4 +_mul(x::Integer, ::Union{_Hex, _HEX}) = x << 4 _div(x::Integer, ::_Dec) = div(x, 10) _div(x::Integer, ::_Bin) = x >> 1 _div(x::Integer, ::_Oct) = x >> 3 -@compat _div(x::Integer, ::Union{_Hex, _HEX}) = x >> 4 +_div(x::Integer, ::Union{_Hex, _HEX}) = x >> 4 function _ndigits(x::Integer, op) # suppose x is non-negative m = 1 @@ -53,21 +53,21 @@ function _ndigits(x::Integer, op) # suppose x is non-negative end _ipre(op) = "" -@compat _ipre(::Union{_Hex, _HEX}) = "0x" +_ipre(::Union{_Hex, _HEX}) = "0x" _ipre(::_Oct) = "0o" _ipre(::_Bin) = "0b" -_digitchar(x::Integer, ::_Bin) = @compat Char(x == 0 ? '0' : '1') -_digitchar(x::Integer, ::_Dec) = @compat Char('0' + x) -_digitchar(x::Integer, ::_Oct) = @compat Char('0' + x) -_digitchar(x::Integer, ::_Hex) = @compat Char(x < 10 ? '0' + x : 'a' + (x - 10)) -_digitchar(x::Integer, ::_HEX) = @compat Char(x < 10 ? '0' + x : 'A' + (x - 10)) +_digitchar(x::Integer, ::_Bin) = Char(x == 0 ? '0' : '1') +_digitchar(x::Integer, ::_Dec) = Char('0' + x) +_digitchar(x::Integer, ::_Oct) = Char('0' + x) +_digitchar(x::Integer, ::_Hex) = Char(x < 10 ? '0' + x : 'a' + (x - 10)) +_digitchar(x::Integer, ::_HEX) = Char(x < 10 ? '0' + x : 'A' + (x - 10)) _signchar(x::Number, s::Char) = x < 0 ? '-' : s == '+' ? '+' : s == ' ' ? ' ' : '\0' -function _pfmt_int{Op}(out::IO, sch::Char, ip::Compat.ASCIIString, zs::Integer, ax::Integer, op::Op) +function _pfmt_int{Op}(out::IO, sch::Char, ip::String, zs::Integer, ax::Integer, op::Op) # print sign if sch != '\0' write(out, sch) @@ -222,8 +222,8 @@ function _pfmt_floate(out::IO, sch::Char, zs::Integer, u::Real, prec::Int, e::In e = -e end (e1, e2) = divrem(e, 10) - write(out, @compat Char('0' + e1)) - write(out, @compat Char('0' + e2)) + write(out, Char('0' + e1)) + write(out, Char('0' + e2)) end diff --git a/src/fmtspec.jl b/src/fmtspec.jl index a566e10..270ba93 100644 --- a/src/fmtspec.jl +++ b/src/fmtspec.jl @@ -176,7 +176,7 @@ function printfmt(io::IO, fs::FormatSpec, x) cls = fs.cls ty = fs.typ if cls == 'i' - ix = @compat Integer(x) + ix = Integer(x) ty == 'd' || ty == 'n' ? _pfmt_i(io, fs, ix, _Dec()) : ty == 'x' ? _pfmt_i(io, fs, ix, _Hex()) : ty == 'X' ? _pfmt_i(io, fs, ix, _HEX()) : @@ -194,7 +194,7 @@ function printfmt(io::IO, fs::FormatSpec, x) elseif cls == 's' _pfmt_s(io, fs, _srepr(x)) else # cls == 'c' - _pfmt_s(io, fs, @compat Char(x)) + _pfmt_s(io, fs, Char(x)) end end diff --git a/src/formatexpr.jl b/src/formatexpr.jl index 5af03c1..f9fb05d 100644 --- a/src/formatexpr.jl +++ b/src/formatexpr.jl @@ -32,7 +32,7 @@ function make_argspec(s::AbstractString, pos::Int) else iarg = ifil > 1 ? parse(Int,s[1:ifil-1]) : -1 hasfil = true - ff = eval(@compat Symbol(s[ifil+2:end])) + ff = eval(Symbol(s[ifil+2:end])) end end @@ -78,10 +78,10 @@ end ### Format expression type FormatExpr - prefix::Compat.UTF8String - suffix::Compat.UTF8String + prefix::String + suffix::String entries::Vector{FormatEntry} - inter::Vector{Compat.UTF8String} + inter::Vector{String} end _raise_unmatched_lbrace() = error("Unmatched { in format expression.") @@ -100,7 +100,7 @@ function find_next_entry_open(s::AbstractString, si::Int) pre = replace(pre, "{{", '{') pre = replace(pre, "}}", '}') end - return (p, convert(Compat.UTF8String, pre)) + return (p, convert(String, pre)) end function find_next_entry_close(s::AbstractString, si::Int) @@ -115,10 +115,10 @@ function FormatExpr(s::AbstractString) slen = length(s) # init - prefix = convert(Compat.UTF8String, "") - suffix = convert(Compat.UTF8String, "") + prefix = "" + suffix = "" entries = FormatEntry[] - inter = Compat.UTF8String[] + inter = String[] # scan (p, prefix) = find_next_entry_open(s, 1) @@ -160,10 +160,10 @@ function printfmt(io::IO, fe::FormatExpr, args...) end printfmt(io::IO, fe::AbstractString, args...) = printfmt(io, FormatExpr(fe), args...) -@compat printfmt(fe::Union{AbstractString,FormatExpr}, args...) = printfmt(STDOUT, fe, args...) +printfmt(fe::Union{AbstractString,FormatExpr}, args...) = printfmt(STDOUT, fe, args...) -@compat printfmtln(io::IO, fe::Union{AbstractString,FormatExpr}, args...) = (printfmt(io, fe, args...); println(io)) -@compat printfmtln(fe::Union{AbstractString,FormatExpr}, args...) = printfmtln(STDOUT, fe, args...) +printfmtln(io::IO, fe::Union{AbstractString,FormatExpr}, args...) = (printfmt(io, fe, args...); println(io)) +printfmtln(fe::Union{AbstractString,FormatExpr}, args...) = printfmtln(STDOUT, fe, args...) -@compat format(fe::Union{AbstractString,FormatExpr}, args...) = +format(fe::Union{AbstractString,FormatExpr}, args...) = sprint(printfmt, fe, args...) diff --git a/test/cformat.jl b/test/cformat.jl index 15b396f..dfd42b1 100644 --- a/test/cformat.jl +++ b/test/cformat.jl @@ -1,5 +1,4 @@ using Formatting -using Compat using Base.Test _erfinv(z) = sqrt(π) * Base.Math.@horner(z, 0, 1, 0, π/12, 0, 7π^2/480, 0, 127π^3/40320, 0,