summaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorHans Hagen <pragma@wxs.nl>2009-11-18 21:51:00 +0100
committerHans Hagen <pragma@wxs.nl>2009-11-18 21:51:00 +0100
commitb309379ef546b7fa819f493fa3cb1dc559d4c3b8 (patch)
treef7244cebdc52206c3a35767ed9eb834dc901313b /scripts
parent9cf4a9e0a6642da57b94730bf7104335735a7ace (diff)
downloadcontext-b309379ef546b7fa819f493fa3cb1dc559d4c3b8.tar.gz
beta 2009.11.18 21:51
Diffstat (limited to 'scripts')
-rw-r--r--scripts/context/lua/luatools.lua395
-rw-r--r--scripts/context/lua/mtx-context.lua23
-rw-r--r--scripts/context/lua/mtx-fonts.lua214
-rw-r--r--scripts/context/lua/mtxrun.lua147
-rw-r--r--scripts/context/stubs/mswin/luatools.lua395
-rw-r--r--scripts/context/stubs/mswin/mtxrun.lua147
-rwxr-xr-xscripts/context/stubs/unix/luatools395
-rwxr-xr-xscripts/context/stubs/unix/mtxrun147
8 files changed, 1383 insertions, 480 deletions
diff --git a/scripts/context/lua/luatools.lua b/scripts/context/lua/luatools.lua
index 2bc943210..abd80b8b4 100644
--- a/scripts/context/lua/luatools.lua
+++ b/scripts/context/lua/luatools.lua
@@ -308,7 +308,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
license = "see context related readme files"
}
-local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
--~ l-lpeg.lua :
@@ -415,6 +415,41 @@ end
--~ return p
--~ end
+--~ from roberto's site:
+--~
+--~ -- decode a two-byte UTF-8 sequence
+--~ local function f2 (s)
+--~ local c1, c2 = string.byte(s, 1, 2)
+--~ return c1 * 64 + c2 - 12416
+--~ end
+--~
+--~ -- decode a three-byte UTF-8 sequence
+--~ local function f3 (s)
+--~ local c1, c2, c3 = string.byte(s, 1, 3)
+--~ return (c1 * 64 + c2) * 64 + c3 - 925824
+--~ end
+--~
+--~ -- decode a four-byte UTF-8 sequence
+--~ local function f4 (s)
+--~ local c1, c2, c3, c4 = string.byte(s, 1, 4)
+--~ return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168
+--~ end
+--~
+--~ local cont = lpeg.R("\128\191") -- continuation byte
+--~
+--~ local utf8 = lpeg.R("\0\127") / string.byte
+--~ + lpeg.R("\194\223") * cont / f2
+--~ + lpeg.R("\224\239") * cont * cont / f3
+--~ + lpeg.R("\240\244") * cont * cont * cont / f4
+--~
+--~ local decode_pattern = lpeg.Ct(utf8^0) * -1
+
+
+local cont = R("\128\191") -- continuation byte
+
+lpeg.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
+
+
end -- of closure
@@ -431,9 +466,9 @@ if not modules then modules = { } end modules ['l-table'] = {
table.join = table.concat
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
-local format, find, gsub, lower, dump = string.format, string.find, string.gsub, string.lower, string.dump
+local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
-local type, next, tostring, ipairs = type, next, tostring, ipairs
+local type, next, tostring, tonumber, ipairs, pairs = type, next, tostring, tonumber, ipairs, pairs
function table.strip(tab)
local lst = { }
@@ -721,6 +756,8 @@ end
--
-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+-- problem: there no good number_to_string converter with the best resolution
+
local function do_serialize(root,name,depth,level,indexed)
if level > 0 then
depth = depth .. " "
@@ -743,6 +780,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -765,10 +803,10 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %s,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
@@ -805,29 +843,29 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%s,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%s,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%s,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%s,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
--~ handle(format("%s %s=%s,",depth,key(k),v))
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
@@ -1036,7 +1074,7 @@ function table.tofile(filename,root,name,reduce,noquotes,hexify)
end
end
-local function flatten(t,f,complete)
+local function flatten(t,f,complete) -- is this used? meybe a variant with next, ...
for i=1,#t do
local v = t[i]
if type(v) == "table" then
@@ -1065,6 +1103,24 @@ end
table.flatten_one_level = table.unnest
+-- a better one:
+
+local function flattened(t,f)
+ if not f then
+ f = { }
+ end
+ for k, v in next, t do
+ if type(v) == "table" then
+ flattened(v,f)
+ else
+ f[k] = v
+ end
+ end
+ return f
+end
+
+table.flattened = flattened
+
-- the next three may disappear
function table.remove_value(t,value) -- todo: n
@@ -1200,7 +1256,7 @@ function table.clone(t,p) -- t is optional or nil or table
elseif not t then
t = { }
end
- setmetatable(t, { __index = function(_,key) return p[key] end })
+ setmetatable(t, { __index = function(_,key) return p[key] end }) -- why not __index = p ?
return t
end
@@ -1615,7 +1671,8 @@ if not modules then modules = { } end modules ['l-os'] = {
license = "see context related readme files"
}
-local find = string.find
+local find, format = string.find, string.format
+local random, ceil = math.random, math.ceil
function os.resultof(command)
return io.popen(command,"r"):read("*all")
@@ -1712,6 +1769,8 @@ function os.currentplatform(name,default)
elseif name == "macosx" then
if find(architecture,"i386") then
platform = "osx-intel"
+ elseif find(architecture,"x86_64") then
+ platform = "osx-64"
else
platform = "osx-ppc"
end
@@ -1738,6 +1797,29 @@ function os.currentplatform(name,default)
return platform
end
+-- beware, we set the randomseed
+--
+
+-- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the
+-- version number as well as two reserved bits. All other bits are set using a random or pseudorandom
+-- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal
+-- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+--
+-- as we don't call this function too often there is not so much risk on repetition
+
+
+local t = { 8, 9, "a", "b" }
+
+function os.uuid()
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
+end
+
end -- of closure
@@ -1778,8 +1860,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -1857,6 +1943,7 @@ function file.collapse_path(str)
return str
end
+--~ print(file.collapse_path("/a"))
--~ print(file.collapse_path("a/./b/.."))
--~ print(file.collapse_path("a/aa/../b/bb"))
--~ print(file.collapse_path("a/../.."))
@@ -3028,9 +3115,9 @@ function aux.make_settings_to_hash_pattern(set,how)
end
end
-function aux.settings_to_hash(str)
+function aux.settings_to_hash(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
if moretolerant then
pattern_b_s:match(str)
else
@@ -3042,9 +3129,9 @@ function aux.settings_to_hash(str)
end
end
-function aux.settings_to_hash_tolerant(str)
+function aux.settings_to_hash_tolerant(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_b_s:match(str)
return hash
else
@@ -3052,9 +3139,9 @@ function aux.settings_to_hash_tolerant(str)
end
end
-function aux.settings_to_hash_strict(str)
+function aux.settings_to_hash_strict(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_c_s:match(str)
return next(hash) and hash
else
@@ -3142,7 +3229,7 @@ function aux.getparameters(self,class,parentclass,settings)
sc = table.clone(self[parent])
self[class] = sc
end
- aux.add_settings_to_array(sc, settings)
+ aux.settings_to_hash(settings,sc)
end
-- temporary here
@@ -3230,12 +3317,15 @@ if not modules then modules = { } end modules ['trac-tra'] = {
-- bound to a variable, like node.new, node.copy etc (contrary to for instance
-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
+local getinfo = debug.getinfo
+local type, next = type, next
+local concat = table.concat
+local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
+
debugger = debugger or { }
local counters = { }
local names = { }
-local getinfo = debug.getinfo
-local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
-- one
@@ -3363,11 +3453,11 @@ end
--~ print("")
--~ debugger.showstats(print,3)
-trackers = trackers or { }
+setters = setters or { }
+setters.data = setters.data or { }
-local data, done = { }, { }
-
-local function set(what,value)
+local function set(t,what,value)
+ local data, done = t.data, t.done
if type(what) == "string" then
what = aux.settings_to_array(what) -- inefficient but ok
end
@@ -3386,28 +3476,30 @@ local function set(what,value)
end
end
-local function reset()
- for d, f in next, data do
+local function reset(t)
+ for d, f in next, t.data do
for i=1,#f do
f[i](false)
end
end
end
-local function enable(what)
- set(what,true)
+local function enable(t,what)
+ set(t,what,true)
end
-local function disable(what)
+local function disable(t,what)
+ local data = t.data
if not what or what == "" then
- done = { }
- reset()
+ t.done = { }
+ reset(t)
else
- set(what,false)
+ set(t,what,false)
end
end
-function trackers.register(what,...)
+function setters.register(t,what,...)
+ local data = t.data
what = lower(what)
local w = data[what]
if not w then
@@ -3419,32 +3511,32 @@ function trackers.register(what,...)
if typ == "function" then
w[#w+1] = fnc
elseif typ == "string" then
- w[#w+1] = function(value) set(fnc,value,nesting) end
+ w[#w+1] = function(value) set(t,fnc,value,nesting) end
end
end
end
-function trackers.enable(what)
- local e = trackers.enable
- trackers.enable, done = enable, { }
- enable(string.simpleesc(what))
- trackers.enable, done = e, { }
+function setters.enable(t,what)
+ local e = t.enable
+ t.enable, t.done = enable, { }
+ enable(t,string.simpleesc(what))
+ t.enable, t.done = e, { }
end
-function trackers.disable(what)
- local e = trackers.disable
- trackers.disable, done = disable, { }
- disable(string.simpleesc(what))
- trackers.disable, done = e, { }
+function setters.disable(t,what)
+ local e = t.disable
+ t.disable, t.done = disable, { }
+ disable(t,string.simpleesc(what))
+ t.disable, t.done = e, { }
end
-function trackers.reset()
- done = { }
- reset()
+function setters.reset(t)
+ t.done = { }
+ reset(t)
end
-function trackers.list() -- pattern
- local list = table.sortedkeys(data)
+function setters.list(t) -- pattern
+ local list = table.sortedkeys(t.data)
local user, system = { }, { }
for l=1,#list do
local what = list[l]
@@ -3457,6 +3549,139 @@ function trackers.list() -- pattern
return user, system
end
+function setters.show(t)
+ commands.writestatus("","")
+ for k,v in ipairs(setters.list(t)) do
+ commands.writestatus(t.name,v)
+ end
+ commands.writestatus("","")
+end
+
+-- we could have used a bit of oo and the trackers:enable syntax but
+-- there is already a lot of code around using the singluar tracker
+
+function setters.new(name)
+ local t
+ t = {
+ data = { },
+ name = name,
+ enable = function(...) setters.enable (t,...) end,
+ disable = function(...) setters.disable (t,...) end,
+ register = function(...) setters.register(t,...) end,
+ list = function(...) setters.list (t,...) end,
+ show = function(...) setters.show (t,...) end,
+ }
+ setters.data[name] = t
+ return t
+end
+
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+
+-- nice trick: we overload two of the directives related functions with variants that
+-- do tracing (itself using a tracker) .. proof of concept
+
+local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+
+local e = directives.enable
+local d = directives.disable
+
+function directives.enable(...)
+ commands.writestatus("directives","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function directives.disable(...)
+ commands.writestatus("directives","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+--~ -- old code:
+--
+--~ trackers = trackers or { }
+--~ local data, done = { }, { }
+--~ local function set(what,value)
+--~ if type(what) == "string" then
+--~ what = aux.settings_to_array(what) -- inefficient but ok
+--~ end
+--~ for i=1,#what do
+--~ local w = what[i]
+--~ for d, f in next, data do
+--~ if done[d] then
+--~ -- prevent recursion due to wildcards
+--~ elseif find(d,w) then
+--~ done[d] = true
+--~ for i=1,#f do
+--~ f[i](value)
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ local function reset()
+--~ for d, f in next, data do
+--~ for i=1,#f do
+--~ f[i](false)
+--~ end
+--~ end
+--~ end
+--~ local function enable(what)
+--~ set(what,true)
+--~ end
+--~ local function disable(what)
+--~ if not what or what == "" then
+--~ done = { }
+--~ reset()
+--~ else
+--~ set(what,false)
+--~ end
+--~ end
+--~ function trackers.register(what,...)
+--~ what = lower(what)
+--~ local w = data[what]
+--~ if not w then
+--~ w = { }
+--~ data[what] = w
+--~ end
+--~ for _, fnc in next, { ... } do
+--~ local typ = type(fnc)
+--~ if typ == "function" then
+--~ w[#w+1] = fnc
+--~ elseif typ == "string" then
+--~ w[#w+1] = function(value) set(fnc,value,nesting) end
+--~ end
+--~ end
+--~ end
+--~ function trackers.enable(what)
+--~ local e = trackers.enable
+--~ trackers.enable, done = enable, { }
+--~ enable(string.simpleesc(what))
+--~ trackers.enable, done = e, { }
+--~ end
+--~ function trackers.disable(what)
+--~ local e = trackers.disable
+--~ trackers.disable, done = disable, { }
+--~ disable(string.simpleesc(what))
+--~ trackers.disable, done = e, { }
+--~ end
+--~ function trackers.reset()
+--~ done = { }
+--~ reset()
+--~ end
+--~ function trackers.list() -- pattern
+--~ local list = table.sortedkeys(data)
+--~ local user, system = { }, { }
+--~ for l=1,#list do
+--~ local what = list[l]
+--~ if find(what,"^%*") then
+--~ system[#system+1] = what
+--~ else
+--~ user[#user+1] = what
+--~ end
+--~ end
+--~ return user, system
+--~ end
+
end -- of closure
@@ -3908,6 +4133,7 @@ function statistics.timed(action,report)
end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4241,6 +4467,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -4629,7 +4857,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -4638,7 +4866,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -4703,9 +4931,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -4734,7 +4962,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -4746,11 +4974,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -4815,13 +5043,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -4829,12 +5061,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -4858,12 +5090,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -4925,7 +5157,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -5184,6 +5416,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -5206,6 +5439,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -5213,6 +5452,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -5467,7 +5707,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -5664,8 +5904,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -5896,7 +6136,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -6048,9 +6288,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -6397,6 +6637,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua
index 344ff42c5..22abf74b1 100644
--- a/scripts/context/lua/mtx-context.lua
+++ b/scripts/context/lua/mtx-context.lua
@@ -992,24 +992,29 @@ local loaded = false
function scripts.context.metapost()
local filename = environment.files[1] or ""
---~ local tempname = "mtx-context-metapost.tex"
---~ local tempdata = string.format(template,"metafun",filename)
---~ io.savedata(tempname,tempdata)
---~ environment.files[1] = tempname
---~ environment.setargument("result",file.removesuffix(filename))
---~ environment.setargument("once",true)
---~ scripts.context.run()
if not loaded then
dofile(resolvers.find_file("mlib-run.lua"))
loaded = true
commands = commands or { }
commands.writestatus = logs.report
end
- local formatname = environment.arguments("format") or "metafun"
+ local formatname = environment.argument("format") or "metafun"
if formatname == "" or type(format) == "boolean" then
formatname = "metafun"
end
- if environment.arguments("svg") then
+ if environment.argument("pdf") then
+ local basename = file.removesuffix(filename)
+ local resultname = environment.argument("result") or basename
+ local jobname = "mtx-context-metapost"
+ local tempname = file.addsuffix(jobname,"tex")
+ io.savedata(tempname,string.format(template,"metafun",filename))
+ environment.files[1] = tempname
+ environment.setargument("result",resultname)
+ environment.setargument("once",true)
+ scripts.context.run()
+ scripts.context.purge_job(jobname,true)
+ scripts.context.purge_job(resultname,true)
+ elseif environment.argument("svg") then
metapost.directrun(formatname,filename,"svg")
else
metapost.directrun(formatname,filename,"mps")
diff --git a/scripts/context/lua/mtx-fonts.lua b/scripts/context/lua/mtx-fonts.lua
index 0cd9a3270..67c48d0a8 100644
--- a/scripts/context/lua/mtx-fonts.lua
+++ b/scripts/context/lua/mtx-fonts.lua
@@ -20,23 +20,46 @@ function scripts.fonts.reload(verbose)
end
function scripts.fonts.names(name)
+ local simpleversion = 1.001
+ local simplelist = { "ttf", "otf", "ttc", "dfont" }
name = name or "luatex-fonts-names.lua"
+ fonts.names.filters.list = simplelist
+ fonts.names.version = simpleversion -- this number is the same as in font-dum.lua
+ logs.report("fontnames","generating font database for 'luatex-fonts' version %s",fonts.names.version)
fonts.names.identify(true)
local data = fonts.names.data
if data then
- data.fallback_mapping = nil
+ local simplemappings = { }
+ local simplified = {
+ mappings = simplemappings,
+ version = simpleversion,
+ }
+ local specifications = data.specifications
+ for _, format in ipairs(simplelist) do
+ for tag, index in pairs(data.mappings[format]) do
+ local s = specifications[index]
+ simplemappings[tag] = { s.rawname, s.filename, s.subfont }
+ end
+ end
logs.report("fontnames","saving names in '%s'",name)
- io.savedata(name,table.serialize(data,true))
+ io.savedata(name,table.serialize(simplified,true))
+ local data = io.loaddata(resolvers.find_file("font-dum.lua","tex"))
+ local dummy = string.match(data,"fonts%.names%.version%s*=%s*([%d%.]+)")
+ if tonumber(dummy) ~= simpleversion then
+ logs.report("fontnames","warning: version number %s in 'font-dum' does not match database version number %s",dummy or "?",simpleversion)
+ end
elseif lfs.isfile(name) then
os.remove(name)
end
end
-local function showfeatures(v,n,f,s,t)
- logs.simple("fontname: %s",v)
- logs.simple("fullname: %s",n)
- logs.simple("filename: %s",f)
- local features = fonts.get_features(f,t)
+local function showfeatures(tag,specification)
+ logs.simple("mapping : %s",tag)
+ logs.simple("fontname: %s",specification.fontname)
+ logs.simple("fullname: %s",specification.fullname)
+ logs.simple("filename: %s",specification.filename)
+ -- maybe more
+ local features = fonts.get_features(specification.filename,specification.format)
if features then
for what, v in table.sortedpairs(features) do
local data = features[what]
@@ -61,6 +84,10 @@ local function showfeatures(v,n,f,s,t)
end
end
end
+ else
+ logs.simple()
+ logs.simple("no features")
+ logs.simple()
end
logs.reportline()
end
@@ -74,7 +101,7 @@ local function make_pattern(pattern) -- will become helper in string
if pattern == "" then
pattern = ".*"
else
- pattern = "^" .. pattern .. "$"
+--~ pattern = "^" .. pattern .. "$"
end
return pattern
end
@@ -87,53 +114,120 @@ local function reloadbase(reload)
end
end
-function scripts.fonts.list_by_pattern(pattern,reload,all,info)
- reloadbase(reload)
- local t = fonts.names.list(make_pattern(pattern))
+local function subfont(sf)
+ if sf then
+ return string.format("index: % 2s", sf)
+ else
+ return ""
+ end
+end
+local function fontweight(fw)
+ if fw then
+ return string.format("conflict: %s", fw)
+ else
+ return ""
+ end
+end
+
+local function list_specifications(t)
if t then
local s, w = table.sortedkeys(t), { 0, 0, 0 }
for k,v in ipairs(s) do
local entry = t[v]
- local n = #v if n > w[1] then w[1] = n end
- local n = #entry[2] if n > w[2] then w[2] = n end
- local n = #entry[3] if n > w[3] then w[3] = n end
+ s[k] = {
+ entry.familyname or "<nofamily>",
+ entry.weight or "<noweight>",
+ entry.style or "<nostyle>",
+ entry.width or "<nowidth>",
+ entry.fontname,
+ entry.filename,
+ subfont(entry.subfont),
+ fontweight(entry.fontweight),
+ }
end
- local template = "%-" .. w[1] .. "s %-" .. w[2] .. "s %-" .. w[3] .. "s %s"
+ table.formatcolumns(s)
for k,v in ipairs(s) do
- local entry = t[v]
- local tag, fontname, filename, sub = v, entry[2], entry[3], entry[4]
- if sub then sub = "(sub)" else sub = "" end
- if info then
- showfeatures(tag,fontname,filename,sub,t)
- else
- print(string.format(template,tag,fontname,filename,sub))
+ texio.write_nl(v)
+ end
+ end
+end
+
+local function list_matches(t)
+ if t then
+ local s, w = table.sortedkeys(t), { 0, 0, 0 }
+ if info then
+ for k,v in ipairs(s) do
+ showfeatures(v,t[v])
+ end
+ else
+ for k,v in ipairs(s) do
+ local entry = t[v]
+ s[k] = {
+ v,
+ entry.fontname,
+ entry.filename,
+ subfont(entry.subfont)
+ }
+ end
+ table.formatcolumns(s)
+ for k,v in ipairs(s) do
+ texio.write_nl(v)
end
end
end
end
-function scripts.fonts.list_by_specification(specification,reload,all,info)
+function scripts.fonts.list()
+
+ local all = environment.argument("all")
+ local info = environment.argument("info")
+ local reload = environment.argument("reload")
+ local pattern = environment.argument("pattern")
+ local filter = environment.argument("filter")
+ local given = environment.files[1]
+
reloadbase(reload)
- local t = fonts.names.collectspec(specification)
- if t then
- local w, tags = { 0, 0, 0 }, { }
- for k,entry in ipairs(t) do
- local s = entry[5] .. "-" .. (entry[6] or "noweight") .. "-" .. (entry[7] or "nostyle") .. "-" .. (entry[8] or "nowidth")
- local n = #s if n > w[1] then w[1] = n end
- local n = #entry[2] if n > w[2] then w[2] = n end
- local n = #entry[3] if n > w[3] then w[3] = n end
- tags[k] = s
+
+ if environment.argument("name") then
+ if pattern then
+ --~ mtxrun --script font --list --name --pattern=*somename*
+ list_matches(fonts.names.list(make_pattern(pattern),reload,all))
+ elseif filter then
+ logs.report("fontnames","not supported: --list --name --filter",name)
+ elseif given then
+ --~ mtxrun --script font --list --name somename
+ list_matches(fonts.names.list(given,reload,all))
+ else
+ logs.report("fontnames","not supported: --list --name <no specification>",name)
end
- local template = "%-" .. w[1] .."s %-" .. w[2] .. "s %-" .. w[3] .. "s %s"
- for k,entry in ipairs(t) do
- local tag, fontname, filename, sub, name, weight, style = tags[k], entry[2], entry[3], entry[4], entry[5], entry[6], entry[7]
- if sub then sub = "(sub)" else sub = "" end
- print(string.format(template,tag,fontname,filename,sub))
+ elseif environment.argument("spec") then
+ if pattern then
+ --~ mtxrun --script font --list --spec --pattern=*somename*
+ logs.report("fontnames","not supported: --list --spec --pattern",name)
+ elseif filter then
+ --~ mtxrun --script font --list --spec --filter="fontname=somename"
+ list_specifications(fonts.names.getlookups(filter),nil,reload)
+ elseif given then
+ --~ mtxrun --script font --list --spec somename
+ list_specifications(fonts.names.collectspec(given,reload,all))
+ else
+ logs.report("fontnames","not supported: --list --spec <no specification>",name)
end
+ elseif pattern then
+ --~ mtxrun --script font --list --pattern=*somename*
+ list_matches(fonts.names.list(make_pattern(pattern),reload,all))
+ elseif given then
+ --~ mtxrun --script font --list somename
+ list_matches(fonts.names.list(given,reload,all))
+ else
+ logs.report("fontnames","not supported: --list <no specification>",name)
end
+
end
-function scripts.fonts.save(name,sub)
+function scripts.fonts.save()
+ local name = environment.files[1] or ""
+ local sub = environment.files[2] or ""
local function save(savename,fontblob)
if fontblob then
savename = savename:lower() .. ".lua"
@@ -171,37 +265,49 @@ function scripts.fonts.save(name,sub)
end
end
-logs.extendbanner("Font Tools 0.20",true)
+logs.extendbanner("Font Tools 0.21",true)
messages.help = [[
--reload generate new font database
---list [--info] list installed fonts (show info)
--save save open type font in raw table
--names generate 'luatex-fonts-names.lua' (not for context!)
+--list list installed fonts (show info)
+
+--name filter by name
+--spec filter by spec
--pattern=str filter files using pattern
+--filter=list key-value pairs
--all provide alternatives
+--info give more details
+--track=list enable trackers
+
+examples:
+
+mtxrun --script font --list somename (== --pattern=*somename*)
+
+mtxrun --script font --list --name somename
+mtxrun --script font --list --name --pattern=*somename*
+
+mtxrun --script font --list --spec somename
+mtxrun --script font --list --spec somename-bold-italic
+mtxrun --script font --list --spec --pattern=*somename*
+mtxrun --script font --list --spec --filter="fontname=somename"
+mtxrun --script font --list --spec --filter="familyname=somename,weight=bold,style=italic,width=condensed"
]]
+local track = environment.argument("track")
+
+if track then trackers.enable(track) end
+
if environment.argument("reload") then
scripts.fonts.reload(true)
elseif environment.argument("names") then
scripts.fonts.names()
-elseif environment.argument("list") then
- local all = environment.argument("all")
- local info = environment.argument("info")
- local reload = environment.argument("reload")
- if environment.argument("pattern") then
- scripts.fonts.list_by_pattern(environment.argument("pattern"),reload,all,info)
- elseif environment.files[1] then
- scripts.fonts.list_by_specification(environment.files[1],reload,all,info)
- else
- scripts.fonts.list_by_pattern("",reload,all,info) -- wildcard
- end
elseif environment.argument("save") then
- local name = environment.files[1] or ""
- local sub = environment.files[2] or ""
- scripts.fonts.save(name,sub)
+ scripts.fonts.save()
+elseif environment.argument("list") then
+ scripts.fonts.list()
else
logs.help(messages.help)
end
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 130ad493c..0d3f08025 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -789,6 +789,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -811,7 +812,7 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %.99g,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
if reduce and tonumber(v) then
@@ -851,25 +852,25 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%.99g,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%.99g,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%.99g,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%.99g,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
@@ -1868,8 +1869,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -4872,7 +4877,7 @@ local noparent = 1 - (lparent+rparent)
local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}
local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"}
-local lp_child = Cc("expr.child(e,'") * R("az","AZ","--","__")^1 * Cc("')")
+local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')")
local lp_string = Cc("'") * R("az","AZ","--","__")^1 * Cc("'")
local lp_content = (P("'") * (1-P("'"))^0 * P("'") + P('"') * (1-P('"'))^0 * P('"'))
@@ -4882,9 +4887,9 @@ local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * val
if expressions[t] then
s = s and s ~= "" and cleaner:match(s)
if s and s ~= "" then
- return "expr." .. t .. "(e," .. s ..")"
+ return "expr." .. t .. "(ll," .. s ..")"
else
- return "expr." .. t .. "(e)"
+ return "expr." .. t .. "(ll)"
end
else
return "expr.error(" .. t .. ")"
@@ -5434,38 +5439,42 @@ expressions.name = function(e,n) -- ns + tg
end
expressions.tag = function(e,n) -- only tg
- local found = false
- n = tonumber(n) or 0
- if n == 0 then
- found = (type(e) == "table") and e -- seems to fail
- elseif n < 0 then
- local d, k = e.__p__.dt, e.ni
- for i=k-1,1,-1 do
- local di = d[i]
- if type(di) == "table" then
- if n == -1 then
- found = di
- break
- else
- n = n + 1
+ if not e then
+ return ""
+ else
+ local found = false
+ n = tonumber(n) or 0
+ if n == 0 then
+ found = (type(e) == "table") and e -- seems to fail
+ elseif n < 0 then
+ local d, k = e.__p__.dt, e.ni
+ for i=k-1,1,-1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == -1 then
+ found = di
+ break
+ else
+ n = n + 1
+ end
end
end
- end
- else
- local d, k = e.__p__.dt, e.ni
- for i=k+1,#d,1 do
- local di = d[i]
- if type(di) == "table" then
- if n == 1 then
- found = di
- break
- else
- n = n - 1
+ else
+ local d, k = e.__p__.dt, e.ni
+ for i=k+1,#d,1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == 1 then
+ found = di
+ break
+ else
+ n = n - 1
+ end
end
end
end
+ return (found and found.tg) or ""
end
- return (found and found.tg) or ""
end
--[[ldx--
@@ -5992,7 +6001,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
--~ local settings = xmldata.settings
--~ settings.parent_root = xmldata -- to be tested
--~ local xi = xmlconvert(data,settings)
- local xi = xml.inheritedconvert(element,xmldata)
+ local xi = xml.inheritedconvert(data,xmldata)
if not xi then
epdt[ek.ni] = "" -- xml.empty(d,k)
else
@@ -7046,7 +7055,6 @@ end
local name, banner = 'report', 'context'
local function report(category,fmt,...)
---~ print(fmt,...)
if fmt then
write_nl(format("%s | %s: %s",name,category,format(fmt,...)))
elseif category then
@@ -7187,6 +7195,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -7575,7 +7585,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -7584,7 +7594,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -7649,9 +7659,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -7680,7 +7690,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -7692,11 +7702,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -7761,13 +7771,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -7775,12 +7789,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -7804,12 +7818,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -7871,7 +7885,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -8130,6 +8144,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -8152,6 +8167,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -8159,6 +8180,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -8413,7 +8435,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -8610,8 +8632,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -8842,7 +8864,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -8994,9 +9016,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -9343,6 +9365,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/stubs/mswin/luatools.lua b/scripts/context/stubs/mswin/luatools.lua
index 2bc943210..abd80b8b4 100644
--- a/scripts/context/stubs/mswin/luatools.lua
+++ b/scripts/context/stubs/mswin/luatools.lua
@@ -308,7 +308,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
license = "see context related readme files"
}
-local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
--~ l-lpeg.lua :
@@ -415,6 +415,41 @@ end
--~ return p
--~ end
+--~ from roberto's site:
+--~
+--~ -- decode a two-byte UTF-8 sequence
+--~ local function f2 (s)
+--~ local c1, c2 = string.byte(s, 1, 2)
+--~ return c1 * 64 + c2 - 12416
+--~ end
+--~
+--~ -- decode a three-byte UTF-8 sequence
+--~ local function f3 (s)
+--~ local c1, c2, c3 = string.byte(s, 1, 3)
+--~ return (c1 * 64 + c2) * 64 + c3 - 925824
+--~ end
+--~
+--~ -- decode a four-byte UTF-8 sequence
+--~ local function f4 (s)
+--~ local c1, c2, c3, c4 = string.byte(s, 1, 4)
+--~ return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168
+--~ end
+--~
+--~ local cont = lpeg.R("\128\191") -- continuation byte
+--~
+--~ local utf8 = lpeg.R("\0\127") / string.byte
+--~ + lpeg.R("\194\223") * cont / f2
+--~ + lpeg.R("\224\239") * cont * cont / f3
+--~ + lpeg.R("\240\244") * cont * cont * cont / f4
+--~
+--~ local decode_pattern = lpeg.Ct(utf8^0) * -1
+
+
+local cont = R("\128\191") -- continuation byte
+
+lpeg.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
+
+
end -- of closure
@@ -431,9 +466,9 @@ if not modules then modules = { } end modules ['l-table'] = {
table.join = table.concat
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
-local format, find, gsub, lower, dump = string.format, string.find, string.gsub, string.lower, string.dump
+local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
-local type, next, tostring, ipairs = type, next, tostring, ipairs
+local type, next, tostring, tonumber, ipairs, pairs = type, next, tostring, tonumber, ipairs, pairs
function table.strip(tab)
local lst = { }
@@ -721,6 +756,8 @@ end
--
-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+-- problem: there no good number_to_string converter with the best resolution
+
local function do_serialize(root,name,depth,level,indexed)
if level > 0 then
depth = depth .. " "
@@ -743,6 +780,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -765,10 +803,10 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %s,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
@@ -805,29 +843,29 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%s,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%s,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%s,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%s,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
--~ handle(format("%s %s=%s,",depth,key(k),v))
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
@@ -1036,7 +1074,7 @@ function table.tofile(filename,root,name,reduce,noquotes,hexify)
end
end
-local function flatten(t,f,complete)
+local function flatten(t,f,complete) -- is this used? meybe a variant with next, ...
for i=1,#t do
local v = t[i]
if type(v) == "table" then
@@ -1065,6 +1103,24 @@ end
table.flatten_one_level = table.unnest
+-- a better one:
+
+local function flattened(t,f)
+ if not f then
+ f = { }
+ end
+ for k, v in next, t do
+ if type(v) == "table" then
+ flattened(v,f)
+ else
+ f[k] = v
+ end
+ end
+ return f
+end
+
+table.flattened = flattened
+
-- the next three may disappear
function table.remove_value(t,value) -- todo: n
@@ -1200,7 +1256,7 @@ function table.clone(t,p) -- t is optional or nil or table
elseif not t then
t = { }
end
- setmetatable(t, { __index = function(_,key) return p[key] end })
+ setmetatable(t, { __index = function(_,key) return p[key] end }) -- why not __index = p ?
return t
end
@@ -1615,7 +1671,8 @@ if not modules then modules = { } end modules ['l-os'] = {
license = "see context related readme files"
}
-local find = string.find
+local find, format = string.find, string.format
+local random, ceil = math.random, math.ceil
function os.resultof(command)
return io.popen(command,"r"):read("*all")
@@ -1712,6 +1769,8 @@ function os.currentplatform(name,default)
elseif name == "macosx" then
if find(architecture,"i386") then
platform = "osx-intel"
+ elseif find(architecture,"x86_64") then
+ platform = "osx-64"
else
platform = "osx-ppc"
end
@@ -1738,6 +1797,29 @@ function os.currentplatform(name,default)
return platform
end
+-- beware, we set the randomseed
+--
+
+-- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the
+-- version number as well as two reserved bits. All other bits are set using a random or pseudorandom
+-- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal
+-- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+--
+-- as we don't call this function too often there is not so much risk on repetition
+
+
+local t = { 8, 9, "a", "b" }
+
+function os.uuid()
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
+end
+
end -- of closure
@@ -1778,8 +1860,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -1857,6 +1943,7 @@ function file.collapse_path(str)
return str
end
+--~ print(file.collapse_path("/a"))
--~ print(file.collapse_path("a/./b/.."))
--~ print(file.collapse_path("a/aa/../b/bb"))
--~ print(file.collapse_path("a/../.."))
@@ -3028,9 +3115,9 @@ function aux.make_settings_to_hash_pattern(set,how)
end
end
-function aux.settings_to_hash(str)
+function aux.settings_to_hash(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
if moretolerant then
pattern_b_s:match(str)
else
@@ -3042,9 +3129,9 @@ function aux.settings_to_hash(str)
end
end
-function aux.settings_to_hash_tolerant(str)
+function aux.settings_to_hash_tolerant(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_b_s:match(str)
return hash
else
@@ -3052,9 +3139,9 @@ function aux.settings_to_hash_tolerant(str)
end
end
-function aux.settings_to_hash_strict(str)
+function aux.settings_to_hash_strict(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_c_s:match(str)
return next(hash) and hash
else
@@ -3142,7 +3229,7 @@ function aux.getparameters(self,class,parentclass,settings)
sc = table.clone(self[parent])
self[class] = sc
end
- aux.add_settings_to_array(sc, settings)
+ aux.settings_to_hash(settings,sc)
end
-- temporary here
@@ -3230,12 +3317,15 @@ if not modules then modules = { } end modules ['trac-tra'] = {
-- bound to a variable, like node.new, node.copy etc (contrary to for instance
-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
+local getinfo = debug.getinfo
+local type, next = type, next
+local concat = table.concat
+local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
+
debugger = debugger or { }
local counters = { }
local names = { }
-local getinfo = debug.getinfo
-local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
-- one
@@ -3363,11 +3453,11 @@ end
--~ print("")
--~ debugger.showstats(print,3)
-trackers = trackers or { }
+setters = setters or { }
+setters.data = setters.data or { }
-local data, done = { }, { }
-
-local function set(what,value)
+local function set(t,what,value)
+ local data, done = t.data, t.done
if type(what) == "string" then
what = aux.settings_to_array(what) -- inefficient but ok
end
@@ -3386,28 +3476,30 @@ local function set(what,value)
end
end
-local function reset()
- for d, f in next, data do
+local function reset(t)
+ for d, f in next, t.data do
for i=1,#f do
f[i](false)
end
end
end
-local function enable(what)
- set(what,true)
+local function enable(t,what)
+ set(t,what,true)
end
-local function disable(what)
+local function disable(t,what)
+ local data = t.data
if not what or what == "" then
- done = { }
- reset()
+ t.done = { }
+ reset(t)
else
- set(what,false)
+ set(t,what,false)
end
end
-function trackers.register(what,...)
+function setters.register(t,what,...)
+ local data = t.data
what = lower(what)
local w = data[what]
if not w then
@@ -3419,32 +3511,32 @@ function trackers.register(what,...)
if typ == "function" then
w[#w+1] = fnc
elseif typ == "string" then
- w[#w+1] = function(value) set(fnc,value,nesting) end
+ w[#w+1] = function(value) set(t,fnc,value,nesting) end
end
end
end
-function trackers.enable(what)
- local e = trackers.enable
- trackers.enable, done = enable, { }
- enable(string.simpleesc(what))
- trackers.enable, done = e, { }
+function setters.enable(t,what)
+ local e = t.enable
+ t.enable, t.done = enable, { }
+ enable(t,string.simpleesc(what))
+ t.enable, t.done = e, { }
end
-function trackers.disable(what)
- local e = trackers.disable
- trackers.disable, done = disable, { }
- disable(string.simpleesc(what))
- trackers.disable, done = e, { }
+function setters.disable(t,what)
+ local e = t.disable
+ t.disable, t.done = disable, { }
+ disable(t,string.simpleesc(what))
+ t.disable, t.done = e, { }
end
-function trackers.reset()
- done = { }
- reset()
+function setters.reset(t)
+ t.done = { }
+ reset(t)
end
-function trackers.list() -- pattern
- local list = table.sortedkeys(data)
+function setters.list(t) -- pattern
+ local list = table.sortedkeys(t.data)
local user, system = { }, { }
for l=1,#list do
local what = list[l]
@@ -3457,6 +3549,139 @@ function trackers.list() -- pattern
return user, system
end
+function setters.show(t)
+ commands.writestatus("","")
+ for k,v in ipairs(setters.list(t)) do
+ commands.writestatus(t.name,v)
+ end
+ commands.writestatus("","")
+end
+
+-- we could have used a bit of oo and the trackers:enable syntax but
+-- there is already a lot of code around using the singluar tracker
+
+function setters.new(name)
+ local t
+ t = {
+ data = { },
+ name = name,
+ enable = function(...) setters.enable (t,...) end,
+ disable = function(...) setters.disable (t,...) end,
+ register = function(...) setters.register(t,...) end,
+ list = function(...) setters.list (t,...) end,
+ show = function(...) setters.show (t,...) end,
+ }
+ setters.data[name] = t
+ return t
+end
+
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+
+-- nice trick: we overload two of the directives related functions with variants that
+-- do tracing (itself using a tracker) .. proof of concept
+
+local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+
+local e = directives.enable
+local d = directives.disable
+
+function directives.enable(...)
+ commands.writestatus("directives","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function directives.disable(...)
+ commands.writestatus("directives","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+--~ -- old code:
+--
+--~ trackers = trackers or { }
+--~ local data, done = { }, { }
+--~ local function set(what,value)
+--~ if type(what) == "string" then
+--~ what = aux.settings_to_array(what) -- inefficient but ok
+--~ end
+--~ for i=1,#what do
+--~ local w = what[i]
+--~ for d, f in next, data do
+--~ if done[d] then
+--~ -- prevent recursion due to wildcards
+--~ elseif find(d,w) then
+--~ done[d] = true
+--~ for i=1,#f do
+--~ f[i](value)
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ local function reset()
+--~ for d, f in next, data do
+--~ for i=1,#f do
+--~ f[i](false)
+--~ end
+--~ end
+--~ end
+--~ local function enable(what)
+--~ set(what,true)
+--~ end
+--~ local function disable(what)
+--~ if not what or what == "" then
+--~ done = { }
+--~ reset()
+--~ else
+--~ set(what,false)
+--~ end
+--~ end
+--~ function trackers.register(what,...)
+--~ what = lower(what)
+--~ local w = data[what]
+--~ if not w then
+--~ w = { }
+--~ data[what] = w
+--~ end
+--~ for _, fnc in next, { ... } do
+--~ local typ = type(fnc)
+--~ if typ == "function" then
+--~ w[#w+1] = fnc
+--~ elseif typ == "string" then
+--~ w[#w+1] = function(value) set(fnc,value,nesting) end
+--~ end
+--~ end
+--~ end
+--~ function trackers.enable(what)
+--~ local e = trackers.enable
+--~ trackers.enable, done = enable, { }
+--~ enable(string.simpleesc(what))
+--~ trackers.enable, done = e, { }
+--~ end
+--~ function trackers.disable(what)
+--~ local e = trackers.disable
+--~ trackers.disable, done = disable, { }
+--~ disable(string.simpleesc(what))
+--~ trackers.disable, done = e, { }
+--~ end
+--~ function trackers.reset()
+--~ done = { }
+--~ reset()
+--~ end
+--~ function trackers.list() -- pattern
+--~ local list = table.sortedkeys(data)
+--~ local user, system = { }, { }
+--~ for l=1,#list do
+--~ local what = list[l]
+--~ if find(what,"^%*") then
+--~ system[#system+1] = what
+--~ else
+--~ user[#user+1] = what
+--~ end
+--~ end
+--~ return user, system
+--~ end
+
end -- of closure
@@ -3908,6 +4133,7 @@ function statistics.timed(action,report)
end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4241,6 +4467,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -4629,7 +4857,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -4638,7 +4866,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -4703,9 +4931,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -4734,7 +4962,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -4746,11 +4974,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -4815,13 +5043,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -4829,12 +5061,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -4858,12 +5090,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -4925,7 +5157,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -5184,6 +5416,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -5206,6 +5439,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -5213,6 +5452,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -5467,7 +5707,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -5664,8 +5904,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -5896,7 +6136,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -6048,9 +6288,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -6397,6 +6637,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua
index 130ad493c..0d3f08025 100644
--- a/scripts/context/stubs/mswin/mtxrun.lua
+++ b/scripts/context/stubs/mswin/mtxrun.lua
@@ -789,6 +789,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -811,7 +812,7 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %.99g,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
if reduce and tonumber(v) then
@@ -851,25 +852,25 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%.99g,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%.99g,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%.99g,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%.99g,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
@@ -1868,8 +1869,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -4872,7 +4877,7 @@ local noparent = 1 - (lparent+rparent)
local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}
local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"}
-local lp_child = Cc("expr.child(e,'") * R("az","AZ","--","__")^1 * Cc("')")
+local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')")
local lp_string = Cc("'") * R("az","AZ","--","__")^1 * Cc("'")
local lp_content = (P("'") * (1-P("'"))^0 * P("'") + P('"') * (1-P('"'))^0 * P('"'))
@@ -4882,9 +4887,9 @@ local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * val
if expressions[t] then
s = s and s ~= "" and cleaner:match(s)
if s and s ~= "" then
- return "expr." .. t .. "(e," .. s ..")"
+ return "expr." .. t .. "(ll," .. s ..")"
else
- return "expr." .. t .. "(e)"
+ return "expr." .. t .. "(ll)"
end
else
return "expr.error(" .. t .. ")"
@@ -5434,38 +5439,42 @@ expressions.name = function(e,n) -- ns + tg
end
expressions.tag = function(e,n) -- only tg
- local found = false
- n = tonumber(n) or 0
- if n == 0 then
- found = (type(e) == "table") and e -- seems to fail
- elseif n < 0 then
- local d, k = e.__p__.dt, e.ni
- for i=k-1,1,-1 do
- local di = d[i]
- if type(di) == "table" then
- if n == -1 then
- found = di
- break
- else
- n = n + 1
+ if not e then
+ return ""
+ else
+ local found = false
+ n = tonumber(n) or 0
+ if n == 0 then
+ found = (type(e) == "table") and e -- seems to fail
+ elseif n < 0 then
+ local d, k = e.__p__.dt, e.ni
+ for i=k-1,1,-1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == -1 then
+ found = di
+ break
+ else
+ n = n + 1
+ end
end
end
- end
- else
- local d, k = e.__p__.dt, e.ni
- for i=k+1,#d,1 do
- local di = d[i]
- if type(di) == "table" then
- if n == 1 then
- found = di
- break
- else
- n = n - 1
+ else
+ local d, k = e.__p__.dt, e.ni
+ for i=k+1,#d,1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == 1 then
+ found = di
+ break
+ else
+ n = n - 1
+ end
end
end
end
+ return (found and found.tg) or ""
end
- return (found and found.tg) or ""
end
--[[ldx--
@@ -5992,7 +6001,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
--~ local settings = xmldata.settings
--~ settings.parent_root = xmldata -- to be tested
--~ local xi = xmlconvert(data,settings)
- local xi = xml.inheritedconvert(element,xmldata)
+ local xi = xml.inheritedconvert(data,xmldata)
if not xi then
epdt[ek.ni] = "" -- xml.empty(d,k)
else
@@ -7046,7 +7055,6 @@ end
local name, banner = 'report', 'context'
local function report(category,fmt,...)
---~ print(fmt,...)
if fmt then
write_nl(format("%s | %s: %s",name,category,format(fmt,...)))
elseif category then
@@ -7187,6 +7195,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -7575,7 +7585,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -7584,7 +7594,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -7649,9 +7659,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -7680,7 +7690,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -7692,11 +7702,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -7761,13 +7771,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -7775,12 +7789,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -7804,12 +7818,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -7871,7 +7885,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -8130,6 +8144,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -8152,6 +8167,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -8159,6 +8180,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -8413,7 +8435,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -8610,8 +8632,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -8842,7 +8864,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -8994,9 +9016,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -9343,6 +9365,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/stubs/unix/luatools b/scripts/context/stubs/unix/luatools
index 2bc943210..abd80b8b4 100755
--- a/scripts/context/stubs/unix/luatools
+++ b/scripts/context/stubs/unix/luatools
@@ -308,7 +308,7 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
license = "see context related readme files"
}
-local P, S, Ct, C, Cs, Cc = lpeg.P, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
+local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
--~ l-lpeg.lua :
@@ -415,6 +415,41 @@ end
--~ return p
--~ end
+--~ from roberto's site:
+--~
+--~ -- decode a two-byte UTF-8 sequence
+--~ local function f2 (s)
+--~ local c1, c2 = string.byte(s, 1, 2)
+--~ return c1 * 64 + c2 - 12416
+--~ end
+--~
+--~ -- decode a three-byte UTF-8 sequence
+--~ local function f3 (s)
+--~ local c1, c2, c3 = string.byte(s, 1, 3)
+--~ return (c1 * 64 + c2) * 64 + c3 - 925824
+--~ end
+--~
+--~ -- decode a four-byte UTF-8 sequence
+--~ local function f4 (s)
+--~ local c1, c2, c3, c4 = string.byte(s, 1, 4)
+--~ return ((c1 * 64 + c2) * 64 + c3) * 64 + c4 - 63447168
+--~ end
+--~
+--~ local cont = lpeg.R("\128\191") -- continuation byte
+--~
+--~ local utf8 = lpeg.R("\0\127") / string.byte
+--~ + lpeg.R("\194\223") * cont / f2
+--~ + lpeg.R("\224\239") * cont * cont / f3
+--~ + lpeg.R("\240\244") * cont * cont * cont / f4
+--~
+--~ local decode_pattern = lpeg.Ct(utf8^0) * -1
+
+
+local cont = R("\128\191") -- continuation byte
+
+lpeg.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
+
+
end -- of closure
@@ -431,9 +466,9 @@ if not modules then modules = { } end modules ['l-table'] = {
table.join = table.concat
local concat, sort, insert, remove = table.concat, table.sort, table.insert, table.remove
-local format, find, gsub, lower, dump = string.format, string.find, string.gsub, string.lower, string.dump
+local format, find, gsub, lower, dump, match = string.format, string.find, string.gsub, string.lower, string.dump, string.match
local getmetatable, setmetatable = getmetatable, setmetatable
-local type, next, tostring, ipairs = type, next, tostring, ipairs
+local type, next, tostring, tonumber, ipairs, pairs = type, next, tostring, tonumber, ipairs, pairs
function table.strip(tab)
local lst = { }
@@ -721,6 +756,8 @@ end
--
-- local propername = lpeg.P(lpeg.R("AZ","az","__") * lpeg.R("09","AZ","az", "__")^0 * lpeg.P(-1) )
+-- problem: there no good number_to_string converter with the best resolution
+
local function do_serialize(root,name,depth,level,indexed)
if level > 0 then
depth = depth .. " "
@@ -743,6 +780,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -765,10 +803,10 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %s,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
@@ -805,29 +843,29 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%s,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%s,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%s,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%s,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
- if reduce and (find(v,"^[%-%+]?[%d]-%.?[%d+]$") == 1) then
+ if reduce and tonumber(v) then
--~ handle(format("%s %s=%s,",depth,key(k),v))
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
@@ -1036,7 +1074,7 @@ function table.tofile(filename,root,name,reduce,noquotes,hexify)
end
end
-local function flatten(t,f,complete)
+local function flatten(t,f,complete) -- is this used? meybe a variant with next, ...
for i=1,#t do
local v = t[i]
if type(v) == "table" then
@@ -1065,6 +1103,24 @@ end
table.flatten_one_level = table.unnest
+-- a better one:
+
+local function flattened(t,f)
+ if not f then
+ f = { }
+ end
+ for k, v in next, t do
+ if type(v) == "table" then
+ flattened(v,f)
+ else
+ f[k] = v
+ end
+ end
+ return f
+end
+
+table.flattened = flattened
+
-- the next three may disappear
function table.remove_value(t,value) -- todo: n
@@ -1200,7 +1256,7 @@ function table.clone(t,p) -- t is optional or nil or table
elseif not t then
t = { }
end
- setmetatable(t, { __index = function(_,key) return p[key] end })
+ setmetatable(t, { __index = function(_,key) return p[key] end }) -- why not __index = p ?
return t
end
@@ -1615,7 +1671,8 @@ if not modules then modules = { } end modules ['l-os'] = {
license = "see context related readme files"
}
-local find = string.find
+local find, format = string.find, string.format
+local random, ceil = math.random, math.ceil
function os.resultof(command)
return io.popen(command,"r"):read("*all")
@@ -1712,6 +1769,8 @@ function os.currentplatform(name,default)
elseif name == "macosx" then
if find(architecture,"i386") then
platform = "osx-intel"
+ elseif find(architecture,"x86_64") then
+ platform = "osx-64"
else
platform = "osx-ppc"
end
@@ -1738,6 +1797,29 @@ function os.currentplatform(name,default)
return platform
end
+-- beware, we set the randomseed
+--
+
+-- from wikipedia: Version 4 UUIDs use a scheme relying only on random numbers. This algorithm sets the
+-- version number as well as two reserved bits. All other bits are set using a random or pseudorandom
+-- data source. Version 4 UUIDs have the form xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx with hexadecimal
+-- digits x and hexadecimal digits 8, 9, A, or B for y. e.g. f47ac10b-58cc-4372-a567-0e02b2c3d479.
+--
+-- as we don't call this function too often there is not so much risk on repetition
+
+
+local t = { 8, 9, "a", "b" }
+
+function os.uuid()
+ return format("%04x%04x-4%03x-%s%03x-%04x-%04x%04x%04x",
+ random(0xFFFF),random(0xFFFF),
+ random(0x0FFF),
+ t[ceil(random(4))] or 8,random(0x0FFF),
+ random(0xFFFF),
+ random(0xFFFF),random(0xFFFF),random(0xFFFF)
+ )
+end
+
end -- of closure
@@ -1778,8 +1860,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -1857,6 +1943,7 @@ function file.collapse_path(str)
return str
end
+--~ print(file.collapse_path("/a"))
--~ print(file.collapse_path("a/./b/.."))
--~ print(file.collapse_path("a/aa/../b/bb"))
--~ print(file.collapse_path("a/../.."))
@@ -3028,9 +3115,9 @@ function aux.make_settings_to_hash_pattern(set,how)
end
end
-function aux.settings_to_hash(str)
+function aux.settings_to_hash(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
if moretolerant then
pattern_b_s:match(str)
else
@@ -3042,9 +3129,9 @@ function aux.settings_to_hash(str)
end
end
-function aux.settings_to_hash_tolerant(str)
+function aux.settings_to_hash_tolerant(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_b_s:match(str)
return hash
else
@@ -3052,9 +3139,9 @@ function aux.settings_to_hash_tolerant(str)
end
end
-function aux.settings_to_hash_strict(str)
+function aux.settings_to_hash_strict(str,existing)
if str and str ~= "" then
- hash = { }
+ hash = existing or { }
pattern_c_s:match(str)
return next(hash) and hash
else
@@ -3142,7 +3229,7 @@ function aux.getparameters(self,class,parentclass,settings)
sc = table.clone(self[parent])
self[class] = sc
end
- aux.add_settings_to_array(sc, settings)
+ aux.settings_to_hash(settings,sc)
end
-- temporary here
@@ -3230,12 +3317,15 @@ if not modules then modules = { } end modules ['trac-tra'] = {
-- bound to a variable, like node.new, node.copy etc (contrary to for instance
-- node.has_attribute which is bound to a has_attribute local variable in mkiv)
+local getinfo = debug.getinfo
+local type, next = type, next
+local concat = table.concat
+local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
+
debugger = debugger or { }
local counters = { }
local names = { }
-local getinfo = debug.getinfo
-local format, find, lower, gmatch, gsub = string.format, string.find, string.lower, string.gmatch, string.gsub
-- one
@@ -3363,11 +3453,11 @@ end
--~ print("")
--~ debugger.showstats(print,3)
-trackers = trackers or { }
+setters = setters or { }
+setters.data = setters.data or { }
-local data, done = { }, { }
-
-local function set(what,value)
+local function set(t,what,value)
+ local data, done = t.data, t.done
if type(what) == "string" then
what = aux.settings_to_array(what) -- inefficient but ok
end
@@ -3386,28 +3476,30 @@ local function set(what,value)
end
end
-local function reset()
- for d, f in next, data do
+local function reset(t)
+ for d, f in next, t.data do
for i=1,#f do
f[i](false)
end
end
end
-local function enable(what)
- set(what,true)
+local function enable(t,what)
+ set(t,what,true)
end
-local function disable(what)
+local function disable(t,what)
+ local data = t.data
if not what or what == "" then
- done = { }
- reset()
+ t.done = { }
+ reset(t)
else
- set(what,false)
+ set(t,what,false)
end
end
-function trackers.register(what,...)
+function setters.register(t,what,...)
+ local data = t.data
what = lower(what)
local w = data[what]
if not w then
@@ -3419,32 +3511,32 @@ function trackers.register(what,...)
if typ == "function" then
w[#w+1] = fnc
elseif typ == "string" then
- w[#w+1] = function(value) set(fnc,value,nesting) end
+ w[#w+1] = function(value) set(t,fnc,value,nesting) end
end
end
end
-function trackers.enable(what)
- local e = trackers.enable
- trackers.enable, done = enable, { }
- enable(string.simpleesc(what))
- trackers.enable, done = e, { }
+function setters.enable(t,what)
+ local e = t.enable
+ t.enable, t.done = enable, { }
+ enable(t,string.simpleesc(what))
+ t.enable, t.done = e, { }
end
-function trackers.disable(what)
- local e = trackers.disable
- trackers.disable, done = disable, { }
- disable(string.simpleesc(what))
- trackers.disable, done = e, { }
+function setters.disable(t,what)
+ local e = t.disable
+ t.disable, t.done = disable, { }
+ disable(t,string.simpleesc(what))
+ t.disable, t.done = e, { }
end
-function trackers.reset()
- done = { }
- reset()
+function setters.reset(t)
+ t.done = { }
+ reset(t)
end
-function trackers.list() -- pattern
- local list = table.sortedkeys(data)
+function setters.list(t) -- pattern
+ local list = table.sortedkeys(t.data)
local user, system = { }, { }
for l=1,#list do
local what = list[l]
@@ -3457,6 +3549,139 @@ function trackers.list() -- pattern
return user, system
end
+function setters.show(t)
+ commands.writestatus("","")
+ for k,v in ipairs(setters.list(t)) do
+ commands.writestatus(t.name,v)
+ end
+ commands.writestatus("","")
+end
+
+-- we could have used a bit of oo and the trackers:enable syntax but
+-- there is already a lot of code around using the singluar tracker
+
+function setters.new(name)
+ local t
+ t = {
+ data = { },
+ name = name,
+ enable = function(...) setters.enable (t,...) end,
+ disable = function(...) setters.disable (t,...) end,
+ register = function(...) setters.register(t,...) end,
+ list = function(...) setters.list (t,...) end,
+ show = function(...) setters.show (t,...) end,
+ }
+ setters.data[name] = t
+ return t
+end
+
+trackers = setters.new("trackers")
+directives = setters.new("directives")
+
+-- nice trick: we overload two of the directives related functions with variants that
+-- do tracing (itself using a tracker) .. proof of concept
+
+local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
+
+local e = directives.enable
+local d = directives.disable
+
+function directives.enable(...)
+ commands.writestatus("directives","enabling: %s",concat({...}," "))
+ e(...)
+end
+
+function directives.disable(...)
+ commands.writestatus("directives","disabling: %s",concat({...}," "))
+ d(...)
+end
+
+--~ -- old code:
+--
+--~ trackers = trackers or { }
+--~ local data, done = { }, { }
+--~ local function set(what,value)
+--~ if type(what) == "string" then
+--~ what = aux.settings_to_array(what) -- inefficient but ok
+--~ end
+--~ for i=1,#what do
+--~ local w = what[i]
+--~ for d, f in next, data do
+--~ if done[d] then
+--~ -- prevent recursion due to wildcards
+--~ elseif find(d,w) then
+--~ done[d] = true
+--~ for i=1,#f do
+--~ f[i](value)
+--~ end
+--~ end
+--~ end
+--~ end
+--~ end
+--~ local function reset()
+--~ for d, f in next, data do
+--~ for i=1,#f do
+--~ f[i](false)
+--~ end
+--~ end
+--~ end
+--~ local function enable(what)
+--~ set(what,true)
+--~ end
+--~ local function disable(what)
+--~ if not what or what == "" then
+--~ done = { }
+--~ reset()
+--~ else
+--~ set(what,false)
+--~ end
+--~ end
+--~ function trackers.register(what,...)
+--~ what = lower(what)
+--~ local w = data[what]
+--~ if not w then
+--~ w = { }
+--~ data[what] = w
+--~ end
+--~ for _, fnc in next, { ... } do
+--~ local typ = type(fnc)
+--~ if typ == "function" then
+--~ w[#w+1] = fnc
+--~ elseif typ == "string" then
+--~ w[#w+1] = function(value) set(fnc,value,nesting) end
+--~ end
+--~ end
+--~ end
+--~ function trackers.enable(what)
+--~ local e = trackers.enable
+--~ trackers.enable, done = enable, { }
+--~ enable(string.simpleesc(what))
+--~ trackers.enable, done = e, { }
+--~ end
+--~ function trackers.disable(what)
+--~ local e = trackers.disable
+--~ trackers.disable, done = disable, { }
+--~ disable(string.simpleesc(what))
+--~ trackers.disable, done = e, { }
+--~ end
+--~ function trackers.reset()
+--~ done = { }
+--~ reset()
+--~ end
+--~ function trackers.list() -- pattern
+--~ local list = table.sortedkeys(data)
+--~ local user, system = { }, { }
+--~ for l=1,#list do
+--~ local what = list[l]
+--~ if find(what,"^%*") then
+--~ system[#system+1] = what
+--~ else
+--~ user[#user+1] = what
+--~ end
+--~ end
+--~ return user, system
+--~ end
+
end -- of closure
@@ -3908,6 +4133,7 @@ function statistics.timed(action,report)
end
+
end -- of closure
do -- create closure to overcome 200 locals limit
@@ -4241,6 +4467,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -4629,7 +4857,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -4638,7 +4866,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -4703,9 +4931,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -4734,7 +4962,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -4746,11 +4974,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -4815,13 +5043,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -4829,12 +5061,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -4858,12 +5090,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -4925,7 +5157,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -5184,6 +5416,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -5206,6 +5439,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -5213,6 +5452,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -5467,7 +5707,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -5664,8 +5904,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -5896,7 +6136,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -6048,9 +6288,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -6397,6 +6637,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else
diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun
index 130ad493c..0d3f08025 100755
--- a/scripts/context/stubs/unix/mtxrun
+++ b/scripts/context/stubs/unix/mtxrun
@@ -789,6 +789,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s{",depth))
end
end
+ -- we could check for k (index) being number (cardinal)
if root and next(root) then
local first, last = nil, 0 -- #root cannot be trusted here
if compact then
@@ -811,7 +812,7 @@ local function do_serialize(root,name,depth,level,indexed)
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
- handle(format("%s %.99g,",depth,v))
+ handle(format("%s %s,",depth,v)) -- %.99g
end
elseif t == "string" then
if reduce and tonumber(v) then
@@ -851,25 +852,25 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if hexify then
--~ handle(format("%s %s=0x%04X,",depth,key(k),v))
--~ else
- --~ handle(format("%s %s=%.99g,",depth,key(k),v))
+ --~ handle(format("%s %s=%s,",depth,key(k),v)) -- %.99g
--~ end
if type(k) == "number" then -- or find(k,"^%d+$") then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
else
- handle(format("%s [%s]=%.99g,",depth,k,v))
+ handle(format("%s [%s]=%s,",depth,k,v)) -- %.99g
end
elseif noquotes and not reserved[k] and find(k,"^%a[%w%_]*$") then
if hexify then
handle(format("%s %s=0x%04X,",depth,k,v))
else
- handle(format("%s %s=%.99g,",depth,k,v))
+ handle(format("%s %s=%s,",depth,k,v)) -- %.99g
end
else
if hexify then
handle(format("%s [%q]=0x%04X,",depth,k,v))
else
- handle(format("%s [%q]=%.99g,",depth,k,v))
+ handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
elseif t == "string" then
@@ -1868,8 +1869,12 @@ function file.dirname(name,default)
return match(name,"^(.+)[/\\].-$") or (default or "")
end
+--~ function file.basename(name)
+--~ return match(name,"^.+[/\\](.-)$") or name
+--~ end
+
function file.basename(name)
- return match(name,"^.+[/\\](.-)$") or name
+ return match(name,"^.*[/\\](.-)$") or name
end
function file.nameonly(name)
@@ -4872,7 +4877,7 @@ local noparent = 1 - (lparent+rparent)
local nested = lpeg.P{lparent * (noparent + lpeg.V(1))^0 * rparent}
local value = lpeg.P(lparent * lpeg.C((noparent + nested)^0) * rparent) -- lpeg.P{"("*C(((1-S("()"))+V(1))^0)*")"}
-local lp_child = Cc("expr.child(e,'") * R("az","AZ","--","__")^1 * Cc("')")
+local lp_child = Cc("expr.child(ll,'") * R("az","AZ","--","__")^1 * Cc("')")
local lp_string = Cc("'") * R("az","AZ","--","__")^1 * Cc("'")
local lp_content = (P("'") * (1-P("'"))^0 * P("'") + P('"') * (1-P('"'))^0 * P('"'))
@@ -4882,9 +4887,9 @@ local lp_special = (C(P("name")+P("text")+P("tag")+P("count")+P("child"))) * val
if expressions[t] then
s = s and s ~= "" and cleaner:match(s)
if s and s ~= "" then
- return "expr." .. t .. "(e," .. s ..")"
+ return "expr." .. t .. "(ll," .. s ..")"
else
- return "expr." .. t .. "(e)"
+ return "expr." .. t .. "(ll)"
end
else
return "expr.error(" .. t .. ")"
@@ -5434,38 +5439,42 @@ expressions.name = function(e,n) -- ns + tg
end
expressions.tag = function(e,n) -- only tg
- local found = false
- n = tonumber(n) or 0
- if n == 0 then
- found = (type(e) == "table") and e -- seems to fail
- elseif n < 0 then
- local d, k = e.__p__.dt, e.ni
- for i=k-1,1,-1 do
- local di = d[i]
- if type(di) == "table" then
- if n == -1 then
- found = di
- break
- else
- n = n + 1
+ if not e then
+ return ""
+ else
+ local found = false
+ n = tonumber(n) or 0
+ if n == 0 then
+ found = (type(e) == "table") and e -- seems to fail
+ elseif n < 0 then
+ local d, k = e.__p__.dt, e.ni
+ for i=k-1,1,-1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == -1 then
+ found = di
+ break
+ else
+ n = n + 1
+ end
end
end
- end
- else
- local d, k = e.__p__.dt, e.ni
- for i=k+1,#d,1 do
- local di = d[i]
- if type(di) == "table" then
- if n == 1 then
- found = di
- break
- else
- n = n - 1
+ else
+ local d, k = e.__p__.dt, e.ni
+ for i=k+1,#d,1 do
+ local di = d[i]
+ if type(di) == "table" then
+ if n == 1 then
+ found = di
+ break
+ else
+ n = n - 1
+ end
end
end
end
+ return (found and found.tg) or ""
end
- return (found and found.tg) or ""
end
--[[ldx--
@@ -5992,7 +6001,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata)
--~ local settings = xmldata.settings
--~ settings.parent_root = xmldata -- to be tested
--~ local xi = xmlconvert(data,settings)
- local xi = xml.inheritedconvert(element,xmldata)
+ local xi = xml.inheritedconvert(data,xmldata)
if not xi then
epdt[ek.ni] = "" -- xml.empty(d,k)
else
@@ -7046,7 +7055,6 @@ end
local name, banner = 'report', 'context'
local function report(category,fmt,...)
---~ print(fmt,...)
if fmt then
write_nl(format("%s | %s: %s",name,category,format(fmt,...)))
elseif category then
@@ -7187,6 +7195,8 @@ local format, gsub, find, lower, upper, match, gmatch = string.format, string.gs
local concat, insert, sortedkeys = table.concat, table.insert, table.sortedkeys
local next, type = next, type
+local collapse_path = file.collapse_path
+
local trace_locating, trace_detail, trace_verbose = false, false, false
trackers.register("resolvers.verbose", function(v) trace_verbose = v end)
@@ -7575,7 +7585,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
end
if ok then
local function validate(s)
- s = file.collapse_path(s)
+ s = collapse_path(s)
return s ~= "" and not find(s,dummy_path_expr) and s
end
for k=1,#pathlist do
@@ -7584,7 +7594,7 @@ local function expanded_path_from_list(pathlist) -- maybe not a list, just a pat
else
for k=1,#pathlist do
for p in gmatch(pathlist[k],"([^,]+)") do
- p = file.collapse_path(p)
+ p = collapse_path(p)
if p ~= "" then newlist[#newlist+1] = p end
end
end
@@ -7649,9 +7659,9 @@ local function identify_own()
local ownpath = resolvers.getownpath() or lfs.currentdir()
local ie = instance.environment
if ownpath then
- if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = file.collapse_path(ownpath) end
- if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = file.collapse_path(ownpath .. "/..") end
- if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = file.collapse_path(ownpath .. "/../..") end
+ if resolvers.env('SELFAUTOLOC') == "" then os.env['SELFAUTOLOC'] = collapse_path(ownpath) end
+ if resolvers.env('SELFAUTODIR') == "" then os.env['SELFAUTODIR'] = collapse_path(ownpath .. "/..") end
+ if resolvers.env('SELFAUTOPARENT') == "" then os.env['SELFAUTOPARENT'] = collapse_path(ownpath .. "/../..") end
else
logs.report("fileio","error: unable to locate ownpath")
os.exit()
@@ -7680,7 +7690,7 @@ function resolvers.identify_cnf()
local function locate(filename,list)
for i=1,#t do
local ti = t[i]
- local texmfcnf = file.collapse_path(file.join(ti,filename))
+ local texmfcnf = collapse_path(file.join(ti,filename))
if lfs.isfile(texmfcnf) then
list[#list+1] = texmfcnf
end
@@ -7692,11 +7702,11 @@ function resolvers.identify_cnf()
end
local function load_cnf_file(fname)
+ -- why don't we just read the file from the cache
+ -- we need to switch to the lua file
fname = resolvers.clean_path(fname)
local lname = file.replacesuffix(fname,'lua')
- local f = io.open(lname)
- if f then -- this will go
- f:close()
+ if lfs.isfile(lname) then
local dname = file.dirname(fname)
if not instance.configuration[dname] then
resolvers.load_data(dname,'configuration',lname and file.basename(lname))
@@ -7761,13 +7771,17 @@ local function collapse_cnf_data() -- potential optimization: pass start index (
end
end
-function resolvers.load_cnf()
- local function loadoldconfigdata()
- for _, fname in ipairs(instance.cnffiles) do
- load_cnf_file(fname)
- end
+local function loadoldconfigdata()
+ for _, fname in ipairs(instance.cnffiles) do
+ load_cnf_file(fname)
end
+end
+
+function resolvers.load_cnf()
-- instance.cnffiles contain complete names now !
+ -- we still use a funny mix of cnf and new but soon
+ -- we will switch to lua exclusively as we only use
+ -- the file to collect the tree roots
if #instance.cnffiles == 0 then
if trace_verbose then
logs.report("fileio","no cnf files found (TEXMFCNF may not be set/known)")
@@ -7775,12 +7789,12 @@ function resolvers.load_cnf()
else
instance.rootpath = instance.cnffiles[1]
for k,fname in ipairs(instance.cnffiles) do
- instance.cnffiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.cnffiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
if instance.diskcache and not instance.renewcache then
resolvers.loadoldconfig(instance.cnffiles)
if instance.loaderror then
@@ -7804,12 +7818,12 @@ function resolvers.load_lua()
else
instance.rootpath = instance.luafiles[1]
for k,fname in ipairs(instance.luafiles) do
- instance.luafiles[k] = file.collapse_path(gsub(fname,"\\",'/'))
+ instance.luafiles[k] = collapse_path(gsub(fname,"\\",'/'))
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
end
- instance.rootpath = file.collapse_path(instance.rootpath)
+ instance.rootpath = collapse_path(instance.rootpath)
resolvers.loadnewconfig()
collapse_cnf_data()
end
@@ -7871,7 +7885,7 @@ function resolvers.locatelists()
if trace_verbose then
logs.report("fileio","locating list of %s",path)
end
- resolvers.locatedatabase(file.collapse_path(path))
+ resolvers.locatedatabase(collapse_path(path))
end
end
@@ -8130,6 +8144,7 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
date = os.date("%Y-%m-%d"),
time = os.date("%H:%M:%S"),
content = files,
+ uuid = os.uuid(),
}
local ok = io.savedata(luaname,resolvers.serialize(data))
if ok then
@@ -8152,6 +8167,12 @@ function resolvers.save_data(dataname, makename) -- untested without cache overl
end
end
+local data_state = { }
+
+function resolvers.data_state()
+ return data_state or { }
+end
+
function resolvers.load_data(pathname,dataname,filename,makename) -- untested without cache overload
filename = ((not filename or (filename == "")) and dataname) or filename
filename = (makename and makename(dataname,filename)) or file.join(pathname,filename)
@@ -8159,6 +8180,7 @@ function resolvers.load_data(pathname,dataname,filename,makename) -- untested wi
if blob then
local data = blob()
if data and data.content and data.type == dataname and data.version == resolvers.cacheversion then
+ data_state[#data_state+1] = data.uuid
if trace_verbose then
logs.report("fileio","loading %s for %s from %s",dataname,pathname,filename)
end
@@ -8413,7 +8435,7 @@ function resolvers.clean_path_list(str)
local t = resolvers.expanded_path_list(str)
if t then
for i=1,#t do
- t[i] = file.collapse_path(resolvers.clean_path(t[i]))
+ t[i] = collapse_path(resolvers.clean_path(t[i]))
end
end
return t
@@ -8610,8 +8632,8 @@ end
local function collect_instance_files(filename,collected) -- todo : plugin (scanners, checkers etc)
local result = collected or { }
local stamp = nil
- filename = file.collapse_path(filename) -- elsewhere
- filename = file.collapse_path(gsub(filename,"\\","/")) -- elsewhere
+ filename = collapse_path(filename) -- elsewhere
+ filename = collapse_path(gsub(filename,"\\","/")) -- elsewhere
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -8842,7 +8864,7 @@ local function collect_instance_files(filename,collected) -- todo : plugin (scan
end
end
for k=1,#result do
- result[k] = file.collapse_path(result[k])
+ result[k] = collapse_path(result[k])
end
if instance.remember then
instance.found[stamp] = result
@@ -8994,9 +9016,9 @@ function resolvers.load(option)
statistics.starttiming(instance)
resolvers.resetconfig()
resolvers.identify_cnf()
- resolvers.load_lua()
+ resolvers.load_lua() -- will become the new method
resolvers.expand_variables()
- resolvers.load_cnf()
+ resolvers.load_cnf() -- will be skipped when we have a lua file
resolvers.expand_variables()
if option ~= "nofiles" then
resolvers.load_hash()
@@ -9343,6 +9365,7 @@ function caches.savedata(filepath,filename,data,raw)
if raw then
reduce, simplify = false, false
end
+ data.cache_uuid = os.uuid()
if caches.direct then
file.savedata(tmaname, table.serialize(data,'return',false,true,false)) -- no hex
else