[examples/ls] Add ls example.
This commit is contained in:
parent
c55267d256
commit
eefe4d3f6c
|
@ -0,0 +1,140 @@
|
|||
#!/bin/env lua
|
||||
-- Basic Unix-style directory listing.
|
||||
-- Demonstrates low-level raw use of a Dir, in order to list even . and .. to
|
||||
-- output.
|
||||
--
|
||||
-- NOTE: the simplistic argument parser doesn't handle merged options like -ht.
|
||||
--
|
||||
-- Example uses:
|
||||
-- lua ls.lua
|
||||
-- lua ls.lua -a ..
|
||||
-- lua ls.lua -a -h src
|
||||
-- lua ls.lua -a -t a.dir b.dir c.dir
|
||||
--
|
||||
-- Author: Lorenzo Cogotti, The DoubleFourteen Code Forge
|
||||
|
||||
local osx = require 'osx'
|
||||
local io = require 'io'
|
||||
local write = io.write
|
||||
|
||||
local sep = osx.sep
|
||||
local aflag = false -- list hidden
|
||||
local tflag = false -- sort by time
|
||||
local Sflag = false -- sort by size
|
||||
local hflag = false -- print size, human readable (equivalent to -sh)
|
||||
|
||||
local function parseargs(...)
|
||||
local args = {}
|
||||
|
||||
for i = 1,select('#', ...) do
|
||||
local arg = select(i, ...)
|
||||
|
||||
if arg == '-a' then
|
||||
aflag = true
|
||||
elseif arg == '-t' then
|
||||
tflag, Sflag = true, false
|
||||
elseif arg == '-S' then
|
||||
Sflag, tflag = true, false
|
||||
elseif arg == '-h' then
|
||||
hflag = true
|
||||
else
|
||||
args[#args+1] = arg
|
||||
end
|
||||
end
|
||||
if #args == 0 then
|
||||
args = { "." } -- current directory by default
|
||||
end
|
||||
return args
|
||||
end
|
||||
|
||||
local function ksize(sz)
|
||||
sz = sz / 1024
|
||||
|
||||
if sz > 0 then
|
||||
return ("%.1fK"):format(sz)
|
||||
else
|
||||
return "0"
|
||||
end
|
||||
end
|
||||
|
||||
local function listfilenames(filenames, bufs, total)
|
||||
table.sort(filenames) -- always sort by name
|
||||
|
||||
if Sflag then
|
||||
table.sort(filenames, function (a, b)
|
||||
a, b = bufs[a], bufs[b]
|
||||
|
||||
local asize = a.size or -1
|
||||
local bsize = b.size or -1
|
||||
return asize > bsize -- sort by size, largest first
|
||||
end)
|
||||
elseif tflag then
|
||||
table.sort(filenames, function(a, b)
|
||||
a, b = bufs[a], bufs[b]
|
||||
|
||||
local atime = a.mtime or -1
|
||||
local btime = b.mtime or -1
|
||||
return atime > btime -- sort by time, latest first
|
||||
end)
|
||||
end
|
||||
|
||||
if hflag then
|
||||
write(ksize(total), " total\n")
|
||||
end
|
||||
for _, filename in ipairs(filenames) do
|
||||
local buf = bufs[filename]
|
||||
|
||||
if hflag then
|
||||
write(ksize(buf.size or 0), " ")
|
||||
end
|
||||
write(filename, '\n')
|
||||
end
|
||||
end
|
||||
|
||||
local function ls(path)
|
||||
local dir, err = osx.opendir(path)
|
||||
if not dir then
|
||||
io.stderr:write(err, "\n")
|
||||
return
|
||||
end
|
||||
|
||||
local filenames = {}
|
||||
local bufs = {}
|
||||
local total = 0
|
||||
|
||||
while true do
|
||||
:: nextfilename ::
|
||||
local filename, err = dir:readdir()
|
||||
if err then
|
||||
-- Report, but tolerate error
|
||||
io.stderr:write(path, ": ", err, "\n")
|
||||
end
|
||||
if not filename then
|
||||
break -- done with this dir
|
||||
end
|
||||
if filename:sub(1, 1) == '.' and not aflag then
|
||||
goto nextfilename -- skip hidden
|
||||
end
|
||||
|
||||
-- stat() file, update counters and store for listing
|
||||
local filepath = path..sep..filename
|
||||
local buf, err = osx.stat(filepath)
|
||||
if not buf then
|
||||
io.stderr:write(filepath, ": ", err, "\n")
|
||||
goto nextfilename
|
||||
end
|
||||
|
||||
total = total + (buf.size or 0)
|
||||
filenames[#filenames+1] = filename
|
||||
bufs[filename] = buf
|
||||
end
|
||||
|
||||
-- Print file list
|
||||
listfilenames(filenames, bufs, total)
|
||||
dir:close() -- NOTE: could have marked this with <close>
|
||||
end
|
||||
|
||||
local args = parseargs(...)
|
||||
for _,path in ipairs(args) do
|
||||
ls(path)
|
||||
end
|
Loading…
Reference in New Issue