Sun, 07 May 2017 20:02:53 +0100
5.3 updates
| 2 | 1 | |
| 2 | module("path", package.seeall) | |
| 3 | ||
| 4 | require("tuple") | |
| 5 | require("lfs") | |
| 6 | require("err") | |
| 7 | require("config") | |
| 8 | ||
| 9 | local sep=config.dirsep | |
| 10 | ||
| 11 | function join(p, f) | |
| 3 | 12 | if p=="" then |
| 13 | return f | |
| 14 | else | |
| 15 | return p..sep..f | |
| 16 | end | |
| 2 | 17 | end |
| 18 | ||
| 19 | function dirbasename(p) | |
| 20 | local d, b = string.match(p, | |
| 3 | 21 | "^(.*)"..sep.."+([^"..sep.."]+)"..sep.."*$") |
| 2 | 22 | if not b then |
| 3 | 23 | return "", p |
| 2 | 24 | else |
| 25 | return d, b | |
| 26 | end | |
| 27 | end | |
| 28 | ||
| 29 | function dirname(p) | |
| 30 | return tuple.fst(dirbasename(p)) | |
| 31 | end | |
| 32 | ||
| 3 | 33 | function dirname_slash(p) |
| 34 | local dn=dirname(p) | |
| 35 | if dn=="" then | |
| 36 | return dn | |
| 37 | else | |
| 38 | return dn..sep | |
| 39 | end | |
| 40 | end | |
| 41 | ||
| 2 | 42 | function basename(p) |
| 43 | return tuple.snd(dirbasename(p)) | |
| 44 | end | |
| 45 | ||
| 3 | 46 | function rmext(p) |
| 47 | return string.gsub(p, "%.[^.]*$", "") | |
| 48 | end | |
| 49 | ||
| 2 | 50 | -- would rather do this as an iterator, but can't |
| 51 | -- coroutine.yield from gsub handler | |
| 52 | function split(p) | |
| 53 | local t={} | |
| 54 | local head="" | |
| 55 | local s, p2 = string.match(p, "^("..sep.."+)(.*)$") | |
| 56 | if s then | |
| 57 | table.insert(t, "/.") -- root | |
| 58 | p=p2 | |
| 59 | end | |
| 3 | 60 | string.gsub(p, "([^"..sep.."]+)", --..sep.."+", |
| 2 | 61 | function(d) table.insert(t, d); end) |
| 62 | return t | |
| 63 | end | |
| 64 | ||
| 3 | 65 | --[[ |
| 2 | 66 | function parts(p) |
| 67 | local s={i=1, t=split(p)} | |
| 68 | local function g(s) | |
| 69 | local v=s.t[s.i] | |
| 70 | s.i=s.i+1 | |
| 71 | return v | |
| 72 | end | |
| 73 | return g, s | |
| 74 | end | |
| 75 | ||
| 3 | 76 | function makepath(p, head) |
| 77 | head=head or "" | |
| 2 | 78 | for d in parts(p) do |
| 79 | head=head..d | |
| 80 | local a=lfs.attributes(head) | |
| 81 | if not a then | |
| 82 | local success, e = lfs.mkdir(head) | |
| 83 | if not success then | |
| 84 | err.file(head, e) | |
| 85 | end | |
| 86 | elseif a.mode~="directory" then | |
| 87 | err.file(head, "not a directory") | |
| 88 | end | |
| 89 | head=head..sep | |
| 90 | end | |
| 91 | end | |
| 3 | 92 | ]] |
| 2 | 93 | |
| 3 | 94 | function simplify(p) |
| 95 | local capts={} | |
| 96 | local start=string.match(p, "^(/)") | |
| 97 | string.gsub(p, "([^/]+)", | |
| 98 | function(e) | |
| 99 | if e==".." and #capts > 1 then | |
| 100 | capts[#capts]=nil | |
| 101 | elseif e~="." then | |
| 102 | table.insert(capts, e) | |
| 103 | end | |
| 104 | end) | |
| 105 | return (start or "")..table.concat(capts, "/") | |
| 2 | 106 | end |
| 107 | ||
| 3 | 108 | function to_root(p) |
| 109 | return string.rep("../",#(split(p))-1) | |
| 110 | end |