Skip to content

Commit

Permalink
Fix issue 110 from Formatting.jl
Browse files Browse the repository at this point in the history
  • Loading branch information
ScottPJones committed Jul 29, 2023
1 parent d9a4845 commit 52a25df
Show file tree
Hide file tree
Showing 5 changed files with 71 additions and 26 deletions.
8 changes: 4 additions & 4 deletions .drone.yml
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
---
kind: pipeline
name: linux - arm64 - Julia 1.5
name: linux - arm64 - Julia 1.9

platform:
os: linux
arch: arm64

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

---
kind: pipeline
name: linux - arm64 - Julia 1.6
name: linux - arm64 - Julia 1.9

platform:
os: linux
arch: arm64

steps:
- name: build
image: julia:1.6
image: julia:1.9
commands:
- "julia --project=. --check-bounds=yes --color=yes -e 'using InteractiveUtils; versioninfo(verbose=true); using Pkg; Pkg.build(); Pkg.test(coverage=true)'"
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ jobs:
fail-fast: false
matrix:
version:
- '1.5'
- '1.6'
- '1.9'
- 'nightly'
os:
- ubuntu-latest
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ keywords = ["Strings", "Formatting"]
license = "MIT"
name = "Format"
uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8"
version = "1.3.2"
version = "1.3.3"

[deps]

Expand Down
77 changes: 57 additions & 20 deletions src/fmtcore.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,12 @@ function _pfmt_s(out::IO, fs::FormatSpec, s::Union{AbstractString,AbstractChar})
slen = length(s)
if wid <= slen
print(out, s)
elseif fs.align == '<'
print(out, s)
_repprint(out, fs.fill, wid-slen)
else
a = fs.align
if a == '<'
print(out, s)
_repprint(out, fs.fill, wid-slen)
else
_repprint(out, fs.fill, wid-slen)
print(out, s)
end
_repprint(out, fs.fill, wid-slen)
print(out, s)
end
end

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

_str(x::Integer, ::_Dec) = string(x, base=10)
_str(x::Integer, ::_Bin) = string(x, base=2)
_str(x::Integer, ::_Oct) = string(x, base=8)
_str(x::Integer, ::Union{_Hex, _HEX}) = string(x, base=16)

function _ndigits(x::Integer, op) # suppose x is non-negative
m = 1
q = _div(x, op)
Expand Down Expand Up @@ -96,15 +98,53 @@ function _pfmt_intdigits(out::IO, ax::T, op::Op) where {Op, T<:Integer}
end
end

function _pfmt_intmin(out::IO, ip::ASCIIStr, zs::Integer, s::String)
# print sign
print(out, '-')
# print prefix
isempty(ip) || print(out, ip)
# print padding zeros
zs > 0 && _repprint(out, '0', zs)
# print actual digits
print(out, SubString(s, 2))
nothing
end

# Special case were abs would give error
function _pfmt_imin(out::IO, fs::FormatSpec, x::Integer, op::Op) where {Op}
s = _str(x, op)
xlen = length(s)
# prefix (e.g. 0x, 0b, 0o)
ip = ""
if fs.ipre
ip = _ipre(op)
xlen += length(ip)
end

# printing
wid = fs.width
if wid <= xlen
_pfmt_intmin(out, ip, 0, s)
elseif fs.zpad
_pfmt_intmin(out, ip, wid-xlen, s)
elseif fs.align == '<'
_pfmt_intmin(out, ip, 0, s)
_repprint(out, fs.fill, wid-xlen)
else
_repprint(out, fs.fill, wid-xlen)
_pfmt_intmin(out, ip, 0, s)
end
end

function _pfmt_i(out::IO, fs::FormatSpec, x::Integer, op::Op) where {Op}
# Specially handle edge case of typemin
x === typemin(typeof(x)) && x isa Signed && return _pfmt_imin(out, fs, x, op)
# calculate actual length
ax = abs(x)
xlen = _ndigits(abs(x), op)
xlen = _ndigits(ax, op)
# sign char
sch = _signchar(x, fs.sign)
if sch != '\0'
xlen += 1
end
xlen += (sch != '\0')
# prefix (e.g. 0x, 0b, 0o)
ip = ""
if fs.ipre
Expand All @@ -118,15 +158,12 @@ function _pfmt_i(out::IO, fs::FormatSpec, x::Integer, op::Op) where {Op}
_pfmt_int(out, sch, ip, 0, ax, op)
elseif fs.zpad
_pfmt_int(out, sch, ip, wid-xlen, ax, op)
elseif fs.align == '<'
_pfmt_int(out, sch, ip, 0, ax, op)
_repprint(out, fs.fill, wid-xlen)
else
a = fs.align
if a == '<'
_pfmt_int(out, sch, ip, 0, ax, op)
_repprint(out, fs.fill, wid-xlen)
else
_repprint(out, fs.fill, wid-xlen)
_pfmt_int(out, sch, ip, 0, ax, op)
end
_repprint(out, fs.fill, wid-xlen)
_pfmt_int(out, sch, ip, 0, ax, op)
end
end

Expand Down
8 changes: 8 additions & 0 deletions test/formatexpr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,11 @@ end
@testset "format with filter" begin
@test format("{1|>abs2} + {2|>abs2:.2f}", 2, 3) == "4 + 9.00"
end

@testset "test typemin/typemax edge cases" begin
f = FormatExpr("{1:+d}")
for T in (Int8,Int16,Int32,Int64)
@test format(f, typemin(T)) == string(typemin(T))
@test format(f, typemax(T)) == "+"*string(typemax(T))
end
end

0 comments on commit 52a25df

Please sign in to comment.