From 59164eb2257fa90ef08f4e6d3132668d7fa90b7b Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sat, 17 Feb 2024 20:42:29 -0500 Subject: [PATCH] add readdirx which returns more object info --- base/exports.jl | 1 + base/file.jl | 65 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 61 insertions(+), 5 deletions(-) diff --git a/base/exports.jl b/base/exports.jl index a31ea1b0fa8420..4b3ca772145861 100644 --- a/base/exports.jl +++ b/base/exports.jl @@ -865,6 +865,7 @@ export readbytes!, readchomp, readdir, + readdirx, readline, readlines, readuntil, diff --git a/base/file.jl b/base/file.jl index 6347f042e3422e..7a1a2d431be1fe 100644 --- a/base/file.jl +++ b/base/file.jl @@ -19,6 +19,7 @@ export rename, readlink, readdir, + readdirx, rm, samefile, sendfile, @@ -29,6 +30,8 @@ export unlink, walkdir +import Base.== + # get and set current directory """ @@ -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 @@ -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 @@ -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)