mirror of
https://github.com/CCLeonOS/LeonOS.git
synced 2026-03-03 06:47:00 +00:00
202 lines
4.6 KiB
Lua
202 lines
4.6 KiB
Lua
-- override the fs library to use this resolution function where necessary
|
|
-- almost identical to the override used in .OS
|
|
|
|
local fs = rawget(_G, "fs")
|
|
|
|
-- split a file path into segments
|
|
function fs.split(path)
|
|
local s = {}
|
|
for S in path:gmatch("[^/\\]+") do
|
|
if S == ".." then
|
|
s[#s] = nil
|
|
elseif S ~= "." then
|
|
s[#s+1] = S
|
|
end
|
|
end
|
|
return s
|
|
end
|
|
|
|
-- package isn't loaded yet, so unfortunately this is necessary
|
|
local function expect(...)
|
|
return require and require("cc.expect").expect(...)
|
|
end
|
|
|
|
-- path resolution:
|
|
-- if the path begins with /leonos, then redirect to wherever that actually
|
|
-- is; otherwise, resolve the path based on the current program's working
|
|
-- directory
|
|
-- this is to allow .OS to run from anywhere
|
|
local function resolve(path)
|
|
local thread = package and package.loaded.thread
|
|
|
|
local root = (thread and thread.getroot()) or "/"
|
|
local pwd = (thread and thread.dir()) or "/"
|
|
|
|
if path:sub(1,1) ~= "/" then
|
|
path = fs.combine(pwd, path)
|
|
end
|
|
path = fs.combine(root, path)
|
|
|
|
local segments = fs.split(path)
|
|
if segments[1] == "rc" then
|
|
return fs.combine(_RC_ROM_DIR, table.concat(segments, "/", 2, #segments))
|
|
else
|
|
return path
|
|
end
|
|
end
|
|
|
|
-- override: fs.combine
|
|
local combine = fs.combine
|
|
function fs.combine(...)
|
|
return "/" .. combine(...)
|
|
end
|
|
|
|
-- override: fs.getDir
|
|
local getDir = fs.getDir
|
|
function fs.getDir(p)
|
|
return "/" .. getDir(p)
|
|
end
|
|
|
|
-- override: fs.exists
|
|
local exists = fs.exists
|
|
function fs.exists(path)
|
|
expect(1, path, "string")
|
|
return exists(resolve(path))
|
|
end
|
|
|
|
-- override: fs.list
|
|
local list = fs.list
|
|
function fs.list(path)
|
|
expect(1, path, "string")
|
|
path = resolve(path)
|
|
local _, files = pcall(list, path)
|
|
if not _ then return nil, files end
|
|
if path == "/" then
|
|
-- inject /leonos into the root listing
|
|
if not exists("/leonos") then
|
|
files[#files+1] = "rc"
|
|
end
|
|
end
|
|
return files
|
|
end
|
|
|
|
-- override: fs.getSize
|
|
local getSize = fs.getSize
|
|
function fs.getSize(path)
|
|
expect(1, path, "string")
|
|
return getSize((resolve(path)))
|
|
end
|
|
|
|
-- override: fs.isDir
|
|
local isDir = fs.isDir
|
|
function fs.isDir(path)
|
|
expect(1, path, "string")
|
|
return isDir(resolve(path))
|
|
end
|
|
|
|
-- override: fs.makeDir
|
|
local makeDir = fs.makeDir
|
|
function fs.makeDir(path)
|
|
expect(1, path, "string")
|
|
return makeDir(resolve(path))
|
|
end
|
|
|
|
-- override: fs.move
|
|
local move = fs.move
|
|
function fs.move(a, b)
|
|
expect(1, a, "string")
|
|
expect(2, b, "string")
|
|
return move(resolve(a), resolve(b))
|
|
end
|
|
|
|
-- override: fs.copy
|
|
local copy = fs.copy
|
|
function fs.copy(a, b)
|
|
expect(1, a, "string")
|
|
expect(2, b, "string")
|
|
return copy(resolve(a), resolve(b))
|
|
end
|
|
|
|
-- override: fs.delete
|
|
local delete = fs.delete
|
|
function fs.delete(path)
|
|
expect(1, path, "string")
|
|
return delete(resolve(path))
|
|
end
|
|
|
|
-- override: fs.open
|
|
local open = fs.open
|
|
function fs.open(file, mode)
|
|
expect(1, file, "string")
|
|
expect(2, mode, "string")
|
|
return open(resolve(file), mode or "r")
|
|
end
|
|
|
|
-- override: fs.find
|
|
local find = fs.find
|
|
function fs.find(path)
|
|
expect(1, path, "string")
|
|
return find(resolve(path))
|
|
end
|
|
|
|
-- override: fs.attributes
|
|
local attributes = fs.attributes
|
|
function fs.attributes(path)
|
|
expect(1, path, "string")
|
|
return attributes(resolve(path))
|
|
end
|
|
|
|
-- new: fs.complete
|
|
function fs.complete(path, location, include_files, include_dirs)
|
|
expect(1, path, "string")
|
|
expect(2, location, "string")
|
|
expect(3, include_files, "boolean", "nil")
|
|
expect(4, include_dirs, "boolean", "nil")
|
|
|
|
if include_files == nil then include_files = true end
|
|
if include_dirs == nil then include_dirs = true end
|
|
|
|
if path:sub(1,1) == "/" and path:sub(-1) ~= "/" then
|
|
location = fs.getDir(path)
|
|
elseif path:sub(-1) == "/" then
|
|
location = path
|
|
else
|
|
location = fs.combine(location, fs.getDir(path))
|
|
end
|
|
|
|
local completions = {}
|
|
|
|
if not fs.exists(location) or not fs.isDir(location) then
|
|
return completions
|
|
end
|
|
|
|
local name = fs.getName(path)
|
|
if path:sub(-1) == "/" then name = "" end
|
|
local files = fs.list(location)
|
|
|
|
for i=1, #files, 1 do
|
|
local file = files[i]
|
|
local full = fs.combine(location, file)
|
|
if file:sub(1, #name) == name then
|
|
local dir = fs.isDir(full)
|
|
if (dir and include_dirs) or include_files then
|
|
completions[#completions+1] = file:sub(#name+1)
|
|
if #completions[#completions] == 0 then
|
|
completions[#completions] = nil
|
|
end
|
|
end
|
|
if dir then
|
|
completions[#completions+1] = file:sub(#name+1) .. "/"
|
|
end
|
|
end
|
|
end
|
|
|
|
return completions
|
|
end
|
|
|
|
function fs.isDriveRoot(path)
|
|
expect(1, path, "string")
|
|
if #path == 0 then path = "/" end
|
|
return path == "/" or fs.getDrive(path) == fs.getDrive(fs.getDir(path))
|
|
end
|