diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/l-dir.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/l-dir.lua | 152 |
1 files changed, 104 insertions, 48 deletions
diff --git a/Master/texmf-dist/tex/context/base/l-dir.lua b/Master/texmf-dist/tex/context/base/l-dir.lua index 5a726303f0c..2643f538b94 100644 --- a/Master/texmf-dist/tex/context/base/l-dir.lua +++ b/Master/texmf-dist/tex/context/base/l-dir.lua @@ -1,16 +1,25 @@ if not modules then modules = { } end modules ['l-dir'] = { version = 1.001, - comment = "companion to luat-lib.tex", + comment = "companion to luat-lib.mkiv", author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", copyright = "PRAGMA ADE / ConTeXt Development Team", license = "see context related readme files" } +-- dir.expand_name will be merged with cleanpath and collapsepath + local type = type -local find, gmatch = string.find, string.gmatch +local find, gmatch, match, gsub = string.find, string.gmatch, string.match, string.gsub +local lpegmatch = lpeg.match dir = dir or { } +-- handy + +function dir.current() + return (gsub(lfs.currentdir(),"\\","/")) +end + -- optimizing for no string.find (*) does not save time local attributes = lfs.attributes @@ -41,6 +50,35 @@ end dir.glob_pattern = glob_pattern +local function collect_pattern(path,patt,recurse,result) + local ok, scanner + result = result or { } + if path == "/" then + ok, scanner = xpcall(function() return walkdir(path..".") end, function() end) -- kepler safe + else + ok, scanner = xpcall(function() return walkdir(path) end, function() end) -- kepler safe + end + if ok and type(scanner) == "function" then + if not find(path,"/$") then path = path .. '/' end + for name in scanner do + local full = path .. name + local attr = attributes(full) + local mode = attr.mode + if mode == 'file' then + if find(full,patt) then + result[name] = attr + end + elseif recurse and (mode == "directory") and (name ~= '.') and (name ~= "..") then + attr.list = collect_pattern(full,patt,recurse) + result[name] = attr + end + end + end + return result +end + +dir.collect_pattern = collect_pattern + local P, S, R, C, Cc, Cs, Ct, Cv, V = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Cv, lpeg.V local pattern = Ct { @@ -60,29 +98,48 @@ local filter = Cs ( ( )^0 ) local function glob(str,t) - if type(str) == "table" then - local t = t or { } - for s=1,#str do - glob(str[s],t) + if type(t) == "function" then + if type(str) == "table" then + for s=1,#str do + glob(str[s],t) + end + elseif lfs.isfile(str) then + t(str) + else + local split = lpegmatch(pattern,str) + if split then + local root, path, base = split[1], split[2], split[3] + local recurse = find(base,"%*%*") + local start = root .. path + local result = lpegmatch(filter,start .. base) + glob_pattern(start,result,recurse,t) + end end - return t - elseif lfs.isfile(str) then - local t = t or { } - t[#t+1] = str - return t else - local split = pattern:match(str) - if split then + if type(str) == "table" then + local t = t or { } + for s=1,#str do + glob(str[s],t) + end + return t + elseif lfs.isfile(str) then local t = t or { } - local action = action or function(name) t[#t+1] = name end - local root, path, base = split[1], split[2], split[3] - local recurse = find(base,"%*%*") - local start = root .. path - local result = filter:match(start .. base) - glob_pattern(start,result,recurse,action) + t[#t+1] = str return t else - return { } + local split = lpegmatch(pattern,str) + if split then + local t = t or { } + local action = action or function(name) t[#t+1] = name end + local root, path, base = split[1], split[2], split[3] + local recurse = find(base,"%*%*") + local start = root .. path + local result = lpegmatch(filter,start .. base) + glob_pattern(start,result,recurse,action) + return t + else + return { } + end end end end @@ -144,11 +201,12 @@ end local make_indeed = true -- false -if string.find(os.getenv("PATH"),";") then +if string.find(os.getenv("PATH"),";") then -- os.type == "windows" function dir.mkdirs(...) - local str, pth = "", "" - for _, s in ipairs({...}) do + local str, pth, t = "", "", { ... } + for i=1,#t do + local s = t[i] if s ~= "" then if str ~= "" then str = str .. "/" .. s @@ -159,13 +217,13 @@ if string.find(os.getenv("PATH"),";") then end local first, middle, last local drive = false - first, middle, last = str:match("^(//)(//*)(.*)$") + first, middle, last = match(str,"^(//)(//*)(.*)$") if first then -- empty network path == local path else - first, last = str:match("^(//)/*(.-)$") + first, last = match(str,"^(//)/*(.-)$") if first then - middle, last = str:match("([^/]+)/+(.-)$") + middle, last = match(str,"([^/]+)/+(.-)$") if middle then pth = "//" .. middle else @@ -173,11 +231,11 @@ if string.find(os.getenv("PATH"),";") then last = "" end else - first, middle, last = str:match("^([a-zA-Z]:)(/*)(.-)$") + first, middle, last = match(str,"^([a-zA-Z]:)(/*)(.-)$") if first then pth, drive = first .. middle, true else - middle, last = str:match("^(/*)(.-)$") + middle, last = match(str,"^(/*)(.-)$") if not middle then last = str end @@ -211,34 +269,31 @@ if string.find(os.getenv("PATH"),";") then --~ print(dir.mkdirs("///a/b/c")) --~ print(dir.mkdirs("a/bbb//ccc/")) - function dir.expand_name(str) - local first, nothing, last = str:match("^(//)(//*)(.*)$") + function dir.expand_name(str) -- will be merged with cleanpath and collapsepath + local first, nothing, last = match(str,"^(//)(//*)(.*)$") if first then - first = lfs.currentdir() .. "/" - first = first:gsub("\\","/") + first = dir.current() .. "/" end if not first then - first, last = str:match("^(//)/*(.*)$") + first, last = match(str,"^(//)/*(.*)$") end if not first then - first, last = str:match("^([a-zA-Z]:)(.*)$") + first, last = match(str,"^([a-zA-Z]:)(.*)$") if first and not find(last,"^/") then local d = lfs.currentdir() if lfs.chdir(first) then - first = lfs.currentdir() - first = first:gsub("\\","/") + first = dir.current() end lfs.chdir(d) end end if not first then - first, last = lfs.currentdir(), str - first = first:gsub("\\","/") + first, last = dir.current(), str end - last = last:gsub("//","/") - last = last:gsub("/%./","/") - last = last:gsub("^/*","") - first = first:gsub("/*$","") + last = gsub(last,"//","/") + last = gsub(last,"/%./","/") + last = gsub(last,"^/*","") + first = gsub(first,"/*$","") if last == "" then return first else @@ -249,8 +304,9 @@ if string.find(os.getenv("PATH"),";") then else function dir.mkdirs(...) - local str, pth = "", "" - for _, s in ipairs({...}) do + local str, pth, t = "", "", { ... } + for i=1,#t do + local s = t[i] if s ~= "" then if str ~= "" then str = str .. "/" .. s @@ -259,7 +315,7 @@ else end end end - str = str:gsub("/+","/") + str = gsub(str,"/+","/") if find(str,"^/") then pth = "/" for s in gmatch(str,"[^/]+") do @@ -293,12 +349,12 @@ else --~ print(dir.mkdirs("///a/b/c")) --~ print(dir.mkdirs("a/bbb//ccc/")) - function dir.expand_name(str) + function dir.expand_name(str) -- will be merged with cleanpath and collapsepath if not find(str,"^/") then str = lfs.currentdir() .. "/" .. str end - str = str:gsub("//","/") - str = str:gsub("/%./","/") + str = gsub(str,"//","/") + str = gsub(str,"/%./","/") return str end |