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.lua187
1 files changed, 119 insertions, 68 deletions
diff --git a/tex/context/base/mkiv/data-res.lua b/tex/context/base/mkiv/data-res.lua
index 4f171c445..9fb33f88d 100644
--- a/tex/context/base/mkiv/data-res.lua
+++ b/tex/context/base/mkiv/data-res.lua
@@ -6,15 +6,6 @@ if not modules then modules = { } end modules ['data-res'] = {
license = "see context related readme files",
}
--- In practice we will work within one tds tree, but i want to keep
--- the option open to build tools that look at multiple trees, which is
--- why we keep the tree specific data in a table. We used to pass the
--- instance but for practical purposes we now avoid this and use a
--- instance variable. We always have one instance active (sort of global).
-
--- I will reimplement this module ... way too fuzzy now and we can work
--- with some sensible constraints as it is only is used for context.
-
-- todo: cache:/// home:/// selfautoparent:/// (sometime end 2012)
local gsub, find, lower, upper, match, gmatch = string.gsub, string.find, string.lower, string.upper, string.match, string.gmatch
@@ -154,8 +145,7 @@ local suffixmap = resolvers.suffixmap
resolvers.defaultsuffixes = { "tex" } -- "mkiv", "cld" -- too tricky
-resolvers.instance = resolvers.instance or nil -- the current one (slow access)
-local instance = resolvers.instance or nil -- the current one (fast access)
+local instance = nil -- the current one (fast access)
-- An instance has an environment (coming from the outside, kept raw), variables
-- (coming from the configuration file), and expansions (variables with nested
@@ -218,7 +208,7 @@ local function expandedvariable(var)
return lpegmatch(variableexpander,var) or var
end
-function resolvers.newinstance() -- todo: all vars will become lowercase and alphanum only
+function resolvers.reset()
-- normally we only need one instance but for special cases we can (re)load one so
-- we stick to this model.
@@ -227,24 +217,27 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
report_resolving("creating instance")
end
- local environment, variables, expansions, order = allocate(), allocate(), allocate(), allocate()
+ local environment = { }
+ local variables = { }
+ local expansions = { }
+ local order = { }
- local newinstance = {
+ instance = {
environment = environment,
variables = variables,
expansions = expansions,
order = order,
- files = allocate(),
- setups = allocate(),
- found = allocate(),
- foundintrees = allocate(),
- hashes = allocate(),
- hashed = allocate(),
+ files = { },
+ setups = { },
+ found = { },
+ foundintrees = { },
+ hashes = { },
+ hashed = { },
pathlists = false,-- delayed
- specification = allocate(),
- lists = allocate(),
- data = allocate(), -- only for loading
- fakepaths = allocate(),
+ specification = { },
+ lists = { },
+ data = { }, -- only for loading
+ fakepaths = { },
remember = true,
diskcache = true,
renewcache = false,
@@ -295,18 +288,10 @@ function resolvers.newinstance() -- todo: all vars will become lowercase and alp
return v
end)
- return newinstance
-
-end
-
-function resolvers.setinstance(someinstance) -- only one instance is active
- instance = someinstance
- resolvers.instance = someinstance
- return someinstance
end
-function resolvers.reset()
- return resolvers.setinstance(resolvers.newinstance())
+function resolvers.initialized()
+ return instance ~= nil
end
local function reset_hashes()
@@ -501,10 +486,15 @@ local function load_configuration_files()
end
end
+function resolvers.configurationfiles()
+ return instance.specification or { }
+end
+
-- scheme magic ... database loading
local function load_file_databases()
- instance.loaderror, instance.files = false, allocate()
+ instance.loaderror = false
+ instance.files = { }
if not instance.renewcache then
local hashes = instance.hashes
for k=1,#hashes do
@@ -693,13 +683,13 @@ function resolvers.datastate()
end
function resolvers.variable(name)
- local name = name and lpegmatch(dollarstripper,name)
+ local name = name and lpegmatch(dollarstripper,name)
local result = name and instance.variables[name]
return result ~= nil and result or ""
end
function resolvers.expansion(name)
- local name = name and lpegmatch(dollarstripper,name)
+ local name = name and lpegmatch(dollarstripper,name)
local result = name and instance.expansions[name]
return result ~= nil and result or ""
end
@@ -745,7 +735,7 @@ end
local done = { }
-function resolvers.resetextrapath()
+function resolvers.resetextrapaths()
local ep = instance.extra_paths
if not ep then
done = { }
@@ -756,6 +746,10 @@ function resolvers.resetextrapath()
end
end
+function resolvers.getextrapaths()
+ return instance.extra_paths or { }
+end
+
function resolvers.registerextrapath(paths,subpaths)
if not subpaths or subpaths == "" then
if not paths or path == "" then
@@ -932,11 +926,7 @@ function resolvers.cleanedpathlist(v) -- can be cached if needed
end
function resolvers.expandbraces(str) -- output variable and brace expansion of STRING
--- local ori = resolvers.variable(str)
--- if ori == "" then
- local ori = str
--- end
- local pth = expandedpathfromlist(resolvers.splitpath(ori))
+ local pth = expandedpathfromlist(resolvers.splitpath(str))
return joinpath(pth)
end
@@ -951,6 +941,20 @@ function resolvers.registerfilehash(name,content,someerror)
end
end
+function resolvers.getfilehashes()
+ return instance and instance.files or { }
+end
+
+function resolvers.gethashes()
+ return instance and instance.hashes or { }
+end
+
+function resolvers.renewcache()
+ if instance then
+ instance.renewcache = true
+ end
+end
+
local function isreadable(name)
local readable = isfile(name) -- not file.is_readable(name) asit can be a dir
if trace_detail then
@@ -968,7 +972,7 @@ end
local function collect_files(names) -- potential files .. sort of too much when asking for just one file
local filelist = { } -- but we need it for pattern matching later on
local noffiles = 0
- local function check(hash,root,pathname,path,name)
+ local function check(hash,root,pathname,path,basename,name)
if not pathname or find(path,pathname) then
local variant = hash.type
local search = filejoin(root,path,name) -- funny no concatinator
@@ -1007,10 +1011,10 @@ local function collect_files(names) -- potential files .. sort of too much when
local metadata = content.metadata
local realroot = metadata and metadata.path or hashname
if type(path) == "string" then
- check(hash,realroot,pathname,path,name)
+ check(hash,realroot,pathname,path,basename,name)
else
for i=1,#path do
- check(hash,realroot,pathname,path[i],name)
+ check(hash,realroot,pathname,path[i],basename,name)
end
end
end
@@ -1029,18 +1033,29 @@ function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname
if usedmethod == "direct" and filename == foundname and fit[foundname] then
-- just an extra lookup after a test on presence
else
+ local collapsed = collapsepath(foundname,true)
local t = {
filename = filename,
- format = format ~= "" and format or nil,
+ format = format ~= "" and format or nil,
filetype = filetype ~= "" and filetype or nil,
usedmethod = usedmethod,
foundname = foundname,
+ fullname = collapsed,
}
fit[foundname] = t
foundintrees[#foundintrees+1] = t
end
end
+function resolvers.foundintrees()
+ return instance.foundintrees or { }
+end
+
+function resolvers.foundintree(fullname)
+ local f = fit[fullname]
+ return f and f.usedmethod == "database"
+end
+
-- split the next one up for readability (but this module needs a cleanup anyway)
local function can_be_dir(name) -- can become local
@@ -1062,15 +1077,17 @@ local preparetreepattern = Cs((P(".")/"%%." + P("-")/"%%-" + P(1))^0 * Cc("$"))
local collect_instance_files
local function find_analyze(filename,askedformat,allresults)
- local filetype, wantedfiles, ext = '', { }, suffixonly(filename)
+ local filetype = ''
+ local filesuffix = suffixonly(filename)
+ local wantedfiles = { }
-- too tricky as filename can be bla.1.2.3:
--
- -- if not suffixmap[ext] then
+ -- if not suffixmap[filesuffix] then
-- wantedfiles[#wantedfiles+1] = filename
-- end
wantedfiles[#wantedfiles+1] = filename
if askedformat == "" then
- if ext == "" or not suffixmap[ext] then
+ if filesuffix == "" or not suffixmap[filesuffix] then
local defaultsuffixes = resolvers.defaultsuffixes
local formatofsuffix = resolvers.formatofsuffix
for i=1,#defaultsuffixes do
@@ -1088,7 +1105,7 @@ local function find_analyze(filename,askedformat,allresults)
end
end
else
- if ext == "" or not suffixmap[ext] then
+ if filesuffix == "" or not suffixmap[filesuffix] then
local format_suffixes = suffixes[askedformat]
if format_suffixes then
for i=1,#format_suffixes do
@@ -1160,11 +1177,10 @@ local function find_qualified(filename,allresults,askedformat,alsostripped) -- t
if alsostripped and suffix and suffix ~= "" then
-- try to find in tree (no suffix manipulation), here we search for the
-- matching last part of the name
- local basename = filebasename(filename)
- local pattern = lpegmatch(preparetreepattern,filename)
- -- messy .. to be sorted out
+ local basename = filebasename(filename)
+ local pattern = lpegmatch(preparetreepattern,filename)
local savedformat = askedformat
- local format = savedformat or ""
+ local format = savedformat or ""
if format == "" then
askedformat = resolvers.formatofsuffix(suffix)
end
@@ -1269,7 +1285,7 @@ end
local function find_intree(filename,filetype,wantedfiles,allresults)
local pathlists = instance.pathlists
if not pathlists then
- pathlists = setmetatableindex(allocate(),makepathlist)
+ pathlists = setmetatableindex({ },makepathlist)
instance.pathlists = pathlists
end
local pathlist = pathlists[filetype]
@@ -1588,9 +1604,9 @@ function resolvers.findpath(filename,filetype)
end
local function findgivenfiles(filename,allresults)
- local base = filebasename(filename)
- local result = { }
- local hashes = instance.hashes
+ 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)
@@ -1645,12 +1661,12 @@ end
-- why bother
local function findwildcardfiles(filename,allresults,result)
- 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
+ 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
@@ -1736,15 +1752,23 @@ function resolvers.automount()
-- implemented later
end
-function resolvers.load(option)
+function resolvers.starttiming()
statistics.starttiming(instance)
+end
+
+function resolvers.stoptiming()
+ statistics.stoptiming(instance)
+end
+
+function resolvers.load(option)
+ resolvers.starttiming()
identify_configuration_files()
load_configuration_files()
if option ~= "nofiles" then
load_databases()
resolvers.automount()
end
- statistics.stoptiming(instance)
+ resolvers.stoptiming()
local files = instance.files
return files and next(files) and true
end
@@ -1851,7 +1875,6 @@ function resolvers.booleanvariable(str,default)
end
function resolvers.dowithfilesintree(pattern,handle,before,after) -- will move, can be a nice iterator instead
- local instance = resolvers.instance
local hashes = instance.hashes
for i=1,#hashes do
local hash = hashes[i]
@@ -1891,3 +1914,31 @@ 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)
+ if instance then
+ local environment = instance.environment
+ local variables = instance.variables
+ local expansions = instance.expansions
+ local order = instance.order
+ local pattern = upper(pattern or "")
+ local result = { }
+ for i=1,#order do
+ for key in next, order[i] do
+ if result[key] == nil and key ~= "" and (pattern == "" or find(upper(key),pattern)) then
+ result[key] = {
+ environment = rawget(environment,key),
+ variable = key,
+ expansion = expansions[key],
+ resolved = resolveprefix(expansions[key]),
+ }
+ end
+ end
+ end
+ return result
+ else
+ return { }
+ end
+end