Skip to content

Commit 52a25df

Browse files
committed
Fix issue 110 from Formatting.jl
1 parent d9a4845 commit 52a25df

File tree

5 files changed

+71
-26
lines changed

5 files changed

+71
-26
lines changed

.drone.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,27 @@
11
---
22
kind: pipeline
3-
name: linux - arm64 - Julia 1.5
3+
name: linux - arm64 - Julia 1.9
44

55
platform:
66
os: linux
77
arch: arm64
88

99
steps:
1010
- name: build
11-
image: julia:1.5
11+
image: julia:1.9
1212
commands:
1313
- "julia --project=. --check-bounds=yes --color=yes -e 'using InteractiveUtils; versioninfo(verbose=true); using Pkg; Pkg.build(); Pkg.test(coverage=true)'"
1414

1515
---
1616
kind: pipeline
17-
name: linux - arm64 - Julia 1.6
17+
name: linux - arm64 - Julia 1.9
1818

1919
platform:
2020
os: linux
2121
arch: arm64
2222

2323
steps:
2424
- name: build
25-
image: julia:1.6
25+
image: julia:1.9
2626
commands:
2727
- "julia --project=. --check-bounds=yes --color=yes -e 'using InteractiveUtils; versioninfo(verbose=true); using Pkg; Pkg.build(); Pkg.test(coverage=true)'"

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ jobs:
1010
fail-fast: false
1111
matrix:
1212
version:
13-
- '1.5'
1413
- '1.6'
14+
- '1.9'
1515
- 'nightly'
1616
os:
1717
- ubuntu-latest

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ keywords = ["Strings", "Formatting"]
2323
license = "MIT"
2424
name = "Format"
2525
uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8"
26-
version = "1.3.2"
26+
version = "1.3.3"
2727

2828
[deps]
2929

src/fmtcore.jl

Lines changed: 57 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,12 @@ function _pfmt_s(out::IO, fs::FormatSpec, s::Union{AbstractString,AbstractChar})
1919
slen = length(s)
2020
if wid <= slen
2121
print(out, s)
22+
elseif fs.align == '<'
23+
print(out, s)
24+
_repprint(out, fs.fill, wid-slen)
2225
else
23-
a = fs.align
24-
if a == '<'
25-
print(out, s)
26-
_repprint(out, fs.fill, wid-slen)
27-
else
28-
_repprint(out, fs.fill, wid-slen)
29-
print(out, s)
30-
end
26+
_repprint(out, fs.fill, wid-slen)
27+
print(out, s)
3128
end
3229
end
3330

@@ -44,6 +41,11 @@ _div(x::Integer, ::_Bin) = x >> 1
4441
_div(x::Integer, ::_Oct) = x >> 3
4542
_div(x::Integer, ::Union{_Hex, _HEX}) = x >> 4
4643

44+
_str(x::Integer, ::_Dec) = string(x, base=10)
45+
_str(x::Integer, ::_Bin) = string(x, base=2)
46+
_str(x::Integer, ::_Oct) = string(x, base=8)
47+
_str(x::Integer, ::Union{_Hex, _HEX}) = string(x, base=16)
48+
4749
function _ndigits(x::Integer, op) # suppose x is non-negative
4850
m = 1
4951
q = _div(x, op)
@@ -96,15 +98,53 @@ function _pfmt_intdigits(out::IO, ax::T, op::Op) where {Op, T<:Integer}
9698
end
9799
end
98100

101+
function _pfmt_intmin(out::IO, ip::ASCIIStr, zs::Integer, s::String)
102+
# print sign
103+
print(out, '-')
104+
# print prefix
105+
isempty(ip) || print(out, ip)
106+
# print padding zeros
107+
zs > 0 && _repprint(out, '0', zs)
108+
# print actual digits
109+
print(out, SubString(s, 2))
110+
nothing
111+
end
112+
113+
# Special case were abs would give error
114+
function _pfmt_imin(out::IO, fs::FormatSpec, x::Integer, op::Op) where {Op}
115+
s = _str(x, op)
116+
xlen = length(s)
117+
# prefix (e.g. 0x, 0b, 0o)
118+
ip = ""
119+
if fs.ipre
120+
ip = _ipre(op)
121+
xlen += length(ip)
122+
end
123+
124+
# printing
125+
wid = fs.width
126+
if wid <= xlen
127+
_pfmt_intmin(out, ip, 0, s)
128+
elseif fs.zpad
129+
_pfmt_intmin(out, ip, wid-xlen, s)
130+
elseif fs.align == '<'
131+
_pfmt_intmin(out, ip, 0, s)
132+
_repprint(out, fs.fill, wid-xlen)
133+
else
134+
_repprint(out, fs.fill, wid-xlen)
135+
_pfmt_intmin(out, ip, 0, s)
136+
end
137+
end
138+
99139
function _pfmt_i(out::IO, fs::FormatSpec, x::Integer, op::Op) where {Op}
140+
# Specially handle edge case of typemin
141+
x === typemin(typeof(x)) && x isa Signed && return _pfmt_imin(out, fs, x, op)
100142
# calculate actual length
101143
ax = abs(x)
102-
xlen = _ndigits(abs(x), op)
144+
xlen = _ndigits(ax, op)
103145
# sign char
104146
sch = _signchar(x, fs.sign)
105-
if sch != '\0'
106-
xlen += 1
107-
end
147+
xlen += (sch != '\0')
108148
# prefix (e.g. 0x, 0b, 0o)
109149
ip = ""
110150
if fs.ipre
@@ -118,15 +158,12 @@ function _pfmt_i(out::IO, fs::FormatSpec, x::Integer, op::Op) where {Op}
118158
_pfmt_int(out, sch, ip, 0, ax, op)
119159
elseif fs.zpad
120160
_pfmt_int(out, sch, ip, wid-xlen, ax, op)
161+
elseif fs.align == '<'
162+
_pfmt_int(out, sch, ip, 0, ax, op)
163+
_repprint(out, fs.fill, wid-xlen)
121164
else
122-
a = fs.align
123-
if a == '<'
124-
_pfmt_int(out, sch, ip, 0, ax, op)
125-
_repprint(out, fs.fill, wid-xlen)
126-
else
127-
_repprint(out, fs.fill, wid-xlen)
128-
_pfmt_int(out, sch, ip, 0, ax, op)
129-
end
165+
_repprint(out, fs.fill, wid-xlen)
166+
_pfmt_int(out, sch, ip, 0, ax, op)
130167
end
131168
end
132169

test/formatexpr.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,11 @@ end
5353
@testset "format with filter" begin
5454
@test format("{1|>abs2} + {2|>abs2:.2f}", 2, 3) == "4 + 9.00"
5555
end
56+
57+
@testset "test typemin/typemax edge cases" begin
58+
f = FormatExpr("{1:+d}")
59+
for T in (Int8,Int16,Int32,Int64)
60+
@test format(f, typemin(T)) == string(typemin(T))
61+
@test format(f, typemax(T)) == "+"*string(typemax(T))
62+
end
63+
end

0 commit comments

Comments
 (0)