From 7ecbcaaf68d152851591dbb5931a6eb15d155019 Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Mon, 25 Nov 2019 23:15:50 +0100 Subject: 2019-11-25 17:37:00 --- tex/context/base/mkiv/data-res.lua | 596 +++++++++++++++++++++---------------- 1 file changed, 332 insertions(+), 264 deletions(-) (limited to 'tex/context/base/mkiv/data-res.lua') 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) -- cgit v1.2.3