Skip to content

Commit 93aabf5

Browse files
committed
Use new Printf.format call directly, don't use macro
1 parent dffbbd7 commit 93aabf5

File tree

2 files changed

+68
-9
lines changed

2 files changed

+68
-9
lines changed

src/cformat.jl

Lines changed: 60 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,67 @@
1+
@static if VERSION > v"1.6.0-DEV.854"
2+
3+
const NoCommas = 0
4+
const CheckCommas = 1
5+
const CheckRat = 2
6+
const AddCommas = 3
7+
8+
const formatters = Dict{ ASCIIStr, Tuple{Printf.Format, Int} }()
9+
10+
function _checkfmt(fmt)
11+
test = Printf.Format(fmt)
12+
len = length(test.formats)
13+
len === 0 && error("Invalid format string $fmt")
14+
len === 1 || error("Only one undecorated format string is allowed")
15+
test
16+
end
17+
18+
function _get_formatter(fmt)
19+
global formatters
20+
21+
chkfmt = get(formatters, fmt, nothing)
22+
chkfmt === nothing || return chkfmt
23+
# Check for thousands separator
24+
if occursin("'", fmt)
25+
conversion = fmt[end]
26+
conversion in "sduifFgG" ||
27+
error( string("thousand separator not defined for ", conversion, " conversion") )
28+
typ = conversion in "dui" ? CheckCommas : conversion === 's' ? CheckRat : AddCommas
29+
formatters[fmt] = (_checkfmt( replace( fmt, "'" => ""; count=1 ) ), typ)
30+
else
31+
formatters[fmt] = (_checkfmt(fmt), NoCommas)
32+
end
33+
end
34+
35+
function cfmt(fmt::ASCIIStr, x::T) where {T}
36+
formatter, typ = _get_formatter(fmt)
37+
s = Printf.format(formatter, x)
38+
typ === NoCommas ? s :
39+
typ === CheckCommas ? checkcommas(s) :
40+
(typ === CheckRat && T <: Rational) ? addcommasrat(s) : addcommasreal(s)
41+
end
42+
43+
function _checkrat(formatter, x::T) where {T}
44+
s = Printf.format(formatter, x)
45+
T <: Rational ? addcommasrat(s) : addcommasreal(s)
46+
end
47+
48+
function generate_formatter( fmt::ASCIIStr )
49+
formatter, typ = _get_formatter(fmt)
50+
typ === NoCommas ? x -> Printf.format(formatter, x) :
51+
typ === CheckCommas ? x -> checkcomma(Printf.format(formatter, x)) :
52+
typ === CheckRat ? x -> _checkrat(formatter, x) :
53+
x -> addcommasreal(Printf.format(formatter, x))
54+
end
55+
56+
else
157
formatters = Dict{ ASCIIStr, Function }()
258

359
cfmt( fmt::ASCIIStr, x ) = m_eval(Expr(:call, generate_formatter( fmt ), x))
460

561
function checkfmt(fmt)
6-
@static if VERSION > v"1.6.0-DEV.854"
7-
test = Printf.Format(fmt)
8-
length(test.formats) == 1 ||
9-
error( "Only one AND undecorated format string is allowed")
10-
else
11-
test = @static VERSION >= v"1.4.0-DEV.180" ? Printf.parse(fmt) : Base.Printf.parse( fmt )
12-
(length( test ) == 1 && typeof( test[1] ) <: Tuple) ||
13-
error( "Only one AND undecorated format string is allowed")
14-
end
62+
test = @static VERSION >= v"1.4.0-DEV.180" ? Printf.parse(fmt) : Base.Printf.parse( fmt )
63+
(length( test ) == 1 && typeof( test[1] ) <: Tuple) ||
64+
error( "Only one AND undecorated format string is allowed")
1565
end
1666

1767
function generate_formatter( fmt::ASCIIStr )
@@ -43,6 +93,7 @@ function generate_formatter( fmt::ASCIIStr )
4393
end
4494
return (formatters[ fmt ] = x->Base.invokelatest(formatter, x))
4595
end
96+
end
4697

4798
function addcommasreal(s)
4899
len = length(s)

src/fmtcore.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,14 @@ function _pfmt_e(out::IO, fs::FormatSpec, x::AbstractFloat)
217217
rax = round(ax; sigdigits = fs.prec + 1)
218218
e = floor(Integer, log10(rax)) # exponent
219219
u = rax * exp10(-e) # significand
220+
i = 0
221+
v10 = 1
222+
while isinf(u)
223+
i += 1
224+
i > 18 && (u = 0.0; e = 0; break)
225+
v10 *= 10
226+
u = v10 * rax * exp(-e - i)
227+
end
220228
end
221229

222230
# calculate length

0 commit comments

Comments
 (0)