diff options
Diffstat (limited to 'acf/path.lua')
-rw-r--r-- | acf/path.lua | 52 |
1 files changed, 37 insertions, 15 deletions
diff --git a/acf/path.lua b/acf/path.lua index 15d3fca..f18d701 100644 --- a/acf/path.lua +++ b/acf/path.lua @@ -5,13 +5,7 @@ See LICENSE file for license details module(..., package.seeall) -require 'stringy' - -local function filter(func, tbl) - local res = {} - for _, v in ipairs(tbl) do if func(v) then table.insert(res, v) end end - return res -end +local map = require('acf.util').map function is_absolute(path) @@ -35,24 +29,52 @@ function to_absolute(path, base) return '/'..table.concat(comps, '/') end -function join(p1, p2, ...) + +local function escape(comp) + local res = string.gsub(comp, '([\\/])', '\\%1') + return res +end + + +function join(parent, name) return mjoin(parent, escape(name)) end + +function mjoin(p1, p2, ...) if not p2 then return p1 end if not is_absolute(p2) then p2 = '/'..p2 end - return join((p1 == '/' and '' or p1)..p2, unpack(arg)) + return mjoin((p1 == '/' and '' or p1)..p2, unpack(arg)) end + function split(path) - -- assume absolute paths - assert(is_absolute(path)) - if path == '/' then return {} end - return filter(function(s) return s > '' end, - stringy.split(string.sub(path, 2, -1), '/')) + local res = {} + local comp = '' + + local function merge(s) if s > '' then table.insert(res, s) end end + + while true do + local prefix, sep, suffix = string.match(path, '([^\\/]*)([\\/])(.*)') + if not prefix then + merge(comp..path) + return res + end + + comp = comp..prefix + if sep == '\\' then + comp = comp..string.sub(suffix, 1, 1) + path = string.sub(suffix, 2, -1) + else + merge(comp) + comp = '' + path = suffix + end + end end + function parent(path) local comps = split(path) table.remove(comps) - return join('/', unpack(comps)) + return mjoin('/', unpack(map(escape, comps))) end function name(path) |