summaryrefslogtreecommitdiff
path: root/scripts/context/lua/mtxrun.lua
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/context/lua/mtxrun.lua')
-rw-r--r--scripts/context/lua/mtxrun.lua197
1 files changed, 160 insertions, 37 deletions
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua
index 8a2d7a123..ef7eda9b0 100644
--- a/scripts/context/lua/mtxrun.lua
+++ b/scripts/context/lua/mtxrun.lua
@@ -347,6 +347,8 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
lpeg = require("lpeg")
+lpeg.patterns = lpeg.patterns or { } -- so that we can share
+
local P, R, S, Ct, C, Cs, Cc = lpeg.P, lpeg.R, lpeg.S, lpeg.Ct, lpeg.C, lpeg.Cs, lpeg.Cc
local match = lpeg.match
@@ -497,11 +499,9 @@ end
--~
--~ 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
-
+lpeg.patterns.utf8 = R("\0\127") + R("\194\223") * cont + R("\224\239") * cont * cont + R("\240\244") * cont * cont * cont
end -- of closure
@@ -1952,6 +1952,21 @@ elseif name == "freebsd" then
return platform
end
+elseif name == "kfreebsd" then
+
+ function os.resolvers.platform(t,k)
+ -- we sometims have HOSTTYPE set so let's check that first
+ local platform, architecture = "", os.getenv("HOSTTYPE") or os.resultof("uname -m") or ""
+ if find(architecture,"x86_64") then
+ platform = "kfreebsd-64"
+ else
+ platform = "kfreebsd-i386"
+ end
+ os.setenv("MTX_PLATFORM",platform)
+ os.platform = platform
+ return platform
+ end
+
else
-- platform = "linux"
@@ -2021,7 +2036,7 @@ if not modules then modules = { } end modules ['l-file'] = {
file = file or { }
local concat = table.concat
-local find, gmatch, match, gsub, sub = string.find, string.gmatch, string.match, string.gsub, string.sub
+local find, gmatch, match, gsub, sub, char = string.find, string.gmatch, string.match, string.gsub, string.sub, string.char
local lpegmatch = lpeg.match
function file.removesuffix(filename)
@@ -2058,14 +2073,33 @@ end
file.suffix = file.extname
---~ print(file.join("x/","/y"))
---~ print(file.join("http://","/y"))
---~ print(file.join("http://a","/y"))
---~ print(file.join("http:///a","/y"))
---~ print(file.join("//nas-1","/y"))
+--~ function file.join(...)
+--~ local pth = concat({...},"/")
+--~ pth = gsub(pth,"\\","/")
+--~ local a, b = match(pth,"^(.*://)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ a, b = match(pth,"^(//)(.*)$")
+--~ if a and b then
+--~ return a .. gsub(b,"//+","/")
+--~ end
+--~ return (gsub(pth,"//+","/"))
+--~ end
+
+local trick_1 = char(1)
+local trick_2 = "^" .. trick_1 .. "/+"
function file.join(...)
- local pth = concat({...},"/")
+ local lst = { ... }
+ local a, b = lst[1], lst[2]
+ if a == "" then
+ lst[1] = trick_1
+ elseif b and find(a,"^/+$") and find(b,"^/") then
+ lst[1] = ""
+ lst[2] = gsub(b,"^/+","")
+ end
+ local pth = concat(lst,"/")
pth = gsub(pth,"\\","/")
local a, b = match(pth,"^(.*://)(.*)$")
if a and b then
@@ -2075,9 +2109,20 @@ function file.join(...)
if a and b then
return a .. gsub(b,"//+","/")
end
+ pth = gsub(pth,trick_2,"")
return (gsub(pth,"//+","/"))
end
+--~ print(file.join("//","/y"))
+--~ print(file.join("/","/y"))
+--~ print(file.join("","/y"))
+--~ print(file.join("/x/","/y"))
+--~ print(file.join("x/","/y"))
+--~ print(file.join("http://","/y"))
+--~ print(file.join("http://a","/y"))
+--~ print(file.join("http:///a","/y"))
+--~ print(file.join("//nas-1","/y"))
+
function file.iswritable(name)
local a = lfs.attributes(name) or lfs.attributes(file.dirname(name,"."))
return a and sub(a.permissions,2,2) == "w"
@@ -2116,16 +2161,22 @@ function file.join_path(tab)
return concat(tab,io.pathseparator) -- can have trailing //
end
+-- we can hash them weakly
+
function file.collapse_path(str)
- str = gsub(str,"/%./","/")
- local n, m = 1, 1
- while n > 0 or m > 0 do
- str, n = gsub(str,"[^/%.]+/%.%.$","")
- str, m = gsub(str,"[^/%.]+/%.%./","")
- end
- str = gsub(str,"([^/])/$","%1")
- str = gsub(str,"^%./","")
- str = gsub(str,"/%.$","")
+ str = gsub(str,"\\","/")
+ if find(str,"/") then
+ str = gsub(str,"^%./",(gsub(lfs.currentdir(),"\\","/")) .. "/") -- ./xx in qualified
+ str = gsub(str,"/%./","/")
+ local n, m = 1, 1
+ while n > 0 or m > 0 do
+ str, n = gsub(str,"[^/%.]+/%.%.$","")
+ str, m = gsub(str,"[^/%.]+/%.%./","")
+ end
+ str = gsub(str,"([^/])/$","%1")
+ -- str = gsub(str,"^%./","") -- ./xx in qualified
+ str = gsub(str,"/%.$","")
+ end
if str == "" then str = "." end
return str
end
@@ -2824,7 +2875,7 @@ else
--~ print(dir.mkdirs("///a/b/c"))
--~ print(dir.mkdirs("a/bbb//ccc/"))
- function dir.expand_name(str)
+ function dir.expand_name(str) -- will be merged with cleanpath and collapsepath
if not find(str,"^/") then
str = lfs.currentdir() .. "/" .. str
end
@@ -3340,6 +3391,8 @@ local stripper = lpeg.Cs((number + 1)^0)
--~ lpegmatch(stripper,str)
--~ print(#str, os.clock()-ts, lpegmatch(stripper,sample))
+lpeg.patterns.strip_zeros = stripper
+
function aux.strip_zeros(str)
return lpegmatch(stripper,str)
end
@@ -3626,14 +3679,14 @@ end
function setters.enable(t,what)
local e = t.enable
t.enable, t.done = enable, { }
- enable(t,string.simpleesc(what))
+ enable(t,string.simpleesc(tostring(what)))
t.enable, t.done = e, { }
end
function setters.disable(t,what)
local e = t.disable
t.disable, t.done = disable, { }
- disable(t,string.simpleesc(what))
+ disable(t,string.simpleesc(tostring(what)))
t.disable, t.done = e, { }
end
@@ -3720,6 +3773,13 @@ function experiments.disable(...)
d(...)
end
+-- a useful example
+
+directives.register("system.nostatistics", function(v)
+ statistics.enable = not v
+end)
+
+
end -- of closure
@@ -3995,9 +4055,9 @@ local function attribute_specification_error(str)
return str
end
-function xml.unknown_dec_entity_format(str) return format("&%s;", str) end
+function xml.unknown_dec_entity_format(str) return (str == "" and "&error;") or format("&%s;",str) end
function xml.unknown_hex_entity_format(str) return format("&#x%s;",str) end
-function xml.unknown_any_entity_format(str) return format("&%s;", str) end
+function xml.unknown_any_entity_format(str) return format("&#x%s;",str) end
local function handle_hex_entity(str)
local h = hcache[str]
@@ -4111,7 +4171,11 @@ local function handle_any_entity(str)
if trace_entities then
logs.report("xml","keeping entity &%s;",str)
end
- a = "&" .. str .. ";"
+ if str == "" then
+ a = "&error;"
+ else
+ a = "&" .. str .. ";"
+ end
end
end
acache[str] = a
@@ -4132,6 +4196,9 @@ local function handle_any_entity(str)
if a then
-- one of the predefined
acache[str] = a
+ elseif str == "" then
+ a = "&error;"
+ acache[str] = a
else
a = "&" .. str .. ";"
acache[str] = a
@@ -4460,7 +4527,7 @@ function xml.checkbom(root) -- can be made faster
local dt, found = root.dt, false
for k=1,#dt do
local v = dt[k]
- if type(v) == "table" and v.special and v.tg == "@pi" and find(v.dt,"xml.*version=") then
+ if type(v) == "table" and v.special and v.tg == "@pi@" and find(v.dt[1],"xml.*version=") then
found = true
break
end
@@ -4842,6 +4909,8 @@ function xml.assign(dt,k,root)
end
end
+-- the following helpers may move
+
--[[ldx--
<p>The next helper assigns a tree (or string). Usage:</p>
<typing>
@@ -4860,6 +4929,22 @@ function xml.tocdata(e,wrapper)
e.dt = { t }
end
+function xml.makestandalone(root)
+ if root.ri then
+ local dt = root.dt
+ for k=1,#dt do
+ local v = dt[k]
+ if type(v) == "table" and v.special and v.tg == "@pi@" then
+ local txt = v.dt[1]
+ if find(txt,"xml.*version=") then
+ v.dt[1] = txt .. " standalone='yes'"
+ break
+ end
+ end
+ end
+ end
+end
+
end -- of closure
@@ -5476,8 +5561,13 @@ local register_initial_child = { kind = "axis", axis = "initial-child"
local register_all_nodes = { kind = "nodes", nodetest = true, nodes = { true, false, false } }
+local skip = { }
+
local function errorrunner_e(str,cnv)
- logs.report("lpath","error in expression: %s => %s",str,cnv)
+ if not skip[str] then
+ logs.report("lpath","error in expression: %s => %s",str,cnv)
+ skip[str] = cnv or str
+ end
return false
end
local function errorrunner_f(str,arg)
@@ -7287,6 +7377,14 @@ function statistics.hastimer(instance)
return instance and instance.starttime
end
+function statistics.resettiming(instance)
+ if not instance then
+ notimer = { timing = 0, loadtime = 0 }
+ else
+ instance.timing, instance.loadtime = 0, 0
+ end
+end
+
function statistics.starttiming(instance)
if not instance then
notimer = { }
@@ -7346,6 +7444,12 @@ function statistics.elapsedindeed(instance)
return t > statistics.threshold
end
+function statistics.elapsedseconds(instance,rest) -- returns nil if 0 seconds
+ if statistics.elapsedindeed(instance) then
+ return format("%s seconds %s", statistics.elapsedtime(instance),rest or "")
+ end
+end
+
-- general function
function statistics.register(tag,fnc)
@@ -7424,6 +7528,23 @@ function statistics.timed(action,report)
report("total runtime: %s",statistics.elapsedtime(timer))
end
+-- where, not really the best spot for this:
+
+commands = commands or { }
+
+local timer
+
+function commands.resettimer()
+ statistics.resettiming(timer)
+ statistics.starttiming(timer)
+end
+
+function commands.elapsedtime()
+ statistics.stoptiming(timer)
+ tex.sprint(statistics.elapsedtime(timer))
+end
+
+commands.resettimer()
end -- of closure
@@ -7861,8 +7982,8 @@ suffixes['lua'] = { 'lua', 'luc', 'tma', 'tmc' }
alternatives['map files'] = 'map'
alternatives['enc files'] = 'enc'
-alternatives['cid files'] = 'cid'
-alternatives['fea files'] = 'fea'
+alternatives['cid maps'] = 'cid' -- great, why no cid files
+alternatives['font feature files'] = 'fea' -- and fea files here
alternatives['opentype fonts'] = 'otf'
alternatives['truetype fonts'] = 'ttf'
alternatives['truetype collections'] = 'ttc'
@@ -8005,8 +8126,10 @@ local function check_configuration() -- not yet ok, no time for debugging now
-- bad luck
end
fix("LUAINPUTS" , ".;$TEXINPUTS;$TEXMFSCRIPTS") -- no progname, hm
- fix("FONTFEATURES", ".;$TEXMF/fonts/fea//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
- fix("FONTCIDMAPS" , ".;$TEXMF/fonts/cid//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ -- this will go away some day
+ fix("FONTFEATURES", ".;$TEXMF/fonts/{data,fea}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ fix("FONTCIDMAPS" , ".;$TEXMF/fonts/{data,cid}//;$OPENTYPEFONTS;$TTFONTS;$T1FONTS;$AFMFONTS")
+ --
fix("LUATEXLIBS" , ".;$TEXMF/luatex/lua//")
end
@@ -8396,7 +8519,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -8425,7 +8548,7 @@ 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] = file.collapse_path(fname)
end
for i=1,3 do
instance.rootpath = file.dirname(instance.rootpath)
@@ -8550,7 +8673,7 @@ local weird = lpeg.P(".")^1 + lpeg.anywhere(lpeg.S("~`!#$%^&*()={}[]:;\"\'||<>,?
--~ local l_forbidden = lpeg.S("~`!#$%^&*()={}[]:;\"\'||\\/<>,?\n\r\t")
--~ local l_confusing = lpeg.P(" ")
---~ local l_character = lpeg.utf8
+--~ local l_character = lpeg.patterns.utf8
--~ local l_dangerous = lpeg.P(".")
--~ local l_normal = (l_character - l_forbidden - l_confusing - l_dangerous) * (l_character - l_forbidden - l_confusing^2)^0 * lpeg.P(-1)
@@ -9290,8 +9413,7 @@ 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 = file.collapse_path(filename)
-- speed up / beware: format problem
if instance.remember then
stamp = filename .. "--" .. instance.engine .. "--" .. instance.progname .. "--" .. instance.format
@@ -9772,12 +9894,13 @@ end
function table.sequenced(t,sep) -- temp here
local s = { }
for k, v in pairs(t) do -- pairs?
- s[#s+1] = k .. "=" .. v
+ s[#s+1] = k .. "=" .. tostring(v)
end
return concat(s, sep or " | ")
end
function resolvers.methodhandler(what, filename, filetype) -- ...
+ filename = file.collapse_path(filename)
local specification = (type(filename) == "string" and resolvers.splitmethod(filename)) or filename -- no or { }, let it bomb
local scheme = specification.scheme
if resolvers[what][scheme] then