Skip to content

Commit

Permalink
add readdirx which returns more object info
Browse files Browse the repository at this point in the history
  • Loading branch information
IanButterworth committed Feb 18, 2024
1 parent 3ed2b49 commit 59164eb
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 5 deletions.
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -865,6 +865,7 @@ export
readbytes!,
readchomp,
readdir,
readdirx,
readline,
readlines,
readuntil,
Expand Down
65 changes: 60 additions & 5 deletions base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export
rename,
readlink,
readdir,
readdirx,
rm,
samefile,
sendfile,
Expand All @@ -29,6 +30,8 @@ export
unlink,
walkdir

import Base.==

# get and set current directory

"""
Expand Down Expand Up @@ -913,7 +916,56 @@ julia> readdir(abspath("base"), join=true)
"/home/JuliaUser/dev/julia/base/weakkeydict.jl"
```
"""
function readdir(dir::AbstractString; join::Bool=false, sort::Bool=true)
readdir(; join::Bool=false, kwargs...) = readdir(join ? pwd() : "."; join, kwargs...)::Vector{String}
readdir(dir::AbstractString; kwargs...) = _readdir(dir; return_objects=false, kwargs...)::Vector{String}

# this might be better as an Enum but they're not available here
# UV_DIRENT_T
const UV_DIRENT_UNKNOWN = Cint(0)
const UV_DIRENT_FILE = Cint(1)
const UV_DIRENT_DIR = Cint(2)
const UV_DIRENT_LINK = Cint(3)
const UV_DIRENT_FIFO = Cint(4)
const UV_DIRENT_SOCKET = Cint(5)
const UV_DIRENT_CHAR = Cint(6)
const UV_DIRENT_BLOCK = Cint(7)
struct FileKind
dir::String
name::String
rawtype::Cint
end
function Base.getproperty(obj::FileKind, p::Symbol)
if p == :path
return joinpath(obj.dir, obj.name)
else
return getfield(obj, p)
end
end
Base.isless(a::FileKind, b::FileKind) = isless(a.name, b.name)
==(a::FileKind, b::FileKind) = a.name == b.name
==(a::AbstractString, b::FileKind) = a == b.name
==(a::FileKind, b::AbstractString) = b == a
joinpath(obj::FileKind, args...) = joinpath(obj.path, args...)
Base.convert(::Type{String}, obj::FileKind) = obj.name
isunknown(obj::FileKind) = obj.rawtype == UV_DIRENT_UNKNOWN
islink(obj::FileKind) = isunknown(obj) ? islink(obj.path) : obj.rawtype == UV_DIRENT_LINK
isfile(obj::FileKind) = (isunknown(obj) || islink(obj)) ? isfile(obj.path) : obj.rawtype == UV_DIRENT_FILE
isdir(obj::FileKind) = (isunknown(obj) || islink(obj)) ? isdir(obj.path) : obj.rawtype == UV_DIRENT_DIR
isfifo(obj::FileKind) = (isunknown(obj) || islink(obj)) ? isfifo(obj.path) : obj.rawtype == UV_DIRENT_FIFO
issocket(obj::FileKind) = (isunknown(obj) || islink(obj)) ? issocket(obj.path) : obj.rawtype == UV_DIRENT_SOCKET
ischardev(obj::FileKind) = (isunknown(obj) || islink(obj)) ? ischardev(obj.path) : obj.rawtype == UV_DIRENT_CHAR
isblockdev(obj::FileKind) = (isunknown(obj) || islink(obj)) ? isblockdev(obj.path) : obj.rawtype == UV_DIRENT_BLOCK

"""
readdirx(dir::AbstractString=pwd();
join::Bool = false,
sort::Bool = true,
) -> Vector{FileKind}
"""
readdirx(; join::Bool=false, kwargs...) = readdirx(join ? pwd() : "."; join, kwargs...)::Vector{FileKind}
readdirx(dir::AbstractString; kwargs...) = _readdir(dir; return_objects=true, kwargs...)::Vector{FileKind}

function _readdir(dir::AbstractString; return_objects::Bool=false, join::Bool=false, sort::Bool=true)
# Allocate space for uv_fs_t struct
req = Libc.malloc(_sizeof_uv_fs)
try
Expand All @@ -923,11 +975,16 @@ function readdir(dir::AbstractString; join::Bool=false, sort::Bool=true)
err < 0 && uv_error("readdir($(repr(dir)))", err)

# iterate the listing into entries
entries = String[]
entries = return_objects ? FileKind[] : String[]
ent = Ref{uv_dirent_t}()
while Base.UV_EOF != ccall(:uv_fs_scandir_next, Cint, (Ptr{Cvoid}, Ptr{uv_dirent_t}), req, ent)
name = unsafe_string(ent[].name)
push!(entries, join ? joinpath(dir, name) : name)
if return_objects
rawtype = ent[].typ
push!(entries, FileKind(dir, name, rawtype))
else
push!(entries, join ? joinpath(dir, name) : name)
end
end

# Clean up the request string
Expand All @@ -941,8 +998,6 @@ function readdir(dir::AbstractString; join::Bool=false, sort::Bool=true)
Libc.free(req)
end
end
readdir(; join::Bool=false, sort::Bool=true) =
readdir(join ? pwd() : ".", join=join, sort=sort)

"""
walkdir(dir; topdown=true, follow_symlinks=false, onerror=throw)
Expand Down

0 comments on commit 59164eb

Please sign in to comment.