path.lua

Mon, 06 Jul 2020 12:19:21 -0500

author
Tuomo Valkonen <tuomov@iki.fi>
date
Mon, 06 Jul 2020 12:19:21 -0500
changeset 23
0ea4b0786b43
parent 7
038275cd92ed
permissions
-rw-r--r--

Only parse metadata if starts on first line


--@module path
local path={}

local tuple=require("tuple")
local lfs=require("lfs")
local err=require("err")
local config=require("config")

local sep=config.dirsep

function path.join(p, f)
    if p=="" then
        return f
    else
        return p..sep..f
    end
end

function path.dirbasename(p)
    local d, b = string.match(p,
        "^(.*)"..sep.."+([^"..sep.."]+)"..sep.."*$")
    if not b then
        return "", p
    else
        return d, b
    end
end

function path.dirname(p)
    return tuple.fst(dirbasename(p))
end

function path.dirname_slash(p)
    local dn=dirname(p)
    if dn=="" then
        return dn
    else
        return dn..sep
    end
end

function path.basename(p)
    return tuple.snd(dirbasename(p))
end

function path.rmext(p)
    return string.gsub(p, "%.[^.]*$", "")
end

-- would rather do this as an iterator, but can't
-- coroutine.yield from gsub handler
function path.split(p)
    local t={}
    local head=""
    local s, p2 = string.match(p, "^("..sep.."+)(.*)$")
    if s then
        table.insert(t, "/.") -- root
        p=p2
    end
    string.gsub(p, "([^"..sep.."]+)", --..sep.."+", 
            function(d) table.insert(t, d); end)
    return t
end

--[[
function path.parts(p)
    local s={i=1, t=split(p)}
    local function g(s)
        local v=s.t[s.i]
        s.i=s.i+1
        return v
    end
    return g, s
end

function path.makepath(p, head)
    head=head or ""
    for d in parts(p) do
        head=head..d
        local a=lfs.attributes(head)
        if not a then
            local success, e = lfs.mkdir(head)
            if not success then
                err.file(head, e)
            end
        elseif a.mode~="directory" then
            err.file(head, "not a directory")
        end
        head=head..sep
    end
end
]]

function path.simplify(p)
    local capts={}
    local start=string.match(p, "^(/)")
    string.gsub(p, "([^/]+)",
    function(e)
        if e==".." and #capts > 1 then
            capts[#capts]=nil
        elseif e~="." then
            table.insert(capts, e)
        end  
    end)
    return (start or "")..table.concat(capts, "/")
end

function path.to_root(p)
    return string.rep("../",#(path.split(p))-1)
end

return path

mercurial