|      1  | 
     1  | 
|      2 module("path", package.seeall) | 
     2 --@module path | 
|         | 
     3 local path={} | 
|      3  | 
     4  | 
|      4 require("tuple") | 
     5 local tuple=require("tuple") | 
|      5 require("lfs") | 
     6 local lfs=require("lfs") | 
|      6 require("err") | 
     7 local err=require("err") | 
|      7 require("config") | 
     8 local config=require("config") | 
|      8  | 
     9  | 
|      9 local sep=config.dirsep | 
    10 local sep=config.dirsep | 
|     10  | 
    11  | 
|     11 function join(p, f) | 
    12 function path.join(p, f) | 
|     12     if p=="" then | 
    13     if p=="" then | 
|     13         return f | 
    14         return f | 
|     14     else | 
    15     else | 
|     15         return p..sep..f | 
    16         return p..sep..f | 
|     16     end | 
    17     end | 
|     17 end | 
    18 end | 
|     18  | 
    19  | 
|     19 function dirbasename(p) | 
    20 function path.dirbasename(p) | 
|     20     local d, b = string.match(p, | 
    21     local d, b = string.match(p, | 
|     21         "^(.*)"..sep.."+([^"..sep.."]+)"..sep.."*$") | 
    22         "^(.*)"..sep.."+([^"..sep.."]+)"..sep.."*$") | 
|     22     if not b then | 
    23     if not b then | 
|     23         return "", p | 
    24         return "", p | 
|     24     else | 
    25     else | 
|     25         return d, b | 
    26         return d, b | 
|     26     end | 
    27     end | 
|     27 end | 
    28 end | 
|     28  | 
    29  | 
|     29 function dirname(p) | 
    30 function path.dirname(p) | 
|     30     return tuple.fst(dirbasename(p)) | 
    31     return tuple.fst(dirbasename(p)) | 
|     31 end | 
    32 end | 
|     32  | 
    33  | 
|     33 function dirname_slash(p) | 
    34 function path.dirname_slash(p) | 
|     34     local dn=dirname(p) | 
    35     local dn=dirname(p) | 
|     35     if dn=="" then | 
    36     if dn=="" then | 
|     36         return dn | 
    37         return dn | 
|     37     else | 
    38     else | 
|     38         return dn..sep | 
    39         return dn..sep | 
|     39     end | 
    40     end | 
|     40 end | 
    41 end | 
|     41  | 
    42  | 
|     42 function basename(p) | 
    43 function path.basename(p) | 
|     43     return tuple.snd(dirbasename(p)) | 
    44     return tuple.snd(dirbasename(p)) | 
|     44 end | 
    45 end | 
|     45  | 
    46  | 
|     46 function rmext(p) | 
    47 function path.rmext(p) | 
|     47     return string.gsub(p, "%.[^.]*$", "") | 
    48     return string.gsub(p, "%.[^.]*$", "") | 
|     48 end | 
    49 end | 
|     49  | 
    50  | 
|     50 -- would rather do this as an iterator, but can't | 
    51 -- would rather do this as an iterator, but can't | 
|     51 -- coroutine.yield from gsub handler | 
    52 -- coroutine.yield from gsub handler | 
|     52 function split(p) | 
    53 function path.split(p) | 
|     53     local t={} | 
    54     local t={} | 
|     54     local head="" | 
    55     local head="" | 
|     55     local s, p2 = string.match(p, "^("..sep.."+)(.*)$") | 
    56     local s, p2 = string.match(p, "^("..sep.."+)(.*)$") | 
|     56     if s then | 
    57     if s then | 
|     57         table.insert(t, "/.") -- root | 
    58         table.insert(t, "/.") -- root | 
|     61             function(d) table.insert(t, d); end) | 
    62             function(d) table.insert(t, d); end) | 
|     62     return t | 
    63     return t | 
|     63 end | 
    64 end | 
|     64  | 
    65  | 
|     65 --[[ | 
    66 --[[ | 
|     66 function parts(p) | 
    67 function path.parts(p) | 
|     67     local s={i=1, t=split(p)} | 
    68     local s={i=1, t=split(p)} | 
|     68     local function g(s) | 
    69     local function g(s) | 
|     69         local v=s.t[s.i] | 
    70         local v=s.t[s.i] | 
|     70         s.i=s.i+1 | 
    71         s.i=s.i+1 | 
|     71         return v | 
    72         return v | 
|     72     end | 
    73     end | 
|     73     return g, s | 
    74     return g, s | 
|     74 end | 
    75 end | 
|     75  | 
    76  | 
|     76 function makepath(p, head) | 
    77 function path.makepath(p, head) | 
|     77     head=head or "" | 
    78     head=head or "" | 
|     78     for d in parts(p) do | 
    79     for d in parts(p) do | 
|     79         head=head..d | 
    80         head=head..d | 
|     80         local a=lfs.attributes(head) | 
    81         local a=lfs.attributes(head) | 
|     81         if not a then | 
    82         if not a then |