Skip to content

Commit

Permalink
reimplement show context global/tls variables as local state containe…
Browse files Browse the repository at this point in the history
…d in a new IOContext lightweight wrapper type
  • Loading branch information
vtjnash committed Dec 24, 2015
1 parent 1fe1391 commit 4706184
Show file tree
Hide file tree
Showing 23 changed files with 344 additions and 282 deletions.
7 changes: 5 additions & 2 deletions base/Enums.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,12 @@ macro enum(T,syms...)
end
end
function Base.show(io::IO,x::$(esc(typename)))
print(io, x, "::", $(esc(typename)), " = ", Int(x))
if Base.limit_output(io)
print(io, x)
else
print(io, x, "::", $(esc(typename)), " = ", Int(x))
end
end
Base.showcompact(io::IO,x::$(esc(typename))) = print(io, x)
function Base.writemime(io::IO,::MIME"text/plain",::Type{$(esc(typename))})
print(io, "Enum ", $(esc(typename)), ":")
for (sym, i) in $vals
Expand Down
11 changes: 5 additions & 6 deletions base/complex.jl
Original file line number Diff line number Diff line change
Expand Up @@ -59,25 +59,24 @@ complex(x::Real, y::Real) = Complex(x, y)
complex(x::Real) = Complex(x)
complex(z::Complex) = z

function complex_show(io::IO, z::Complex, compact::Bool)
function show(io::IO, z::Complex)
r, i = reim(z)
compact ? showcompact(io,r) : show(io,r)
compact = limit_output(io)
showcompact_lim(io, r)
if signbit(i) && !isnan(i)
i = -i
print(io, compact ? "-" : " - ")
else
print(io, compact ? "+" : " + ")
end
compact ? showcompact(io, i) : show(io, i)
showcompact_lim(io, i)
if !(isa(i,Integer) && !isa(i,Bool) || isa(i,AbstractFloat) && isfinite(i))
print(io, "*")
end
print(io, "im")
end
complex_show(io::IO, z::Complex{Bool}, compact::Bool) =
show(io::IO, z::Complex{Bool}) =
print(io, z == im ? "im" : "Complex($(z.re),$(z.im))")
show(io::IO, z::Complex) = complex_show(io, z, false)
showcompact(io::IO, z::Complex) = complex_show(io, z, true)

function read{T<:Real}(s::IO, ::Type{Complex{T}})
r = read(s,T)
Expand Down
139 changes: 66 additions & 73 deletions base/dict.jl
Original file line number Diff line number Diff line change
Expand Up @@ -61,87 +61,79 @@ function _truncate_at_width_or_chars(str, width, chars="", truncmark="…")
end

