diff options
Diffstat (limited to 'scripts/context/lua/mtxrun.lua')
-rw-r--r-- | scripts/context/lua/mtxrun.lua | 2146 |
1 files changed, 1504 insertions, 642 deletions
diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 873770cac..3374a364a 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -56,7 +56,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-lua"] = package.loaded["l-lua"] or true --- original size: 5125, stripped down to: 2881 +-- original size: 6230, stripped down to: 3662 if not modules then modules={} end modules ['l-lua']={ version=1.001, @@ -65,14 +65,16 @@ if not modules then modules={} end modules ['l-lua']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -_MAJORVERSION,_MINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$") -_MAJORVERSION=tonumber(_MAJORVERSION) or 5 -_MINORVERSION=tonumber(_MINORVERSION) or 1 -_LUAVERSION=_MAJORVERSION+_MINORVERSION/10 -if _LUAVERSION<5.2 and jit then - _MINORVERSION=2 - _LUAVERSION=5.2 -end +local next,type,tonumber=next,type,tonumber +LUAMAJORVERSION,LUAMINORVERSION=string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$") +LUAMAJORVERSION=tonumber(LUAMAJORVERSION) or 5 +LUAMINORVERSION=tonumber(LUAMINORVERSION) or 1 +LUAVERSION=LUAMAJORVERSION+LUAMINORVERSION/10 +if LUAVERSION<5.2 and jit then + MINORVERSION=2 + LUAVERSION=5.2 +end +_LUAVERSION=LUAVERSION if not lpeg then lpeg=require("lpeg") end @@ -172,6 +174,166 @@ if not FFISUPPORTED then elseif not ffi.number then ffi.number=tonumber end +if not bit32 then + bit32=require("l-bit32") +end +local loaded=package.loaded +if not loaded["socket"] then loaded["socket"]=loaded["socket.core"] end +if not loaded["mime"] then loaded["mime"]=loaded["mime.core"] end +if not socket.mime then socket.mime=package.loaded["mime"] end +if not loaded["socket.mime"] then loaded["socket.mime"]=socket.mime end +if not loaded["socket.http"] then loaded["socket.http"]=socket.http end +if not loaded["socket.ftp"] then loaded["socket.ftp"]=socket.ftp end +if not loaded["socket.smtp"] then loaded["socket.smtp"]=socket.smtp end +if not loaded["socket.tp"] then loaded["socket.tp"]=socket.tp end +if not loaded["socket.url"] then loaded["socket.url"]=socket.url end + + +end -- of closure + +do -- create closure to overcome 200 locals limit + +package.loaded["l-macro"] = package.loaded["l-macro"] or true + +-- original size: 6393, stripped down to: 3659 + +if not modules then modules={} end modules ['l-macros']={ + version=1.001, + comment="companion to luat-lib.mkiv", + author="Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright="PRAGMA ADE / ConTeXt Development Team", + license="see context related readme files" +} +local S,P,R,V,C,Cs,Cc,Ct,Carg=lpeg.S,lpeg.P,lpeg.R,lpeg.V,lpeg.C,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Carg +local lpegmatch=lpeg.match +local concat=table.concat +local next=next +local newline=S("\n\r")^1 +local continue=P("\\")*newline +local spaces=S(" \t")+continue +local name=R("az","AZ","__","09")^1 +local body=((1+continue/"")-newline)^1 +local lparent=P("(") +local rparent=P(")") +local noparent=1-(lparent+rparent) +local nested=P { lparent*(noparent+V(1))^0*rparent } +local escaped=P("\\")*P(1) +local squote=P("'") +local dquote=P('"') +local quoted=dquote*(escaped+(1-dquote))^0*dquote+squote*(escaped+(1-squote))^0*squote +local arguments=lparent*Ct((Cs((nested+(quoted+1-S("),")))^1)+S(", "))^0)*rparent +local macros=lua.macros or {} +lua.macros=macros +local patterns={} +local definitions={} +local resolve +local subparser +resolve=C(C(name)*arguments^-1)/function(raw,s,a) + local d=definitions[s] + if d then + if a then + local n=#a + local p=patterns[s][n] + if p then + local d=d[n] + for i=1,n do + a[i]=lpegmatch(subparser,a[i]) or a[i] + end + return lpegmatch(p,d,1,a) or d + else + return raw + end + else + return d[0] or raw + end + elseif a then + for i=1,#a do + a[i]=lpegmatch(subparser,a[i]) or a[i] + end + return s.."("..concat(a,",")..")" + else + return raw + end +end +subparser=Cs((resolve+P(1))^1) +local enddefine=P("#enddefine")/"" +local beginregister=(C(name)*spaces^0*(arguments+Cc(false))*C((1-enddefine)^1)*enddefine)/function(k,a,v) + local n=0 + if a then + n=#a + local pattern=P(false) + for i=1,n do + pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end + end + pattern=Cs((pattern+P(1))^1) + local p=patterns[k] + if not p then + p={ [0]=false,false,false,false,false,false,false,false,false } + patterns[k]=p + end + p[n]=pattern + end + local d=definitions[k] + if not d then + d={ [0]=false,false,false,false,false,false,false,false,false } + definitions[k]=d + end + d[n]=lpegmatch(subparser,v) or v + return "" +end +local register=(C(name)*spaces^0*(arguments+Cc(false))*spaces^0*C(body))/function(k,a,v) + local n=0 + if a then + n=#a + local pattern=P(false) + for i=1,n do + pattern=pattern+(P(a[i])*Carg(1))/function(t) return t[i] end + end + pattern=Cs((pattern+P(1))^1) + local p=patterns[k] + if not p then + p={ [0]=false,false,false,false,false,false,false,false,false } + patterns[k]=p + end + p[n]=pattern + end + local d=definitions[k] + if not d then + d={ [0]=false,false,false,false,false,false,false,false,false } + definitions[k]=d + end + d[n]=lpegmatch(subparser,v) or v + return "" +end +local unregister=(C(name)*spaces^0*(arguments+Cc(false)))/function(k,a) + local n=0 + if a then + n=#a + local p=patterns[k] + if p then + p[n]=false + end + end + local d=definitions[k] + if d then + d[n]=false + end + return "" +end +local begindefine=(P("begindefine")*spaces^0/"")*beginregister +local define=(P("define" )*spaces^0/"")*register +local undefine=(P("undefine" )*spaces^0/"")*unregister +local parser=Cs((((P("#")/"")*(define+begindefine+undefine)*(newline^0/"") )+resolve+P(1) )^0 ) +function macros.reset() + definitions={} + patterns={} +end +function macros.resolvestring(str) + return lpegmatch(parser,str) or str +end +function macros.resolving() + return next(patterns) +end end -- of closure @@ -180,7 +342,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-sandbox"] = package.loaded["l-sandbox"] or true --- original size: 9667, stripped down to: 6678 +-- original size: 9678, stripped down to: 6688 if not modules then modules={} end modules ['l-sandbox']={ version=1.001, @@ -193,7 +355,7 @@ local global=_G local next=next local unpack=unpack or table.unpack local type=type -local tprint=texio.write_nl or print +local tprint=texio and texio.write_nl or print local tostring=tostring local format=string.format local concat=table.concat @@ -447,7 +609,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-package"] = package.loaded["l-package"] or true --- original size: 10587, stripped down to: 7815 +-- original size: 11564, stripped down to: 8625 if not modules then modules={} end modules ['l-package']={ version=1.001, @@ -461,6 +623,7 @@ local gsub,format,find=string.gsub,string.format,string.find local P,S,Cs,lpegmatch=lpeg.P,lpeg.S,lpeg.Cs,lpeg.match local package=package local searchers=package.searchers or package.loaders +local insert,remove=table.insert,table.remove local filejoin=file and file.join or function(path,name) return path.."/"..name end local isreadable=file and file.is_readable or function(name) local f=io.open(name) if f then f:close() return true end end local addsuffix=file and file.addsuffix or function(name,suffix) return name.."."..suffix end @@ -594,15 +757,43 @@ local function registerpath(tag,what,target,...) add(path) end end - return paths +end +local function pushpath(tag,what,target,path) + local path=helpers.cleanpath(path) + insert(target,1,path) + if helpers.trace then + helpers.report("pushing %s path in front: %s",tag,path) + end +end +local function poppath(tag,what,target) + local path=remove(target,1) + if helpers.trace then + if path then + helpers.report("popping %s path from front: %s",tag,path) + else + helpers.report("no %s path to pop",tag) + end + end end helpers.registerpath=registerpath function package.extraluapath(...) registerpath("extra lua","lua",extraluapaths,...) end +function package.pushluapath(path) + pushpath("extra lua","lua",extraluapaths,path) +end +function package.popluapath() + poppath("extra lua","lua",extraluapaths) +end function package.extralibpath(...) registerpath("extra lib","lib",extralibpaths,...) end +function package.pushlibpath(path) + pushpath("extra lib","lib",extralibpaths,path) +end +function package.poplibpath() + poppath("extra lib","lua",extralibpaths) +end local function loadedaslib(resolved,rawname) local base=gsub(rawname,"%.","_") local init="luaopen_"..gsub(base,"%.","_") @@ -737,7 +928,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-lpeg"] = package.loaded["l-lpeg"] or true --- original size: 37748, stripped down to: 20111 +-- original size: 38582, stripped down to: 20518 if not modules then modules={} end modules ['l-lpeg']={ version=1.001, @@ -746,7 +937,8 @@ if not modules then modules={} end modules ['l-lpeg']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -lpeg=require("lpeg") +lpeg=require("lpeg") +local lpeg=lpeg if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end local type,next,tostring=type,next,tostring local byte,char,gmatch,format=string.byte,string.char,string.gmatch,string.format @@ -768,11 +960,14 @@ patterns.alwaysmatched=alwaysmatched local sign=S('+-') local zero=P('0') local digit=R('09') +local digits=digit^1 local octdigit=R("07") +local octdigits=octdigit^1 local lowercase=R("az") local uppercase=R("AZ") local underscore=P("_") local hexdigit=digit+lowercase+uppercase +local hexdigits=hexdigit^1 local cr,lf,crlf=P("\r"),P("\n"),P("\r\n") local newline=P("\r")*(P("\n")+P(true))+P("\n") local escaped=P("\\")*anything @@ -874,27 +1069,30 @@ patterns.singlequoted=squote*patterns.nosquote*squote patterns.doublequoted=dquote*patterns.nodquote*dquote patterns.quoted=patterns.doublequoted+patterns.singlequoted patterns.digit=digit +patterns.digits=digits patterns.octdigit=octdigit +patterns.octdigits=octdigits patterns.hexdigit=hexdigit +patterns.hexdigits=hexdigits patterns.sign=sign -patterns.cardinal=digit^1 -patterns.integer=sign^-1*digit^1 -patterns.unsigned=digit^0*period*digit^1 +patterns.cardinal=digits +patterns.integer=sign^-1*digits +patterns.unsigned=digit^0*period*digits patterns.float=sign^-1*patterns.unsigned -patterns.cunsigned=digit^0*comma*digit^1 -patterns.cpunsigned=digit^0*(period+comma)*digit^1 +patterns.cunsigned=digit^0*comma*digits +patterns.cpunsigned=digit^0*(period+comma)*digits patterns.cfloat=sign^-1*patterns.cunsigned patterns.cpfloat=sign^-1*patterns.cpunsigned patterns.number=patterns.float+patterns.integer patterns.cnumber=patterns.cfloat+patterns.integer patterns.cpnumber=patterns.cpfloat+patterns.integer -patterns.oct=zero*octdigit^1 +patterns.oct=zero*octdigits patterns.octal=patterns.oct patterns.HEX=zero*P("X")*(digit+uppercase)^1 patterns.hex=zero*P("x")*(digit+lowercase)^1 -patterns.hexadecimal=zero*S("xX")*hexdigit^1 -patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigit^1+hexdigit^1*period*hexdigit^0+hexdigit^1)*(S("pP")*sign^-1*hexdigit^1)^-1 -patterns.decafloat=sign^-1*(digit^0*period*digit^1+digit^1*period*digit^0+digit^1)*S("eE")*sign^-1*digit^1 +patterns.hexadecimal=zero*S("xX")*hexdigits +patterns.hexafloat=sign^-1*zero*S("xX")*(hexdigit^0*period*hexdigits+hexdigits*period*hexdigit^0+hexdigits)*(S("pP")*sign^-1*hexdigits)^-1 +patterns.decafloat=sign^-1*(digit^0*period*digits+digits*period*digit^0+digits)*S("eE")*sign^-1*digits patterns.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring patterns.somecontent=(anything-newline-space)^1 patterns.beginline=#(1-newline) @@ -1141,11 +1339,13 @@ function lpeg.balancer(left,right) left,right=P(left),P(right) return P { left*((1-left-right)+V(1))^0*right } end -local nany=utf8char/"" -function lpeg.counter(pattern) - pattern=Cs((P(pattern)/" "+nany)^0) - return function(str) - return #lpegmatch(pattern,str) +function lpeg.counter(pattern,action) + local n=0 + local pattern=(P(pattern)/function() n=n+1 end+anything)^0 + if action then + return function(str) n=0;lpegmatch(pattern,str);action(n) end + else + return function(str) n=0;lpegmatch(pattern,str);return n end end end utf=utf or (unicode and unicode.utf8) or {} @@ -1306,7 +1506,13 @@ function lpeg.append(list,pp,delayed,checked) end local p_false=P(false) local p_true=P(true) -local function make(t,rest) +local lower=utf and utf.lower or string.lower +local upper=utf and utf.upper or string.upper +function lpeg.setutfcasers(l,u) + lower=l or lower + upper=u or upper +end +local function make1(t,rest) local p=p_false local keys=sortedkeys(t) for i=1,#keys do @@ -1317,7 +1523,7 @@ local function make(t,rest) p=p+P(k)*p_true elseif v==false then else - p=p+P(k)*make(v,v[""]) + p=p+P(k)*make1(v,v[""]) end end end @@ -1326,32 +1532,27 @@ local function make(t,rest) end return p end -local function collapse(t,x) - if type(t)~="table" then - return t,x - else - local n=next(t) - if n==nil then - return t,x - elseif next(t,n)==nil then - local k=n +local function make2(t,rest) + local p=p_false + local keys=sortedkeys(t) + for i=1,#keys do + local k=keys[i] + if k~="" then local v=t[k] - if type(v)=="table" then - return collapse(v,x..k) + if v==true then + p=p+(P(lower(k))+P(upper(k)))*p_true + elseif v==false then else - return v,x..k + p=p+(P(lower(k))+P(upper(k)))*make2(v,v[""]) end - else - local tt={} - for k,v in next,t do - local vv,kk=collapse(v,k) - tt[kk]=vv - end - return tt,x end end + if rest then + p=p+p_true + end + return p end -function lpeg.utfchartabletopattern(list) +function lpeg.utfchartabletopattern(list,insensitive) local tree={} local n=#list if n==0 then @@ -1422,7 +1623,7 @@ function lpeg.utfchartabletopattern(list) end end end - return make(tree) + return (insensitive and make2 or make1)(tree) end patterns.containseol=lpeg.finder(eol) local function nextstep(n,step,result) @@ -1456,7 +1657,7 @@ end local trailingzeros=zero^0*-digit local case_1=period*trailingzeros/"" local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"") -local number=digit^1*(case_1+case_2) +local number=digits*(case_1+case_2) local stripper=Cs((number+1)^0) lpeg.patterns.stripzeros=stripper local byte_to_HEX={} @@ -1545,7 +1746,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-string"] = package.loaded["l-string"] or true --- original size: 6419, stripped down to: 3339 +-- original size: 6461, stripped down to: 3341 if not modules then modules={} end modules ['l-string']={ version=1.001, @@ -1647,9 +1848,9 @@ function string.tformat(fmt,...) end string.quote=string.quoted string.unquote=string.unquoted -if not string.bytetable then +if not string.bytetable then local limit=5000 - function string.bytetable(str) + function string.bytetable(str) local n=#str if n>limit then local t={ byte(str,1,limit) } @@ -1670,7 +1871,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-table"] = package.loaded["l-table"] or true --- original size: 39608, stripped down to: 23165 +-- original size: 40161, stripped down to: 23559 if not modules then modules={} end modules ['l-table']={ version=1.001, @@ -1679,7 +1880,7 @@ if not modules then modules={} end modules ['l-table']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local type,next,tostring,tonumber,ipairs,select=type,next,tostring,tonumber,ipairs,select +local type,next,tostring,tonumber,select=type,next,tostring,tonumber,select local table,string=table,string local concat,sort,insert,remove=table.concat,table.sort,table.insert,table.remove local format,lower,dump=string.format,string.lower,string.dump @@ -1688,6 +1889,9 @@ local getinfo=debug.getinfo local lpegmatch,patterns=lpeg.match,lpeg.patterns local floor=math.floor local stripper=patterns.stripper +function table.getn(t) + return t and #t +end function table.strip(tab) local lst,l={},0 for i=1,#tab do @@ -1981,7 +2185,7 @@ function table.tohash(t,value) local h={} if t then if value==nil then value=true end - for _,v in next,t do + for _,v in next,t do h[v]=value end end @@ -1989,7 +2193,7 @@ function table.tohash(t,value) end function table.fromhash(t) local hsh,h={},0 - for k,v in next,t do + for k,v in next,t do if v then h=h+1 hsh[h]=k @@ -2464,7 +2668,9 @@ function table.unnest(t) return unnest(t) end local function are_equal(a,b,n,m) - if a and b and #a==#b then + if a==b then + return true + elseif a and b and #a==#b then n=n or 1 m=m or #a for i=n,m do @@ -2484,15 +2690,17 @@ local function are_equal(a,b,n,m) end end local function identical(a,b) - for ka,va in next,a do - local vb=b[ka] - if va==vb then - elseif type(va)=="table" and type(vb)=="table" then - if not identical(va,vb) then + if a~=b then + for ka,va in next,a do + local vb=b[ka] + if va==vb then + elseif type(va)=="table" and type(vb)=="table" then + if not identical(va,vb) then + return false + end + else return false end - else - return false end end return true @@ -2714,6 +2922,24 @@ function table.filtered(t,pattern,sort,cmp) return nothing end end +if not table.move then + function table.move(a1,f,e,t,a2) + if a2 and a1~=a2 then + for i=f,e do + a2[t]=a1[i] + t=t+1 + end + return a2 + else + t=t+e-f + for i=e,f,-1 do + a1[t]=a1[i] + t=t-1 + end + return a1 + end + end +end end -- of closure @@ -2722,7 +2948,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-io"] = package.loaded["l-io"] or true --- original size: 11790, stripped down to: 6961 +-- original size: 11823, stripped down to: 6945 if not modules then modules={} end modules ['l-io']={ version=1.001, @@ -2735,16 +2961,15 @@ local io=io local open,flush,write,read=io.open,io.flush,io.write,io.read local byte,find,gsub,format=string.byte,string.find,string.gsub,string.format local concat=table.concat -local floor=math.floor local type=type if string.find(os.getenv("PATH"),";",1,true) then io.fileseparator,io.pathseparator="\\",";" else io.fileseparator,io.pathseparator="/",":" end -local large=2^24 -local medium=large/16 -local small=medium/8 +local large=0x01000000 +local medium=0x00100000 +local small=0x00020000 local function readall(f) local size=f:seek("end") if size>0 then @@ -3075,7 +3300,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-number"] = package.loaded["l-number"] or true --- original size: 5358, stripped down to: 3177 +-- original size: 5645, stripped down to: 2253 if not modules then modules={} end modules ['l-number']={ version=1.001, @@ -3091,33 +3316,6 @@ local lpegmatch=lpeg.match local floor=math.floor number=number or {} local number=number -if bit32 then - local btest,bor=bit32.btest,bit32.bor - function number.bit(p) - return 2^(p-1) - end - number.hasbit=btest - number.setbit=bor - function number.setbit(x,p) - return btest(x,p) and x or x+p - end - function number.clearbit(x,p) - return btest(x,p) and x-p or x - end -else - function number.bit(p) - return 2^(p-1) - end - function number.hasbit(x,p) - return x%(p+p)>=p - end - function number.setbit(x,p) - return (x%(p+p)>=p) and x or x+p - end - function number.clearbit(x,p) - return (x%(p+p)>=p) and x-p or x - end -end if bit32 then local bextract=bit32.extract local t={ @@ -3193,26 +3391,6 @@ function number.toevenhex(n) return "0"..s end end -local one=lpeg.C(1-lpeg.S('')/tonumber)^1 -function number.toset(n) - return lpegmatch(one,tostring(n)) -end -local function bits(n,i,...) - if n>0 then - local m=n%2 - local n=floor(n/2) - if m>0 then - return bits(n,i+1,i,...) - else - return bits(n,i+1,...) - end - else - return... - end -end -function number.bits(n) - return { bits(n,1) } -end function number.bytetodecimal(b) local d=floor(b*100/255+0.5) if d>100 then @@ -3689,7 +3867,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-file"] = package.loaded["l-file"] or true --- original size: 20997, stripped down to: 9986 +-- original size: 21616, stripped down to: 10359 if not modules then modules={} end modules ['l-file']={ version=1.001, @@ -3725,6 +3903,9 @@ end function lfs.isfile(name) return attributes(name,"mode")=="file" end +function lfs.isfound(name) + return attributes(name,"mode")=="file" and name or nil +end local colon=P(":") local period=P(".") local periods=P("..") @@ -4063,6 +4244,23 @@ function lfs.mkdirs(path) lfs.mkdir(full) end end +function file.withinbase(path) + local l=0 + if not find(path,"^/") then + path="/"..path + end + for dir in gmatch(path,"/([^/]+)") do + if dir==".." then + l=l-1 + elseif dir~="." then + l=l+1 + end + if l<0 then + return false + end + end + return true +end end -- of closure @@ -4215,7 +4413,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-url"] = package.loaded["l-url"] or true --- original size: 12531, stripped down to: 5721 +-- original size: 14755, stripped down to: 7236 if not modules then modules={} end modules ['l-url']={ version=1.001, @@ -4226,24 +4424,51 @@ if not modules then modules={} end modules ['l-url']={ } local char,format,byte=string.char,string.format,string.byte local concat=table.concat -local tonumber,type=tonumber,type +local tonumber,type,next=tonumber,type,next local P,C,R,S,Cs,Cc,Ct,Cf,Cg,V=lpeg.P,lpeg.C,lpeg.R,lpeg.S,lpeg.Cs,lpeg.Cc,lpeg.Ct,lpeg.Cf,lpeg.Cg,lpeg.V local lpegmatch,lpegpatterns,replacer=lpeg.match,lpeg.patterns,lpeg.replacer +local sortedhash=table.sortedhash url=url or {} local url=url -local tochar=function(s) return char(tonumber(s,16)) end +local unescapes={} +local escapes={} +setmetatable(unescapes,{ __index=function(t,k) + local v=char(tonumber(k,16)) + t[k]=v + return v +end }) +setmetatable(escapes,{ __index=function(t,k) + local v=format("%%%02X",byte(k)) + t[k]=v + return v +end }) local colon=P(":") local qmark=P("?") local hash=P("#") local slash=P("/") +local atsign=P("@") local percent=P("%") local endofstring=P(-1) local hexdigit=R("09","AF","af") local plus=P("+") local nothing=Cc("") -local escapedchar=(percent*C(hexdigit*hexdigit))/tochar +local okay=R("09","AZ","az")+S("-_.,:=+*~!'()@&$") +local escapedchar=(percent*C(hexdigit*hexdigit))/unescapes +local unescapedchar=P(1)/escapes local escaped=(plus/" ")+escapedchar local noslash=P("/")/"" +local plustospace=P("+")/" " +local decoder=Cs(( + plustospace+escapedchar+P("\r\n")/"\n"+P(1) + )^0 ) +local encoder=Cs(( + R("09","AZ","az")^1+S("-./_")^1+P(" ")/"+"+P("\n")/"\r\n"+unescapedchar + )^0 ) +lpegpatterns.urldecoder=decoder +lpegpatterns.urlencoder=encoder +function url.decode (str) return str and lpegmatch(decoder,str) or str end +function url.encode (str) return str and lpegmatch(encoder,str) or str end +function url.unescape(str) return str and lpegmatch(unescaper,str) or str end local schemestr=Cs((escaped+(1-colon-slash-qmark-hash))^2) local authoritystr=Cs((escaped+(1- slash-qmark-hash))^0) local pathstr=Cs((escaped+(1- qmark-hash))^0) @@ -4258,13 +4483,7 @@ local validurl=scheme*authority*path*query*fragment local parser=Ct(validurl) lpegpatterns.url=validurl lpegpatterns.urlsplitter=parser -local escapes={} -setmetatable(escapes,{ __index=function(t,k) - local v=format("%%%02X",byte(k)) - t[k]=v - return v -end }) -local escaper=Cs((R("09","AZ","az")^1+P(" ")/"%%20"+S("-./_")^1+P(1)/escapes)^0) +local escaper=Cs((R("09","AZ","az")^1+P(" ")/"%%20"+S("-./_:")^1+P(1)/escapes)^0) local unescaper=Cs((escapedchar+1)^0) local getcleaner=Cs((P("+++")/"%%2B"+P("+")/"%%20"+P(1))^1) lpegpatterns.urlunescaped=escapedchar @@ -4294,12 +4513,15 @@ local barswapper=replacer("|",":") local backslashswapper=replacer("\\","/") local equal=P("=") local amp=P("&") -local key=Cs(((escapedchar+1)-equal )^0) -local value=Cs(((escapedchar+1)-amp -endofstring)^0) +local key=Cs(((plustospace+escapedchar+1)-equal )^0) +local value=Cs(((plustospace+escapedchar+1)-amp-endofstring)^0) local splitquery=Cf (Ct("")*P { "sequence", sequence=V("pair")*(amp*V("pair"))^0, pair=Cg(key*equal*value), },rawset) +local userpart=(1-atsign-colon)^1 +local serverpart=(1-colon)^1 +local splitauthority=((Cs(userpart)*colon*Cs(userpart)+Cs(userpart)*Cc(nil))*atsign+Cc(nil)*Cc(nil))*Cs(serverpart)*(colon*(serverpart/tonumber)+Cc(nil)) local function hashed(str) if not str or str=="" then return { @@ -4332,7 +4554,14 @@ local function hashed(str) end local authority=detailed[2] local path=detailed[3] - local filename=nil + local filename + local username + local password + local host + local port + if authority~="" then + username,password,host,port=lpegmatch(splitauthority,authority) + end if authority=="" then filename=path elseif path=="" then @@ -4350,6 +4579,8 @@ local function hashed(str) original=str, noscheme=false, filename=filename, + host=host, + port=port, } end url.split=split @@ -4365,24 +4596,38 @@ function url.addscheme(str,scheme) end end function url.construct(hash) - local fullurl,f={},0 - local scheme,authority,path,query,fragment=hash.scheme,hash.authority,hash.path,hash.query,hash.fragment + local result,r={},0 + local scheme=hash.scheme + local authority=hash.authority + local path=hash.path + local queries=hash.queries + local fragment=hash.fragment if scheme and scheme~="" then - f=f+1;fullurl[f]=scheme.."://" + r=r+1;result[r]=lpegmatch(escaper,scheme) + r=r+1;result[r]="://" end if authority and authority~="" then - f=f+1;fullurl[f]=authority + r=r+1;result[r]=lpegmatch(escaper,authority) end if path and path~="" then - f=f+1;fullurl[f]="/"..path + r=r+1;result[r]="/" + r=r+1;result[r]=lpegmatch(escaper,path) end - if query and query~="" then - f=f+1;fullurl[f]="?"..query + if queries then + local done=false + for k,v in sortedhash(queries) do + r=r+1;result[r]=done and "&" or "?" + r=r+1;result[r]=lpegmatch(escaper,k) + r=r+1;result[r]="=" + r=r+1;result[r]=lpegmatch(escaper,v) + done=true + end end if fragment and fragment~="" then - f=f+1;fullurl[f]="#"..fragment + r=r+1;result[r]="#" + r=r+1;result[r]=lpegmatch(escaper,fragment) end - return lpegmatch(escaper,concat(fullurl)) + return concat(result) end local pattern=Cs(slash^-1/""*R("az","AZ")*((S(":|")/":")+P(":"))*slash*P(1)^0) function url.filename(filename) @@ -4998,7 +5243,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-unicode"] = package.loaded["l-unicode"] or true --- original size: 38263, stripped down to: 16330 +-- original size: 40036, stripped down to: 17837 if not modules then modules={} end modules ['l-unicode']={ version=1.001, @@ -5034,37 +5279,73 @@ if not unicode then unicode={ utf=utf } end if not utf.char then - local floor,char=math.floor,string.char - function utf.char(n) - if n<0x80 then - return char(n) - elseif n<0x800 then - return char( - 0xC0+floor(n/0x40), - 0x80+(n%0x40) - ) - elseif n<0x10000 then - return char( - 0xE0+floor(n/0x1000), - 0x80+(floor(n/0x40)%0x40), - 0x80+(n%0x40) - ) - elseif n<0x200000 then - return char( - 0xF0+floor(n/0x40000), - 0x80+(floor(n/0x1000)%0x40), - 0x80+(floor(n/0x40)%0x40), - 0x80+(n%0x40) - ) + utf.char=string.utfcharacter or (utf8 and utf8.char) + if not utf.char then + local char=string.char + if bit32 then + local rshift=bit32.rshift + function utf.char(n) + if n<0x80 then + return char(n) + elseif n<0x800 then + return char( + 0xC0+rshift(n,6), + 0x80+(n%0x40) + ) + elseif n<0x10000 then + return char( + 0xE0+rshift(n,12), + 0x80+(rshift(n,6)%0x40), + 0x80+(n%0x40) + ) + elseif n<0x200000 then + return char( + 0xF0+rshift(n,18), + 0x80+(rshift(n,12)%0x40), + 0x80+(rshift(n,6)%0x40), + 0x80+(n%0x40) + ) + else + return "" + end + end else - return "" + local floor=math.floor + function utf.char(n) + if n<0x80 then + return char(n) + elseif n<0x800 then + return char( + 0xC0+floor(n/0x40), + 0x80+(n%0x40) + ) + elseif n<0x10000 then + return char( + 0xE0+floor(n/0x1000), + 0x80+(floor(n/0x40)%0x40), + 0x80+(n%0x40) + ) + elseif n<0x200000 then + return char( + 0xF0+floor(n/0x40000), + 0x80+(floor(n/0x1000)%0x40), + 0x80+(floor(n/0x40)%0x40), + 0x80+(n%0x40) + ) + else + return "" + end + end end end end if not utf.byte then - local utf8byte=patterns.utf8byte - function utf.byte(c) - return lpegmatch(utf8byte,c) + utf.byte=string.utfvalue or (utf8 and utf8.codepoint) + if not utf.byte then + local utf8byte=patterns.utf8byte + function utf.byte(c) + return lpegmatch(utf8byte,c) + end end end local utfchar,utfbyte=utf.char,utf.byte @@ -5115,19 +5396,22 @@ function utf.is_valid(str) return type(str)=="string" and lpegmatch(validatedutf,str) or false end if not utf.len then - local n,f=0,1 - local utfcharcounter=patterns.utfbom^-1*Cmt ( - Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1, - function(_,t,d) - n=n+(t-f)/d - f=t - return true + utf.len=string.utflength or (utf8 and utf8.len) + if not utf.len then + local n,f=0,1 + local utfcharcounter=patterns.utfbom^-1*Cmt ( + Cc(1)*patterns.utf8one^1+Cc(2)*patterns.utf8two^1+Cc(3)*patterns.utf8three^1+Cc(4)*patterns.utf8four^1, + function(_,t,d) + n=n+(t-f)/d + f=t + return true + end + )^0 + function utf.len(str) + n,f=0,1 + lpegmatch(utfcharcounter,str or "") + return n end - )^0 - function utf.len(str) - n,f=0,1 - lpegmatch(utfcharcounter,str or "") - return n end end utf.length=utf.len @@ -5475,20 +5759,22 @@ function utf.utf32_to_utf8_t(t,endian) end local function little(b) if b<0x10000 then - return char(b%256,b/256) + return char(b%256,rshift(b,8)) else b=b-0x10000 - local b1,b2=b/1024+0xD800,b%1024+0xDC00 - return char(b1%256,b1/256,b2%256,b2/256) + local b1=rshift(b,10)+0xD800 + local b2=b%1024+0xDC00 + return char(b1%256,rshift(b1,8),b2%256,rshift(b2,8)) end end local function big(b) if b<0x10000 then - return char(b/256,b%256) + return char(rshift(b,8),b%256) else b=b-0x10000 - local b1,b2=b/1024+0xD800,b%1024+0xDC00 - return char(b1/256,b1%256,b2/256,b2%256) + local b1=rshift(b,10)+0xD800 + local b2=b%1024+0xDC00 + return char(rshift(b1,8),b1%256,rshift(b2,8),b2%256) end end local l_remap=Cs((p_utf8byte/little+P(1)/"")^0) @@ -5609,22 +5895,43 @@ function utf.chrlen(u) (u<0xFC and 5) or (u<0xFE and 6) or 0 end -local extract=bit32.extract -local char=string.char -function unicode.toutf32string(n) - if n<=0xFF then - return - char(n).."\000\000\000" - elseif n<=0xFFFF then - return - char(extract(n,0,8))..char(extract(n,8,8)).."\000\000" - elseif n<=0xFFFFFF then - return - char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000" - else - return - char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8)) +if bit32 then + local extract=bit32.extract + local char=string.char + function unicode.toutf32string(n) + if n<=0xFF then + return + char(n).."\000\000\000" + elseif n<=0xFFFF then + return + char(extract(n,0,8))..char(extract(n,8,8)).."\000\000" + elseif n<=0xFFFFFF then + return + char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8)).."\000" + else + return + char(extract(n,0,8))..char(extract(n,8,8))..char(extract(n,16,8))..char(extract(n,24,8)) + end + end +end +local len=utf.len +local rep=rep +function string.utfpadd(s,n) + if n and n~=0 then + local l=len(s) + if n>0 then + local d=n-l + if d>0 then + return rep(c or " ",d)..s + end + else + local d=- n-l + if d>0 then + return s..rep(c or " ",d) + end + end end + return s end @@ -5634,7 +5941,7 @@ do -- create closure to overcome 200 locals limit package.loaded["l-math"] = package.loaded["l-math"] or true --- original size: 974, stripped down to: 890 +-- original size: 2555, stripped down to: 1900 if not modules then modules={} end modules ['l-math']={ version=1.001, @@ -5643,21 +5950,23 @@ if not modules then modules={} end modules ['l-math']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local floor,sin,cos,tan=math.floor,math.sin,math.cos,math.tan if not math.ceiling then math.ceiling=math.ceil end if not math.round then + local floor=math.floor function math.round(x) return floor(x+0.5) end end if not math.div then + local floor=math.floor function math.div(n,m) return floor(n/m) end end if not math.mod then function math.mod(n,m) return n%m end end -local pipi=2*math.pi/360 if not math.sind then + local sin,cos,tan=math.sin,math.cos,math.tan + local pipi=2*math.pi/360 function math.sind(d) return sin(d*pipi) end function math.cosd(d) return cos(d*pipi) end function math.tand(d) return tan(d*pipi) end @@ -5666,6 +5975,60 @@ if not math.odd then function math.odd (n) return n%2~=0 end function math.even(n) return n%2==0 end end +if not math.cosh then + local exp=math.exp + function math.cosh(x) + local xx=exp(x) + return (xx+1/xx)/2 + end + function math.sinh(x) + local xx=exp(x) + return (xx-1/xx)/2 + end + function math.tanh(x) + local xx=exp(x) + return (xx-1/xx)/(xx+1/xx) + end +end +if not math.pow then + function math.pow(x,y) + return x^y + end +end +if not math.atan2 then + math.atan2=math.atan +end +if not math.ldexp then + function math.ldexp(x,e) + return x*2.0^e + end +end +if not math.log10 then + local log=math.log + function math.log10(x) + return log(x,10) + end +end +if not math.type then + function math.type() + return "float" + end +end +if not math.tointeger then + math.mininteger=-0x4FFFFFFFFFFF + math.maxinteger=0x4FFFFFFFFFFF + local floor=math.floor + function math.tointeger(n) + local f=floor(n) + return f==n and f or nil + end +end +if not math.ult then + local floor=math.floor + function math.tointeger(m,n) + return floor(m)<floor(n) + end +end end -- of closure @@ -5674,7 +6037,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-str"] = package.loaded["util-str"] or true --- original size: 36148, stripped down to: 20179 +-- original size: 38725, stripped down to: 21726 if not modules then modules={} end modules ['util-str']={ version=1.001, @@ -5688,13 +6051,13 @@ utilities.strings=utilities.strings or {} local strings=utilities.strings local format,gsub,rep,sub,find=string.format,string.gsub,string.rep,string.sub,string.find local load,dump=load,string.dump -local tonumber,type,tostring=tonumber,type,tostring +local tonumber,type,tostring,next=tonumber,type,tostring,next local unpack,concat=table.unpack,table.concat local P,V,C,S,R,Ct,Cs,Cp,Carg,Cc=lpeg.P,lpeg.V,lpeg.C,lpeg.S,lpeg.R,lpeg.Ct,lpeg.Cs,lpeg.Cp,lpeg.Carg,lpeg.Cc local patterns,lpegmatch=lpeg.patterns,lpeg.match -local utfchar,utfbyte=utf.char,utf.byte +local utfchar,utfbyte,utflen=utf.char,utf.byte,utf.len local loadstripped=nil -if _LUAVERSION<5.2 then +if LUAVERSION<5.2 then loadstripped=function(str,shortcuts) return load(str) end @@ -5782,6 +6145,17 @@ local pattern=Carg(1)/function(t) function strings.tabtospace(str,tab) return lpegmatch(pattern,str,1,tab or 7) end +function string.utfpadding(s,n) + if not n or n==0 then + return "" + end + local l=utflen(s) + if n>0 then + return nspaces[n-l] + else + return nspaces[-n-l] + end +end local space=spacer^0 local nospace=space/"" local endofline=nospace*newline @@ -5888,6 +6262,21 @@ function number.formatted(n,sep1,sep2) return lpegmatch(splitter,s,1,sep1 or ",",sep2 or ".") end end +local p=Cs( + P("-")^0*(P("0")^1/"")^0*(1-P("."))^0*(P(".")*P("0")^1*P(-1)/""+P(".")^0)*P(1-P("0")^1*P(-1))^0 + ) +function number.compactfloat(n,fmt) + if n==0 then + return "0" + elseif n==1 then + return "1" + end + n=lpegmatch(p,format(fmt or "%0.3f",n)) + if n=="." or n=="" or n=="-" then + return "0" + end + return n +end local zero=P("0")^1/"" local plus=P("+")/"" local minus=P("-") @@ -5940,7 +6329,7 @@ local template=[[ return function(%s) return %s end ]] local preamble,environment="",{} -if _LUAVERSION<5.2 then +if LUAVERSION<5.2 then preamble=[[ local lpeg=lpeg local type=type @@ -5955,6 +6344,7 @@ local utfchar=utf.char local utfbyte=utf.byte local lpegmatch=lpeg.match local nspaces=string.nspaces +local utfpadding=string.utfpadding local tracedchar=string.tracedchar local autosingle=string.autosingle local autodouble=string.autodouble @@ -5979,6 +6369,7 @@ else utfbyte=utf.byte, lpegmatch=lpeg.match, nspaces=string.nspaces, + utfpadding=string.utfpadding, tracedchar=string.tracedchar, autosingle=string.autosingle, autodouble=string.autodouble, @@ -6014,9 +6405,32 @@ local format_S=function(f) return format("tostring(a%s)",n) end end +local format_right=function(f) + n=n+1 + f=tonumber(f) + if not f or f==0 then + return format("(a%s or '')",n) + elseif f>0 then + return format("utfpadding(a%s,%i)..a%s",n,f,n) + else + return format("a%s..utfpadding(a%s,%i)",n,n,f) + end +end +local format_left=function(f) + n=n+1 + f=tonumber(f) + if not f or f==0 then + return format("(a%s or '')",n) + end + if f<0 then + return format("utfpadding(a%s,%i)..a%s",n,-f,n) + else + return format("a%s..utfpadding(a%s,%i)",n,n,-f) + end +end local format_q=function() n=n+1 - return format("(a%s and format('%%q',a%s) or '')",n,n) + return format("(a%s ~= nil and format('%%q',tostring(a%s)) or '')",n,n) end local format_Q=function() n=n+1 @@ -6268,6 +6682,8 @@ local builder=Cs { "start", +V("j")+V("J") +V("m")+V("M") +V("z") ++V(">") ++V("<") )+V("*") )*(P(-1)+Carg(1)) )^0, @@ -6285,7 +6701,7 @@ local builder=Cs { "start", ["X"]=(prefix_any*P("X"))/format_X, ["o"]=(prefix_any*P("o"))/format_o, ["S"]=(prefix_any*P("S"))/format_S, - ["Q"]=(prefix_any*P("Q"))/format_S, + ["Q"]=(prefix_any*P("Q"))/format_Q, ["N"]=(prefix_any*P("N"))/format_N, ["k"]=(prefix_sub*P("k"))/format_k, ["c"]=(prefix_any*P("c"))/format_c, @@ -6311,6 +6727,8 @@ local builder=Cs { "start", ["z"]=(prefix_any*P("z"))/format_z, ["a"]=(prefix_any*P("a"))/format_a, ["A"]=(prefix_any*P("A"))/format_A, + ["<"]=(prefix_any*P("<"))/format_left, + [">"]=(prefix_any*P(">"))/format_right, ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest, ["?"]=Cs(((1-P("%"))^1 )^1)/format_rest, ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, @@ -6341,7 +6759,7 @@ local function use(t,fmt,...) return t[fmt](...) end strings.formatters={} -if _LUAVERSION<5.2 then +if LUAVERSION<5.2 then function strings.formatters.new(noconcat) local t={ _type_="formatter",_connector_=noconcat and "," or "..",_extensions_={},_preamble_=preamble,_environment_={} } setmetatable(t,{ __index=make,__call=use }) @@ -6378,7 +6796,7 @@ patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"" patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) patterns.luaescape=Cs(((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0) patterns.luaquoted=Cs(Cc('"')*((1-S('"\n'))^1+P('"')/'\\"'+P('\n')/'\\n"')^0*Cc('"')) -if _LUAVERSION<5.2 then +if LUAVERSION<5.2 then add(formatters,"xml",[[lpegmatch(xmlescape,%s)]],"local xmlescape = lpeg.patterns.xmlescape") add(formatters,"tex",[[lpegmatch(texescape,%s)]],"local texescape = lpeg.patterns.texescape") add(formatters,"lua",[[lpegmatch(luaescape,%s)]],"local luaescape = lpeg.patterns.luaescape") @@ -6400,6 +6818,21 @@ local pattern=Cs((newline/(os.newline or "\r")+1)^0) function string.replacenewlines(str) return lpegmatch(pattern,str) end +function strings.newcollector() + local result,r={},0 + return + function(fmt,str,...) + r=r+1 + result[r]=str==nil and fmt or formatters[fmt](str,...) + end, + function(connector) + if result then + local str=concat(result,connector) + result,r={},0 + return str + end + end +end end -- of closure @@ -6408,7 +6841,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tab"] = package.loaded["util-tab"] or true --- original size: 27407, stripped down to: 17116 +-- original size: 27665, stripped down to: 17051 if not modules then modules={} end modules ['util-tab']={ version=1.001, @@ -6788,11 +7221,6 @@ function table.drop(t,slow) return fastdrop(t) end end -function table.autokey(t,k) - local v={} - t[k]=v - return v -end local selfmapper={ __index=function(t,k) t[k]=k return k end } function table.twowaymapper(t) if not t then @@ -7037,7 +7465,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-fil"] = package.loaded["util-fil"] or true --- original size: 7567, stripped down to: 5575 +-- original size: 7787, stripped down to: 5858 if not modules then modules={} end modules ['util-fil']={ version=1.001, @@ -7048,8 +7476,6 @@ if not modules then modules={} end modules ['util-fil']={ } local byte=string.byte local char=string.char -local extract=bit32 and bit32.extract -local floor=math.floor utilities=utilities or {} local files={} utilities.files=files @@ -7066,7 +7492,10 @@ function files.close(f) f:close() end function files.size(f) - return f:seek("end") + local current=f:seek() + local size=f:seek("end") + f:seek("set",current) + return size end files.getsize=files.size function files.setposition(f,n) @@ -7216,7 +7645,7 @@ function files.readfixed4(f) return (0x100*a+b )+(0x100*c+d)/0x10000 end end -if extract then +if bit32 then local extract=bit32.extract local band=bit32.band function files.read2dot14(f) @@ -7236,19 +7665,30 @@ end function files.skiplong(f,n) f:read(4*(n or 1)) end -function files.writecardinal2(f,n) - local a=char(n%256) - n=floor(n/256) - local b=char(n%256) - f:write(b,a) +if bit32 then + local rshift=bit32.rshift + function files.writecardinal2(f,n) + local a=char(n%256) + n=rshift(n,8) + local b=char(n%256) + f:write(b,a) + end +else + local floor=math.floor + function files.writecardinal2(f,n) + local a=char(n%256) + n=floor(n/256) + local b=char(n%256) + f:write(b,a) + end end function files.writecardinal4(f,n) local a=char(n%256) - n=floor(n/256) + n=rshift(n,8) local b=char(n%256) - n=floor(n/256) + n=rshift(n,8) local c=char(n%256) - n=floor(n/256) + n=rshift(n,8) local d=char(n%256) f:write(d,c,b,a) end @@ -7267,6 +7707,8 @@ if fio and fio.readcardinal1 then files.readinteger2=fio.readinteger2 files.readinteger3=fio.readinteger3 files.readinteger4=fio.readinteger4 + files.readfixed2=fio.readfixed2 + files.readfixed4=fio.readfixed4 files.read2dot14=fio.read2dot14 files.setposition=fio.setposition files.getposition=fio.getposition @@ -7634,7 +8076,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-sto"] = package.loaded["util-sto"] or true --- original size: 3926, stripped down to: 2742 +-- original size: 6449, stripped down to: 3069 if not modules then modules={} end modules ['util-sto']={ version=1.001, @@ -7643,7 +8085,7 @@ if not modules then modules={} end modules ['util-sto']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local setmetatable,getmetatable,type=setmetatable,getmetatable,type +local setmetatable,getmetatable,rawset,type=setmetatable,getmetatable,rawset,type utilities=utilities or {} utilities.storage=utilities.storage or {} local storage=utilities.storage @@ -7753,6 +8195,25 @@ function table.setmetatablecall(t,f) end return t end +function table.setmetatableindices(t,f,n,c) + if type(t)~="table" then + f,t=t,{} + end + local m=getmetatable(t) + local i=f_index[f] or f + if m then + m.__index=i + m.__newindex=n + m.__call=c + else + setmetatable(t,{ + __index=i, + __newindex=n, + __call=c, + }) + end + return t +end function table.setmetatablekey(t,key,value) local m=getmetatable(t) if not m then @@ -7774,7 +8235,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-prs"] = package.loaded["util-prs"] or true --- original size: 22883, stripped down to: 16045 +-- original size: 22956, stripped down to: 16106 if not modules then modules={} end modules ['util-prs']={ version=1.001, @@ -8192,14 +8653,16 @@ function parsers.rfc4180splitter(specification) local field=escaped+non_escaped+Cc("") local record=Ct(field*(separator*field)^1) local headerline=record*Cp() - local wholeblob=Ct((newline^(specification.strict and -1 or 1)*record)^0) + local morerecords=(newline^(specification.strict and -1 or 1)*record)^0 + local headeryes=Ct(morerecords) + local headernop=Ct(record*morerecords) return function(data,getheader) if getheader then local header,position=lpegmatch(headerline,data) - local data=lpegmatch(wholeblob,data,position) + local data=lpegmatch(headeryes,data,position) return data,header else - return lpegmatch(wholeblob,data) + return lpegmatch(headernop,data) end end end @@ -8220,8 +8683,8 @@ end local cardinal=lpegpatterns.cardinal/tonumber local spacers=lpegpatterns.spacer^0 local endofstring=lpegpatterns.endofstring -local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1 -local stepper=spacers*(C(cardinal)*(spacers*S(":-")*spacers*(C(cardinal)+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring +local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1 +local stepper=spacers*(cardinal*(spacers*S(":-")*spacers*(cardinal+(P("*")+endofstring)*Cc(true) )+Cc(false) )*Carg(1)*Carg(2)/ranger*S(", ")^0 )^1*endofstring function parsers.stepper(str,n,action) if type(n)=="function" then lpegmatch(stepper,str,1,false,n or print) @@ -8408,7 +8871,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-set"] = package.loaded["trac-set"] or true --- original size: 12454, stripped down to: 8840 +-- original size: 13044, stripped down to: 9231 if not modules then modules={} end modules ['trac-set']={ version=1.001, @@ -8417,8 +8880,8 @@ if not modules then modules={} end modules ['trac-set']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local type,next,tostring=type,next,tostring -local concat=table.concat +local type,next,tostring,tonumber=type,next,tostring,tonumber +local concat,sortedhash=table.concat,table.sortedhash local format,find,lower,gsub,topattern=string.format,string.find,string.lower,string.gsub,string.topattern local is_boolean=string.is_boolean local settings_to_hash=utilities.parsers.settings_to_hash @@ -8435,7 +8898,7 @@ function setters.initialize(filename,name,values) frozen=true local data=setter.data if data then - for key,newvalue in next,values do + for key,newvalue in sortedhash(values) do local newvalue=is_boolean(newvalue,newvalue,true) local functions=data[key] if functions then @@ -8484,7 +8947,7 @@ local function set(t,what,newvalue) done={} t.done=done end - for w,value in next,what do + for w,value in sortedhash(what) do if value=="" then value=newvalue elseif not value then @@ -8493,7 +8956,7 @@ local function set(t,what,newvalue) value=is_boolean(value,value,true) end w=topattern(w,true,true) - for name,functions in next,data do + for name,functions in sortedhash(data) do if done[name] then elseif find(name,w) then done[name]=true @@ -8509,7 +8972,7 @@ end local function reset(t) local data=t.data if not data.frozen then - for name,functions in next,data do + for name,functions in sortedthash(data) do for i=1,#functions do functions[i](false) end @@ -8600,13 +9063,30 @@ function setters.show(t) local name=list[k] local functions=t.data[name] if functions then - local value,default,modules=functions.value,functions.default,#functions - value=value==nil and "unset" or tostring(value) - default=default==nil and "unset" or tostring(default) - t.report("%-50s modules: %2i default: %-12s value: %-12s",name,modules,default,value) + local value=functions.value + local default=functions.default + local modules=#functions + if default==nil then + default="unset" + elseif type(default)=="table" then + default=concat(default,"|") + else + default=tostring(default) + end + if value==nil then + value="unset" + elseif type(value)=="table" then + value=concat(value,"|") + else + value=tostring(value) + end + t.report(name) + t.report(" modules : %i",modules) + t.report(" default : %s",default) + t.report(" value : %s",value) + t.report() end end - t.report() end local enable,disable,register,list,show=setters.enable,setters.disable,setters.register,setters.list,setters.show function setters.report(setter,...) @@ -8720,7 +9200,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-log"] = package.loaded["trac-log"] or true --- original size: 30007, stripped down to: 20818 +-- original size: 32737, stripped down to: 22946 if not modules then modules={} end modules ['trac-log']={ version=1.001, @@ -8739,7 +9219,8 @@ local datetime=os.date local openfile=io.open local setmetatableindex=table.setmetatableindex local formatters=string.formatters -local texgetcount=tex and tex.getcount +local settings_to_hash=utilities.parsers.settings_to_hash +local sortedkeys=table.sortedkeys local variant="default" logs=logs or {} local logs=logs @@ -9166,14 +9647,14 @@ logs.direct=direct logs.subdirect=subdirect logs.writer=writer logs.newline=newline -local data,states={},nil +local data={} +local states=nil +local force=false function logs.reporter(category,subcategory) local logger=data[category] if not logger then - local state=false - if states==true then - state=true - elseif type(states)=="table" then + local state=states==true + if not state and type(states)=="table" then for c,_ in next,states do if find(category,c) then state=true @@ -9191,7 +9672,7 @@ function logs.reporter(category,subcategory) if not reporter then if subcategory then reporter=function(...) - if not logger.state then + if force or not logger.state then subreport(category,subcategory,...) end end @@ -9199,7 +9680,7 @@ function logs.reporter(category,subcategory) else local tag=category reporter=function(...) - if not logger.state then + if force or not logger.state then report(category,...) end end @@ -9225,7 +9706,7 @@ function logs.messenger(category,subcategory) end end local function setblocked(category,value) - if category==true then + if category==true or category=="all" then category,value="*",true elseif category==false then category,value="*",false @@ -9238,7 +9719,8 @@ local function setblocked(category,value) v.state=value end else - states=utilities.parsers.settings_to_hash(category,type(states)=="table" and states or nil) + alllocked=false + states=settings_to_hash(category,type(states)=="table" and states or nil) for c in next,states do local v=data[c] if v then @@ -9261,7 +9743,7 @@ function logs.enable(category) setblocked(category,false) end function logs.categories() - return table.sortedkeys(data) + return sortedkeys(data) end function logs.show() local n,c,s,max=0,0,0,0 @@ -9283,7 +9765,7 @@ function logs.show() max=m end end - local subcategories=concat(table.sortedkeys(reporters),", ") + local subcategories=concat(sortedkeys(reporters),", ") if state==true then state="disabled" elseif state==false then @@ -9310,54 +9792,57 @@ end) directives.register("logs.target",function(v) settarget(v) end) -local report_pages=logs.reporter("pages") -local real,user,sub -function logs.start_page_number() - real=texgetcount("realpageno") - user=texgetcount("userpageno") - sub=texgetcount("subpageno") -end -local timing=false -local starttime=nil -local lasttime=nil -trackers.register("pages.timing",function(v) - starttime=os.clock() - timing=true -end) -function logs.stop_page_number() - if timing then - local elapsed,average - local stoptime=os.clock() - if not lasttime or real<2 then - elapsed=stoptime - average=stoptime - starttime=stoptime - else - elapsed=stoptime-lasttime - average=(stoptime-starttime)/(real-1) - end - lasttime=stoptime - if real<=0 then - report_pages("flushing page, time %0.04f / %0.04f",elapsed,average) - elseif user<=0 then - report_pages("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average) - elseif sub<=0 then - report_pages("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average) - else - report_pages("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average) - end - else - if real<=0 then - report_pages("flushing page") - elseif user<=0 then - report_pages("flushing realpage %s",real) - elseif sub<=0 then - report_pages("flushing realpage %s, userpage %s",real,user) +if tex then + local report=logs.reporter("pages") + local texgetcount=tex and tex.getcount + local real,user,sub + function logs.start_page_number() + real=texgetcount("realpageno") + user=texgetcount("userpageno") + sub=texgetcount("subpageno") + end + local timing=false + local starttime=nil + local lasttime=nil + trackers.register("pages.timing",function(v) + starttime=os.clock() + timing=true + end) + function logs.stop_page_number() + if timing then + local elapsed,average + local stoptime=os.clock() + if not lasttime or real<2 then + elapsed=stoptime + average=stoptime + starttime=stoptime + else + elapsed=stoptime-lasttime + average=(stoptime-starttime)/(real-1) + end + lasttime=stoptime + if real<=0 then + report("flushing page, time %0.04f / %0.04f",elapsed,average) + elseif user<=0 then + report("flushing realpage %s, time %0.04f / %0.04f",real,elapsed,average) + elseif sub<=0 then + report("flushing realpage %s, userpage %s, time %0.04f / %0.04f",real,user,elapsed,average) + else + report("flushing realpage %s, userpage %s, subpage %s, time %0.04f / %0.04f",real,user,sub,elapsed,average) + end else - report_pages("flushing realpage %s, userpage %s, subpage %s",real,user,sub) + if real<=0 then + report("flushing page") + elseif user<=0 then + report("flushing realpage %s",real) + elseif sub<=0 then + report("flushing realpage %s, userpage %s",real,user) + else + report("flushing realpage %s, userpage %s, subpage %s",real,user,sub) + end end + logs.flush() end - logs.flush() end local nesting=0 local verbose=false @@ -9512,6 +9997,92 @@ io.stderr:setvbuf('no') if package.helpers.report then package.helpers.report=logs.reporter("package loader") end +if tex then + local finalactions={} + local fatalerrors={} + local possiblefatal={} + local loggingerrors=false + function logs.loggingerrors() + return loggingerrors + end + directives.register("logs.errors",function(v) + loggingerrors=v + if type(v)=="string" then + fatalerrors=settings_to_hash(v) + else + fatalerrors={} + end + end) + function logs.registerfinalactions(...) + insert(finalactions,...) + end + local what=nil + local report=nil + local state=nil + local target=nil + local function startlogging(t,r,w,s) + target=t + state=force + force=true + report=type(r)=="function" and r or logs.reporter(r) + what=w + pushtarget(target) + newline() + if s then + report("start %s: %s",what,s) + else + report("start %s",what) + end + if target=="logfile" then + newline() + end + return report + end + local function stoplogging() + if target=="logfile" then + newline() + end + report("stop %s",what) + if target=="logfile" then + newline() + end + poptarget() + state=oldstate + end + function logs.startfilelogging(...) + return startlogging("logfile",...) + end + logs.stopfilelogging=stoplogging + local done=false + function logs.starterrorlogging(r,w,...) + if not done then + pushtarget("terminal") + newline() + logs.report("error logging","start possible issues") + poptarget() + done=true + end + if fatalerrors[w] then + possiblefatal[w]=true + end + return startlogging("terminal",r,w,...) + end + logs.stoperrorlogging=stoplogging + function logs.finalactions() + if #finalactions>0 then + for i=1,#finalactions do + finalactions[i]() + end + if done then + pushtarget("terminal") + newline() + logs.report("error logging","stop possible issues") + poptarget() + end + return next(possiblefatal) and sortedkeys(possiblefatal) or false + end + end +end end -- of closure @@ -9520,7 +10091,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-inf"] = package.loaded["trac-inf"] or true --- original size: 8036, stripped down to: 5567 +-- original size: 8284, stripped down to: 5698 if not modules then modules={} end modules ['trac-inf']={ version=1.001, @@ -9556,7 +10127,7 @@ local ticks=clock local seconds=function(n) return n or 0 end local function starttiming(instance) local timer=timers[instance or "notimer"] - local it=timer.timing or 0 + local it=timer.timing if it==0 then timer.starttime=ticks() if not timer.loadtime then @@ -9586,7 +10157,7 @@ local function stoptiming(instance) end local function elapsed(instance) if type(instance)=="number" then - return instance or 0 + return instance else local timer=timers[instance or "notimer"] return timer and seconds(timer.loadtime) or 0 @@ -9627,8 +10198,9 @@ function statistics.show() return format("%s, type: %s, binary subtree: %s", os.platform or "unknown",os.type or "unknown",environment.texos or "unknown") end) - register("luatex banner",function() - return lower(status.banner) + register("used engine",function() + return format("%s version %s with functionality level %s, banner: %s", + LUATEXENGINE,LUATEXVERSION,LUATEXFUNCTIONALITY,lower(status.banner)) end) register("control sequences",function() return format("%s of %s + %s",status.cs_count,status.hash_size,status.hash_extra) @@ -9650,8 +10222,9 @@ function statistics.show() local hashchar=tonumber(status.luatex_hashchars) local hashtype=status.luatex_hashtype local mask=lua.mask or "ascii" - return format("engine: %s, used memory: %s, hash type: %s, hash chars: min(%s,40), symbol mask: %s (%s)", + return format("engine: %s %s, used memory: %s, hash type: %s, hash chars: min(%i,40), symbol mask: %s (%s)", jit and "luajit" or "lua", + LUAVERSION, statistics.memused(), hashtype or "default", hashchar and 2^hashchar or "unknown", @@ -9707,7 +10280,7 @@ do -- create closure to overcome 200 locals limit package.loaded["trac-pro"] = package.loaded["trac-pro"] or true --- original size: 5829, stripped down to: 3501 +-- original size: 5841, stripped down to: 3511 if not modules then modules={} end modules ['trac-pro']={ version=1.001, @@ -9716,7 +10289,7 @@ if not modules then modules={} end modules ['trac-pro']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local getmetatable,setmetatable,rawset,type=getmetatable,setmetatable,rawset,type +local getmetatable,setmetatable,rawset,type,next=getmetatable,setmetatable,rawset,type,next local trace_namespaces=false trackers.register("system.namespaces",function(v) trace_namespaces=v end) local report_system=logs.reporter("system","protection") namespaces=namespaces or {} @@ -9854,7 +10427,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-lua"] = package.loaded["util-lua"] or true --- original size: 5396, stripped down to: 3708 +-- original size: 6921, stripped down to: 4998 if not modules then modules={} end modules ['util-lua']={ version=1.001, @@ -9865,13 +10438,14 @@ if not modules then modules={} end modules ['util-lua']={ license="see context related readme files" } local rep,sub,byte,dump,format=string.rep,string.sub,string.byte,string.dump,string.format -local load,loadfile,type=load,loadfile,type +local load,loadfile,type,collectgarbage=load,loadfile,type,collectgarbage utilities=utilities or {} utilities.lua=utilities.lua or {} local luautilities=utilities.lua local report_lua=logs.reporter("system","lua") +local report_mem=logs.reporter("system","lua memory") local tracestripping=false -local forcestupidcompile=true +local tracememory=false luautilities.stripcode=true luautilities.alwaysstripcode=false luautilities.nofstrippedchunks=0 @@ -9915,11 +10489,19 @@ local function stupidcompile(luafile,lucfile,strip) end return false,0 end -function luautilities.loadedluacode(fullname,forcestrip,name) +function luautilities.loadedluacode(fullname,forcestrip,name,macros) name=name or fullname local code,message - if environment.loadpreprocessedfile then - code,message=environment.loadpreprocessedfile(fullname) + if macros then + macros=lua.macros + end + if macros and macros.enabled then + local f=io.open(fullname,"rb") local c=f:read("*a") f:close() + local n=c and macros.resolvestring("--[["..fullname.."]] "..c) + if n and #n~=#c then + report_lua("preprocessed file %a: %i => %i bytes",fullname,#c,#n) + end + code,message=load(n or c) else code,message=loadfile(fullname) end @@ -9945,7 +10527,7 @@ function luautilities.loadedluacode(fullname,forcestrip,name) return code,0 end end -function luautilities.strippedloadstring(code,forcestrip,name) +function luautilities.strippedloadstring(code,name,forcestrip) local code,message=load(code) if not code then report_lua("loading of file %a failed:\n\t%s",name,message or "no message") @@ -9957,6 +10539,13 @@ function luautilities.strippedloadstring(code,forcestrip,name) return code,0 end end +function luautilities.loadstring(code,name) + local code,message=load(code) + if not code then + report_lua("loading of file %a failed:\n\t%s",name,message or "no message") + end + return code,0 +end function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) report_lua("compiling %a into %a",luafile,lucfile) os.remove(lucfile) @@ -9987,6 +10576,26 @@ setmetatable(finalizers,{ function luautilities.registerfinalizer(f) finalizers[#finalizers+1]=f end +function luautilities.checkmemory(previous,threshold,trace) + local current=collectgarbage("count") + if previous then + local checked=(threshold or 64)*1024 + local delta=current-previous + if current-previous>checked then + collectgarbage("collect") + local afterwards=collectgarbage("count") + if trace or tracememory then + report_mem("previous %i MB, current %i MB, delta %i MB, threshold %i MB, afterwards %i MB", + previous/1024,current/1024,delta/1024,threshold,afterwards) + end + return afterwards + elseif trace or tracememory then + report_mem("previous %i MB, current %i MB, delta %i MB, threshold %i MB", + previous/1024,current/1024,delta/1024,threshold) + end + end + return current +end end -- of closure @@ -9995,7 +10604,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-deb"] = package.loaded["util-deb"] or true --- original size: 8911, stripped down to: 6504 +-- original size: 8984, stripped down to: 6573 if not modules then modules={} end modules ['util-deb']={ version=1.001, @@ -10121,7 +10730,8 @@ function debugger.showstats(printer,threshold) local functions=0 local dataset={} local length=0 - local wholetime=0 + local realtime=0 + local totaltime=0 local threshold=threshold or 0 for name,sources in next,names do for source,lines in next,sources do @@ -10138,8 +10748,9 @@ function debugger.showstats(printer,threshold) if real<0 then real=0 end - wholetime=wholetime+real + realtime=realtime+real end + totaltime=totaltime+total if line<0 then line=0 end @@ -10174,7 +10785,7 @@ function debugger.showstats(printer,threshold) if length>50 then length=50 end - local fmt=string.formatters["%4.9k %4.9k %3.3k %8i %-"..length.."s %4i %s"] + local fmt=string.formatters["%4.9k s %3.3k %% %4.9k s %3.3k %% %8i # %-"..length.."s %4i %s"] for i=1,#dataset do local data=dataset[i] local real=data[1] @@ -10183,14 +10794,13 @@ function debugger.showstats(printer,threshold) local name=data[4] local source=data[5] local line=data[6] - local percent=real/wholetime calls=calls+count functions=functions+1 name=gsub(name,"%s+"," ") if #name>length then name=sub(name,1,length) end - printer(fmt(seconds(total),seconds(real),percent,count,name,line,source)) + printer(fmt(seconds(total),100*total/totaltime,seconds(real),100*real/realtime,count,name,line,source)) end printer("") printer(format("functions : %i",functions)) @@ -10254,7 +10864,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-tpl"] = package.loaded["util-tpl"] or true --- original size: 7100, stripped down to: 3978 +-- original size: 7112, stripped down to: 3988 if not modules then modules={} end modules ['util-tpl']={ version=1.001, @@ -10267,7 +10877,7 @@ utilities.templates=utilities.templates or {} local templates=utilities.templates local trace_template=false trackers.register("templates.trace",function(v) trace_template=v end) local report_template=logs.reporter("template") -local tostring=tostring +local tostring,next=tostring,next local format,sub,byte=string.format,string.sub,string.byte local P,C,R,Cs,Cc,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.R,lpeg.Cs,lpeg.Cc,lpeg.Carg,lpeg.match,lpeg.patterns local replacer @@ -10399,7 +11009,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-sbx"] = package.loaded["util-sbx"] or true --- original size: 20309, stripped down to: 13848 +-- original size: 20393, stripped down to: 13924 if not modules then modules={} end modules ['util-sbx']={ version=1.001, @@ -10424,6 +11034,7 @@ local concat=string.concat local unquoted=string.unquoted local optionalquoted=string.optionalquoted local basename=file.basename +local nameonly=file.nameonly local sandbox=sandbox local validroots={} local validrunners={} @@ -10503,9 +11114,9 @@ local function registerlibrary(name) return end if validlibraries==true then - validlibraries={ [name]=true } + validlibraries={ [nameonly(name)]=true } else - validlibraries[name]=true + validlibraries[nameonly(name)]=true end elseif name==true then validlibraries={} @@ -10780,7 +11391,7 @@ function sandbox.getrunner(name) return name and validrunners[name] end local function suspicious(str) - return (find(str,"[/\\]") or find(command,"%.%.")) and true or false + return (find(str,"[/\\]") or find(command,"..",1,true)) and true or false end local function binaryrunner(action,command,...) if validbinaries==false then @@ -10830,15 +11441,15 @@ if FFISUPPORTED and ffi then end end end - local load=ffi.load - if load then + local fiiload=ffi.load + if fiiload then local reported={} function ffi.load(name,...) if validlibraries==false then elseif validlibraries==true then - return load(name,...) - elseif validlibraries[name] then - return load(name,...) + return fiiload(name,...) + elseif validlibraries[nameonly(name)] then + return fiiload(name,...) else end if not reported[name] then @@ -11083,7 +11694,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-env"] = package.loaded["util-env"] or true --- original size: 9246, stripped down to: 5038 +-- original size: 9400, stripped down to: 5499 if not modules then modules={} end modules ['util-env']={ version=1.001, @@ -11098,8 +11709,21 @@ local unquoted,quoted,optionalquoted=string.unquoted,string.quoted,string.option local concat,insert,remove=table.concat,table.insert,table.remove environment=environment or {} local environment=environment -os.setlocale(nil,nil) -function os.setlocale() +local setlocale=os.setlocale +setlocale(nil,nil) +local report=logs.reporter("system") +function os.setlocale(a,b) + if a or b then + if report then + report() + report("You're messing with os.locale in a supposedly locale neutral enviroment. From") + report("now on are on your own and without support. Crashes or unexpected side effects") + report("can happen but don't bother the luatex and context developer team with it.") + report() + report=nil + end + setlocale(a,b) + end end local validengines=allocate { ["luatex"]=true, @@ -11270,7 +11894,7 @@ do -- create closure to overcome 200 locals limit package.loaded["luat-env"] = package.loaded["luat-env"] or true --- original size: 6174, stripped down to: 4141 +-- original size: 5820, stripped down to: 4155 if not modules then modules={} end modules ['luat-env']={ version=1.001, @@ -11344,11 +11968,11 @@ local function strippable(filename) return false end end -function environment.luafilechunk(filename,silent) +function environment.luafilechunk(filename,silent,macros) filename=file.replacesuffix(filename,"lua") local fullname=environment.luafile(filename) if fullname and fullname~="" then - local data=luautilities.loadedluacode(fullname,strippable,filename) + local data=luautilities.loadedluacode(fullname,strippable,filename,macros) if not silent then report_lua("loading file %a %s",fullname,not data and "failed" or "succeeded") end @@ -11423,7 +12047,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-tab"] = package.loaded["lxml-tab"] or true --- original size: 57003, stripped down to: 35696 +-- original size: 59638, stripped down to: 37936 if not modules then modules={} end modules ['lxml-tab']={ version=1.001, @@ -11469,8 +12093,17 @@ local entities,parameters local strip,utfize,resolve,cleanup,resolve_predefined,unify_predefined local dcache,hcache,acache local mt,dt,nt +local currentfilename,currentline,linenumbers +local grammar_parsed_text_one +local grammar_parsed_text_two +local grammar_unparsed_text +local handle_hex_entity +local handle_dec_entity +local handle_any_entity_dtd +local handle_any_entity_text local function preparexmlstate(settings) if settings then + linenumbers=settings.linenumbers stack={} level=0 top={} @@ -11487,6 +12120,8 @@ local function preparexmlstate(settings) unify_predefined=settings.unify_predefined_entities cleanup=settings.text_cleanup entities=settings.entities or {} + currentfilename=settings.currentresource + currentline=1 parameters={} reported_at_errors={} dcache={} @@ -11501,6 +12136,7 @@ local function preparexmlstate(settings) resolve_predefined=true end else + linenumbers=false stack=nil level=nil top=nil @@ -11522,6 +12158,8 @@ local function preparexmlstate(settings) dcache=nil hcache=nil acache=nil + currentfilename=nil + currentline=1 end end local function initialize_mt(root) @@ -11559,14 +12197,24 @@ local function add_empty(spacing,namespace,tag) top=stack[level] dt=top.dt nt=#dt+1 - local t={ + local t=linenumbers and { + ns=namespace or "", + rn=resolved, + tg=tag, + at=at, + dt={}, + ni=nt, + cf=currentfilename, + cl=currentline, + __p__=top, + } or { ns=namespace or "", rn=resolved, tg=tag, at=at, dt={}, ni=nt, - __p__=top + __p__=top, } dt[nt]=t setmetatable(t,mt) @@ -11581,18 +12229,28 @@ local function add_begin(spacing,namespace,tag) dt[nt]=spacing end local resolved=namespace=="" and xmlns[#xmlns] or nsremap[namespace] or namespace - top={ + dt={} + top=linenumbers and { ns=namespace or "", rn=resolved, tg=tag, at=at, - dt={}, + dt=dt, + ni=nil, + cf=currentfilename, + cl=currentline, + __p__=stack[level], + } or { + ns=namespace or "", + rn=resolved, + tg=tag, + at=at, + dt=dt, ni=nil, - __p__=stack[level] + __p__=stack[level], } setmetatable(top,mt) - dt=top.dt - nt=#dt + nt=0 level=level+1 stack[level]=top at={} @@ -11660,7 +12318,15 @@ local function add_special(what,spacing,text) if strip and (what=="@cm@" or what=="@dt@") then else nt=nt+1 - dt[nt]={ + dt[nt]=linenumbers and { + special=true, + ns="", + tg=what, + ni=nil, + dt={ text }, + cf=currentfilename, + cl=currentline, + } or { special=true, ns="", tg=what, @@ -11688,12 +12354,6 @@ local function attribute_specification_error(str) end return str end -local grammar_parsed_text_one -local grammar_parsed_text_two -local handle_hex_entity -local handle_dec_entity -local handle_any_entity_dtd -local handle_any_entity_text do local badentity="&" xml.placeholders={ @@ -12095,7 +12755,13 @@ local function handle_crap_error(chr) add_text(chr) return chr end +local function handlenewline() + currentline=currentline+1 +end +local spacetab=S(' \t') local space=S(' \r\n\t') +local newline=lpegpatterns.newline/handlenewline +local anything=P(1) local open=P('<') local close=P('>') local squote=S("'") @@ -12111,43 +12777,9 @@ local name_nop=C(P(true))*C(valid^1) local name=name_yes+name_nop local utfbom=lpegpatterns.utfbom local spacing=C(space^0) -local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0 -local hexentitycontent=R("AF","af","09")^1 -local decentitycontent=R("09")^1 -local parsedentity=P("#")/""*( - P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity) - )+(anyentitycontent/handle_any_entity_dtd) -local parsedentity_text=P("#")/""*( - P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity) - )+(anyentitycontent/handle_any_entity_text) -local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity) -local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity) -local text_unparsed=C((1-open)^1) -local text_parsed=(Cs((1-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1 -local somespace=space^1 -local optionalspace=space^0 -local value=(squote*Cs((entity+(1-squote))^0)*squote)+(dquote*Cs((entity+(1-dquote))^0)*dquote) -local endofattributes=slash*close+close -local whatever=space*name*optionalspace*equal -local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error -local attributevalue=value+wrongvalue -local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute -local attributes=(attribute+somespace^-1*(((1-endofattributes)^1)/attribute_specification_error))^0 -local parsedtext=text_parsed -local unparsedtext=text_unparsed/add_text -local balanced=P { "["*((1-S"[]")+V(1))^0*"]" } -local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty -local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin -local endelement=(spacing*open*slash*name*optionalspace*close)/add_end -local begincomment=open*P("!--") -local endcomment=P("--")*close -local begininstruction=open*P("?") -local endinstruction=P("?")*close -local begincdata=open*P("![CDATA[") -local endcdata=P("]]")*close -local someinstruction=C((1-endinstruction)^0) -local somecomment=C((1-endcomment )^0) -local somecdata=C((1-endcdata )^0) +local space_nl=spacetab+newline +local spacing_nl=Cs((space_nl)^0) +local anything_nl=newline+P(1) local function weirdentity(k,v) if trace_entities then report_xml("registering %s entity %a as %a","weird",k,v) @@ -12172,59 +12804,114 @@ local function publicentity(k,v,n) end entities[k]=v end -local begindoctype=open*P("!DOCTYPE") -local enddoctype=close -local beginset=P("[") -local endset=P("]") -local wrdtypename=C((1-somespace-P(";"))^1) -local doctypename=C((1-somespace-close)^0) -local elementdoctype=optionalspace*P("<!ELEMENT")*(1-close)^0*close -local basiccomment=begincomment*((1-endcomment)^0)*endcomment -local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity -local normalentitytype=(doctypename*somespace*value)/normalentity -local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity -local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity -local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close -local function weirdresolve(s) - lpegmatch(entitydoctype,parameters[s]) -end -local function normalresolve(s) - lpegmatch(entitydoctype,entities[s]) -end -local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";") -entitydoctype=entitydoctype+entityresolve -local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset -local definitiondoctype=doctypename*somespace*doctypeset -local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset -local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset -local simpledoctype=(1-close)^1 -local somedoctype=C((somespace*(publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0) -local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end -local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end -local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end -local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end -local crap_parsed=1-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand -local crap_unparsed=1-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata -local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error -local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error -local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error -local trailer=space^0*(text_unparsed/set_message)^0 -grammar_parsed_text_one=P { "preamble", - preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0, -} -grammar_parsed_text_two=P { "followup", - followup=V("parent")*trailer, - parent=beginelement*V("children")^0*endelement, - children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap, -} -local grammar_unparsed_text=P { "preamble", - preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer, - parent=beginelement*V("children")^0*endelement, - children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap, -} -local function _xmlconvert_(data,settings) +local function install(spacenewline,spacing,anything) + local anyentitycontent=(1-open-semicolon-space-close-ampersand)^0 + local hexentitycontent=R("AF","af","09")^1 + local decentitycontent=R("09")^1 + local parsedentity=P("#")/""*( + P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity) + )+(anyentitycontent/handle_any_entity_dtd) + local parsedentity_text=P("#")/""*( + P("x")/""*(hexentitycontent/handle_hex_entity)+(decentitycontent/handle_dec_entity) + )+(anyentitycontent/handle_any_entity_text) + local entity=(ampersand/"")*parsedentity*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity) + local entity_text=(ampersand/"")*parsedentity_text*(semicolon/"")+ampersand*(anyentitycontent/handle_end_entity) + local text_unparsed=Cs((anything-open)^1) + local text_parsed=(Cs((anything-open-ampersand)^1)/add_text+Cs(entity_text)/add_text)^1 + local somespace=(spacenewline)^1 + local optionalspace=(spacenewline)^0 + local value=(squote*Cs((entity+(anything-squote))^0)*squote)+(dquote*Cs((entity+(anything-dquote))^0)*dquote) + local endofattributes=slash*close+close + local whatever=space*name*optionalspace*equal + local wrongvalue=Cs(P(entity+(1-space-endofattributes))^1)/attribute_value_error + local attributevalue=value+wrongvalue + local attribute=(somespace*name*optionalspace*equal*optionalspace*attributevalue)/add_attribute + local attributes=(attribute+somespace^-1*(((anything-endofattributes)^1)/attribute_specification_error))^0 + local parsedtext=text_parsed + local unparsedtext=text_unparsed/add_text + local balanced=P { "["*((anything-S"[]")+V(1))^0*"]" } + local emptyelement=(spacing*open*name*attributes*optionalspace*slash*close)/add_empty + local beginelement=(spacing*open*name*attributes*optionalspace*close)/add_begin + local endelement=(spacing*open*slash*name*optionalspace*close)/add_end + local begincomment=open*P("!--") + local endcomment=P("--")*close + local begininstruction=open*P("?") + local endinstruction=P("?")*close + local begincdata=open*P("![CDATA[") + local endcdata=P("]]")*close + local someinstruction=C((anything-endinstruction)^0) + local somecomment=C((anything-endcomment )^0) + local somecdata=C((anything-endcdata )^0) + local begindoctype=open*P("!DOCTYPE") + local enddoctype=close + local beginset=P("[") + local endset=P("]") + local wrdtypename=C((anything-somespace-P(";"))^1) + local doctypename=C((anything-somespace-close)^0) + local elementdoctype=optionalspace*P("<!ELEMENT")*(anything-close)^0*close + local basiccomment=begincomment*((anything-endcomment)^0)*endcomment + local weirdentitytype=P("%")*(somespace*doctypename*somespace*value)/weirdentity + local normalentitytype=(doctypename*somespace*value)/normalentity + local publicentitytype=(doctypename*somespace*P("PUBLIC")*somespace*value)/publicentity + local systementitytype=(doctypename*somespace*P("SYSTEM")*somespace*value*somespace*P("NDATA")*somespace*doctypename)/systementity + local entitydoctype=optionalspace*P("<!ENTITY")*somespace*(systementitytype+publicentitytype+normalentitytype+weirdentitytype)*optionalspace*close + local function weirdresolve(s) + lpegmatch(entitydoctype,parameters[s]) + end + local function normalresolve(s) + lpegmatch(entitydoctype,entities[s]) + end + local entityresolve=P("%")*(wrdtypename/weirdresolve )*P(";")+P("&")*(wrdtypename/normalresolve)*P(";") + entitydoctype=entitydoctype+entityresolve + local doctypeset=beginset*optionalspace*P(elementdoctype+entitydoctype+entityresolve+basiccomment+space)^0*optionalspace*endset + local definitiondoctype=doctypename*somespace*doctypeset + local publicdoctype=doctypename*somespace*P("PUBLIC")*somespace*value*somespace*value*somespace*doctypeset + local systemdoctype=doctypename*somespace*P("SYSTEM")*somespace*value*somespace*doctypeset + local simpledoctype=(anything-close)^1 + local somedoctype=C((somespace*(publicdoctype+systemdoctype+definitiondoctype+simpledoctype)*optionalspace)^0) + local instruction=(spacing*begininstruction*someinstruction*endinstruction)/function(...) add_special("@pi@",...) end + local comment=(spacing*begincomment*somecomment*endcomment )/function(...) add_special("@cm@",...) end + local cdata=(spacing*begincdata*somecdata*endcdata )/function(...) add_special("@cd@",...) end + local doctype=(spacing*begindoctype*somedoctype*enddoctype )/function(...) add_special("@dt@",...) end + local crap_parsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata-ampersand + local crap_unparsed=anything-beginelement-endelement-emptyelement-begininstruction-begincomment-begincdata + local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error + local parsedcrap=Cs((crap_parsed^1+entity_text)^1)/handle_crap_error + local unparsedcrap=Cs((crap_unparsed )^1)/handle_crap_error + local trailer=space^0*(text_unparsed/set_message)^0 + local grammar_parsed_text_one=P { "preamble", + preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0, + } + local grammar_parsed_text_two=P { "followup", + followup=V("parent")*trailer, + parent=beginelement*V("children")^0*endelement, + children=parsedtext+V("parent")+emptyelement+comment+cdata+instruction+parsedcrap, + } + local grammar_unparsed_text=P { "preamble", + preamble=utfbom^0*instruction^0*(doctype+comment+instruction)^0*V("parent")*trailer, + parent=beginelement*V("children")^0*endelement, + children=unparsedtext+V("parent")+emptyelement+comment+cdata+instruction+unparsedcrap, + } + return grammar_parsed_text_one,grammar_parsed_text_two,grammar_unparsed_text +end +grammar_parsed_text_one_nop, +grammar_parsed_text_two_nop, +grammar_unparsed_text_nop=install(space,spacing,anything) +grammar_parsed_text_one_yes, +grammar_parsed_text_two_yes, +grammar_unparsed_text_yes=install(space_nl,spacing_nl,anything_nl) +local function _xmlconvert_(data,settings,detail) settings=settings or {} preparexmlstate(settings) + if settings.linenumbers then + grammar_parsed_text_one=grammar_parsed_text_one_yes + grammar_parsed_text_two=grammar_parsed_text_two_yes + grammar_unparsed_text=grammar_unparsed_text_yes + else + grammar_parsed_text_one=grammar_parsed_text_one_nop + grammar_parsed_text_two=grammar_parsed_text_two_nop + grammar_unparsed_text=grammar_unparsed_text_nop + end local preprocessor=settings.preprocessor if data and data~="" and type(preprocessor)=="function" then data=preprocessor(data,settings) or data @@ -12241,6 +12928,8 @@ local function _xmlconvert_(data,settings) nt=0 if not data or data=="" then errorstr="empty xml file" + elseif data==true then + errorstr=detail or "problematic xml file" elseif utfize or resolve then local m=lpegmatch(grammar_parsed_text_one,data) if m then @@ -12272,7 +12961,7 @@ local function _xmlconvert_(data,settings) if errorhandler then local currentresource=settings.currentresource if currentresource and currentresource~="" then - xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr)) + xml.errorhandler(formatters["load error in [%s]: %s"](currentresource,errorstr),currentresource) else xml.errorhandler(formatters["load error: %s"](errorstr)) end @@ -12315,8 +13004,10 @@ local function xmlconvert(data,settings) local ok,result=pcall(function() return _xmlconvert_(data,settings) end) if ok then return result + elseif type(result)=="string" then + return _xmlconvert_(true,settings,result) else - return _xmlconvert_("",settings) + return _xmlconvert_(true,settings) end end xml.convert=xmlconvert @@ -13945,7 +14636,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-mis"] = package.loaded["lxml-mis"] or true --- original size: 3684, stripped down to: 1957 +-- original size: 3574, stripped down to: 1863 if not modules then modules={} end modules ['lxml-mis']={ version=1.001, @@ -13955,8 +14646,8 @@ if not modules then modules={} end modules ['lxml-mis']={ license="see context related readme files" } local xml,lpeg,string=xml,lpeg,string +local type=type local concat=table.concat -local type,next,tonumber,tostring,setmetatable,loadstring=type,next,tonumber,tostring,setmetatable,loadstring local format,gsub,match=string.format,string.gsub,string.match local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns local P,S,R,C,V,Cc,Cs=lpeg.P,lpeg.S,lpeg.R,lpeg.C,lpeg.V,lpeg.Cc,lpeg.Cs @@ -14014,7 +14705,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-aux"] = package.loaded["lxml-aux"] or true --- original size: 29835, stripped down to: 21174 +-- original size: 30650, stripped down to: 21793 if not modules then modules={} end modules ['lxml-aux']={ version=1.001, @@ -14034,7 +14725,7 @@ local type,next,setmetatable,getmetatable=type,next,setmetatable,getmetatable local insert,remove,fastcopy,concat=table.insert,table.remove,table.fastcopy,table.concat local gmatch,gsub,format,find,strip=string.gmatch,string.gsub,string.format,string.find,string.strip local utfbyte=utf.byte -local lpegmatch=lpeg.match +local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns local striplinepatterns=utilities.strings.striplinepatterns local function report(what,pattern,c,e) report_xml("%s element %a, root %a, position %a, index %a, pattern %a",what,xmlname(e),xmlname(e.__p__),c,e.ni,pattern) @@ -14375,7 +15066,9 @@ local function include(xmldata,pattern,attribute,recursive,loaddata,level) end local data=nil if name and name~="" then - data=loaddata(name) or "" + local d,n=loaddata(name) + data=d or "" + name=n or name if trace_inclusions then report_xml("including %s bytes from %a at level %s by pattern %a and attribute %a (%srecursing)",#data,name,level,pattern,attribute or "",recursive and "" or "not ") end @@ -14385,6 +15078,9 @@ local function include(xmldata,pattern,attribute,recursive,loaddata,level) elseif ekat["parse"]=="text" then epdt[ek.ni]=xml.escaped(data) else +local settings=xmldata.settings +local savedresource=settings.currentresource +settings.currentresource=name local xi=xmlinheritedconvert(data,xmldata) if not xi then epdt[ek.ni]="" @@ -14395,6 +15091,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata,level) local child=xml.body(xi) child.__p__=ekrt child.__f__=name +child.cf=name epdt[ek.ni]=child local settings=xmldata.settings local inclusions=settings and settings.inclusions @@ -14415,6 +15112,7 @@ local function include(xmldata,pattern,attribute,recursive,loaddata,level) end end end +settings.currentresource=savedresource end end end @@ -14458,13 +15156,12 @@ end function xml.badinclusions(e,sorted) return getinclusions("badinclusions",e,sorted) end -local b_collapser=lpeg.patterns.b_collapser -local m_collapser=lpeg.patterns.m_collapser -local e_collapser=lpeg.patterns.e_collapser -local b_stripper=lpeg.patterns.b_stripper -local m_stripper=lpeg.patterns.m_stripper -local e_stripper=lpeg.patterns.e_stripper -local lpegmatch=lpeg.match +local b_collapser=lpegpatterns.b_collapser +local m_collapser=lpegpatterns.m_collapser +local e_collapser=lpegpatterns.e_collapser +local b_stripper=lpegpatterns.b_stripper +local m_stripper=lpegpatterns.m_stripper +local e_stripper=lpegpatterns.e_stripper local function stripelement(e,nolines,anywhere) local edt=e.dt if edt then @@ -14876,6 +15573,27 @@ function xml.totable(x,strip,flat) return convert(x,strip,flat) end end +function xml.rename(e,namespace,name,attributes) + if type(e)~="table" or not e.tg then + return + end + if type(name)=="table" then + attributes=name + name=namespace + namespace="" + elseif type(name)~="string" then + attributes={} + name=namespace + namespace="" + end + if type(attributes)~="table" then + attributes={} + end + e.ns=namespace + e.rn=namespace + e.tg=name + e.at=attributes +end end -- of closure @@ -14884,7 +15602,7 @@ do -- create closure to overcome 200 locals limit package.loaded["lxml-xml"] = package.loaded["lxml-xml"] or true --- original size: 10274, stripped down to: 7538 +-- original size: 10412, stripped down to: 7669 if not modules then modules={} end modules ['lxml-xml']={ version=1.001, @@ -14893,6 +15611,7 @@ if not modules then modules={} end modules ['lxml-xml']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } +local tonumber,next=tonumber,next local concat=table.concat local find,lower,upper=string.find,string.lower,string.upper local xml=xml @@ -15012,6 +15731,9 @@ local function xmltotext(root) return xmlserialize(root,xmltexthandler) or "" end end +function xml.serializetotext(root) + return root and xmlserialize(root,xmltexthandler) or "" +end local function text(collected) if collected then local e=collected[1] or collected @@ -15684,7 +16406,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-exp"] = package.loaded["data-exp"] or true --- original size: 17958, stripped down to: 10705 +-- original size: 18105, stripped down to: 11207 if not modules then modules={} end modules ['data-exp']={ version=1.001, @@ -15883,38 +16605,41 @@ local nofscans=0 local scancache={} local fullcache={} local nofsharedscans=0 +local addcasecraptoo=true local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant) local full=path=="" and spec or (spec..path..'/') - local dirs={} + local dirlist={} local nofdirs=0 local pattern=tolerant and lessweird or weird + local filelist={} + local noffiles=0 for name in directory(full) do if not lpegmatch(pattern,name) then local mode=attributes(full..name,"mode") if mode=="file" then n=n+1 - local lower=lower(name) - local paths=files[lower] - if paths then - if onlyone then - else - if type(paths)=="string" then - files[lower]={ paths,path } - else - paths[#paths+1]=path - end - if name~=lower then - local rl=remap[lower] - if not rl then - remap[lower]=name - r=r+1 - elseif trace_globbing and rl~=name then - report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl) - end - end - end - else - files[lower]=path + noffiles=noffiles+1 + filelist[noffiles]=name + elseif mode=="directory" then + m=m+1 + nofdirs=nofdirs+1 + if path~="" then + dirlist[nofdirs]=path.."/"..name + else + dirlist[nofdirs]=name + end + end + end + end + if noffiles>0 then + sort(filelist) + for i=1,noffiles do + local name=filelist[i] + local lower=lower(name) + local paths=files[lower] + if paths then + if onlyone then + else if name~=lower then local rl=remap[lower] if not rl then @@ -15923,23 +16648,41 @@ local function scan(files,remap,spec,path,n,m,r,onlyone,tolerant) elseif trace_globbing and rl~=name then report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl) end + if addcasecraptoo then + local paths=files[name] + if not paths then + files[name]=path + elseif type(paths)=="string" then + files[name]={ paths,path } + else + paths[#paths+1]=path + end + end + end + if type(paths)=="string" then + files[lower]={ paths,path } + else + paths[#paths+1]=path end end - elseif mode=="directory" then - m=m+1 - nofdirs=nofdirs+1 - if path~="" then - dirs[nofdirs]=path.."/"..name - else - dirs[nofdirs]=name + else + files[lower]=path + if name~=lower then + local rl=remap[lower] + if not rl then + remap[lower]=name + r=r+1 + elseif trace_globbing and rl~=name then + report_globbing("confusing filename, name: %a, lower: %a, already: %a",name,lower,rl) + end end end end end if nofdirs>0 then - sort(dirs) + sort(dirlist) for i=1,nofdirs do - files,remap,n,m,r=scan(files,remap,spec,dirs[i],n,m,r,onlyonce,tolerant) + files,remap,n,m,r=scan(files,remap,spec,dirlist[i],n,m,r,onlyonce,tolerant) end end scancache[sub(full,1,-2)]=files @@ -16068,7 +16811,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-env"] = package.loaded["data-env"] or true --- original size: 9342, stripped down to: 6887 +-- original size: 9360, stripped down to: 6903 if not modules then modules={} end modules ['data-env']={ version=1.001, @@ -16078,6 +16821,7 @@ if not modules then modules={} end modules ['data-env']={ license="see context related readme files", } local lower,gsub=string.lower,string.gsub +local next=next local resolvers=resolvers local allocate=utilities.storage.allocate local setmetatableindex=table.setmetatableindex @@ -16352,7 +17096,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-tmp"] = package.loaded["data-tmp"] or true --- original size: 16088, stripped down to: 11435 +-- original size: 16116, stripped down to: 11459 if not modules then modules={} end modules ['data-tmp']={ version=1.100, @@ -16366,6 +17110,7 @@ local concat=table.concat local mkdirs,isdir,isfile=dir.mkdirs,lfs.isdir,lfs.isfile local addsuffix,is_writable,is_readable=file.addsuffix,file.is_writable,file.is_readable local formatters=string.formatters +local next,type=next,type local trace_locating=false trackers.register("resolvers.locating",function(v) trace_locating=v end) local trace_cache=false trackers.register("resolvers.cache",function(v) trace_cache=v end) local report_caches=logs.reporter("resolvers","caches") @@ -16500,7 +17245,7 @@ function caches.usedpaths(separator) end end function caches.configfiles() - return concat(resolvers.instance.specification,";") + return concat(resolvers.configurationfiles(),";") end function caches.hashed(tree) tree=gsub(tree,"[\\/]+$","") @@ -16838,7 +17583,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-res"] = package.loaded["data-res"] or true --- original size: 67524, stripped down to: 46632 +-- original size: 68263, stripped down to: 47789 if not modules then modules={} end modules ['data-res']={ version=1.001, @@ -16912,8 +17657,7 @@ local usertypes=resolvers.usertypes local dangerous=resolvers.dangerous local suffixmap=resolvers.suffixmap resolvers.defaultsuffixes={ "tex" } -resolvers.instance=resolvers.instance or nil -local instance=resolvers.instance or nil +local instance=nil function resolvers.setenv(key,value,raw) if instance then instance.environment[key]=value @@ -16948,27 +17692,30 @@ local variableresolver=Cs((variable+P(1))^0) local function expandedvariable(var) return lpegmatch(variableexpander,var) or var end -function resolvers.newinstance() +function resolvers.reset() if trace_locating then report_resolving("creating instance") end - local environment,variables,expansions,order=allocate(),allocate(),allocate(),allocate() - local newinstance={ + local environment={} + local variables={} + local expansions={} + local order={} + instance={ environment=environment, variables=variables, expansions=expansions, order=order, - files=allocate(), - setups=allocate(), - found=allocate(), - foundintrees=allocate(), - hashes=allocate(), - hashed=allocate(), + files={}, + setups={}, + found={}, + foundintrees={}, + hashes={}, + hashed={}, pathlists=false, - specification=allocate(), - lists=allocate(), - data=allocate(), - fakepaths=allocate(), + specification={}, + lists={}, + data={}, + fakepaths={}, remember=true, diskcache=true, renewcache=false, @@ -17015,15 +17762,9 @@ function resolvers.newinstance() t[k]=v return v end) - return newinstance -end -function resolvers.setinstance(someinstance) - instance=someinstance - resolvers.instance=someinstance - return someinstance end -function resolvers.reset() - return resolvers.setinstance(resolvers.newinstance()) +function resolvers.initialized() + return instance~=nil end local function reset_hashes() instance.lists={} @@ -17192,8 +17933,12 @@ local function load_configuration_files() report_resolving("warning: no lua configuration files found") end end +function resolvers.configurationfiles() + return instance.specification or {} +end local function load_file_databases() - instance.loaderror,instance.files=false,allocate() + instance.loaderror=false + instance.files={} if not instance.renewcache then local hashes=instance.hashes for k=1,#hashes do @@ -17404,7 +18149,7 @@ function resolvers.stackpath() return currentpath~="" and currentpath or nil end local done={} -function resolvers.resetextrapath() +function resolvers.resetextrapaths() local ep=instance.extra_paths if not ep then done={} @@ -17414,6 +18159,9 @@ function resolvers.resetextrapath() reset_caches() end end +function resolvers.getextrapaths() + return instance.extra_paths or {} +end function resolvers.registerextrapath(paths,subpaths) if not subpaths or subpaths=="" then if not paths or path=="" then @@ -17573,9 +18321,8 @@ function resolvers.cleanedpathlist(v) end return t end -function resolvers.expandbraces(str) - local ori=str - local pth=expandedpathfromlist(resolvers.splitpath(ori)) +function resolvers.expandbraces(str) + local pth=expandedpathfromlist(resolvers.splitpath(str)) return joinpath(pth) end function resolvers.registerfilehash(name,content,someerror) @@ -17588,6 +18335,17 @@ function resolvers.registerfilehash(name,content,someerror) end end end +function resolvers.getfilehashes() + return instance and instance.files or {} +end +function resolvers.gethashes() + return instance and instance.hashes or {} +end +function resolvers.renewcache() + if instance then + instance.renewcache=true + end +end local function isreadable(name) local readable=isfile(name) if trace_detail then @@ -17602,7 +18360,7 @@ end local function collect_files(names) local filelist={} local noffiles=0 - local function check(hash,root,pathname,path,name) + local function check(hash,root,pathname,path,basename,name) if not pathname or find(path,pathname) then local variant=hash.type local search=filejoin(root,path,name) @@ -17641,10 +18399,10 @@ local function collect_files(names) local metadata=content.metadata local realroot=metadata and metadata.path or hashname if type(path)=="string" then - check(hash,realroot,pathname,path,name) + check(hash,realroot,pathname,path,basename,name) else for i=1,#path do - check(hash,realroot,pathname,path[i],name) + check(hash,realroot,pathname,path[i],basename,name) end end end @@ -17660,17 +18418,26 @@ function resolvers.registerintrees(filename,format,filetype,usedmethod,foundname local foundintrees=instance.foundintrees if usedmethod=="direct" and filename==foundname and fit[foundname] then else + local collapsed=collapsepath(foundname,true) local t={ filename=filename, - format=format~="" and format or nil, + format=format~="" and format or nil, filetype=filetype~="" and filetype or nil, usedmethod=usedmethod, foundname=foundname, + fullname=collapsed, } fit[foundname]=t foundintrees[#foundintrees+1]=t end end +function resolvers.foundintrees() + return instance.foundintrees or {} +end +function resolvers.foundintree(fullname) + local f=fit[fullname] + return f and f.usedmethod=="database" +end local function can_be_dir(name) local fakepaths=instance.fakepaths if not fakepaths[name] then @@ -17685,10 +18452,12 @@ end local preparetreepattern=Cs((P(".")/"%%."+P("-")/"%%-"+P(1))^0*Cc("$")) local collect_instance_files local function find_analyze(filename,askedformat,allresults) - local filetype,wantedfiles,ext='',{},suffixonly(filename) + local filetype='' + local filesuffix=suffixonly(filename) + local wantedfiles={} wantedfiles[#wantedfiles+1]=filename if askedformat=="" then - if ext=="" or not suffixmap[ext] then + if filesuffix=="" or not suffixmap[filesuffix] then local defaultsuffixes=resolvers.defaultsuffixes local formatofsuffix=resolvers.formatofsuffix for i=1,#defaultsuffixes do @@ -17706,7 +18475,7 @@ local function find_analyze(filename,askedformat,allresults) end end else - if ext=="" or not suffixmap[ext] then + if filesuffix=="" or not suffixmap[filesuffix] then local format_suffixes=suffixes[askedformat] if format_suffixes then for i=1,#format_suffixes do @@ -17851,7 +18620,7 @@ end local function find_intree(filename,filetype,wantedfiles,allresults) local pathlists=instance.pathlists if not pathlists then - pathlists=setmetatableindex(allocate(),makepathlist) + pathlists=setmetatableindex({},makepathlist) instance.pathlists=pathlists end local pathlist=pathlists[filetype] @@ -18254,15 +19023,21 @@ function resolvers.findwildcardfile(filename) end function resolvers.automount() end -function resolvers.load(option) +function resolvers.starttiming() statistics.starttiming(instance) +end +function resolvers.stoptiming() + statistics.stoptiming(instance) +end +function resolvers.load(option) + resolvers.starttiming() identify_configuration_files() load_configuration_files() if option~="nofiles" then load_databases() resolvers.automount() end - statistics.stoptiming(instance) + resolvers.stoptiming() local files=instance.files return files and next(files) and true end @@ -18354,7 +19129,6 @@ function resolvers.booleanvariable(str,default) end end function resolvers.dowithfilesintree(pattern,handle,before,after) - local instance=resolvers.instance local hashes=instance.hashes for i=1,#hashes do local hash=hashes[i] @@ -18392,6 +19166,31 @@ local obsolete=resolvers.obsolete or {} resolvers.obsolete=obsolete resolvers.find_file=resolvers.findfile obsolete.find_file=resolvers.findfile resolvers.find_files=resolvers.findfiles obsolete.find_files=resolvers.findfiles +function resolvers.knownvariables(pattern) + if instance then + local environment=instance.environment + local variables=instance.variables + local expansions=instance.expansions + local order=instance.order + local pattern=upper(pattern or "") + local result={} + for i=1,#order do + for key in next,order[i] do + if result[key]==nil and key~="" and (pattern=="" or find(upper(key),pattern)) then + result[key]={ + environment=rawget(environment,key), + variable=key, + expansion=expansions[key], + resolved=resolveprefix(expansions[key]), + } + end + end + end + return result + else + return {} + end +end end -- of closure @@ -18802,7 +19601,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-use"] = package.loaded["data-use"] or true --- original size: 4045, stripped down to: 3110 +-- original size: 4272, stripped down to: 3289 if not modules then modules={} end modules ['data-use']={ version=1.001, @@ -18822,7 +19621,7 @@ function resolvers.automount(usecache) mountpaths=caches.getreadablepaths("mount") end if mountpaths and #mountpaths>0 then - statistics.starttiming(resolvers.instance) + resolvers.starttiming() for k=1,#mountpaths do local root=mountpaths[k] local f=io.open(root.."/url.tmi") @@ -18842,7 +19641,7 @@ function resolvers.automount(usecache) f:close() end end - statistics.stoptiming(resolvers.instance) + resolvers.stoptiming() end end statistics.register("used config file",function() return caches.configfiles() end) @@ -18856,6 +19655,7 @@ function statistics.savefmtstatus(texname,formatbanner,sourcefile,kind,banner) formatbanner=formatbanner, sourcehash=md5.hex(io.loaddata(resolvers.findfile(sourcefile)) or "unknown"), sourcefile=sourcefile, + luaversion=LUAVERSION, } io.savedata(luvname,table.serialize(luvdata,true)) lua.registerfinalizer(function() @@ -18880,6 +19680,10 @@ function statistics.checkfmtstatus(texname) if luvhash~=sourcehash then return format("source mismatch (luv: %s <> bin: %s)",luvhash,sourcehash) end + local luvluaversion=luv.luaversion or 0 + if luvluaversion~=LUAVERSION then + return format("lua mismatch (luv: %s <> bin: %s)",luvluaversion,LUAVERSION) + end else return "invalid status file" end @@ -18897,7 +19701,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-zip"] = package.loaded["data-zip"] or true --- original size: 8772, stripped down to: 6841 +-- original size: 8716, stripped down to: 6795 if not modules then modules={} end modules ['data-zip']={ version=1.001, @@ -19070,17 +19874,16 @@ function resolvers.usezipfile(archive) if archive and not registeredfiles[archive] then local z=zip.openarchive(archive) if z then - local instance=resolvers.instance local tree=url.query(specification.query).tree or "" if trace_locating then report_zip("registering: archive %a",archive) end - statistics.starttiming(instance) + resolvers.starttiming() resolvers.prependhash('zip',archive) resolvers.extendtexmfvariable(archive) registeredfiles[archive]=z - instance.files[archive]=resolvers.registerzipfile(z,tree) - statistics.stoptiming(instance) + resolvers.registerfilehash(archive,resolvers.registerzipfile(z,tree)) + resolvers.stoptiming() elseif trace_locating then report_zip("registering: unknown archive %a",archive) end @@ -19323,7 +20126,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-sch"] = package.loaded["data-sch"] or true --- original size: 6653, stripped down to: 5467 +-- original size: 6753, stripped down to: 5511 if not modules then modules={} end modules ['data-sch']={ version=1.001, @@ -19332,13 +20135,14 @@ if not modules then modules={} end modules ['data-sch']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local load=load +local load,tonumber=load,tonumber local gsub,concat,format=string.gsub,table.concat,string.format local finders,openers,loaders=resolvers.finders,resolvers.openers,resolvers.loaders local trace_schemes=false trackers.register("resolvers.schemes",function(v) trace_schemes=v end) local report_schemes=logs.reporter("resolvers","schemes") local http=require("socket.http") local ltn12=require("ltn12") +if mbox then mbox=nil end local resolvers=resolvers local schemes=resolvers.schemes or {} resolvers.schemes=schemes @@ -19378,7 +20182,7 @@ local runner=sandbox.registerrunner { name="curl resolver", method="execute", program="curl", - template="--silent -- insecure --create-dirs --output %cachename% %original%", + template="--silent --insecure --create-dirs --output %cachename% %original%", checkers={ cachename="cache", original="url", @@ -19624,7 +20428,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-aux"] = package.loaded["data-aux"] or true --- original size: 2431, stripped down to: 1996 +-- original size: 2438, stripped down to: 2003 if not modules then modules={} end modules ['data-aux']={ version=1.001, @@ -19660,7 +20464,7 @@ function resolvers.updatescript(oldname,newname) if trace_locating then report_scripts("old and new script are the same") end - elseif not find(newscript,scriptpath) then + elseif not find(newscript,scriptpath,1,true) then if trace_locating then report_scripts("new script should come from %a",scriptpath) end @@ -19747,7 +20551,7 @@ do -- create closure to overcome 200 locals limit package.loaded["data-lst"] = package.loaded["data-lst"] or true --- original size: 2734, stripped down to: 2354 +-- original size: 1823, stripped down to: 1591 if not modules then modules={} end modules ['data-lst']={ version=1.001, @@ -19756,14 +20560,14 @@ if not modules then modules={} end modules ['data-lst']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local rawget,type,next=rawget,type,next -local find,concat,upper=string.find,table.concat,string.upper -local fastcopy,sortedpairs=table.fastcopy,table.sortedpairs +local type=type +local concat,sortedhash=table.concat,table.sortedhash local resolvers=resolvers local listers=resolvers.listers or {} resolvers.listers=listers local resolveprefix=resolvers.resolve local report_lists=logs.reporter("resolvers","lists") +local report_resolved=logs.reporter("system","resolved") local function tabstr(str) if type(str)=='table' then return concat(str," | ") @@ -19772,39 +20576,17 @@ local function tabstr(str) end end function listers.variables(pattern) - local instance=resolvers.instance - local environment=instance.environment - local variables=instance.variables - local expansions=instance.expansions - local pattern=upper(pattern or "") - local configured={} - local order=instance.order - for i=1,#order do - for k,v in next,order[i] do - if v~=nil and configured[k]==nil then - configured[k]=v - end - end - end - local env=fastcopy(environment) - local var=fastcopy(variables) - local exp=fastcopy(expansions) - for key,value in sortedpairs(configured) do - if key~="" and (pattern=="" or find(upper(key),pattern)) then - report_lists(key) - report_lists(" env: %s",tabstr(rawget(environment,key)) or "unset") - report_lists(" var: %s",tabstr(configured[key]) or "unset") - report_lists(" exp: %s",tabstr(expansions[key]) or "unset") - report_lists(" res: %s",tabstr(resolveprefix(expansions[key])) or "unset") - end - end - instance.environment=fastcopy(env) - instance.variables=fastcopy(var) - instance.expansions=fastcopy(exp) + local result=resolvers.knownvariables(pattern) + for key,value in sortedhash(result) do + report_lists(key) + report_lists(" env: %s",tabstr(value.environment or "unset")) + report_lists(" var: %s",tabstr(value.variable or "unset")) + report_lists(" exp: %s",tabstr(value.expansion or "unset")) + report_lists(" res: %s",tabstr(value.resolved or "unset")) + end end -local report_resolved=logs.reporter("system","resolved") function listers.configurations() - local configurations=resolvers.instance.specification + local configurations=resolvers.configurationfiles() for i=1,#configurations do report_resolved("file : %s",resolveprefix(configurations[i])) end @@ -19827,7 +20609,7 @@ do -- create closure to overcome 200 locals limit package.loaded["util-lib"] = package.loaded["util-lib"] or true --- original size: 13595, stripped down to: 7500 +-- original size: 14943, stripped down to: 8305 if not modules then modules={} end modules ['util-lib']={ version=1.001, @@ -19846,6 +20628,7 @@ local pathpart=file.pathpart local nameonly=file.nameonly local joinfile=file.join local removesuffix=file.removesuffix +local addsuffix=file.addsuffix local findfile=resolvers.findfile local findfiles=resolvers.findfiles local expandpaths=resolvers.expandedpathlistfromvariable @@ -19865,13 +20648,20 @@ local function locate(required,version,trace,report,action) local required_path=pathpart(required_full) local required_base=nameonly(required_full) if qualifiedpath(required) then - if isfile(required) then + if isfile(addsuffix(required,os.libsuffix)) then + if trace then + report("qualified name %a found",required) + end found_library=required + else + if trace then + report("qualified name %a not found",required) + end end else local required_name=required_base.."."..os.libsuffix local version=type(version)=="string" and version~="" and version or false - local engine=environment.ownmain or false + local engine="luatex" if trace and not done then local list=expandpaths("lib") for i=1,#list do @@ -19930,9 +20720,11 @@ local function locate(required,version,trace,report,action) end package.extralibpath(environment.ownpath) local paths=package.libpaths() + local pattern="/[^/]+%."..os.libsuffix.."$" for i=1,#paths do - local found=check(lfs.isfile) - if found and (not checkpattern or find(found,checkpattern)) then + required_path=gsub(paths[i],pattern,"") + local found=check(lfs.isfound) + if type(found)=="string" and (not checkpattern or find(found,checkpattern)) then return found end end @@ -19962,18 +20754,20 @@ local function locate(required,version,trace,report,action) if trace then report("found: %a",found_library) end - local message,result=action(found_library,required_base) + local result,message=action(found_library,required_base) if result then library=result else library=false - report("load error: message %a, library %a",tostring(message),found_library or "no library") + report("load error: message %a, library %a",tostring(message or "unknown"),found_library or "no library") end end - if not library then - report("unknown: %a",required) - elseif trace then - report("stored: %a",required) + if trace then + if not library then + report("unknown library: %a",required) + else + report("stored library: %a",required) + end end return library end @@ -20000,13 +20794,12 @@ do local libtype=type(library) if libtype=="function" then library=library() - message=true else report_swiglib("load error: %a returns %a, message %a, library %a",opener,libtype,(string.gsub(message or "no message","[%s]+$","")),found_library or "no library") library=false end popdir() - return message,library + return library end) loadedlibs[required]=library or false end @@ -20050,29 +20843,48 @@ if FFISUPPORTED and ffi and ffi.load then local trace_ffilib=false local savedffiload=ffi.load trackers.register("resolvers.ffilib",function(v) trace_ffilib=v end) + local loaded={} local function locateindeed(name) - local message,library=pcall(savedffiload,removesuffix(name)) - if type(library)=="userdata" then - return library - else - return false + name=removesuffix(name) + local l=loaded[name] + if l==nil then + local message,library=pcall(savedffiload,name) + if type(message)=="userdata" then + l=message + elseif type(library)=="userdata" then + l=library + else + l=false + end + loaded[name]=l + elseif trace_ffilib then + report_ffilib("reusing already loaded %a",name) end + return l end - function ffilib(required,version) - if version=="system" then + function ffilib(name,version) + name=removesuffix(name) + local l=loaded[name] + if l~=nil then + if trace_ffilib then + report_ffilib("reusing already loaded %a",name) + end + return l + elseif version=="system" then return locateindeed(name) else - return locate(required,version,trace_ffilib,report_ffilib,locateindeed) + return locate(name,version,trace_ffilib,report_ffilib,locateindeed) end end function ffi.load(name) local library=ffilib(name) if type(library)=="userdata" then return library - else + end + if trace_ffilib then report_ffilib("trying to load %a using normal loader",name) - return savedffiload(name) end + return savedffiload(name) end end @@ -20186,7 +20998,7 @@ do -- create closure to overcome 200 locals limit package.loaded["luat-fmt"] = package.loaded["luat-fmt"] or true --- original size: 9144, stripped down to: 7291 +-- original size: 9268, stripped down to: 7401 if not modules then modules={} end modules ['luat-fmt']={ version=1.001, @@ -20225,6 +21037,9 @@ local function secondaryflags() if arguments.silent then flags[#flags+1]="--c:silent" end + if arguments.errors then + flags[#flags+1]="--c:errors" + end if arguments.jit then flags[#flags+1]="--c:jiton" end @@ -20261,6 +21076,7 @@ local runners={ function environment.make_format(name,arguments) local engine=environment.ownmain or "luatex" local silent=environment.arguments.silent + local errors=environment.arguments.errors local olddir=dir.current() local path=caches.getwritablepath("formats",engine) or "" if path~="" then @@ -20416,10 +21232,10 @@ end end -- of closure --- used libraries : l-lua.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua +-- used libraries : l-lua.lua l-macro.lua l-sandbox.lua l-package.lua l-lpeg.lua l-function.lua l-string.lua l-table.lua l-io.lua l-number.lua l-set.lua l-os.lua l-file.lua l-gzip.lua l-md5.lua l-url.lua l-dir.lua l-boolean.lua l-unicode.lua l-math.lua util-str.lua util-tab.lua util-fil.lua util-sac.lua util-sto.lua util-prs.lua util-fmt.lua trac-set.lua trac-log.lua trac-inf.lua trac-pro.lua util-lua.lua util-deb.lua util-tpl.lua util-sbx.lua util-mrg.lua util-env.lua luat-env.lua lxml-tab.lua lxml-lpt.lua lxml-mis.lua lxml-aux.lua lxml-xml.lua trac-xml.lua data-ini.lua data-exp.lua data-env.lua data-tmp.lua data-met.lua data-res.lua data-pre.lua data-inp.lua data-out.lua data-fil.lua data-con.lua data-use.lua data-zip.lua data-tre.lua data-sch.lua data-lua.lua data-aux.lua data-tmf.lua data-lst.lua util-lib.lua luat-sta.lua luat-fmt.lua -- skipped libraries : - --- original bytes : 842443 --- stripped bytes : 306317 +-- original bytes : 874849 +-- stripped bytes : 317531 -- end library merge @@ -20443,6 +21259,7 @@ local owntree = environment and environment.ownpath or ownpath local ownlibs = { -- order can be made better 'l-lua.lua', + 'l-macro.lua', 'l-sandbox.lua', 'l-package.lua', 'l-lpeg.lua', @@ -20607,30 +21424,37 @@ local e_verbose = false -- some common flags (also passed through environment) local e_silent = environment.argument("silent") +local e_errors = environment.argument("errors") local e_noconsole = environment.argument("noconsole") local e_trackers = environment.argument("trackers") local e_directives = environment.argument("directives") local e_experiments = environment.argument("experiments") -if e_silent == true then - e_silent = "*" +local t = { } + +if type(e_directives) == "string" then + t[#t+1] = e_directives end if type(e_silent) == "string" then - if type(e_directives) == "string" then - e_directives = format("%s,logs.blocked={%s}",e_directives,e_silent) - else - e_directives = format("logs.blocked={%s}",e_silent) - end + t[#t+1] = format("logs.blocked={%s}",e_silent) +elseif e_silent == true then + t[#t+1] = "logs.blocked" +end + +if type(e_errors) == "string" then + t[#t+1] = format("logs.errors={%s}",e_errors) +elseif e_errors == true then + t[#t+1] = "logs.errors" end if e_noconsole then - if type(e_directives) == "string" then - e_directives = format("%s,logs.target=file",e_directives) - else - e_directives = format("logs.target=file") - end + t[#t+1] = format("logs.target=file") +end + +if #t > 0 then + e_directives = concat(t,",") end if e_trackers then trackers .enable(e_trackers) end @@ -20643,7 +21467,7 @@ if not environment.experiments then environment.experiments = e_experiments end -- -local instance = resolvers.reset() +resolvers.reset() local helpinfo = [[ <?xml version="1.0" ?> @@ -20651,7 +21475,7 @@ local helpinfo = [[ <metadata> <entry name="name">mtxrun</entry> <entry name="detail">ConTeXt TDS Runner Tool</entry> - <entry name="version">1.32</entry> + <entry name="version">1.33</entry> </metadata> <flags> <category name="basic"> @@ -21199,7 +22023,7 @@ function runners.execute_ctx_script(filename,...) end -- retry after generate but only if --autogenerate if fullname == "" and environment.argument("autogenerate") then -- might become the default - instance.renewcache = true + resolvers.renewcache() trackers.enable("resolvers.locating") resolvers.load() -- @@ -21224,7 +22048,7 @@ function runners.execute_ctx_script(filename,...) end filename = environment.files[1] if e_verbose then - report("using script: %s\n",fullname) + report("using script: %s (if --path is used don't run on path where mtxrun lives)\n",fullname) end environment.ownscript = fullname dofile(fullname) @@ -21378,8 +22202,6 @@ local before, after = environment.splitarguments(filename) environment.arguments_before, environment.arguments_after = before, after environment.initializearguments(before) -instance.lsrmode = environment.argument("lsr") or false - e_verbose = environment.arguments["verbose"] -- delayed till here (we need the ones before script) if e_verbose then @@ -21466,7 +22288,7 @@ else function runners.loadbase(...) if not resolvers.load(...) then report("forcing cache reload") - instance.renewcache = true + resolvers.renewcache() trackers.enable("resolvers.locating") if not resolvers.load(...) then report("the resolver databases are not present or outdated") @@ -21480,6 +22302,42 @@ end -- joke .. reminds me of messing with gigi terminals +do + + local a_locale = e_argument("locale") + + if a_locale then + + -- I really hate this crap but am too tired of discussing it over and over + -- again so for the sake of usiage outside context we will provide ways to + -- use locales in an otherwise supposed to be locale agnostic system. And + -- forget about support in case of interferences. + + report() + report(what == "force" and "forcing locale:" or "original locale:") + report() + report(" collate : %s",status.lc_collate or "<unset>") + report(" ctype : %s",status.lc_ctype or "<unset>") + report(" monetary : %s",status.lc_monetary or "<unset>") + report(" numeric : %s",status.lc_numeric or "<unset>") + report(" time : %s",status.lc_time or "<unset>") + report() + + end + + if a_locale == "force" then + os.setlocale(status.lc_collate ,"collate") + os.setlocale(status.lc_ctype ,"ctype") + os.setlocale(status.lc_monetary,"monetary") + os.setlocale(status.lc_numeric ,"numeric") + os.setlocale(status.lc_time ,"time") + else + function os.setlocale() + end + end + +end + if e_argument("ansi") then logs.setformatters("ansi") @@ -21673,7 +22531,7 @@ elseif e_argument("find-path") then -- luatools: runners.execute_ctx_script("mtx-base","--find-path",filename) resolvers.load() - local path = resolvers.findpath(filename, instance.my_format) + local path = resolvers.findpath(filename) if e_verbose then report(path) else @@ -21754,7 +22612,7 @@ elseif e_argument("generate") then trackers.enable("resolvers.locating") resolvers.renew(filename) else - instance.renewcache = true + resolvers.renewcache() trackers.enable("resolvers.locating") resolvers.load() end @@ -21814,6 +22672,10 @@ elseif e_argument("systeminfo") then runners.systeminfo() +elseif e_argument("locale") then + + -- already done + elseif e_argument("help") or filename=='help' or filename == "" then application.help() |