Revision f82f82fb856f5b999ed59130b62a85edd1ac5a54 authored by Jeff Bezanson on 18 January 2018, 21:58:06 UTC, committed by GitHub on 18 January 2018, 21:58:06 UTC
remove some underscores
interactiveutil.jl
# This file is a part of Julia. License is MIT: https://julialang.org/license
# editing files
"""
editor()
Determine the editor to use when running functions like `edit`. Return an `Array` compatible
for use within backticks. You can change the editor by setting `JULIA_EDITOR`, `VISUAL` or
`EDITOR` as an environment variable.
"""
function editor()
if Sys.iswindows() || Sys.isapple()
default_editor = "open"
elseif isfile("/etc/alternatives/editor")
default_editor = "/etc/alternatives/editor"
else
default_editor = "emacs"
end
# Note: the editor path can include spaces (if escaped) and flags.
args = shell_split(get(ENV,"JULIA_EDITOR", get(ENV,"VISUAL", get(ENV,"EDITOR", default_editor))))
isempty(args) && error("editor is empty")
return args
end
"""
edit(path::AbstractString, line::Integer=0)
Edit a file or directory optionally providing a line number to edit the file at.
Return to the `julia` prompt when you quit the editor. The editor can be changed
by setting `JULIA_EDITOR`, `VISUAL` or `EDITOR` as an environment variable.
"""
function edit(path::AbstractString, line::Integer=0)
command = editor()
name = basename(first(command))
if endswith(path, ".jl")
f = find_source_file(path)
f !== nothing && (path = f)
end
background = true
line_unsupported = false
if startswith(name, "vim.") || name == "vi" || name == "vim" || name == "nvim" ||
name == "mvim" || name == "nano" ||
name == "emacs" && any(c -> c in ["-nw", "--no-window-system" ], command) ||
name == "emacsclient" && any(c -> c in ["-nw", "-t", "-tty"], command)
cmd = line != 0 ? `$command +$line $path` : `$command $path`
background = false
elseif startswith(name, "emacs") || name == "gedit" || startswith(name, "gvim")
cmd = line != 0 ? `$command +$line $path` : `$command $path`
elseif name == "textmate" || name == "mate" || name == "kate"
cmd = line != 0 ? `$command $path -l $line` : `$command $path`
elseif startswith(name, "subl") || startswith(name, "atom")
cmd = line != 0 ? `$command $path:$line` : `$command $path`
elseif name == "code" || (Sys.iswindows() && uppercase(name) == "CODE.EXE")
cmd = line != 0 ? `$command -g $path:$line` : `$command -g $path`
elseif startswith(name, "notepad++")
cmd = line != 0 ? `$command $path -n$line` : `$command $path`
elseif Sys.isapple() && name == "open"
cmd = `open -t $path`
line_unsupported = true
else
cmd = `$command $path`
background = false
line_unsupported = true
end
if Sys.iswindows() && name == "open"
@static Sys.iswindows() && # don't emit this ccall on other platforms
systemerror(:edit, ccall((:ShellExecuteW, "shell32"), stdcall, Int,
(Ptr{Cvoid}, Cwstring, Cwstring, Ptr{Cvoid}, Ptr{Cvoid}, Cint),
C_NULL, "open", path, C_NULL, C_NULL, 10) ≤ 32)
elseif background
spawn(pipeline(cmd, stderr=STDERR))
else
run(cmd)
end
line != 0 && line_unsupported && println("Unknown editor: no line number information passed.\nThe method is defined at line $line.")
nothing
end
"""
edit(function, [types])
Edit the definition of a function, optionally specifying a tuple of types to
indicate which method to edit. The editor can be changed by setting `JULIA_EDITOR`,
`VISUAL` or `EDITOR` as an environment variable.
"""
edit(f) = edit(functionloc(f)...)
edit(f, @nospecialize t) = edit(functionloc(f,t)...)
edit(file, line::Integer) = error("could not find source file for function")
# terminal pager
if Sys.iswindows()
function less(file::AbstractString, line::Integer)
pager = shell_split(get(ENV, "PAGER", "more"))
g = pager[1] == "more" ? "" : "g"
run(Cmd(`$pager +$(line)$(g) \"$file\"`, windows_verbatim = true))
end
else
function less(file::AbstractString, line::Integer)
pager = shell_split(get(ENV, "PAGER", "less"))
run(`$pager +$(line)g $file`)
end
end
"""
less(file::AbstractString, [line::Integer])
Show a file using the default pager, optionally providing a starting line number. Returns to
the `julia` prompt when you quit the pager.
"""
less(file::AbstractString) = less(file, 1)
"""
less(function, [types])
Show the definition of a function using the default pager, optionally specifying a tuple of
types to indicate which method to see.
"""
less(f) = less(functionloc(f)...)
less(f, @nospecialize t) = less(functionloc(f,t)...)
less(file, line::Integer) = error("could not find source file for function")
# clipboard copy and paste
if Sys.isapple()
function clipboard(x)
open(pipeline(`pbcopy`, stderr=STDERR), "w") do io
print(io, x)
end
end
clipboard() = read(`pbpaste`, String)
elseif Sys.islinux() || Sys.KERNEL === :FreeBSD
_clipboardcmd = nothing
const _clipboardcmds = Dict(
:copy => Dict(
:xsel => Sys.islinux() ?
`xsel --nodetach --input --clipboard` : `xsel -c`,
:xclip => `xclip -silent -in -selection clipboard`,
),
:paste => Dict(
:xsel => Sys.islinux() ?
`xsel --nodetach --output --clipboard` : `xsel -p`,
:xclip => `xclip -quiet -out -selection clipboard`,
)
)
function clipboardcmd()
global _clipboardcmd
_clipboardcmd !== nothing && return _clipboardcmd
for cmd in (:xclip, :xsel)
success(pipeline(`which $cmd`, DevNull)) && return _clipboardcmd = cmd
end
pkgs = @static if Sys.islinux()
"xsel or xclip"
elseif Sys.KERNEL === :FreeBSD
"x11/xsel or x11/xclip"
end
error("no clipboard command found, please install $pkgs")
end
function clipboard(x)
c = clipboardcmd()
cmd = get(_clipboardcmds[:copy], c, nothing)
if cmd === nothing
error("unexpected clipboard command: $c")
end
open(pipeline(cmd, stderr=STDERR), "w") do io
print(io, x)
end
end
function clipboard()
c = clipboardcmd()
cmd = get(_clipboardcmds[:paste], c, nothing)
if cmd === nothing
error("unexpected clipboard command: $c")
end
read(pipeline(cmd, stderr=STDERR), String)
end
elseif Sys.iswindows()
# TODO: these functions leak memory and memory locks if they throw an error
function clipboard(x::AbstractString)
if containsnul(x)
throw(ArgumentError("Windows clipboard strings cannot contain NUL character"))
end
systemerror(:OpenClipboard, 0==ccall((:OpenClipboard, "user32"), stdcall, Cint, (Ptr{Cvoid},), C_NULL))
systemerror(:EmptyClipboard, 0==ccall((:EmptyClipboard, "user32"), stdcall, Cint, ()))
x_u16 = cwstring(x)
# copy data to locked, allocated space
p = ccall((:GlobalAlloc, "kernel32"), stdcall, Ptr{UInt16}, (UInt16, Int32), 2, sizeof(x_u16))
systemerror(:GlobalAlloc, p==C_NULL)
plock = ccall((:GlobalLock, "kernel32"), stdcall, Ptr{UInt16}, (Ptr{UInt16},), p)
systemerror(:GlobalLock, plock==C_NULL)
ccall(:memcpy, Ptr{UInt16}, (Ptr{UInt16},Ptr{UInt16},Int), plock, x_u16, sizeof(x_u16))
systemerror(:GlobalUnlock, 0==ccall((:GlobalUnlock, "kernel32"), stdcall, Cint, (Ptr{Cvoid},), plock))
pdata = ccall((:SetClipboardData, "user32"), stdcall, Ptr{UInt16}, (UInt32, Ptr{UInt16}), 13, p)
systemerror(:SetClipboardData, pdata!=p)
ccall((:CloseClipboard, "user32"), stdcall, Cvoid, ())
end
clipboard(x) = clipboard(sprint(print, x)::String)
function clipboard()
systemerror(:OpenClipboard, 0==ccall((:OpenClipboard, "user32"), stdcall, Cint, (Ptr{Cvoid},), C_NULL))
pdata = ccall((:GetClipboardData, "user32"), stdcall, Ptr{UInt16}, (UInt32,), 13)
systemerror(:SetClipboardData, pdata==C_NULL)
systemerror(:CloseClipboard, 0==ccall((:CloseClipboard, "user32"), stdcall, Cint, ()))
plock = ccall((:GlobalLock, "kernel32"), stdcall, Ptr{UInt16}, (Ptr{UInt16},), pdata)
systemerror(:GlobalLock, plock==C_NULL)
# find NUL terminator (0x0000 16-bit code unit)
len = 0
while unsafe_load(plock, len+1) != 0; len += 1; end
# get Vector{UInt16}, transcode data to UTF-8, make a String of it
s = transcode(String, unsafe_wrap(Array, plock, len))
systemerror(:GlobalUnlock, 0==ccall((:GlobalUnlock, "kernel32"), stdcall, Cint, (Ptr{UInt16},), plock))
return s
end
else
clipboard(x="") = error("`clipboard` function not implemented for $(Sys.KERNEL)")
end
"""
clipboard(x)
Send a printed form of `x` to the operating system clipboard ("copy").
"""
clipboard(x)
"""
clipboard() -> AbstractString
Return a string with the contents of the operating system clipboard ("paste").
"""
clipboard()
# system information
# used by sysinfo.jl
function _show_cpuinfo(io::IO, info::Sys.CPUinfo, header::Bool=true, prefix::AbstractString=" ")
tck = Sys.SC_CLK_TCK
if header
println(io, info.model, ": ")
print(io, " "^length(prefix))
if tck > 0
Printf.@printf(io, " %5s %9s %9s %9s %9s %9s\n",
"speed", "user", "nice", "sys", "idle", "irq")
else
Printf.@printf(io, " %5s %9s %9s %9s %9s %9s ticks\n",
"speed", "user", "nice", "sys", "idle", "irq")
end
end
print(io, prefix)
if tck > 0
Printf.@printf(io, "%5d MHz %9d s %9d s %9d s %9d s %9d s",
info.speed, info.cpu_times!user / tck, info.cpu_times!nice / tck,
info.cpu_times!sys / tck, info.cpu_times!idle / tck, info.cpu_times!irq / tck)
else
Printf.@printf(io, "%5d MHz %9d %9d %9d %9d %9d ticks",
info.speed, info.cpu_times!user, info.cpu_times!nice,
info.cpu_times!sys, info.cpu_times!idle, info.cpu_times!irq)
end
end
"""
versioninfo(io::IO=STDOUT; verbose::Bool=false, packages::Bool=false)
Print information about the version of Julia in use. The output is
controlled with boolean keyword arguments:
- `packages`: print information about installed packages
- `verbose`: print all additional information
"""
function versioninfo(io::IO=STDOUT; verbose::Bool=false, packages::Bool=false)
println(io, "Julia Version $VERSION")
if !isempty(GIT_VERSION_INFO.commit_short)
println(io, "Commit $(GIT_VERSION_INFO.commit_short) ($(GIT_VERSION_INFO.date_string))")
end
if ccall(:jl_is_debugbuild, Cint, ())!=0
println(io, "DEBUG build")
end
println(io, "Platform Info:")
println(io, " OS: ", Sys.iswindows() ? "Windows" : Sys.isapple() ?
"macOS" : Sys.KERNEL, " (", Sys.MACHINE, ")")
if verbose
lsb = ""
if Sys.islinux()
try lsb = readchomp(pipeline(`lsb_release -ds`, stderr=DevNull)) end
end
if Sys.iswindows()
try lsb = strip(read(`$(ENV["COMSPEC"]) /c ver`, String)) end
end
if !isempty(lsb)
println(io, " ", lsb)
end
if Sys.isunix()
println(io, " uname: ", readchomp(`uname -mprsv`))
end
end
if verbose
cpuio = IOBuffer() # print cpu_summary with correct alignment
Sys.cpu_summary(cpuio)
for (i, line) in enumerate(split(String(take!(cpuio)), "\n"))
prefix = i == 1 ? " CPU: " : " "
println(io, prefix, line)
end
else
cpu = Sys.cpu_info()
println(io, " CPU: ", cpu[1].model)
end
if verbose
println(io, " Memory: $(Sys.total_memory()/2^30) GB ($(Sys.free_memory()/2^20) MB free)")
try println(io, " Uptime: $(Sys.uptime()) sec") end
print(io, " Load Avg: ")
print_matrix(io, Sys.loadavg()')
println(io)
end
println(io, " WORD_SIZE: ", Sys.WORD_SIZE)
println(io, " LIBM: ",libm_name)
println(io, " LLVM: libLLVM-",libllvm_version," (", Sys.JIT, ", ", Sys.CPU_NAME, ")")
println(io, "Environment:")
for (k,v) in ENV
if contains(String(k), r"JULIA")
println(io, " $(k) = $(v)")
end
end
if verbose
for (k,v) in ENV
if contains(String(k), r"PATH|FLAG|^TERM$|HOME")
println(io, " $(k) = $(v)")
end
end
end
if packages || verbose
println(io, "Packages:")
println(io, " Package Directory: ", Pkg.dir())
print(io, " Package Status:")
if isdir(Pkg.dir())
println(io, "")
Pkg.status(io)
else
println(io, " no packages installed")
end
end
end
# displaying type-ambiguity warnings
"""
code_warntype([io::IO], f, types)
Prints lowered and type-inferred ASTs for the methods matching the given generic function
and type signature to `io` which defaults to `STDOUT`. The ASTs are annotated in such a way
as to cause "non-leaf" types to be emphasized (if color is available, displayed in red).
This serves as a warning of potential type instability. Not all non-leaf types are particularly
problematic for performance, so the results need to be used judiciously.
In particular, unions containing either [`missing`](@ref) or [`nothing`](@ref) are displayed in yellow, since
these are often intentional.
See [`@code_warntype`](@ref man-code-warntype) for more information.
"""
function code_warntype(io::IO, f, @nospecialize(t))
function slots_used(ci, slotnames)
used = falses(length(slotnames))
scan_exprs!(used, ci.code)
return used
end
function scan_exprs!(used, exprs)
for ex in exprs
if isa(ex, Slot)
used[ex.id] = true
elseif isa(ex, Expr)
scan_exprs!(used, ex.args)
end
end
end
emph_io = IOContext(io, :TYPEEMPHASIZE => true)
for (src, rettype) in code_typed(f, t)
println(emph_io, "Variables:")
slotnames = sourceinfo_slotnames(src)
used_slotids = slots_used(src, slotnames)
for i = 1:length(slotnames)
if used_slotids[i]
print(emph_io, " ", slotnames[i])
if isa(src.slottypes, Array)
show_expr_type(emph_io, src.slottypes[i], true)
end
print(emph_io, '\n')
elseif !('#' in slotnames[i] || '@' in slotnames[i])
print(emph_io, " ", slotnames[i], "<optimized out>\n")
end
end
print(emph_io, "\nBody:\n ")
body = Expr(:body)
body.args = src.code
body.typ = rettype
# Fix slot names and types in function body
show_unquoted(IOContext(emph_io, :SOURCEINFO => src, :SOURCE_SLOTNAMES => slotnames),
body, 2)
print(emph_io, '\n')
end
nothing
end
code_warntype(f, @nospecialize(t)) = code_warntype(STDOUT, f, t)
typesof(args...) = Tuple{Any[ Core.Typeof(a) for a in args ]...}
function gen_call_with_extracted_types(__module__, fcn, ex0)
if isa(ex0, Expr)
if any(a->(Meta.isexpr(a, :kw) || Meta.isexpr(a, :parameters)), ex0.args)
# remove keyword args, but call the kwfunc
args = filter(a->!(Meta.isexpr(a, :kw) || Meta.isexpr(a, :parameters)), ex0.args)
return quote
local arg1 = $(esc(args[1]))
$(fcn)(Core.kwfunc(arg1),
Tuple{Any, Core.Typeof(arg1),
$(typesof)($(map(esc, args[2:end])...)).parameters...})
end
elseif ex0.head == :call
return Expr(:call, fcn, esc(ex0.args[1]),
Expr(:call, typesof, map(esc, ex0.args[2:end])...))
elseif ex0.head == :(.)
return Expr(:call, fcn, :getproperty,
Expr(:call, typesof, map(esc, ex0.args)...))
elseif ex0.head == :(=) && length(ex0.args) == 2 && ex0.args[1].head == :(.)
return Expr(:call, fcn, :(setproperty!),
Expr(:call, typesof, map(esc, [ex0.args[1].args..., ex0.args[2]])...))
end
end
if isa(ex0, Expr) && ex0.head == :macrocall # Make @edit @time 1+2 edit the macro by using the types of the *expressions*
return Expr(:call, fcn, esc(ex0.args[1]), Tuple{#=__source__=#LineNumberNode, #=__module__=#Module, Any[ Core.Typeof(a) for a in ex0.args[3:end] ]...})
end
ex = Meta.lower(__module__, ex0)
exret = Expr(:none)
if !isa(ex, Expr)
exret = Expr(:call, :error, "expression is not a function call or symbol")
elseif ex.head == :call
if any(e->(isa(e, Expr) && e.head==:(...)), ex0.args) &&
(ex.args[1] === GlobalRef(Core,:_apply) ||
ex.args[1] === GlobalRef(Base,:_apply))
# check for splatting
exret = Expr(:call, ex.args[1], fcn,
Expr(:tuple, esc(ex.args[2]),
Expr(:call, typesof, map(esc, ex.args[3:end])...)))
else
exret = Expr(:call, fcn, esc(ex.args[1]),
Expr(:call, typesof, map(esc, ex.args[2:end])...))
end
elseif ex.head == :body
a1 = ex.args[1]
if isa(a1, Expr) && a1.head == :call
a11 = a1.args[1]
if a11 == :setindex!
exret = Expr(:call, fcn, a11,
Expr(:call, typesof, map(esc, a1.args[2:end])...))
end
end
end
if ex.head == :thunk || exret.head == :none
exret = Expr(:call, :error, "expression is not a function call, "
* "or is too complex for @$fcn to analyze; "
* "break it down to simpler parts if possible")
end
return exret
end
for fname in [:which, :less, :edit, :functionloc, :code_warntype,
:code_llvm, :code_llvm_raw, :code_native]
@eval begin
macro ($fname)(ex0)
gen_call_with_extracted_types(__module__, $(Expr(:quote, fname)), ex0)
end
end
end
macro which(ex0::Symbol)
ex0 = QuoteNode(ex0)
return :(which_module($__module__, $ex0))
end
for fname in [:code_typed, :code_lowered]
@eval begin
macro ($fname)(ex0)
thecall = gen_call_with_extracted_types(__module__, $(Expr(:quote, fname)), ex0)
quote
results = $thecall
length(results) == 1 ? results[1] : results
end
end
end
end
"""
@which
Applied to a function or macro call, it evaluates the arguments to the specified call, and
returns the `Method` object for the method that would be called for those arguments. Applied
to a variable, it returns the module in which the variable was bound. It calls out to the
`which` function.
"""
:@which
"""
@less
Evaluates the arguments to the function or macro call, determines their types, and calls the `less`
function on the resulting expression.
"""
:@less
"""
@edit
Evaluates the arguments to the function or macro call, determines their types, and calls the `edit`
function on the resulting expression.
"""
:@edit
"""
@functionloc
Applied to a function or macro call, it evaluates the arguments to the specified call, and
returns a tuple `(filename,line)` giving the location for the method that would be called for those arguments.
It calls out to the `functionloc` function.
"""
:@functionloc
"""
@code_typed
Evaluates the arguments to the function or macro call, determines their types, and calls
[`code_typed`](@ref) on the resulting expression.
"""
:@code_typed
"""
@code_warntype
Evaluates the arguments to the function or macro call, determines their types, and calls
[`code_warntype`](@ref) on the resulting expression.
"""
:@code_warntype
"""
@code_lowered
Evaluates the arguments to the function or macro call, determines their types, and calls
[`code_lowered`](@ref) on the resulting expression.
"""
:@code_lowered
"""
@code_llvm
Evaluates the arguments to the function or macro call, determines their types, and calls
[`code_llvm`](@ref) on the resulting expression.
"""
:@code_llvm
"""
@code_native
Evaluates the arguments to the function or macro call, determines their types, and calls
[`code_native`](@ref) on the resulting expression.
"""
:@code_native
function type_close_enough(@nospecialize(x), @nospecialize(t))
x == t && return true
return (isa(x,DataType) && isa(t,DataType) && x.name === t.name &&
!_isleaftype(t) && x <: t) ||
(isa(x,Union) && isa(t,DataType) && (type_close_enough(x.a, t) || type_close_enough(x.b, t)))
end
# `methodswith` -- shows a list of methods using the type given
"""
methodswith(typ[, module or function][, showparents::Bool=false])
Return an array of methods with an argument of type `typ`.
The optional second argument restricts the search to a particular module or function
(the default is all top-level modules).
If optional `showparents` is `true`, also return arguments with a parent type of `typ`,
excluding type `Any`.
"""
function methodswith(t::Type, f::Function, showparents::Bool=false, meths = Method[])
for d in methods(f)
if any(function (x)
let x = rewrap_unionall(x, d.sig)
(type_close_enough(x, t) ||
(showparents ? (t <: x && (!isa(x,TypeVar) || x.ub != Any)) :
(isa(x,TypeVar) && x.ub != Any && t == x.ub)) &&
x != Any)
end
end,
unwrap_unionall(d.sig).parameters)
push!(meths, d)
end
end
return meths
end
function _methodswith(t::Type, m::Module, showparents::Bool)
meths = Method[]
for nm in names(m)
if isdefined(m, nm)
f = getfield(m, nm)
if isa(f, Function)
methodswith(t, f, showparents, meths)
end
end
end
return unique(meths)
end
methodswith(t::Type, m::Module, showparents::Bool=false) = _methodswith(t, m, showparents)
function methodswith(t::Type, showparents::Bool=false)
meths = Method[]
for mod in loaded_modules_array()
append!(meths, _methodswith(t, mod, showparents))
end
return unique(meths)
end
# file downloading
downloadcmd = nothing
if Sys.iswindows()
downloadcmd = :powershell
function download(url::AbstractString, filename::AbstractString)
ps = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"
tls12 = "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
client = "New-Object System.Net.Webclient"
# in the following we escape ' with '' (see https://ss64.com/ps/syntax-esc.html)
downloadfile = "($client).DownloadFile('$(replace(url, "'" => "''"))', '$(replace(filename, "'" => "''"))')"
run(`$ps -NoProfile -Command "$tls12; $downloadfile"`)
filename
end
else
function download(url::AbstractString, filename::AbstractString)
global downloadcmd
if downloadcmd === nothing
for checkcmd in (:curl, :wget, :fetch)
if success(pipeline(`which $checkcmd`, DevNull))
downloadcmd = checkcmd
break
end
end
end
if downloadcmd == :wget
try
run(`wget -O $filename $url`)
catch
rm(filename) # wget always creates a file
rethrow()
end
elseif downloadcmd == :curl
run(`curl -g -L -f -o $filename $url`)
elseif downloadcmd == :fetch
run(`fetch -f $filename $url`)
else
error("no download agent available; install curl, wget, or fetch")
end
filename
end
end
function download(url::AbstractString)
filename = tempname()
download(url, filename)
end
"""
download(url::AbstractString, [localfile::AbstractString])
Download a file from the given url, optionally renaming it to the given local file name.
Note that this function relies on the availability of external tools such as `curl`, `wget`
or `fetch` to download the file and is provided for convenience. For production use or
situations in which more options are needed, please use a package that provides the desired
functionality instead.
"""
download(url, filename)
# testing
"""
Base.runtests(tests=["all"], numcores=ceil(Int, Sys.CPU_CORES / 2);
exit_on_error=false, [seed])
Run the Julia unit tests listed in `tests`, which can be either a string or an array of
strings, using `numcores` processors. If `exit_on_error` is `false`, when one test
fails, all remaining tests in other files will still be run; they are otherwise discarded,
when `exit_on_error == true`.
If a seed is provided via the keyword argument, it is used to seed the
global RNG in the context where the tests are run; otherwise the seed is chosen randomly.
"""
function runtests(tests = ["all"], numcores = ceil(Int, Sys.CPU_CORES / 2);
exit_on_error=false,
seed::Union{BitInteger,Nothing}=nothing)
if isa(tests,AbstractString)
tests = split(tests)
end
exit_on_error && push!(tests, "--exit-on-error")
seed != nothing && push!(tests, "--seed=0x$(hex(seed % UInt128))") # cast to UInt128 to avoid a minus sign
ENV2 = copy(ENV)
ENV2["JULIA_CPU_CORES"] = "$numcores"
try
run(setenv(`$(julia_cmd()) $(joinpath(Sys.BINDIR,
Base.DATAROOTDIR, "julia", "test", "runtests.jl")) $tests`, ENV2))
catch
buf = PipeBuffer()
versioninfo(buf)
error("A test has failed. Please submit a bug report (https://github.com/JuliaLang/julia/issues)\n" *
"including error messages above and the output of versioninfo():\n$(read(buf, String))")
end
end
# testing
"""
varinfo(m::Module=Main, pattern::Regex=r"")
Return a markdown table giving information about exported global variables in a module, optionally restricted
to those matching `pattern`.
The memory consumption estimate is an approximate lower bound on the size of the internal structure of the object.
"""
function varinfo(m::Module=Main, pattern::Regex=r"")
rows =
Any[ let value = getfield(m, v)
Any[string(v),
(any(x -> x === value, (Base, Main, Core)) ? "" : format_bytes(summarysize(value))),
summary(value)]
end
for v in sort!(names(m)) if isdefined(m, v) && contains(string(v), pattern) ]
pushfirst!(rows, Any["name", "size", "summary"])
return Markdown.MD(Any[Markdown.Table(rows, Symbol[:l, :r, :l])])
end
varinfo(pat::Regex) = varinfo(Main, pat)
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...