-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
adding dynamic width and precision to printf #40105
Conversation
Anything left to be done here or can we merge this? |
Looks like a botched merge/rebase? |
@stevengj Yes, complete fubar, how do I get out of this? |
I put together a cleaned-up branch that contains all your changes to
|
Bump. Would be nice to eventually get this in, but the PR is still in a bad state. @johanmon are you still willing to push this through? |
0164cbe
to
b7dcefd
Compare
I force-pushed the rebase. |
ae36c8e
to
243e954
Compare
Co-authored-by: Mosè Giordano <giordano@users.noreply.github.com>
Good to merge? |
As far as I know yes. |
hmm.... just compiled everything and there is a duplication of code in Printf.jl
occures twice? |
@johanmon, good catch — looks like a manual-rebase snafu. Should be fixed now. |
From a JET report I'm seeing this: rmdynamic(spec::Printf.Spec{T}, args, argp) where T @ Printf ~/.julia/juliaup/julia-1.11.0-rc1+0.x64.linux.gnu/share/julia/stdlib/v1.11/Printf/src/Printf.jl:297
297 function rmdynamic(spec::Printf.Spec{Val{'s'}}::Spec{T}, args::NTuple{5, String}, argp::Int64) where {T}
298 zero::Bool, width::Int64, precision::Int64 = spec::Printf.Spec{Val{'s'}}.zero::Bool, spec::Printf.Spec{Val{'s'}}.width::Int64, spec::Printf.Spec{Val{'s'}}.precision::Int64
299 if spec::Printf.Spec{Val{'s'}}.dynamic_width::Bool
300 width::String = args::NTuple{5, String}[argp::Int64]::String
301 (argp::Int64 += 1)::Int64
302 end
303 if spec::Printf.Spec{Val{'s'}}.dynamic_precision::Bool
304 precision::String = args::NTuple{5, String}[argp::Int64]::String
305 if zero::Bool && T <: Ints::Type{Union{Val{'d'}, Val{'i'}, Val{'u'}, Val{'x'}, Val{'X'}, Val{'o'}}}::Bool && precision > 0
306 zero = false
307 end
308 (argp::Int64 += 1)::Int64
309 end
310 (Spec::Type{Printf.Spec}{T}::Type{Printf.Spec{Val{'s'}}}(spec::Printf.Spec{Val{'s'}}.leftalign::Bool, spec::Printf.Spec{Val{'s'}}.plus::Bool, spec::Printf.Spec{Val{'s'}}.space::Bool, zero::Bool, spec::Printf.Spec{Val{'s'}}.hash::Bool, width::Union{Int64, String}, precision::Union{Int64, String}, false, false)::Printf.Spec{Val{'s'}}, argp::Int64)::Tuple{Printf.Spec{Val{'s'}}, Int64}
311 end It seems to think that julia/stdlib/Printf/src/Printf.jl Lines 33 to 43 in 0945b9d
The call chain is as follows:
|
So this is a second attempt to add dynamic width and precision to printf.
In order to handle dynamic width and precision I've added two fields to the Spec data structure. These indicate if the specification uses dynamic width and/or precision. I've also added a field to the Format data structure that tells us how many arguments a format string requires (this is no longer simply the number of specifications).
I've tried to keep as much of the existing code intact so fmt(buf, pos, arg, spec) is unchanged. We have a function fmt(buf, pos, args, argp, spec) and depending on if the specification uses dynamic width and/or precision call fmt(buf, pos, args[argp], spec). If the specification was dynamic the actual values are taken from the args and the specification is updated (we need to patch the zero flag for Ints since we now know the precision.
The plength(f, args) is handled in the same way so we first check if we have a dynamic specification and if so update it. The function now also returns the next argument position since it could be that we use one or two for dynamic values.
For the tests I've added a few explicit test but then only checked that the version with dynamic width an precision return the same string as the static versions.
Closes #40654
The previous pull request was: #33278 but since I rewrote everything and the Printf moved I thought it was better to do a new.