From d87a24c24181b313ae41c2c023515b15d2c387d0 Mon Sep 17 00:00:00 2001 From: ScottPJones Date: Thu, 15 Feb 2024 14:21:27 -0500 Subject: [PATCH] Use textwidth and handle precision with wide characters correctly for cfmt --- Project.toml | 2 +- src/printf.jl | 29 ++++++++++++++++++----------- test/cformat.jl | 6 ++++++ 3 files changed, 25 insertions(+), 12 deletions(-) diff --git a/Project.toml b/Project.toml index c177ca6..653e98f 100644 --- a/Project.toml +++ b/Project.toml @@ -23,7 +23,7 @@ keywords = ["Strings", "Formatting"] license = "MIT" name = "Format" uuid = "1fa38f19-a742-5d3f-a2b9-30dd87b9d5f8" -version = "1.3.4" +version = "1.3.5" [deps] diff --git a/src/printf.jl b/src/printf.jl index cfe7412..bad09d5 100644 --- a/src/printf.jl +++ b/src/printf.jl @@ -234,21 +234,28 @@ end # strings function _fmt(buf, pos, spec::FmtSpec{FmtStr}, arg) altf, width, prec = spec.altf, spec.width, spec.prec - str = altf && (arg isa Symbol || arg isa AbstractString) ? repr(arg) : string(arg) - slen = length(str) - op = p = prec == -1 ? slen : min(slen, prec) + s = altf && (arg isa Symbol || arg isa AbstractString) ? repr(arg) : string(arg) + slen = textwidth(s) + str, slen = 0 <= prec < slen ? _truncstr(s, slen, prec) : (s, slen) + prepad = postpad = 0 + pad = width - slen + if pad > 0 + if spec.leftalign + postpad = pad + else + prepad = pad + end + end + # Make sure there is enough room in buffer - nlen = max(width, p) - buflen = sizeof(buf) - pos - buflen < nlen && resize!(buf, nlen + pos) - !spec.leftalign && width > p && (pos = padn(buf, pos, width - p)) + nlen = pos + prepad + sizeof(str) + postpad + nlen > sizeof(buf) && resize!(buf, nlen) + + prepad == 0 || (pos = padn(buf, pos, prepad)) for c in str - p == 0 && break pos = writechar(buf, pos, c) - p -= 1 end - spec.leftalign && width > op && return padn(buf, pos, width - op) - return pos + return postpad == 0 ? pos : padn(buf, pos, postpad) end const BaseInt = Union{Int8, Int16, Int32, Int64, Int128} diff --git a/test/cformat.jl b/test/cformat.jl index 176915f..1db7a69 100644 --- a/test/cformat.jl +++ b/test/cformat.jl @@ -49,12 +49,18 @@ include("speedtest.jl") @test cfmt( "%'f", -Inf ) == "-Inf" @test cfmt( "%'s", 1000.0 ) == "1,000.0" @test cfmt( "%'s", 1234567.0 ) == "1.234567e6" + @test cfmt( "%'g", 1000.0 ) == "1,000" end @testset "Test bug introduced by stdlib/Printf rewrite" begin @test cfmt( "%4.2s", "a" ) == " a" end +@testset "Test precision with wide characters" begin + @test cfmt( "%10.9s", "\U1f355" ^ 6) == " " * "\U1f355" ^ 4 + @test cfmt( "%10.10s", "\U1f355" ^ 6) == "\U1f355" ^ 5 +end + @testset "test format..." begin @test format( 10 ) == "10" @test format( 10.0 ) == "10"