2024-07-13 16:26:34 +00:00
-- mkdir only
-- A portable filesystem API using LuaJIT's FFI
-- Retrieved 2024-07-13 from https://gist.githubusercontent.com/Techcable/503f35ceea9554fb81cf3a5c1aa550da/raw/33a29f59207335b743824fbb657e4721a12ce280/fs.lua
local ffi = require ( " ffi " )
local table = require ( " table " )
require ( " string " )
-- Cache needed functions and locals
local C , errno , string = ffi.C , ffi.errno , ffi.string
local concat , insert = table.concat , table.insert
-- "Standard" C99 functions
ffi.cdef [ [
char * strerror ( int errnum ) ;
] ]
local exists , mkdir , PATH_SEPARATOR
if ffi.os == " Windows " then
ffi.cdef [ [
bool CreateDirectoryA ( const char * path , void * lpSecurityAttributes ) ;
] ]
function mkdir ( path , _ )
assert ( type ( path ) == " string " , " path isn't a string " )
if not C.CreateDirectoryA ( path , nil ) then
local message = string ( C.strerror ( errno ( ) ) )
error ( " Unable to create directory " .. path .. " : " .. message )
end
end
PATH_SEPARATOR = " \\ "
elseif ffi.os == " Linux " or ffi.os == " OSX " then
ffi.cdef [ [
int mkdir ( const char * path , int mode ) ;
] ]
function mkdir ( path , mode )
assert ( type ( path ) == " string " , " path isn't a string " )
local mode = tonumber ( mode or " 755 " , 8 )
if C.mkdir ( path , mode ) ~= 0 then
local message = string ( C.strerror ( errno ( ) ) )
error ( " Unable to create directory " .. path .. " : " .. message )
end
end
PATH_SEPARATOR = " / "
else
error ( " Unsupported operating system: " .. ffi.os )
end
local function join ( ... )
local parts = { }
for i = 1 , select ( " # " , ... ) do
local part = select ( i , ... )
insert ( parts , part )
end
return concat ( parts , PATH_SEPARATOR )
end
local function splitPath ( path )
assert ( type ( path ) == " string " , " path isn't a string! " )
local parts = { }
local lastIndex = 0
for i = 1 , path : len ( ) do
if path : sub ( i , i ) == PATH_SEPARATOR then
insert ( parts , path : sub ( lastIndex , i - 1 ) )
lastIndex = i + 1
end
end
insert ( parts , path : sub ( lastIndex ) )
return parts
end
local function mkdirs ( path )
local parts = splitPath ( path )
local currentPath = parts [ 1 ]
for i = 2 , # parts do
if not exists ( currentPath ) then
mkdir ( currentPath )
end
-- Note: This isn't suboptimal, since we really do need the intermediate results
currentPath = currentPath .. PATH_SEPARATOR .. parts [ i ]
end
if not exists ( path ) then
mkdir ( path )
end
end
2024-07-18 20:00:51 +00:00
--- Check if a file or directory exists in this path
function exists ( file )
local ok , err , code = os.rename ( file , file )
if not ok then
if code == 13 then
-- Permission denied, but it exists
return true
end
end
return ok , err
end
2024-07-13 16:26:34 +00:00
return {
exists = exists ,
join = join ,
mkdir = mkdir ,
mkdirs = mkdirs ,
splitPath = splitPath ,
PATH_SEPERATOR = PATH_SEPARATOR
}