showdict(t::Associative; kw...) = showdict(STDOUT, t; kw...)
function showdict{K,V}(io::IO, t::Associative{K,V}; limit::Bool = false, compact = false,
function showdict{K,V}(io::IO, t::Associative{K,V}; compact = false,
sz=(s = tty_size(); (s[1]-3, s[2])))
shown_set = get(task_local_storage(), :SHOWNSET, nothing)
if shown_set === nothing
shown_set = ObjectIdDict()
task_local_storage(:SHOWNSET, shown_set)
end
t in keys(shown_set) && (print(io, "#= circular reference =#"); return)

try
shown_set[t] = true
if compact
# show in a Julia-syntax-like form: Dict(k=>v, ...)
if isempty(t)
print(io, typeof(t), "()")
(:SHOWN_SET => t) in io && (print(io, "#= circular reference =#"); return)

recur_io = IOContext(io, :SHOWN_SET => t)
limit::Bool = limit_output(io)
if compact
# show in a Julia-syntax-like form: Dict(k=>v, ...)
if isempty(t)
print(io, typeof(t), "()")
else
if isleaftype(K) && isleaftype(V)
print(io, typeof(t).name)
else
if isleaftype(K) && isleaftype(V)
print(io, typeof(t).name)
else
print(io, typeof(t))
end
print(io, '(')
first = true
n = 0
for (k, v) in t
first || print(io, ',')
first = false
show(io, k)
print(io, "=>")
show(io, v)
n+=1
limit && n >= 10 && (print(io, ""); break)
end
print(io, ')')
print(io, typeof(t))
end
print(io, '(')
first = true
n = 0
for (k, v) in t
first || print(io, ',')
first = false
show(recur_io, k)
print(io, "=>")
show(recur_io, v)
n+=1
limit && n >= 10 && (print(io, ""); break)
end
return
print(io, ')')
end
return
end

# Otherwise show more descriptively, with one line per key/value pair
rows, cols = sz
print(io, summary(t))
isempty(t) && return
print(io, ":")
if limit
rows < 2 && (print(io, ""); return)
cols < 12 && (cols = 12) # Minimum widths of 2 for key, 4 for value
cols -= 6 # Subtract the widths of prefix " " separator " => "
rows -= 2 # Subtract the summary and final ⋮ continuation lines

# determine max key width to align the output, caching the strings
ks = Array(AbstractString, min(rows, length(t)))
keylen = 0
for (i, k) in enumerate(keys(t))
i > rows && break
ks[i] = sprint(show, k)
keylen = clamp(length(ks[i]), keylen, div(cols, 3))
end
# Otherwise show more descriptively, with one line per key/value pair
rows, cols = sz
print(io, summary(t))
isempty(t) && return
print(io, ":")
if limit
rows < 2 && (print(io, ""); return)
cols < 12 && (cols = 12) # Minimum widths of 2 for key, 4 for value
cols -= 6 # Subtract the widths of prefix " " separator " => "
rows -= 2 # Subtract the summary and final ⋮ continuation lines

# determine max key width to align the output, caching the strings
ks = Array(AbstractString, min(rows, length(t)))
keylen = 0
for (i, k) in enumerate(keys(t))
i > rows && break
ks[i] = sprint(0, show, k, env=recur_io)
keylen = clamp(length(ks[i]), keylen, div(cols, 3))
end
end

for (i, (k, v)) in enumerate(t)
print(io, "\n ")
limit && i > rows && (print(io, rpad("", keylen), " => ⋮"); break)
for (i, (k, v)) in enumerate(t)
print(io, "\n ")
limit && i > rows && (print(io, rpad("", keylen), " => ⋮"); break)

if limit
key = rpad(_truncate_at_width_or_chars(ks[i], keylen, "\r\n"), keylen)
else
key = sprint(show, k)
end
print(io, key)
print(io, " => ")
if limit
key = rpad(_truncate_at_width_or_chars(ks[i], keylen, "\r\n"), keylen)
else
key = sprint(0, show, k, env=recur_io)
end
print(recur_io, key)
print(io, " => ")

if limit
val = with_output_limit(()->sprint(show, v))
val = _truncate_at_width_or_chars(val, cols - keylen, "\r\n")
print(io, val)
else
show(io, v)
end
if limit
val = sprint(0, show, v, env=recur_io)
val = _truncate_at_width_or_chars(val, cols - keylen, "\r\n")
print(io, val)
else
show(recur_io, v)
end
finally
delete!(shown_set, t)
end
end

Expand All @@ -158,8 +150,9 @@ summary{T<:Union{KeyIterator,ValueIterator}}(iter::T) =
show(io::IO, iter::Union{KeyIterator,ValueIterator}) = show(io, collect(iter))

showkv(iter::Union{KeyIterator,ValueIterator}; kw...) = showkv(STDOUT, iter; kw...)
function showkv{T<:Union{KeyIterator,ValueIterator}}(io::IO, iter::T; limit::Bool = false,
function showkv{T<:Union{KeyIterator,ValueIterator}}(io::IO, iter::T;
sz=(s = tty_size(); (s[1]-3, s[2])))
limit::Bool = limit_output(io)
rows, cols = sz
print(io, summary(iter))
isempty(iter) && return
Expand All @@ -176,7 +169,7 @@ function showkv{T<:Union{KeyIterator,ValueIterator}}(io::IO, iter::T; limit::Boo
limit && i >= rows && (print(io, ""); break)

if limit
str = with_output_limit(()->sprint(show, v))
str = sprint(0, show, v, env=io)
str = _truncate_at_width_or_chars(str, cols, "\r\n")
print(io, str)
else
Expand Down
5 changes: 3 additions & 2 deletions base/docs/helpdb/Base.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3043,9 +3043,10 @@ Show an expression and result, returning the result.
"""
showcompact(x)
Show a more compact representation of a value. This is used for printing array elements. If
a new type has a different compact representation, it should overload `showcompact(io, x)`
where the first argument is a stream.
a new type has a different compact representation,
it should test `Base.limit_output(io)` in its normal `show` method.
"""
showcompact

Expand Down
2 changes: 1 addition & 1 deletion base/grisu.jl
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ function _show(io::IO, x::AbstractFloat, mode, n::Int, typed, nanstr, infstr)
nothing
end

Base.show(io::IO, x::AbstractFloat) = _show(io, x, SHORTEST, 0, true)
Base.show(io::IO, x::AbstractFloat) = Base.limit_output(io) ? showcompact(io, x) : _show(io, x, SHORTEST, 0, true)

Base.print(io::IO, x::Float32) = _show(io, x, SHORTEST, 0, false)
Base.print(io::IO, x::Float16) = _show(io, x, SHORTEST, 0, false)
Expand Down
28 changes: 12 additions & 16 deletions base/interactiveutil.jl
Original file line number Diff line number Diff line change
Expand Up @@ -220,23 +220,19 @@ versioninfo(verbose::Bool) = versioninfo(STDOUT,verbose)
# displaying type-ambiguity warnings

function code_warntype(io::IO, f, t::ANY)
task_local_storage(:TYPEEMPHASIZE, true)
try
ct = code_typed(f, t)
for ast in ct
println(io, "Variables:")
vars = ast.args[2][1]
for v in vars
print(io, " ", v[1])
show_expr_type(io, v[2])
print(io, '\n')
end
print(io, "\nBody:\n ")
show_unquoted(io, ast.args[3], 2)
print(io, '\n')
emph_io = IOContext(io, :TYPEEMPHASIZE => true)
ct = code_typed(f, t)
for ast in ct
println(emph_io, "Variables:")
vars = ast.args[2][1]
for v in vars
print(emph_io, " ", v[1])
show_expr_type(emph_io, v[2])
print(emph_io, '\n')
end
finally
task_local_storage(:TYPEEMPHASIZE, false)
print(emph_io, "\nBody:\n ")
show_unquoted(emph_io, ast.args[3], 2)
print(emph_io, '\n')
end
nothing
end
Expand Down
33 changes: 33 additions & 0 deletions base/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,39 @@ function eof end
read(s::IO, ::Type{UInt8}) = error(typeof(s)," does not support byte I/O")
write(s::IO, x::UInt8) = error(typeof(s)," does not support byte I/O")

# Generic wrappers around other IO objects
abstract AbstractPipe <: IO
function pipe_reader end
function pipe_writer end

write(io::AbstractPipe, byte::UInt8) = write(pipe_writer(io), byte)
write(io::AbstractPipe, bytes::Vector{UInt8}) = write(pipe_writer(io), bytes)
write{T<:AbstractPipe}(io::T, args...) = write(pipe_writer(io), args...)
write{S<:AbstractPipe}(io::S, a::Array) = write(pipe_writer(io), a)
buffer_or_write(io::AbstractPipe, p::Ptr, n::Integer) = buffer_or_write(pipe_writer(io), p, n)
buffer_writes(io::AbstractPipe, args...) = buffer_writes(pipe_writer(io), args...)
flush(io::AbstractPipe) = flush(pipe_writer(io))

read(io::AbstractPipe, byte::Type{UInt8}) = read(pipe_reader(io), byte)
read!(io::AbstractPipe, bytes::Vector{UInt8}) = read!(pipe_reader(io), bytes)
read{T<:AbstractPipe}(io::T, args...) = read(pipe_reader(io), args...)
read!{T<:AbstractPipe}(io::T, args...) = read!(pipe_reader(io), args...)
readuntil{T<:AbstractPipe}(io::T, args...) = readuntil(pipe_reader(io), args...)
readbytes(io::AbstractPipe) = readbytes(pipe_reader(io))
readavailable(io::AbstractPipe) = readavailable(pipe_reader(io))

isreadable(io::AbstractPipe) = isreadable(pipe_reader(io))
iswritable(io::AbstractPipe) = iswritable(pipe_writer(io))
isopen(io::AbstractPipe) = isopen(pipe_writer(io)) || isopen(pipe_reader(io))
close(io::AbstractPipe) = (close(pipe_writer(io)); close(pipe_reader(io)))
wait_readnb(io::AbstractPipe, nb::Int) = wait_readnb(pipe_reader(io), nb)
wait_readbyte(io::AbstractPipe, byte::UInt8) = wait_readbyte(pipe_reader(io), byte)
wait_close(io::AbstractPipe) = (wait_close(pipe_writer(io)); wait_close(pipe_reader(io)))
nb_available(io::AbstractPipe) = nb_available(pipe_reader(io))
eof(io::AbstractPipe) = eof(pipe_reader(io))
reseteof(io::AbstractPipe) = reseteof(pipe_reader(io))


## byte-order mark, ntoh & hton ##

const ENDIAN_BOM = reinterpret(UInt32,UInt8[1:4;])[1]
Expand Down
9 changes: 0 additions & 9 deletions base/iostream.jl
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,6 @@ function takebuf_raw(s::IOStream)
return buf, sz
end

function sprint(size::Integer, f::Function, args...)
s = IOBuffer(Array(UInt8,size), true, true)
truncate(s,0)
f(s, args...)
takebuf_string(s)
end

sprint(f::Function, args...) = sprint(0, f, args...)

write(x) = write(STDOUT::IO, x)

function readuntil(s::IOStream, delim::UInt8)
Expand Down
6 changes: 3 additions & 3 deletions base/irrationals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,8 @@ log(::Irrational{:e}) = 1 # use 1 to correctly promote expressions like log(x)/l
log(::Irrational{:e}, x) = log(x)

# align along = for nice Array printing
function alignment(x::Irrational)
m = match(r"^(.*?)(=.*)$", sprint(showcompact_lim, x))
m === nothing ? (length(sprint(showcompact_lim, x)), 0) :
function alignment(io::IO, x::Irrational)
m = match(r"^(.*?)(=.*)$", sprint(0, showcompact_lim, x, env=io))
m === nothing ? (length(sprint(0, showcompact_lim, x, env=io)), 0) :
(length(m.captures[1]), length(m.captures[2]))
end
2 changes: 1 addition & 1 deletion base/methodshow.jl
Original file line number Diff line number Diff line change
Expand Up @@ -181,4 +181,4 @@ end

# override usual show method for Vector{Method}: don't abbreviate long lists
writemime(io::IO, mime::MIME"text/plain", mt::AbstractVector{Method}) =
showarray(io, mt, limit=false)
showarray(IOContext(io, :limit_output => false), mt)
3 changes: 1 addition & 2 deletions base/mpfr.jl
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import
exp, exp2, exponent, factorial, floor, fma, hypot, isinteger,
isfinite, isinf, isnan, ldexp, log, log2, log10, max, min, mod, modf,
nextfloat, prevfloat, promote_rule, rem, round, show,
showcompact, sum, sqrt, string, print, trunc, precision, exp10, expm1,
sum, sqrt, string, print, trunc, precision, exp10, expm1,
gamma, lgamma, digamma, erf, erfc, zeta, eta, log1p, airyai,
eps, signbit, sin, cos, tan, sec, csc, cot, acos, asin, atan,
cosh, sinh, tanh, sech, csch, coth, acosh, asinh, atanh, atan2,
Expand Down Expand Up @@ -863,7 +863,6 @@ end

print(io::IO, b::BigFloat) = print(io, string(b))
show(io::IO, b::BigFloat) = print(io, string(b))
showcompact(io::IO, b::BigFloat) = print(io, string(b))

# get/set exponent min/max
get_emax() = ccall((:mpfr_get_emax, :libmpfr), Clong, ())
Expand Down
4 changes: 2 additions & 2 deletions base/precompile.jl
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ precompile(Base.abspath, (UTF8String, UTF8String))
precompile(Base.abspath, (UTF8String,))
precompile(Base.abspath, (ASCIIString, ASCIIString))
precompile(Base.abspath, (ASCIIString,))
precompile(Base.alignment, (Float64,))
precompile(Base.alignment, (Base.IOContext, Float64,))
precompile(Base.any, (Function, Array{Any,1}))
precompile(Base.arg_gen, (ASCIIString,))
precompile(Base.associate_julia_struct, (Ptr{Void}, Base.TTY))
Expand Down Expand Up @@ -379,7 +379,7 @@ precompile(Base.setindex!, (Vector{Any}, Vector{Any}, Int))
precompile(Base.show, (Base.Terminals.TTYTerminal, Int))
precompile(Base.show, (Float64,))
precompile(Base.show, (IOStream, Int32))
precompile(Base.showlimited, (Base.Terminals.TTYTerminal, Int))
precompile(Base.showcompact, (Base.Terminals.TTYTerminal, Int))
precompile(Base.similar, (Array{Base.LineEdit.Prompt, 1}, Type{Base.LineEdit.TextInterface}, Tuple{Int}))
precompile(Base.size, (Base.Terminals.TTYTerminal,))
precompile(Base.sizehint!, (Base.Dict{Symbol, Any}, Int))
Expand Down
Loading

0 comments on commit 4706184

Please sign in to comment.