Revision b0ef6fc6fff067f6daa937d9b36a7879e6ea4b61 authored by Jameson Nash on 02 January 2018, 17:29:04 UTC, committed by Jameson Nash on 02 January 2018, 17:29:06 UTC
A GitHub link is not necessarily the most stable reference, and also appears to only list the top 100. The updated text is intended to make it clear that this lists may not be fully accurate (as JuliaLang does not have full control over it), and inform the user of an alternate method of listing the JuliaLang authorship history through git.
1 parent 2cc82d2
TestHelpers.jl
# This file is a part of Julia. License is MIT: https://julialang.org/license
module TestHelpers
include("dimensionful.jl")
export Furlong
mutable struct FakeTerminal <: Base.Terminals.UnixTerminal
in_stream::Base.IO
out_stream::Base.IO
err_stream::Base.IO
hascolor::Bool
raw::Bool
FakeTerminal(stdin,stdout,stderr,hascolor=true) =
new(stdin,stdout,stderr,hascolor,false)
end
Base.Terminals.hascolor(t::FakeTerminal) = t.hascolor
Base.Terminals.raw!(t::FakeTerminal, raw::Bool) = t.raw = raw
Base.Terminals.size(t::FakeTerminal) = (24, 80)
function open_fake_pty()
@static if Sys.iswindows()
error("Unable to create a fake PTY in Windows")
end
O_RDWR = Base.Filesystem.JL_O_RDWR
O_NOCTTY = Base.Filesystem.JL_O_NOCTTY
fdm = ccall(:posix_openpt, Cint, (Cint,), O_RDWR|O_NOCTTY)
fdm == -1 && error("Failed to open PTY master")
rc = ccall(:grantpt, Cint, (Cint,), fdm)
rc != 0 && error("grantpt failed")
rc = ccall(:unlockpt, Cint, (Cint,), fdm)
rc != 0 && error("unlockpt")
fds = ccall(:open, Cint, (Ptr{UInt8}, Cint),
ccall(:ptsname, Ptr{UInt8}, (Cint,), fdm), O_RDWR|O_NOCTTY)
# slave
slave = RawFD(fds)
master = Base.TTY(RawFD(fdm); readable = true)
slave, master
end
function with_fake_pty(f)
slave, master = open_fake_pty()
try
f(slave, master)
finally
ccall(:close,Cint,(Cint,),slave) # XXX: this causes the kernel to throw away all unread data on the pty
close(master)
end
end
function challenge_prompt(code::Expr, challenges; timeout::Integer=10, debug::Bool=true)
output_file = tempname()
wrapped_code = quote
result = let
$code
end
open($output_file, "w") do fp
serialize(fp, result)
end
end
cmd = `$(Base.julia_cmd()) --startup-file=no -e $wrapped_code`
try
challenge_prompt(cmd, challenges, timeout=timeout, debug=debug)
return open(output_file, "r") do fp
deserialize(fp)
end
finally
isfile(output_file) && rm(output_file)
end
return nothing
end
function challenge_prompt(cmd::Cmd, challenges; timeout::Integer=10, debug::Bool=true)
function format_output(output)
!debug && return ""
str = read(seekstart(output), String)
isempty(str) && return ""
"Process output found:\n\"\"\"\n$str\n\"\"\""
end
out = IOBuffer()
with_fake_pty() do slave, master
p = spawn(detach(cmd), slave, slave, slave)
# Kill the process if it takes too long. Typically occurs when process is waiting
# for input.
done = Channel(1)
@async begin
sleep(timeout)
if process_running(p)
kill(p)
put!(done, :timed_out)
else
put!(done, :exited)
end
close(master)
end
try
for (challenge, response) in challenges
write(out, readuntil(master, challenge))
if !isopen(master)
error("Could not locate challenge: \"$challenge\". ",
format_output(out))
end
write(master, response)
end
wait(p)
finally
kill(p)
end
# Process timed out or aborted
if !success(p)
write(out, readavailable(master))
if isready(done) && fetch(done) == :timed_out
error("Process timed out possibly waiting for a response. ",
format_output(out))
else
error("Failed process. ", format_output(out), "\n", p)
end
end
end
nothing
end
# OffsetArrays (arrays with indexing that doesn't start at 1)
# This test file is designed to exercise support for generic indexing,
# even though offset arrays aren't implemented in Base.
module OAs
using Base: Indices, IndexCartesian, IndexLinear, tail
export OffsetArray
struct OffsetArray{T,N,AA<:AbstractArray} <: AbstractArray{T,N}
parent::AA
offsets::NTuple{N,Int}
end
OffsetVector{T,AA<:AbstractArray} = OffsetArray{T,1,AA}
OffsetArray(A::AbstractArray{T,N}, offsets::NTuple{N,Int}) where {T,N} = OffsetArray{T,N,typeof(A)}(A, offsets)
OffsetArray(A::AbstractArray{T,N}, offsets::Vararg{Int,N}) where {T,N} = OffsetArray(A, offsets)
OffsetArray{T,N}(::Uninitialized, inds::Indices{N}) where {T,N} =
OffsetArray{T,N,Array{T,N}}(Array{T,N}(uninitialized, map(length, inds)), map(indsoffset, inds))
OffsetArray{T}(::Uninitialized, inds::Indices{N}) where {T,N} =
OffsetArray{T,N}(uninitialized, inds)
Base.IndexStyle(::Type{T}) where {T<:OffsetArray} = Base.IndexStyle(parenttype(T))
parenttype(::Type{OffsetArray{T,N,AA}}) where {T,N,AA} = AA
parenttype(A::OffsetArray) = parenttype(typeof(A))
Base.parent(A::OffsetArray) = A.parent
errmsg(A) = error("size not supported for arrays with indices $(axes(A)); see https://docs.julialang.org/en/latest/devdocs/offset-arrays/")
Base.size(A::OffsetArray) = errmsg(A)
Base.size(A::OffsetArray, d) = errmsg(A)
Base.eachindex(::IndexCartesian, A::OffsetArray) = CartesianIndices(axes(A))
Base.eachindex(::IndexLinear, A::OffsetVector) = axes(A, 1)
# Implementations of indices and indices1. Since bounds-checking is
# performance-critical and relies on indices, these are usually worth
# optimizing thoroughly.
@inline Base.axes(A::OffsetArray, d) = 1 <= d <= length(A.offsets) ? axes(parent(A))[d] .+ A.offsets[d] : (1:1)
@inline Base.axes(A::OffsetArray) = _indices(axes(parent(A)), A.offsets) # would rather use ntuple, but see #15276
@inline _indices(inds, offsets) = (inds[1] .+ offsets[1], _indices(tail(inds), tail(offsets))...)
_indices(::Tuple{}, ::Tuple{}) = ()
Base.indices1(A::OffsetArray{T,0}) where {T} = 1:1 # we only need to specialize this one
function Base.similar(A::OffsetArray, T::Type, dims::Dims)
B = similar(parent(A), T, dims)
end
function Base.similar(A::AbstractArray, T::Type, inds::Tuple{UnitRange,Vararg{UnitRange}})
B = similar(A, T, map(length, inds))
OffsetArray(B, map(indsoffset, inds))
end
Base.similar(f::Union{Function,Type}, shape::Tuple{UnitRange,Vararg{UnitRange}}) =
OffsetArray(f(map(length, shape)), map(indsoffset, shape))
Base.similar(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) where {T<:Array} =
OffsetArray(T(uninitialized, map(length, shape)), map(indsoffset, shape))
Base.similar(::Type{T}, shape::Tuple{UnitRange,Vararg{UnitRange}}) where {T<:BitArray} =
OffsetArray(T(uninitialized, map(length, shape)), map(indsoffset, shape))
Base.reshape(A::AbstractArray, inds::Tuple{UnitRange,Vararg{UnitRange}}) = OffsetArray(reshape(A, map(length, inds)), map(indsoffset, inds))
@inline function Base.getindex(A::OffsetArray{T,N}, I::Vararg{Int,N}) where {T,N}
checkbounds(A, I...)
@inbounds ret = parent(A)[offset(A.offsets, I)...]
ret
end
# Vectors don't support one-based linear indexing; they always use the offsets
@inline function Base.getindex(A::OffsetVector, i::Int)
checkbounds(A, i)
@inbounds ret = parent(A)[offset(A.offsets, (i,))[1]]
ret
end
# But multidimensional arrays allow one-based linear indexing
@inline function Base.getindex(A::OffsetArray, i::Int)
checkbounds(A, i)
@inbounds ret = parent(A)[i]
ret
end
@inline function Base.setindex!(A::OffsetArray{T,N}, val, I::Vararg{Int,N}) where {T,N}
checkbounds(A, I...)
@inbounds parent(A)[offset(A.offsets, I)...] = val
val
end
@inline function Base.setindex!(A::OffsetVector, val, i::Int)
checkbounds(A, i)
@inbounds parent(A)[offset(A.offsets, (i,))[1]] = val
val
end
@inline function Base.setindex!(A::OffsetArray, val, i::Int)
checkbounds(A, i)
@inbounds parent(A)[i] = val
val
end
@inline function Base.deleteat!(A::OffsetArray, i::Int)
checkbounds(A, i)
@inbounds deleteat!(parent(A), offset(A.offsets, (i,))[1])
end
@inline function Base.deleteat!(A::OffsetArray{T,N}, I::Vararg{Int, N}) where {T,N}
checkbounds(A, I...)
@inbounds deleteat!(parent(A), offset(A.offsets, I)...)
end
@inline function Base.deleteat!(A::OffsetArray, i::UnitRange{Int})
checkbounds(A, first(i))
checkbounds(A, last(i))
first_idx = offset(A.offsets, (first(i),))[1]
last_idx = offset(A.offsets, (last(i),))[1]
@inbounds deleteat!(parent(A), first_idx:last_idx)
end
# Computing a shifted index (subtracting the offset)
offset(offsets::NTuple{N,Int}, inds::NTuple{N,Int}) where {N} = _offset((), offsets, inds)
_offset(out, ::Tuple{}, ::Tuple{}) = out
@inline _offset(out, offsets, inds) = _offset((out..., inds[1]-offsets[1]), Base.tail(offsets), Base.tail(inds))
indsoffset(r::AbstractRange) = first(r) - 1
indsoffset(i::Integer) = 0
Base.resize!(A::OffsetVector, nl::Integer) = (resize!(A.parent, nl); A)
end
end
![swh spinner](/static/img/swh-spinner.gif)
Computing file changes ...