diff options
Diffstat (limited to 'scripts/context/lua/mtxrun.lua')
| -rw-r--r-- | scripts/context/lua/mtxrun.lua | 197 | 
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 | 
