summaryrefslogtreecommitdiff
path: root/tex/context/base/mkiv/data-res.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/mkiv/data-res.lua')
-rw-r--r--tex/context/base/mkiv/data-res.lua596
1 files changed, 332 insertions, 264 deletions
diff --git a/tex/context/base/mkiv/data-res.lua b/tex/context/base/mkiv/data-res.lua
index 15d9f3db9..01b8f1aca 100644
--- a/tex/context/base/mkiv/data-res.lua
+++ b/tex/context/base/mkiv/data-res.lua
@@ -10,7 +10,9 @@ if not modules then modules = { } end modules ['data-res'] = {
local gsub, find, lower, upper, match, gmatch = string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch
local concat, insert, remove = table.concat, table.insert, table.remove
-local next, type, rawget = next, type, rawget
+local next, type, rawget, loadfile = next, type, rawget, loadfile
+local mergedtable = table.merged
+
local os = os
local P, S, R, C, Cc, Cs, Ct, Carg = lpeg.P, lpeg.S, lpeg.R, lpeg.C, lpeg.Cc, lpeg.Cs, lpeg.Ct, lpeg.Carg
@@ -30,6 +32,8 @@ local is_qualified_path = file.is_qualified_path
local allocate = utilities.storage.allocate
local settings_to_array = utilities.parsers.settings_to_array
+local urlhasscheme = url.hasscheme
+
local getcurrentdir = lfs.currentdir
local isfile = lfs.isfile
local isdir = lfs.isdir
@@ -63,11 +67,19 @@ local ostype, osname, osenv, ossetenv, osgetenv = os.type, os.name, os.env, os.s
resolvers.cacheversion = "1.100"
resolvers.configbanner = ""
resolvers.homedir = environment.homedir
-resolvers.criticalvars = allocate { "SELFAUTOLOC", "SELFAUTODIR", "SELFAUTOPARENT", "TEXMFCNF", "TEXMF", "TEXOS" }
resolvers.luacnfname = "texmfcnf.lua"
resolvers.luacnffallback = "contextcnf.lua"
resolvers.luacnfstate = "unknown"
+local criticalvars = {
+ "SELFAUTOLOC",
+ "SELFAUTODIR",
+ "SELFAUTOPARENT",
+ "TEXMFCNF",
+ "TEXMF",
+ "TEXOS",
+}
+
-- The web2c tex binaries as well as kpse have built in paths for the configuration
-- files and there can be a depressing truckload of them. This is actually the weak
-- spot of a distribution. So we don't want:
@@ -145,14 +157,27 @@ local suffixmap = resolvers.suffixmap
resolvers.defaultsuffixes = { "tex" } -- "mkiv", "cld" -- too tricky
-local instance = nil -- the current one (fast access)
+local instance = nil -- the current one (fast access)
+
+-- forward declarations
+
+local variable
+local expansion
+local setenv
+local getenv
+
+-- done
+
+local formatofsuffix = resolvers.formatofsuffix
+local splitpath = resolvers.splitpath
+local splitmethod = resolvers.splitmethod
-- An instance has an environment (coming from the outside, kept raw), variables
-- (coming from the configuration file), and expansions (variables with nested
-- variables replaced). One can push something into the outer environment and
-- its internal copy, but only the later one will be the raw unprefixed variant.
-function resolvers.setenv(key,value,raw)
+setenv = function(key,value,raw)
if instance then
-- this one will be consulted first when we stay inside
-- the current environment (prefixes are not resolved here)
@@ -167,7 +192,7 @@ end
-- Beware we don't want empty here as this one can be called early on
-- and therefore we use rawget.
-local function getenv(key)
+getenv = function(key)
local value = rawget(instance.environment,key)
if value and value ~= "" then
return value
@@ -178,115 +203,121 @@ local function getenv(key)
end
resolvers.getenv = getenv
-resolvers.env = getenv
+resolvers.setenv = setenv
-- We are going to use some metatable trickery where we backtrack from
-- expansion to variable to environment.
-local function resolvevariable(k)
- return instance.expansions[k]
-end
-
local dollarstripper = lpeg.stripper("$")
local inhibitstripper = P("!")^0 * Cs(P(1)^0)
-local somevariable = P("$") / ""
-local somekey = C(R("az","AZ","09","__","--")^1)
-local somethingelse = P(";") * ((1-S("!{}/\\"))^1 * P(";") / "")
- + P(";") * (P(";") / "")
- + P(1)
-local variableexpander = Cs( (somevariable * (somekey/resolvevariable) + somethingelse)^1 )
+local expandedvariable, resolvedvariable do
-local cleaner = P("\\") / "/" + P(";") * S("!{}/\\")^0 * P(";")^1 / ";"
-local variablecleaner = Cs((cleaner + P(1))^0)
+ local function resolveinstancevariable(k)
+ return instance.expansions[k]
+ end
-local somevariable = R("az","AZ","09","__","--")^1 / resolvevariable
-local variable = (P("$")/"") * (somevariable + (P("{")/"") * somevariable * (P("}")/""))
-local variableresolver = Cs((variable + P(1))^0)
+ local p_variable = P("$") / ""
+ local p_key = C(R("az","AZ","09","__","--")^1)
+ local p_whatever = P(";") * ((1-S("!{}/\\"))^1 * P(";") / "")
+ + P(";") * (P(";") / "")
+ + P(1)
+ local variableexpander = Cs( (p_variable * (p_key/resolveinstancevariable) + p_whatever)^1 )
-local function expandedvariable(var)
- return lpegmatch(variableexpander,var) or var
-end
+ local p_cleaner = P("\\") / "/" + P(";") * S("!{}/\\")^0 * P(";")^1 / ";"
+ local variablecleaner = Cs((p_cleaner + P(1))^0)
-function resolvers.reset()
+ local p_variable = R("az","AZ","09","__","--")^1 / resolveinstancevariable
+ local p_variable = (P("$")/"") * (p_variable + (P("{")/"") * p_variable * (P("}")/""))
+ local variableresolver = Cs((p_variable + P(1))^0)
- -- normally we only need one instance but for special cases we can (re)load one so
- -- we stick to this model.
+ expandedvariable = function(var)
+ return lpegmatch(variableexpander,var) or var
+ end
- if trace_locating then
- report_resolving("creating instance")
- end
-
- local environment = { }
- local variables = { }
- local expansions = { }
- local order = { }
-
- instance = {
- environment = environment,
- variables = variables,
- expansions = expansions,
- order = order,
- files = { },
- setups = { },
- found = { },
- foundintrees = { },
- hashes = { },
- hashed = { },
- pathlists = false,-- delayed
- specification = { },
- lists = { },
- data = { }, -- only for loading
- fakepaths = { },
- remember = true,
- diskcache = true,
- renewcache = false,
- renewtree = false,
- loaderror = false,
- savelists = true,
- pattern = nil, -- lists
- force_suffixes = true,
- pathstack = { },
- }
-
- setmetatableindex(variables,function(t,k)
- local v
- for i=1,#order do
- v = order[i][k]
- if v ~= nil then
- t[k] = v
- return v
+ function resolvers.reset()
+
+ -- normally we only need one instance but for special cases we can (re)load one so
+ -- we stick to this model.
+
+ if trace_locating then
+ report_resolving("creating instance")
+ end
+
+ local environment = { }
+ local variables = { }
+ local expansions = { }
+ local order = { }
+
+ instance = {
+ environment = environment,
+ variables = variables,
+ expansions = expansions,
+ order = order,
+ files = { },
+ setups = { },
+ found = { },
+ foundintrees = { },
+ hashes = { },
+ hashed = { },
+ pathlists = false,-- delayed
+ specification = { },
+ lists = { },
+ data = { }, -- only for loading
+ fakepaths = { },
+ remember = true,
+ diskcache = true,
+ renewcache = false,
+ renewtree = false,
+ loaderror = false,
+ savelists = true,
+ pattern = nil, -- lists
+ force_suffixes = true,
+ pathstack = { },
+ }
+
+ setmetatableindex(variables,function(t,k)
+ local v
+ for i=1,#order do
+ v = order[i][k]
+ if v ~= nil then
+ t[k] = v
+ return v
+ end
end
- end
- if v == nil then
- v = ""
- end
- t[k] = v
- return v
- end)
+ if v == nil then
+ v = ""
+ end
+ t[k] = v
+ return v
+ end)
- setmetatableindex(environment, function(t,k)
- local v = osgetenv(k)
- if v == nil then
- v = variables[k]
- end
- if v ~= nil then
- v = checkedvariable(v) or ""
- end
- v = resolvers.repath(v) -- for taco who has a : separated osfontdir
- t[k] = v
- return v
- end)
+ local repath = resolvers.repath
- setmetatableindex(expansions, function(t,k)
- local v = environment[k]
- if type(v) == "string" then
- v = lpegmatch(variableresolver,v)
- v = lpegmatch(variablecleaner,v)
- end
- t[k] = v
- return v
- end)
+ setmetatableindex(environment, function(t,k)
+ local v = osgetenv(k)
+ if v == nil then
+ v = variables[k]
+ end
+ if v ~= nil then
+ v = checkedvariable(v) or ""
+ end
+ v = repath(v) -- for taco who has a : separated osfontdir
+ t[k] = v
+ return v
+ end)
+
+ setmetatableindex(expansions, function(t,k)
+ local v = environment[k]
+ if type(v) == "string" then
+ v = lpegmatch(variableresolver,v)
+ v = lpegmatch(variablecleaner,v)
+ end
+ t[k] = v
+ return v
+ end)
+
+ end
end
@@ -305,40 +336,44 @@ local function reset_caches()
instance.pathlists = false
end
-local slash = P("/")
+local makepathexpression do
-local pathexpressionpattern = Cs ( -- create lpeg instead (2013/2014)
- Cc("^") * (
- Cc("%") * S(".-")
- + slash^2 * P(-1) / "/.*"
- -- + slash^2 / "/.-/"
- -- + slash^2 / "/[^/]*/*" -- too general
- + slash^2 / "/"
- + (1-slash) * P(-1) * Cc("/")
- + P(1)
- )^1 * Cc("$") -- yes or no $
-)
+ local slash = P("/")
-local cache = { }
+ local pathexpressionpattern = Cs ( -- create lpeg instead (2013/2014)
+ Cc("^") * (
+ Cc("%") * S(".-")
+ + slash^2 * P(-1) / "/.*"
+ -- + slash^2 / "/.-/"
+ -- + slash^2 / "/[^/]*/*" -- too general
+ + slash^2 / "/"
+ + (1-slash) * P(-1) * Cc("/")
+ + P(1)
+ )^1 * Cc("$") -- yes or no $
+ )
-local function makepathexpression(str)
- if str == "." then
- return "^%./$"
- else
- local c = cache[str]
- if not c then
- c = lpegmatch(pathexpressionpattern,str)
- cache[str] = c
+ local cache = { }
+
+ makepathexpression = function(str)
+ if str == "." then
+ return "^%./$"
+ else
+ local c = cache[str]
+ if not c then
+ c = lpegmatch(pathexpressionpattern,str)
+ cache[str] = c
+ end
+ return c
end
- return c
end
+
end
local function reportcriticalvariables(cnfspec)
if trace_locating then
- for i=1,#resolvers.criticalvars do
- local k = resolvers.criticalvars[i]
- local v = resolvers.getenv(k) or "unknown" -- this one will not resolve !
+ for i=1,#criticalvars do
+ local k = criticalvars[i]
+ local v = getenv(k) or "unknown" -- this one will not resolve !
report_resolving("variable %a set to %a",k,v)
end
report_resolving()
@@ -361,7 +396,7 @@ local function identify_configuration_files()
resolvers.luacnfstate = "environment"
end
reportcriticalvariables(cnfspec)
- local cnfpaths = expandedpathfromlist(resolvers.splitpath(cnfspec))
+ local cnfpaths = expandedpathfromlist(splitpath(cnfspec))
local function locatecnf(luacnfname,kind)
for i=1,#cnfpaths do
@@ -398,6 +433,8 @@ end
local function load_configuration_files()
local specification = instance.specification
+ local setups = instance.setups
+ local order = instance.order
if #specification > 0 then
local luacnfname = resolvers.luacnfname
for i=1,#specification do
@@ -407,7 +444,6 @@ local function load_configuration_files()
local realname = resolveprefix(filename) -- no shortcut
local blob = loadfile(realname)
if blob then
- local setups = instance.setups
local data = blob()
local parent = data and data.parent
if parent then
@@ -418,7 +454,7 @@ local function load_configuration_files()
local parentdata = blob()
if parentdata then
report_resolving("loading configuration file %a",filename)
- data = table.merged(parentdata,data)
+ data = mergedtable(parentdata,data)
end
end
end
@@ -454,7 +490,7 @@ local function load_configuration_files()
-- we push the value into the main environment (osenv) so
-- that it takes precedence over the default one and therefore
-- also over following definitions
- resolvers.setenv("TEXMFCNF",cnfspec) -- resolves prefixes
+ setenv("TEXMFCNF",cnfspec) -- resolves prefixes
-- we now identify and load the specified configuration files
instance.specification = { }
identify_configuration_files()
@@ -476,7 +512,7 @@ local function load_configuration_files()
elseif trace_locating then
report_resolving("skipping configuration file %a (no valid format)",filename)
end
- instance.order[#instance.order+1] = instance.setups[pathname]
+ order[#order+1] = setups[pathname]
if instance.loaderror then
break
end
@@ -486,6 +522,13 @@ local function load_configuration_files()
end
end
+-- forward declarations:
+
+local expandedpathlist
+local unexpandedpathlist
+
+-- done
+
function resolvers.configurationfiles()
return instance.specification or { }
end
@@ -507,7 +550,7 @@ end
local function locate_file_databases()
-- todo: cache:// and tree:// (runtime)
- local texmfpaths = resolvers.expandedpathlist("TEXMF")
+ local texmfpaths = expandedpathlist("TEXMF")
if #texmfpaths > 0 then
for i=1,#texmfpaths do
local path = collapsepath(texmfpaths[i])
@@ -516,7 +559,7 @@ local function locate_file_databases()
if stripped ~= "" then
local runtime = stripped == path
path = cleanpath(path)
- local spec = resolvers.splitmethod(stripped)
+ local spec = splitmethod(stripped)
if runtime and (spec.noscheme or spec.scheme == "file") then
stripped = "tree:///" .. stripped
elseif spec.scheme == "cache" or spec.scheme == "file" then
@@ -552,11 +595,13 @@ local function generate_file_databases()
end
local function save_file_databases() -- will become cachers
- for i=1,#instance.hashes do
- local hash = instance.hashes[i]
+ local hashes = instance.hashes
+ local files = instance.files
+ for i=1,#hashes do
+ local hash = hashes[i]
local cachename = hash.name
if hash.cache then
- local content = instance.files[cachename]
+ local content = files[cachename]
caches.collapsecontent(content)
if trace_locating then
report_resolving("saving tree %a",cachename)
@@ -569,8 +614,9 @@ local function save_file_databases() -- will become cachers
end
function resolvers.renew(hashname)
+ local files = instance.files
if hashname and hashname ~= "" then
- local expanded = resolvers.expansion(hashname) or ""
+ local expanded = expansion(hashname) or ""
if expanded ~= "" then
if trace_locating then
report_resolving("identifying tree %a from %a",expanded,hashname)
@@ -588,7 +634,7 @@ function resolvers.renew(hashname)
end
methodhandler('generators',hashname)
-- could be shared
- local content = instance.files[hashname]
+ local content = files[hashname]
caches.collapsecontent(content)
if trace_locating then
report_resolving("saving tree %a",hashname)
@@ -618,35 +664,43 @@ local function load_databases()
end
function resolvers.appendhash(type,name,cache)
- -- safeguard ... tricky as it's actually a bug when seen twice
- if not instance.hashed[name] then
+ local hashed = instance.hashed
+ local hashes = instance.hashes
+ if hashed[name] then
+ -- safeguard ... tricky as it's actually a bug when seen twice
+ else
if trace_locating then
report_resolving("hash %a appended",name)
end
- insert(instance.hashes, { type = type, name = name, cache = cache } )
- instance.hashed[name] = cache
+ insert(hashes, { type = type, name = name, cache = cache } )
+ hashed[name] = cache
end
end
function resolvers.prependhash(type,name,cache)
- -- safeguard ... tricky as it's actually a bug when seen twice
- if not instance.hashed[name] then
+ local hashed = instance.hashed
+ local hashes = instance.hashes
+ if hashed[name] then
+ -- safeguard ... tricky as it's actually a bug when seen twice
+ else
if trace_locating then
report_resolving("hash %a prepended",name)
end
- insert(instance.hashes, 1, { type = type, name = name, cache = cache } )
- instance.hashed[name] = cache
+ insert(hashes, 1, { type = type, name = name, cache = cache } )
+ hashed[name] = cache
end
end
function resolvers.extendtexmfvariable(specification) -- crap, we could better prepend the hash
- local t = resolvers.splitpath(getenv("TEXMF")) -- okay?
- insert(t,1,specification)
- local newspec = concat(t,",") -- not ;
- if instance.environment["TEXMF"] then
- instance.environment["TEXMF"] = newspec
- elseif instance.variables["TEXMF"] then
- instance.variables["TEXMF"] = newspec
+ local environment = instance.environment
+ local variables = instance.variables
+ local texmftrees = splitpath(getenv("TEXMF")) -- okay?
+ insert(texmftrees,1,specification)
+ texmftrees = concat(texmftrees,",") -- not ;
+ if environment["TEXMF"] then
+ environment["TEXMF"] = texmftrees
+ elseif variables["TEXMF"] then
+ variables["TEXMF"] = texmftrees
else
-- weird
end
@@ -654,8 +708,8 @@ function resolvers.extendtexmfvariable(specification) -- crap, we could better p
end
function resolvers.splitexpansions()
- local ie = instance.expansions
- for k,v in next, ie do
+ local expansions = instance.expansions
+ for k, v in next, expansions do
local t, tn, h, p = { }, 0, { }, splitconfigurationpath(v)
for kk=1,#p do
local vv = p[kk]
@@ -665,10 +719,10 @@ function resolvers.splitexpansions()
h[vv] = true
end
end
- if #t > 1 then
- ie[k] = t
+ if tn > 1 then
+ expansions[k] = t
else
- ie[k] = t[1]
+ expansions[k] = t[1]
end
end
end
@@ -682,26 +736,31 @@ function resolvers.datastate()
return caches.contentstate()
end
-function resolvers.variable(name)
+variable = function(name)
+ local variables = instance.variables
local name = name and lpegmatch(dollarstripper,name)
- local result = name and instance.variables[name]
+ local result = name and variables[name]
return result ~= nil and result or ""
end
-function resolvers.expansion(name)
+expansion = function(name)
+ local expansions =instance.expansions
local name = name and lpegmatch(dollarstripper,name)
- local result = name and instance.expansions[name]
+ local result = name and expansions[name]
return result ~= nil and result or ""
end
-function resolvers.unexpandedpathlist(str)
- local pth = resolvers.variable(str)
- local lst = resolvers.splitpath(pth)
+resolvers.variable = variable
+resolvers.expansion = expansion
+
+unexpandedpathlist = function(str)
+ local pth = variable(str)
+ local lst = splitpath(pth)
return expandedpathfromlist(lst)
end
function resolvers.unexpandedpath(str)
- return joinpath(resolvers.unexpandedpathlist(str))
+ return joinpath(unexpandedpathlist(str))
end
function resolvers.pushpath(name)
@@ -736,8 +795,8 @@ end
local done = { }
function resolvers.resetextrapaths()
- local ep = instance.extra_paths
- if not ep then
+ local extra_paths = instance.extra_paths
+ if not extra_paths then
done = { }
instance.extra_paths = { }
elseif #ep > 0 then
@@ -760,8 +819,8 @@ function resolvers.registerextrapath(paths,subpaths)
end
local paths = settings_to_array(paths)
local subpaths = settings_to_array(subpaths)
- local ep = instance.extra_paths or { }
- local oldn = #ep
+ local extra_paths = instance.extra_paths or { }
+ local oldn = #extra_paths
local newn = oldn
local nofpaths = #paths
local nofsubpaths = #subpaths
@@ -774,7 +833,7 @@ function resolvers.registerextrapath(paths,subpaths)
local ps = p .. "/" .. s
if not done[ps] then
newn = newn + 1
- ep[newn] = cleanpath(ps)
+ extra_paths[newn] = cleanpath(ps)
done[ps] = true
end
end
@@ -784,7 +843,7 @@ function resolvers.registerextrapath(paths,subpaths)
local p = paths[i]
if not done[p] then
newn = newn + 1
- ep[newn] = cleanpath(p)
+ extra_paths[newn] = cleanpath(p)
done[p] = true
end
end
@@ -793,17 +852,17 @@ function resolvers.registerextrapath(paths,subpaths)
for i=1,oldn do
for j=1,nofsubpaths do
local s = subpaths[j]
- local ps = ep[i] .. "/" .. s
+ local ps = extra_paths[i] .. "/" .. s
if not done[ps] then
newn = newn + 1
- ep[newn] = cleanpath(ps)
+ extra_paths[newn] = cleanpath(ps)
done[ps] = true
end
end
end
end
if newn > 0 then
- instance.extra_paths = ep -- register paths
+ instance.extra_paths = extra_paths -- register paths
end
if newn ~= oldn then
reset_caches()
@@ -812,8 +871,9 @@ end
function resolvers.pushextrapath(path)
local paths = settings_to_array(path)
- if instance.extra_stack then
- insert(instance.extra_stack,1,paths)
+ local extra_stack = instance.extra_stack
+ if extra_stack then
+ insert(extra_stack,1,paths)
else
instance.extra_stack = { paths }
end
@@ -821,9 +881,10 @@ function resolvers.pushextrapath(path)
end
function resolvers.popextrapath()
- if instance.extra_stack then
+ local extra_stack = instance.extra_stack
+ if extra_stack then
reset_caches()
- return remove(instance.extra_stack,1)
+ return remove(extra_stack,1)
end
end
@@ -856,17 +917,17 @@ local function made_list(instance,list,extra_too)
end
end
if extra_too then
+ local extra_stack = instance.extra_stack
+ local extra_paths = instance.extra_paths
-- first the stacked paths
- local es = instance.extra_stack
- if es and #es > 0 then
- for k=1,#es do
- add(es[k])
+ if extra_stack and #extra_stack > 0 then
+ for k=1,#extra_stack do
+ add(extra_stack[k])
end
end
-- then the extra paths
- local ep = instance.extra_paths
- if ep and #ep > 0 then
- add(ep)
+ if extra_paths and #extra_paths > 0 then
+ add(extra_paths)
end
end
-- last the formal paths
@@ -874,21 +935,7 @@ local function made_list(instance,list,extra_too)
return new
end
-function resolvers.cleanpathlist(str)
- local t = resolvers.expandedpathlist(str)
- if t then
- for i=1,#t do
- t[i] = collapsepath(cleanpath(t[i]))
- end
- end
- return t
-end
-
-function resolvers.expandpath(str)
- return joinpath(resolvers.expandedpathlist(str))
-end
-
-function resolvers.expandedpathlist(str,extra_too)
+expandedpathlist = function(str,extra_too)
if not str then
return { }
elseif instance.savelists then -- hm, what if two cases, with and without extra_too
@@ -896,45 +943,65 @@ function resolvers.expandedpathlist(str,extra_too)
local lists = instance.lists
local lst = lists[str]
if not lst then
- local l = made_list(instance,resolvers.splitpath(resolvers.expansion(str)),extra_too)
+ local l = made_list(instance,splitpath(expansion(str)),extra_too)
lst = expandedpathfromlist(l)
lists[str] = lst
end
return lst
else
- local lst = resolvers.splitpath(resolvers.expansion(str))
+ local lst = splitpath(expansion(str))
return made_list(instance,expandedpathfromlist(lst),extra_too)
end
end
-function resolvers.expandedpathlistfromvariable(str) -- brrr / could also have cleaner ^!! /$ //
+resolvers.expandedpathlist = expandedpathlist
+resolvers.unexpandedpathlist = unexpandedpathlist
+
+function resolvers.cleanpathlist(str)
+ local t = expandedpathlist(str)
+ if t then
+ for i=1,#t do
+ t[i] = collapsepath(cleanpath(t[i]))
+ end
+ end
+ return t
+end
+
+function resolvers.expandpath(str)
+ return joinpath(expandedpathlist(str))
+end
+
+local function expandedpathlistfromvariable(str) -- brrr / could also have cleaner ^!! /$ //
str = lpegmatch(dollarstripper,str)
local tmp = resolvers.variableofformatorsuffix(str)
- return resolvers.expandedpathlist(tmp ~= "" and tmp or str)
+ return expandedpathlist(tmp ~= "" and tmp or str)
end
function resolvers.expandpathfromvariable(str)
- return joinpath(resolvers.expandedpathlistfromvariable(str))
+ return joinpath(expandedpathlistfromvariable(str))
end
+resolvers.expandedpathlistfromvariable = expandedpathlistfromvariable
+
function resolvers.cleanedpathlist(v) -- can be cached if needed
- local t = resolvers.expandedpathlist(v)
+ local t = expandedpathlist(v)
for i=1,#t do
- t[i] = resolvers.resolve(resolvers.cleanpath(t[i]))
+ t[i] = resolveprefix(cleanpath(t[i]))
end
return t
end
function resolvers.expandbraces(str) -- output variable and brace expansion of STRING
- local pth = expandedpathfromlist(resolvers.splitpath(str))
+ local pth = expandedpathfromlist(splitpath(str))
return joinpath(pth)
end
function resolvers.registerfilehash(name,content,someerror)
+ local files = instance.files
if content then
- instance.files[name] = content
+ files[name] = content
else
- instance.files[name] = { }
+ files[name] = { }
if somerror == true then -- can be unset
instance.loaderror = someerror
end
@@ -998,10 +1065,11 @@ local function collect_files(names) -- potential files .. sort of too much when
pathname = "/" .. pathname .. "$"
end
local hashes = instance.hashes
+ local files = instance.files
for h=1,#hashes do
local hash = hashes[h]
local hashname = hash.name
- local content = hashname and instance.files[hashname]
+ local content = hashname and files[hashname]
if content then
if trace_details then
report_resolving("deep checking %a, base %a, pattern %a",hashname,basename,pathname)
@@ -1089,7 +1157,6 @@ local function find_analyze(filename,askedformat,allresults)
if askedformat == "" then
if filesuffix == "" or not suffixmap[filesuffix] then
local defaultsuffixes = resolvers.defaultsuffixes
- local formatofsuffix = resolvers.formatofsuffix
for i=1,#defaultsuffixes do
local forcedname = filename .. '.' .. defaultsuffixes[i]
wantedfiles[#wantedfiles+1] = forcedname
@@ -1099,7 +1166,7 @@ local function find_analyze(filename,askedformat,allresults)
end
end
else
- filetype = resolvers.formatofsuffix(filename)
+ filetype = formatofsuffix(filename)
if trace_locating then
report_resolving("using suffix based filetype %a",filetype)
end
@@ -1163,11 +1230,11 @@ local function find_qualified(filename,allresults,askedformat,alsostripped) -- t
local format_suffixes = askedformat == "" and resolvers.defaultsuffixes or suffixes[askedformat]
if format_suffixes then
for i=1,#format_suffixes do
- local s = format_suffixes[i]
- forcedname = filename .. "." .. s
+ local suffix = format_suffixes[i]
+ forcedname = filename .. "." .. suffix
if isreadable(forcedname) then
if trace_locating then
- report_resolving("no suffix, forcing format filetype %a", s)
+ report_resolving("no suffix, forcing format filetype %a", suffix)
end
return "qualified", { forcedname }
end
@@ -1182,7 +1249,7 @@ local function find_qualified(filename,allresults,askedformat,alsostripped) -- t
local savedformat = askedformat
local format = savedformat or ""
if format == "" then
- askedformat = resolvers.formatofsuffix(suffix)
+ askedformat = formatofsuffix(suffix)
end
if not format then
askedformat = "othertextfiles" -- kind of everything, maybe all
@@ -1244,7 +1311,7 @@ end
local function makepathlist(list,filetype)
local typespec = resolvers.variableofformat(filetype)
- local pathlist = resolvers.expandedpathlist(typespec,filetype and usertypes[filetype]) -- only extra path with user files
+ local pathlist = expandedpathlist(typespec,filetype and usertypes[filetype]) -- only extra path with user files
local entry = { }
if pathlist and #pathlist > 0 then
for k=1,#pathlist do
@@ -1255,7 +1322,7 @@ local function makepathlist(list,filetype)
local expression = makepathexpression(pathname)
local barename = gsub(pathname,"/+$","")
barename = resolveprefix(barename)
- local scheme = url.hasscheme(barename)
+ local scheme = urlhasscheme(barename)
local schemename = gsub(barename,"%.%*$",'') -- after scheme
-- local prescanned = path ~= pathname -- ^!!
-- local resursive = find(pathname,'//$')
@@ -1480,10 +1547,8 @@ collect_instance_files = function(filename,askedformat,allresults) -- uses neste
return { }
end
askedformat = askedformat or ""
- filename = collapsepath(filename,".")
-
- filename = gsub(filename,"^%./",getcurrentdir().."/") -- we will merge dir.expandname and collapse some day
-
+ filename = collapsepath(filename,".")
+ filename = gsub(filename,"^%./",getcurrentdir().."/") -- we will merge dir.expandname and collapse some day
if allresults then
-- no need for caching, only used for tracing
local filetype, wantedfiles = find_analyze(filename,askedformat)
@@ -1495,7 +1560,9 @@ collect_instance_files = function(filename,askedformat,allresults) -- uses neste
{ find_onpath (filename,filetype,wantedfiles,true) },
{ find_otherwise(filename,filetype,wantedfiles,true) },
}
- local result, status, done = { }, { }, { }
+ local result = { }
+ local status = { }
+ local done = { }
for k, r in next, results do
local method, list = r[1], r[2]
if method and list then
@@ -1570,6 +1637,9 @@ local function findfiles(filename,filetype,allresults)
if not filename or filename == "" then
return { }
end
+ if allresults == nil then
+ allresults = true
+ end
local result, status = collect_instance_files(filename,filetype or "",allresults)
if not result or #result == 0 then
local lowered = lower(filename)
@@ -1580,32 +1650,29 @@ local function findfiles(filename,filetype,allresults)
return result or { }, status
end
-function resolvers.findfiles(filename,filetype)
- if not filename or filename == "" then
- -- weird ... why called then
- return ""
- else
- return findfiles(filename,filetype,true)
- end
-end
-
-function resolvers.findfile(filename,filetype)
+local function findfile(filename,filetype)
if not filename or filename == "" then
- -- weird ... why called then
return ""
else
return findfiles(filename,filetype,false)[1] or ""
end
end
+resolvers.findfiles = findfiles
+resolvers.findfile = findfile
+
+resolvers.find_file = findfile -- obsolete
+resolvers.find_files = findfiles -- obsolete
+
function resolvers.findpath(filename,filetype)
return filedirname(findfiles(filename,filetype,false)[1] or "")
end
local function findgivenfiles(filename,allresults)
+ local hashes = instance.hashes
+ local files = instance.files
local base = filebasename(filename)
local result = { }
- local hashes = instance.hashes
--
local function okay(hash,path,name)
local found = methodhandler('concatinators',hash.type,hash.name,path,name)
@@ -1617,7 +1684,7 @@ local function findgivenfiles(filename,allresults)
--
for k=1,#hashes do
local hash = hashes[k]
- local content = instance.files[hash.name]
+ local content = files[hash.name]
if content then
local path, name = lookup(content,base)
if not path then
@@ -1660,15 +1727,16 @@ end
-- why bother
local function findwildcardfiles(filename,allresults,result)
+ local files = instance.files
+ local hashes = instance.hashes
+ --
local result = result or { }
local base = filebasename(filename)
local dirn = filedirname(filename)
local path = lower(lpegmatch(makewildcard,dirn) or dirn)
local name = lower(lpegmatch(makewildcard,base) or base)
- local files = instance.files
--
if find(name,"*",1,true) then
- local hashes = instance.hashes
local function okay(found,path,base,hashname,hashtype)
if find(found,path) then
local full = methodhandler('concatinators',hashtype,hashname,found,base)
@@ -1709,7 +1777,6 @@ local function findwildcardfiles(filename,allresults,result)
end
end
--
- local hashes = instance.hashes
for k=1,#hashes do
local hash = hashes[k]
local hashname = hash.name
@@ -1745,18 +1812,30 @@ function resolvers.findwildcardfile(filename)
return findwildcardfiles(filename,false)[1] or ""
end
--- main user functions
+do
-function resolvers.automount()
- -- implemented later
-end
+ local starttiming = statistics.starttiming
+ local stoptiming = statistics.stoptiming
+ local elapsedtime = statistics.elapsedtime
+
+ function resolvers.starttiming()
+ starttiming(instance)
+ end
+
+ function resolvers.stoptiming()
+ stoptiming(instance)
+ end
+
+ function resolvers.loadtime()
+ return elapsedtime(instance)
+ end
-function resolvers.starttiming()
- statistics.starttiming(instance)
end
-function resolvers.stoptiming()
- statistics.stoptiming(instance)
+-- main user functions
+
+function resolvers.automount()
+ -- implemented later (maybe a one-time setter like textopener)
end
function resolvers.load(option)
@@ -1772,10 +1851,6 @@ function resolvers.load(option)
return files and next(files) and true
end
-function resolvers.loadtime()
- return statistics.elapsedtime(instance)
-end
-
local function report(str)
if trace_locating then
report_resolving(str) -- has already verbose
@@ -1806,13 +1881,11 @@ function resolvers.dowithfilesandreport(command, files, ...) -- will move
end
end
--- obsolete
-
-- resolvers.varvalue = resolvers.variable -- output the value of variable $STRING.
--- resolvers.expandvar = resolvers.expansion -- output variable expansion of STRING.
+-- resolvers.expandvar = expansion -- output variable expansion of STRING.
function resolvers.showpath(str) -- output search path for file type NAME
- return joinpath(resolvers.expandedpathlist(resolvers.formatofvariable(str)))
+ return joinpath(expandedpathlist(resolvers.formatofvariable(str)))
end
function resolvers.registerfile(files, name, path)
@@ -1828,7 +1901,7 @@ function resolvers.registerfile(files, name, path)
end
function resolvers.dowithpath(name,func)
- local pathlist = resolvers.expandedpathlist(name)
+ local pathlist = expandedpathlist(name)
for i=1,#pathlist do
func("^"..cleanpath(pathlist[i]))
end
@@ -1844,7 +1917,7 @@ function resolvers.locateformat(name)
local fullname = addsuffix(barename,"fmt")
local fmtname = caches.getfirstreadablefile(fullname,"formats",engine) or ""
if fmtname == "" then
- fmtname = resolvers.findfile(fullname)
+ fmtname = findfile(fullname)
fmtname = cleanpath(fmtname)
end
if fmtname ~= "" then
@@ -1864,7 +1937,7 @@ function resolvers.locateformat(name)
end
function resolvers.booleanvariable(str,default)
- local b = resolvers.expansion(str)
+ local b = expansion(str)
if b == "" then
return default
else
@@ -1875,6 +1948,7 @@ end
function resolvers.dowithfilesintree(pattern,handle,before,after) -- will move, can be a nice iterator instead
local hashes = instance.hashes
+ local files = instance.files
for i=1,#hashes do
local hash = hashes[i]
local blobtype = hash.type
@@ -1886,7 +1960,7 @@ function resolvers.dowithfilesintree(pattern,handle,before,after) -- will move,
if before then
before(blobtype,blobpath,pattern)
end
- for path, name in filtered(instance.files[blobpath],pattern) do
+ for path, name in filtered(files[blobpath],pattern) do
if type(path) == "string" then
checked = checked + 1
if handle(blobtype,blobpath,path,name) then
@@ -1908,12 +1982,6 @@ function resolvers.dowithfilesintree(pattern,handle,before,after) -- will move,
end
end
-local obsolete = resolvers.obsolete or { }
-resolvers.obsolete = obsolete
-
-resolvers.find_file = resolvers.findfile obsolete.find_file = resolvers.findfile
-resolvers.find_files = resolvers.findfiles obsolete.find_files = resolvers.findfiles
-
-- moved here
function resolvers.knownvariables(pattern)