summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/data-tre.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/data-tre.lua')
-rw-r--r--tex/context/base/mkiv/data-tre.lua355
1 files changed, 203 insertions, 152 deletions
diff --git a/tex/context/base/mkiv/data-tre.lua b/tex/context/base/mkiv/data-tre.lua
index c4d43e3eb..da3d1f14f 100644
--- a/tex/context/base/mkiv/data-tre.lua
+++ b/tex/context/base/mkiv/data-tre.lua
@@ -6,6 +6,10 @@ if not modules then modules = { } end modules ['data-tre'] = {
license = "see context related readme files"
}
+-- A tree search is rather dumb ... there is some basic caching of searched trees
+-- but nothing is cached over runs ... it's also a wildcard one so we cannot use
+-- the normal scanner.
+
-- tree://e:/temporary/mb-mp/**/drawing.jpg
-- tree://e:/temporary/mb-mp/**/Drawing.jpg
-- tree://t:./**/tufte.tex
@@ -28,83 +32,119 @@ local trace_locating = false trackers.register("resolvers.locating", function(v
local report_trees = logs.reporter("resolvers","trees")
-local resolvers = resolvers
-local resolveprefix = resolvers.resolve
-local notfound = resolvers.finders.notfound
-local lookup = resolvers.get_from_content
+local resolvers = resolvers
+local finders = resolvers.finders
+local openers = resolvers.openers
+local loaders = resolvers.loaders
+local locators = resolvers.locators
+local hashers = resolvers.hashers
+local generators = resolvers.generators
--- A tree search is rather dumb ... there is some basic caching of searched trees
--- but nothing is cached over runs ... it's also a wildcard one so we cannot use
--- the normal scanner.
+do
-local collectors = { }
-local found = { }
-
-function resolvers.finders.tree(specification) -- to be adapted to new formats
- local spec = specification.filename
- local okay = found[spec]
- if okay == nil then
- if spec ~= "" then
- local path = dirname(spec)
- local name = basename(spec)
- if path == "" then
- path = "."
- end
- local names = collectors[path]
- if not names then
- local pattern = find(path,"/%*+$") and path or (path .. "/*")
- names = globdir(pattern)
- collectors[path] = names
- end
- local pattern = "/" .. gsub(name,"([%.%-%+])", "%%%1") .. "$"
- for i=1,#names do
- local fullname = names[i]
- if find(fullname,pattern) then
- found[spec] = fullname
- return fullname
+ local collectors = { }
+ local found = { }
+ local notfound = finders.notfound
+
+ function finders.tree(specification) -- to be adapted to new formats
+ local spec = specification.filename
+ local okay = found[spec]
+ if okay == nil then
+ if spec ~= "" then
+ local path = dirname(spec)
+ local name = basename(spec)
+ if path == "" then
+ path = "."
end
- end
- -- let's be nice:
- local pattern = lower(pattern)
- for i=1,#names do
- local fullname = lower(names[i])
- if find(fullname,pattern) then
- if isfile(fullname) then
+ local names = collectors[path]
+ if not names then
+ local pattern = find(path,"/%*+$") and path or (path .. "/*")
+ names = globdir(pattern)
+ collectors[path] = names
+ end
+ local pattern = "/" .. gsub(name,"([%.%-%+])", "%%%1") .. "$"
+ for i=1,#names do
+ local fullname = names[i]
+ if find(fullname,pattern) then
found[spec] = fullname
return fullname
- else
- -- no os name mapping
- break
+ end
+ end
+ -- let's be nice:
+ local pattern = lower(pattern)
+ for i=1,#names do
+ local fullname = lower(names[i])
+ if find(fullname,pattern) then
+ if isfile(fullname) then
+ found[spec] = fullname
+ return fullname
+ else
+ -- no os name mapping
+ break
+ end
end
end
end
+ okay = notfound() -- false
+ found[spec] = okay
end
- okay = notfound() -- false
- found[spec] = okay
+ return okay
end
- return okay
+
end
-function resolvers.locators.tree(specification)
- local name = specification.filename
- local realname = resolveprefix(name) -- no shortcut
- if realname and realname ~= '' and isdir(realname) then
- if trace_locating then
- report_trees("locator %a found",realname)
+do
+
+ local resolveprefix = resolvers.resolve
+ local appendhash = resolvers.appendhash
+
+ local function dolocate(specification)
+ local name = specification.filename
+ local realname = resolveprefix(name) -- no shortcut
+ if realname and realname ~= '' and isdir(realname) then
+ if trace_locating then
+ report_trees("locator %a found",realname)
+ end
+ appendhash('tree',name,false) -- don't cache
+ elseif trace_locating then
+ report_trees("locator %a not found",name)
end
- resolvers.appendhash('tree',name,false) -- don't cache
- elseif trace_locating then
- report_trees("locator %a not found",name)
end
+
+ locators.tree = dolocate
+ locators.dirlist = dolocate
+ locators.dirfile = dolocate
+
end
-function resolvers.hashers.tree(specification)
- local name = specification.filename
- if trace_locating then
- report_trees("analyzing %a",name)
+
+do
+
+ local filegenerator = generators.file
+
+ generators.dirlist = filegenerator
+ generators.dirfile = filegenerator
+
+end
+
+do
+
+ local filegenerator = generators.file
+ local methodhandler = resolvers.methodhandler
+
+ local function dohash(specification)
+ local name = specification.filename
+ if trace_locating then
+ report_trees("analyzing %a",name)
+ end
+ methodhandler("hashers",name)
+ filegenerator(specification)
end
- resolvers.methodhandler("hashers",name)
- resolvers.generators.file(specification)
+
+ hashers.tree = dohash
+ hashers.dirlist = dohash
+ hashers.dirfile = dohash
+
end
-- This is a variation on tree lookups but this time we do cache in the given
@@ -112,120 +152,131 @@ end
-- for instance trees with 50K xml files plus a similar amount of resources to
-- deal and we don't want too much overhead.
-local collectors = { }
-local splitter = lpeg.splitat("/**/")
-local stripper = lpeg.replacer { [P("/") * P("*")^1 * P(-1)] = "" }
-
-table.setmetatableindex(collectors, function(t,k)
- local rootname = lpegmatch(stripper,k)
- local dataname = joinname(rootname,"dirlist")
- local content = caches.loadcontent(dataname,"files",dataname)
- if not content then
- -- path branch usecache onlyonce tolerant
- content = resolvers.scanfiles(rootname,nil,nil,false,true) -- so we accept crap
- caches.savecontent(dataname,"files",content,dataname)
- end
- t[k] = content
- return content
-end)
+local resolve do
+
+ local collectors = { }
+ local splitter = lpeg.splitat("/**/")
+ local stripper = lpeg.replacer { [P("/") * P("*")^1 * P(-1)] = "" }
+
+ local loadcontent = caches.loadcontent
+ local savecontent = caches.savecontent
+
+ local notfound = finders.notfound
+ local scanfiles = resolvers.scanfiles
+ local lookup = resolvers.get_from_content
-local function checked(root,p,n)
- if p then
- if type(p) == "table" then
- for i=1,#p do
- local fullname = joinname(root,p[i],n)
+ table.setmetatableindex(collectors, function(t,k)
+ local rootname = lpegmatch(stripper,k)
+ local dataname = joinname(rootname,"dirlist")
+ local content = loadcontent(dataname,"files",dataname)
+ if not content then
+ -- path branch usecache onlyonce tolerant
+ content = scanfiles(rootname,nil,nil,false,true) -- so we accept crap
+ savecontent(dataname,"files",content,dataname)
+ end
+ t[k] = content
+ return content
+ end)
+
+ local function checked(root,p,n)
+ if p then
+ if type(p) == "table" then
+ for i=1,#p do
+ local fullname = joinname(root,p[i],n)
+ if isfile(fullname) then -- safeguard
+ return fullname
+ end
+ end
+ else
+ local fullname = joinname(root,p,n)
if isfile(fullname) then -- safeguard
return fullname
end
end
- else
- local fullname = joinname(root,p,n)
- if isfile(fullname) then -- safeguard
- return fullname
- end
end
+ return notfound()
end
- return notfound()
-end
--- no funny characters in path but in filename permitted .. sigh
-
-local function resolve(specification) -- can be called directly too
- local filename = specification.filename
- -- inspect(specification)
- if filename ~= "" then
- local root, rest = lpegmatch(splitter,filename)
- if root and rest then
- local path, name = dirname(rest), basename(rest)
- if name ~= rest then
- local content = collectors[root]
- local p, n = lookup(content,name)
- if not p then
- return notfound()
- end
- local pattern = ".*/" .. path .. "$"
- local istable = type(p) == "table"
- if istable then
- for i=1,#p do
- local pi = p[i]
- if pi == path or find(pi,pattern) then
- local fullname = joinname(root,pi,n)
- if isfile(fullname) then -- safeguard
- return fullname
+ -- no funny characters in path but in filename permitted .. sigh
+
+ resolve = function(specification) -- can be called directly too
+ local filename = specification.filename
+ -- inspect(specification)
+ if filename ~= "" then
+ local root, rest = lpegmatch(splitter,filename)
+ if root and rest then
+ local path, name = dirname(rest), basename(rest)
+ if name ~= rest then
+ local content = collectors[root]
+ local p, n = lookup(content,name)
+ if not p then
+ return notfound()
+ end
+ local pattern = ".*/" .. path .. "$"
+ local istable = type(p) == "table"
+ if istable then
+ for i=1,#p do
+ local pi = p[i]
+ if pi == path or find(pi,pattern) then
+ local fullname = joinname(root,pi,n)
+ if isfile(fullname) then -- safeguard
+ return fullname
+ end
end
end
+ elseif p == path or find(p,pattern) then
+ local fullname = joinname(root,p,n)
+ if isfile(fullname) then -- safeguard
+ return fullname
+ end
end
- elseif p == path or find(p,pattern) then
- local fullname = joinname(root,p,n)
- if isfile(fullname) then -- safeguard
- return fullname
+ local queries = specification.queries
+ if queries and queries.option == "fileonly" then
+ return checked(root,p,n)
+ else
+ return notfound()
end
end
- local queries = specification.queries
- if queries and queries.option == "fileonly" then
- return checked(root,p,n)
- else
- return notfound()
- end
+ end
+ local path = dirname(filename)
+ local name = basename(filename)
+ local root = lpegmatch(stripper,path)
+ local content = collectors[path]
+ local p, n = lookup(content,name)
+ if p then
+ return checked(root,p,n)
end
end
- local path, name = dirname(filename), basename(filename)
- local root = lpegmatch(stripper,path)
- local content = collectors[path]
- local p, n = lookup(content,name)
- if p then
- return checked(root,p,n)
- end
+ return notfound()
end
- return notfound()
-end
-resolvers.finders .dirlist = resolve
-resolvers.locators .dirlist = resolvers.locators .tree
-resolvers.hashers .dirlist = resolvers.hashers .tree
-resolvers.generators.dirlist = resolvers.generators.file
-resolvers.openers .dirlist = resolvers.openers .file
-resolvers.loaders .dirlist = resolvers.loaders .file
-
-function resolvers.finders.dirfile(specification)
- local queries = specification.queries
- if queries then
- queries.option = "fileonly"
- else
- specification.queries = { option = "fileonly" }
+ finders.dirlist = resolve
+
+ function finders.dirfile(specification)
+ local queries = specification.queries
+ if queries then
+ queries.option = "fileonly"
+ else
+ specification.queries = { option = "fileonly" }
+ end
+ return resolve(specification)
end
- return resolve(specification)
+
end
-resolvers.locators .dirfile = resolvers.locators .dirlist
-resolvers.hashers .dirfile = resolvers.hashers .dirlist
-resolvers.generators.dirfile = resolvers.generators.dirlist
-resolvers.openers .dirfile = resolvers.openers .dirlist
-resolvers.loaders .dirfile = resolvers.loaders .dirlist
+do
--- local locate = collectors[ [[E:\temporary\mb-mp]] ]
--- local locate = collectors( [[\\storage-2\resources\mb-mp]] )
+ local fileopener = openers.file
+ local fileloader = loaders.file
+
+ openers.dirlist = fileopener
+ loaders.dirlist = fileloader
+
+ openers.dirfile = fileopener
+ loaders.dirfile = fileloader
+
+end
-- print(resolvers.findtexfile("tree://e:/temporary/mb-mp/**/VB_wmf_03_vw_01d_ant.jpg"))
-- print(resolvers.findtexfile("tree://t:/**/tufte.tex"))