123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- --[[
- MIT License
- Copyright (c) 2019 Mitchell Davis <coding.jackalope@gmail.com>
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in all
- copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- SOFTWARE.
- --]]
- local FileSystem = {}
- function FileSystem.Separator()
- -- Lua/Love2D returns all paths with back slashes.
- return "/"
- end
- local OS = love.system.getOS() -- Cache it, as it's not expected to change
- local function BackslashEscapeQuotes(Str)
- return "'" .. ("\\'"):rep(#Str) .. "'"
- end
- local function EscParam(Param)
- if OS == "Windows" then
- -- TODO: safer parameter quoting
- return '"' .. Param .. '"'
- end
- return "'" .. Param:gsub("'+", BackslashEscapeQuotes) .. "'"
- end
- -- Unit tests
- --[=====[
- assert(EscParam("\"abc\"'def''gh") == "'\"abc\"'\\''def'\\'\\''gh'", "fails 1")
- assert(EscParam("") == "''", "fails 2")
- -- single quotes at the beginning and end could be improved...
- assert(EscParam("''abc''") == "''\\'\\''abc'\\'\\'''", "fails 3")
- assert(EscParam("\0") == "'\0'", "fails 4")
- assert(EscParam("\0xyz\0xyz\0") == "'\0xyz\0xyz\0'", "fails 5")
- print("EscParam tests passed")
- --]=====]
- function FileSystem.GetDirectoryItems(Directory, Options)
- Options = Options == nil and {} or Options
- Options.Files = Options.Files == nil and true or Options.Files
- Options.Directories = Options.Directories == nil and true or Options.Directories
- Options.Filter = Options.Filter ~= nil and Options.Filter or OS == "Windows" and "*.*" or "*"
- local Cmd = ""
- if string.sub(Directory, #Directory, #Directory) ~= FileSystem.Separator() then
- Directory = Directory .. FileSystem.Separator()
- end
- -- TODO: should ShowHidden be a user option?
- local ShowHidden = false
- if OS == "Windows" then
- local HiddenStr = ShowHidden and '' or ' /A:-H'
- Directory = string.gsub(Directory, "/", "\\")
- if Options.Files and not Options.Directories then
- Cmd = 'DIR ' .. EscParam(Directory .. Options.Filter) .. ' /B /A:-D' .. HiddenStr
- elseif Options.Directories and not Options.Files then
- Cmd = 'DIR ' .. EscParam(Directory) .. ' /B /A:D' .. HiddenStr
- else
- Cmd = 'DIR ' .. EscParam(Directory) .. ' /B' .. HiddenStr
- end
- else
- local HiddenStr = ShowHidden and "" or " \\( '!' -name .\\* \\)"
- if Options.Files and not Options.Directories then
- Cmd = 'find ' .. EscParam(Directory) .. " -maxdepth 1 '!' -type d -iname " .. EscParam(Options.Filter) .. HiddenStr .. ' -print0'
- elseif Options.Directories and not Options.Files then
- Cmd = 'find ' .. EscParam(Directory) .. ' -mindepth 1 -maxdepth 1 -type d' .. HiddenStr .. ' -print0'
- else
- Cmd = 'find ' .. EscParam(Directory) .. ' -mindepth 1 -maxdepth 1' .. HiddenStr .. ' -print0'
- end
- end
- local Result = {}
- local Handle, Error = io.popen(Cmd)
- if Handle ~= nil then
- local I = 1
- local Iterator
- if OS == 'Windows' then
- Iterator = Handle:lines()
- else
- Iterator = Handle:read('*all'):gmatch('%Z+')
- end
- for Item in Iterator do
- if Item ~= "nil" or OS ~= "Windows" then
- Result[I] = Item
- I = I + 1
- end
- end
- io.close(Handle)
- end
- return Result
- end
- function FileSystem.Exists(Path)
- local Handle = io.open(Path)
- if Handle ~= nil then
- io.close(Handle)
- return true
- else
- if OS == "Windows" then
- local OK, Error, Code = os.rename(Path, Path)
- if OK then
- return true
- else
- if Code == 13 then
- return true
- end
- end
- end
- end
- return false
- end
- function FileSystem.IsDirectory(Path)
- return FileSystem.Exists(Path .. FileSystem.Separator())
- end
- function FileSystem.Parent(Path)
- local Result = Path
- local Index = 1
- local I = Index
- repeat
- Index = I
- I = string.find(Path, FileSystem.Separator(), Index + 1, true)
- until I == nil
- if Index > 1 then
- Result = string.sub(Path, 1, Index - 1)
- end
- return Result
- end
- function FileSystem.GetBaseName(Path, RemoveExtension)
- local Result = string.match(Path, "^.+/(.+)$")
- if Result == nil then
- Result = Path
- end
- if RemoveExtension then
- Result = FileSystem.RemoveExtension(Result)
- end
- return Result
- end
- function FileSystem.GetDirectory(Path)
- local Result = string.match(Path, "(.+)/")
- if Result == nil then
- Result = Path
- end
- return Result
- end
- function FileSystem.GetRootDirectory(Path)
- local Result = Path
- local Index = string.find(Path, FileSystem.Separator(), 1, true)
- if Index ~= nil then
- Result = string.sub(Path, 1, Index - 1)
- end
- return Result
- end
- function FileSystem.GetSlabPath()
- local Path = love.filesystem.getSource()
- if not FileSystem.IsDirectory(Path) then
- Path = love.filesystem.getSourceBaseDirectory()
- end
- return Path .. "/Slab"
- end
- function FileSystem.RemoveExtension(Path)
- local Result = string.match(Path, "(.+)%.")
- if Result == nil then
- Result = Path
- end
- return Result
- end
- function FileSystem.ReadContents(Path, IsBinary)
- local Result = nil
- local Mode = IsBinary and "rb" or "r"
- local Handle, Error = io.open(Path, Mode)
- if Handle ~= nil then
- Result = Handle:read("*a")
- Handle:close()
- end
- return Result, Error
- end
- function FileSystem.SaveContents(Path, Contents)
- local Result = false
- local Handle, Error = io.open(Path, "w")
- if Handle ~= nil then
- Handle:write(Contents)
- Handle:close()
- Result = true
- end
- return Result, Error
- end
- return FileSystem
|