IonutParau 687cfebd00 testing version of LuaBIOS and OpenOS
people were having issues getting them to work so now we promote consistency
2025-06-28 20:41:49 +02:00

132 lines
2.9 KiB
Lua

local shell = require("shell")
local args, options = shell.parse(...)
local error_code = 0
local function pop(key, convert)
local result = options[key]
options[key] = nil
if result and convert then
local c = tonumber(result)
if not c then
io.stderr:write(string.format("use --%s=n where n is a number\n", key))
options.help = true
error_code = 1
end
result = c
end
return result
end
local bytes = pop('bytes', true)
local lines = pop('lines', true)
local quiet = {pop('q'), pop('quiet'), pop('silent')}
quiet = quiet[1] or quiet[2] or quiet[3]
local verbose = {pop('v'), pop('verbose')}
verbose = verbose[1] or verbose[2]
local help = pop('help')
if help or next(options) then
local invalid_key = next(options)
if invalid_key then
invalid_key = string.format('invalid option: %s\n', invalid_key)
error_code = 1
else
invalid_key = ''
end
print(invalid_key .. [[Usage: head [--lines=n] file
Print the first 10 lines of each FILE to stdout.
For more info run: man head]])
os.exit(error_code)
end
if #args == 0 then
args = {'-'}
end
if quiet and verbose then
quiet = false
end
local function new_stream()
return
{
open=true,
capacity=math.abs(lines or bytes or 10),
bytes=bytes,
buffer=(lines and lines < 0 and {}) or (bytes and bytes < 0 and '')
}
end
local function close(stream)
if stream.buffer then
if type(stream.buffer) == 'table' then
stream.buffer = table.concat(stream.buffer)
end
io.stdout:write(stream.buffer)
stream.buffer = nil
end
stream.open = false
end
local function push(stream, line)
if not line then
return close(stream)
end
local cost = stream.bytes and line:len() or 1
stream.capacity = stream.capacity - cost
if not stream.buffer then
if stream.bytes and stream.capacity < 0 then
line = line:sub(1,stream.capacity-1)
end
io.write(line)
if stream.capacity <= 0 then
return close(stream)
end
else
if type(stream.buffer) == 'table' then -- line storage
stream.buffer[#stream.buffer+1] = line
if stream.capacity < 0 then
table.remove(stream.buffer, 1)
stream.capacity = 0 -- zero out
end
else -- byte storage
stream.buffer = stream.buffer .. line
if stream.capacity < 0 then
stream.buffer = stream.buffer:sub(-stream.capacity+1)
stream.capacity = 0 -- zero out
end
end
end
end
for i=1,#args do
local arg = args[i]
local file, reason
if arg == '-' then
arg = 'standard input'
file = io.stdin
else
file, reason = io.open(arg, 'r')
if not file then
io.stderr:write(string.format([[head: cannot open '%s' for reading: %s]], arg, reason))
end
end
if file then
if verbose or #args > 1 then
io.write(string.format('==> %s <==\n', arg))
end
local stream = new_stream()
while stream.open do
push(stream, file:read('*L'))
end
file:close()
end
end