diff options
Diffstat (limited to 'Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua')
-rw-r--r-- | Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua | 704 |
1 files changed, 407 insertions, 297 deletions
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua index 249f8c7f51b..8c9e4c3a126 100644 --- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua +++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua @@ -1,6 +1,6 @@ -- merged file : lualibs-extended-merged.lua -- parent file : lualibs-extended.lua --- merge date : Thu May 23 21:13:25 2013 +-- merge date : Wed Jul 24 11:48:34 2013 do -- begin closure to overcome local limits and interference @@ -178,7 +178,7 @@ setmetatable(arguments,{ __index=function(t,k) end }) local prefix_any=C((S("+- .")+R("09"))^0) -local prefix_tab=C((1-R("az","AZ","09","%%"))^0) +local prefix_tab=P("{")*C((1-P("}"))^0)*P("}")+C((1-R("az","AZ","09","%%"))^0) local format_s=function(f) n=n+1 if f and f~="" then @@ -208,7 +208,7 @@ local format_i=function(f) if f and f~="" then return format("format('%%%si',a%s)",f,n) else - return format("a%s",n) + return format("format('%%i',a%s)",n) end end local format_d=format_i @@ -428,14 +428,14 @@ local builder=Cs { "start", ["b"]=(prefix_any*P("b"))/format_b, ["t"]=(prefix_tab*P("t"))/format_t, ["T"]=(prefix_tab*P("T"))/format_T, - ["l"]=(prefix_tab*P("l"))/format_l, - ["L"]=(prefix_tab*P("L"))/format_L, + ["l"]=(prefix_any*P("l"))/format_l, + ["L"]=(prefix_any*P("L"))/format_L, ["I"]=(prefix_any*P("I"))/format_I, ["w"]=(prefix_any*P("w"))/format_w, ["W"]=(prefix_any*P("W"))/format_W, ["a"]=(prefix_any*P("a"))/format_a, ["A"]=(prefix_any*P("A"))/format_A, - ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%%%")^1)/format_rest, + ["*"]=Cs(((1-P("%"))^1+P("%%")/"%%")^1)/format_rest, ["!"]=Carg(2)*prefix_any*P("!")*C((1-P("!"))^1)*P("!")/format_extension, } local direct=Cs ( @@ -481,10 +481,13 @@ local function add(t,name,template,preamble) end end strings.formatters.add=add -lpeg.patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) -lpeg.patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0) +patterns.xmlescape=Cs((P("<")/"<"+P(">")/">"+P("&")/"&"+P('"')/"""+P(1))^0) +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('"')) 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]]) end -- closure @@ -505,7 +508,7 @@ local concat,insert,remove=table.concat,table.insert,table.remove local setmetatable,getmetatable,tonumber,tostring=setmetatable,getmetatable,tonumber,tostring local type,next,rawset,tonumber,tostring,load,select=type,next,rawset,tonumber,tostring,load,select local lpegmatch,P,Cs,Cc=lpeg.match,lpeg.P,lpeg.Cs,lpeg.Cc -local serialize,sortedkeys,sortedpairs=table.serialize,table.sortedkeys,table.sortedpairs +local sortedkeys,sortedpairs=table.sortedkeys,table.sortedpairs local formatters=string.formatters local splitter=lpeg.tsplitat(".") function tables.definetable(target,nofirst,nolast) @@ -710,47 +713,58 @@ function tables.encapsulate(core,capsule,protect) } ) end end -local function fastserialize(t,r,outer) - r[#r+1]="{" - local n=#t - if n>0 then - for i=1,n do - local v=t[i] - local tv=type(v) - if tv=="string" then - r[#r+1]=formatters["%q,"](v) - elseif tv=="number" then - r[#r+1]=formatters["%s,"](v) - elseif tv=="table" then - fastserialize(v,r) - elseif tv=="boolean" then - r[#r+1]=formatters["%S,"](v) +local f_hashed_string=formatters["[%q]=%q,"] +local f_hashed_number=formatters["[%q]=%s,"] +local f_hashed_boolean=formatters["[%q]=%l,"] +local f_hashed_table=formatters["[%q]="] +local f_indexed_string=formatters["%q,"] +local f_indexed_number=formatters["%s,"] +local f_indexed_boolean=formatters["%l,"] +function table.fastserialize(t,prefix) + local r={ prefix or "return" } + local m=1 + local function fastserialize(t,outer) + local n=#t + m=m+1 + r[m]="{" + if n>0 then + for i=1,n do + local v=t[i] + local tv=type(v) + if tv=="string" then + m=m+1 r[m]=f_indexed_string(v) + elseif tv=="number" then + m=m+1 r[m]=f_indexed_number(v) + elseif tv=="table" then + fastserialize(v) + elseif tv=="boolean" then + m=m+1 r[m]=f_indexed_boolean(v) + end end - end - else - for k,v in next,t do - local tv=type(v) - if tv=="string" then - r[#r+1]=formatters["[%q]=%q,"](k,v) - elseif tv=="number" then - r[#r+1]=formatters["[%q]=%s,"](k,v) - elseif tv=="table" then - r[#r+1]=formatters["[%q]="](k) - fastserialize(v,r) - elseif tv=="boolean" then - r[#r+1]=formatters["[%q]=%S,"](k,v) + else + for k,v in next,t do + local tv=type(v) + if tv=="string" then + m=m+1 r[m]=f_hashed_string(k,v) + elseif tv=="number" then + m=m+1 r[m]=f_hashed_number(k,v) + elseif tv=="table" then + m=m+1 r[m]=f_hashed_table(k) + fastserialize(v) + elseif tv=="boolean" then + m=m+1 r[m]=f_hashed_boolean(k,v) + end end end + m=m+1 + if outer then + r[m]="}" + else + r[m]="}," + end + return r end - if outer then - r[#r+1]="}" - else - r[#r+1]="}," - end - return r -end -function table.fastserialize(t,prefix) - return concat(fastserialize(t,{ prefix or "return" },true)) + return concat(fastserialize(t,true)) end function table.deserialize(str) if not str or str=="" then @@ -781,9 +795,12 @@ function table.load(filename,loader) end end function table.save(filename,t,n,...) - io.savedata(filename,serialize(t,n==nil and true or n,...)) + io.savedata(filename,table.serialize(t,n==nil and true or n,...)) end -local function slowdrop(t) +local f_key_value=formatters["%s=%q"] +local f_add_table=formatters[" {%t},\n"] +local f_return_table=formatters["return {\n%t}"] +local function slowdrop(t) local r={} local l={} for i=1,#t do @@ -791,23 +808,25 @@ local function slowdrop(t) local j=0 for k,v in next,ti do j=j+1 - l[j]=formatters["%s=%q"](k,v) + l[j]=f_key_value(k,v) end - r[i]=formatters[" {%t},\n"](l) + r[i]=f_add_table(l) end - return formatters["return {\n%st}"](r) + return f_return_table(r) end local function fastdrop(t) local r={ "return {\n" } + local m=1 for i=1,#t do local ti=t[i] - r[#r+1]=" {" + m=m+1 r[m]=" {" for k,v in next,ti do - r[#r+1]=formatters["%s=%q"](k,v) + m=m+1 r[m]=f_key_value(k,v) end - r[#r+1]="},\n" + m=m+1 r[m]="},\n" end - r[#r+1]="}" + m=m+1 + r[m]="}" return concat(r) end function table.drop(t,slow) @@ -842,6 +861,216 @@ function table.twowaymapper(t) setmetatable(t,selfmapper) return t end +local f_start_key_idx=formatters["%w{"] +local f_start_key_num=formatters["%w[%s]={"] +local f_start_key_str=formatters["%w[%q]={"] +local f_start_key_boo=formatters["%w[%l]={"] +local f_start_key_nop=formatters["%w{"] +local f_stop=formatters["%w},"] +local f_key_num_value_num=formatters["%w[%s]=%s,"] +local f_key_str_value_num=formatters["%w[%q]=%s,"] +local f_key_boo_value_num=formatters["%w[%l]=%s,"] +local f_key_num_value_str=formatters["%w[%s]=%q,"] +local f_key_str_value_str=formatters["%w[%q]=%q,"] +local f_key_boo_value_str=formatters["%w[%l]=%q,"] +local f_key_num_value_boo=formatters["%w[%s]=%l,"] +local f_key_str_value_boo=formatters["%w[%q]=%l,"] +local f_key_boo_value_boo=formatters["%w[%l]=%l,"] +local f_key_num_value_not=formatters["%w[%s]={},"] +local f_key_str_value_not=formatters["%w[%q]={},"] +local f_key_boo_value_not=formatters["%w[%l]={},"] +local f_key_num_value_seq=formatters["%w[%s]={ %, t },"] +local f_key_str_value_seq=formatters["%w[%q]={ %, t },"] +local f_key_boo_value_seq=formatters["%w[%l]={ %, t },"] +local f_val_num=formatters["%w%s,"] +local f_val_str=formatters["%w%q,"] +local f_val_boo=formatters["%w%l,"] +local f_val_not=formatters["%w{},"] +local f_val_seq=formatters["%w{ %, t },"] +local f_table_return=formatters["return {"] +local f_table_name=formatters["%s={"] +local f_table_direct=formatters["{"] +local f_table_entry=formatters["[%q]={"] +local f_table_finish=formatters["}"] +local spaces=utilities.strings.newrepeater(" ") +local serialize=table.serialize +function table.serialize(root,name,specification) + if type(specification)=="table" then + return serialize(root,name,specification) + end + local t + local n=1 + local function simple_table(t) + if #t>0 then + local n=0 + for _,v in next,t do + n=n+1 + if type(v)=="table" then + return nil + end + end + if n==#t then + local tt={} + local nt=0 + for i=1,#t do + local v=t[i] + local tv=type(v) + nt=nt+1 + if tv=="number" then + tt[nt]=v + elseif tv=="string" then + tt[nt]=format("%q",v) + elseif tv=="boolean" then + tt[nt]=v and "true" or "false" + else + return nil + end + end + return tt + end + end + return nil + end + local function do_serialize(root,name,depth,level,indexed) + if level>0 then + n=n+1 + if indexed then + t[n]=f_start_key_idx(depth) + else + local tn=type(name) + if tn=="number" then + t[n]=f_start_key_num(depth,name) + elseif tn=="string" then + t[n]=f_start_key_str(depth,name) + elseif tn=="boolean" then + t[n]=f_start_key_boo(depth,name) + else + t[n]=f_start_key_nop(depth) + end + end + depth=depth+1 + end + if root and next(root) then + local first=nil + local last=0 + last=#root + for k=1,last do + if root[k]==nil then + last=k-1 + break + end + end + if last>0 then + first=1 + end + local sk=sortedkeys(root) + for i=1,#sk do + local k=sk[i] + local v=root[k] + local tv=type(v) + local tk=type(k) + if first and tk=="number" and k>=first and k<=last then + if tv=="number" then + n=n+1 t[n]=f_val_num(depth,v) + elseif tv=="string" then + n=n+1 t[n]=f_val_str(depth,v) + elseif tv=="table" then + if not next(v) then + n=n+1 t[n]=f_val_not(depth) + else + local st=simple_table(v) + if st then + n=n+1 t[n]=f_val_seq(depth,st) + else + do_serialize(v,k,depth,level+1,true) + end + end + elseif tv=="boolean" then + n=n+1 t[n]=f_val_boo(depth,v) + end + elseif tv=="number" then + if tk=="number" then + n=n+1 t[n]=f_key_num_value_num(depth,k,v) + elseif tk=="string" then + n=n+1 t[n]=f_key_str_value_num(depth,k,v) + elseif tk=="boolean" then + n=n+1 t[n]=f_key_boo_value_num(depth,k,v) + end + elseif tv=="string" then + if tk=="number" then + n=n+1 t[n]=f_key_num_value_str(depth,k,v) + elseif tk=="string" then + n=n+1 t[n]=f_key_str_value_str(depth,k,v) + elseif tk=="boolean" then + n=n+1 t[n]=f_key_boo_value_str(depth,k,v) + end + elseif tv=="table" then + if not next(v) then + if tk=="number" then + n=n+1 t[n]=f_key_num_value_not(depth,k,v) + elseif tk=="string" then + n=n+1 t[n]=f_key_str_value_not(depth,k,v) + elseif tk=="boolean" then + n=n+1 t[n]=f_key_boo_value_not(depth,k,v) + end + else + local st=simple_table(v) + if not st then + do_serialize(v,k,depth,level+1) + elseif tk=="number" then + n=n+1 t[n]=f_key_num_value_seq(depth,k,st) + elseif tk=="string" then + n=n+1 t[n]=f_key_str_value_seq(depth,k,st) + elseif tk=="boolean" then + n=n+1 t[n]=f_key_boo_value_seq(depth,k,st) + end + end + elseif tv=="boolean" then + if tk=="number" then + n=n+1 t[n]=f_key_num_value_boo(depth,k,v) + elseif tk=="string" then + n=n+1 t[n]=f_key_str_value_boo(depth,k,v) + elseif tk=="boolean" then + n=n+1 t[n]=f_key_boo_value_boo(depth,k,v) + end + end + end + end + if level>0 then + n=n+1 t[n]=f_stop(depth-1) + end + end + local tname=type(name) + if tname=="string" then + if name=="return" then + t={ f_table_return() } + else + t={ f_table_name(name) } + end + elseif tname=="number" then + t={ f_table_entry(name) } + elseif tname=="boolean" then + if name then + t={ f_table_return() } + else + t={ f_table_direct() } + end + else + t={ f_table_name("t") } + end + if root then + if getmetatable(root) then + local dummy=root._w_h_a_t_e_v_e_r_ + root._w_h_a_t_e_v_e_r_=nil + end + if next(root) then + do_serialize(root,name,1,0) + end + end + n=n+1 + t[n]=f_table_finish() + return concat(t,"\n") +end end -- closure @@ -1008,8 +1237,9 @@ if not modules then modules={} end modules ['util-prs']={ local lpeg,table,string=lpeg,table,string local P,R,V,S,C,Ct,Cs,Carg,Cc,Cg,Cf,Cp=lpeg.P,lpeg.R,lpeg.V,lpeg.S,lpeg.C,lpeg.Ct,lpeg.Cs,lpeg.Carg,lpeg.Cc,lpeg.Cg,lpeg.Cf,lpeg.Cp local lpegmatch,lpegpatterns=lpeg.match,lpeg.patterns -local concat,format,gmatch,find=table.concat,string.format,string.gmatch,string.find +local concat,gmatch,find=table.concat,string.gmatch,string.find local tostring,type,next,rawset=tostring,type,next,rawset +local mod,div=math.mod,math.div utilities=utilities or {} local parsers=utilities.parsers or {} utilities.parsers=parsers @@ -1317,7 +1547,7 @@ function parsers.csvsplitter(specification) end whatever=quotedata+whatever end - local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r"))^0 ) + local parser=Ct((Ct(whatever*(separator*whatever)^0)*S("\n\r")^1)^0 ) return function(data) return lpegmatch(parser,data) end @@ -1437,6 +1667,18 @@ local merge=Cf(parser,process) function utilities.parsers.mergehashes(hash,list) return lpegmatch(merge,list,1,hash) end +function utilities.parsers.runtime(time) + if not time then + time=os.runtime() + end + local days=div(time,24*60*60) + time=mod(time,24*60*60) + local hours=div(time,60*60) + time=mod(time,60*60) + local minutes=div(time,60) + local seconds=mod(time,60) + return days,hours,minutes,seconds +end end -- closure @@ -1454,6 +1696,7 @@ local P,S,R,Cc,C,lpegmatch=lpeg.P,lpeg.S,lpeg.R,lpeg.Cc,lpeg.C,lpeg.match local allocate=utilities.storage.allocate local setmetatableindex=table.setmetatableindex local formatters=string.formatters +local texget=tex and tex.get or function() return 65536*10*100 end number=number or {} local number=number number.tonumberf=function(n) return match(format("%.20f",n),"(.-0?)0*$") end @@ -1500,7 +1743,7 @@ function number.tociceros (n,fmt) return numbertodimen(n,"cc",fmt) end function number.tonewdidots (n,fmt) return numbertodimen(n,"nd",fmt) end function number.tonewciceros (n,fmt) return numbertodimen(n,"nc",fmt) end local amount=(S("+-")^0*R("09")^0*P(".")^0*R("09")^0)+Cc("0") -local unit=R("az")^1 +local unit=R("az")^1+P("%") local dimenpair=amount/tonumber*(unit^1/dimenfactors+Cc(1)) lpeg.patterns.dimenpair=dimenpair local splitter=amount/tonumber*C(unit^1) @@ -1574,10 +1817,10 @@ function dimen(a) a=k else local value,unit=lpegmatch(dimenpair,a) - if type(unit)=="function" then - k=value/unit() + if value and unit then + k=value/unit else - k=value/unit + k=0 end known[a]=k a=k @@ -1612,7 +1855,7 @@ function number.toscaled(d) return format("%0.5f",d/2^16) end function number.percent(n,d) - d=d or tex.hsize + d=d or texget("hsize") if type(d)=="string" then d=stringtodimen(d) end @@ -1648,8 +1891,16 @@ local colon=P(":") local dquote=P('"') local whitespace=lpeg.patterns.whitespace local optionalws=whitespace^0 -local escape=C(P("\\u")/"0x"*S("09","AF","af"))/function(s) return utfchar(tonumber(s)) end -local jstring=dquote*Cs((escape+(1-dquote))^0)*dquote +local escapes={ + ["b"]="\010", + ["f"]="\014", + ["n"]="\n", + ["r"]="\r", + ["t"]="\t", +} +local escape_un=C(P("\\u")/"0x"*S("09","AF","af"))/function(s) return utfchar(tonumber(s)) end +local escape_bs=P([[\]])/""*(P(1)/escapes) +local jstring=dquote*Cs((escape_un+escape_bs+(1-dquote))^0)*dquote local jtrue=P("true")*Cc(true) local jfalse=P("false")*Cc(false) local jnull=P("null")*Cc(nil) @@ -1732,16 +1983,19 @@ if not modules then modules={} end modules ['trac-inf']={ copyright="PRAGMA ADE / ConTeXt Development Team", license="see context related readme files" } -local type,tonumber=type,tonumber +local type,tonumber,select=type,tonumber,select local format,lower=string.format,string.lower local concat=table.concat local clock=os.gettimeofday or os.clock +local setmetatableindex=table.setmetatableindex +local serialize=table.serialize +local formatters=string.formatters statistics=statistics or {} local statistics=statistics statistics.enable=true statistics.threshold=0.01 local statusinfo,n,registered,timers={},0,{},{} -table.setmetatableindex(timers,function(t,k) +setmetatableindex(timers,function(t,k) local v={ timing=0,loadtime=0 } t[k]=v return v @@ -1870,6 +2124,16 @@ function statistics.timed(action) stoptiming("run") report("total runtime: %s",elapsedtime("run")) end +function statistics.tracefunction(base,tag,...) + for i=1,select("#",...) do + local name=select(i,...) + local stat={} + local func=base[name] + setmetatableindex(stat,function(t,k) t[k]=0 return 0 end) + base[name]=function(n,k,v) stat[k]=stat[k]+1 return func(n,k,v) end + statistics.register(formatters["%s.%s"](tag,name),function() return serialize(stat,"calls") end) + end +end commands=commands or {} function commands.resettimer(name) resettiming(name or "whatever") @@ -1917,251 +2181,92 @@ luautilities.suffixes={ tua="tua", tuc="tuc", } -if jit or status.luatex_version>=74 then - local function register(name) - if tracestripping then - report_lua("stripped bytecode from %a",name or "unknown") - end - strippedchunks[#strippedchunks+1]=name - luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 - end - local function stupidcompile(luafile,lucfile,strip) - local code=io.loaddata(luafile) - if code and code~="" then - code=load(code) - if code then - code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) - if code and code~="" then - register(name) - io.savedata(lucfile,code) - return true,0 - end - else - report_lua("fatal error %a in file %a",1,luafile) - end - else - report_lua("fatal error %a in file %a",2,luafile) - end - return false,0 +local function register(name) + if tracestripping then + report_lua("stripped bytecode from %a",name or "unknown") end - function luautilities.loadedluacode(fullname,forcestrip,name) - name=name or fullname - local code=environment.loadpreprocessedfile and environment.loadpreprocessedfile(fullname) or loadfile(fullname) + strippedchunks[#strippedchunks+1]=name + luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 +end +local function stupidcompile(luafile,lucfile,strip) + local code=io.loaddata(luafile) + if code and code~="" then + code=load(code) if code then - code() - end - if forcestrip and luautilities.stripcode then - if type(forcestrip)=="function" then - forcestrip=forcestrip(fullname) - end - if forcestrip or luautilities.alwaysstripcode then + code=dump(code,strip and luautilities.stripcode or luautilities.alwaysstripcode) + if code and code~="" then register(name) - return load(dump(code,true)),0 - else - return code,0 + io.savedata(lucfile,code) + return true,0 end - elseif luautilities.alwaysstripcode then - register(name) - return load(dump(code,true)),0 else - return code,0 + report_lua("fatal error %a in file %a",1,luafile) end + else + report_lua("fatal error %a in file %a",2,luafile) end - function luautilities.strippedloadstring(code,forcestrip,name) - if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then - code=load(code) - if not code then - report_lua("fatal error %a in file %a",3,name) - end - register(name) - code=dump(code,true) - end - return load(code),0 - end - function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) - report_lua("compiling %a into %a",luafile,lucfile) - os.remove(lucfile) - local done=stupidcompile(luafile,lucfile,strip~=false) - if done then - report_lua("dumping %a into %a stripped",luafile,lucfile) - if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then - report_lua("removing %a",luafile) - os.remove(luafile) - end - end - return done - end - function luautilities.loadstripped(...) - local l=load(...) - if l then - return load(dump(l,true)) - end - end -else - local function register(name,before,after) - local delta=before-after - if tracestripping then - report_lua("bytecodes stripped from %a, # before %s, # after %s, delta %s",name,before,after,delta) - end - strippedchunks[#strippedchunks+1]=name - luautilities.nofstrippedchunks=luautilities.nofstrippedchunks+1 - luautilities.nofstrippedbytes=luautilities.nofstrippedbytes+delta - return delta - end - local strip_code_pc - if _MAJORVERSION==5 and _MINORVERSION==1 then - strip_code_pc=function(dump,name) - local before=#dump - local version,format,endian,int,size,ins,num=byte(dump,5,11) - local subint - if endian==1 then - subint=function(dump,i,l) - local val=0 - for n=l,1,-1 do - val=val*256+byte(dump,i+n-1) - end - return val,i+l - end - else - subint=function(dump,i,l) - local val=0 - for n=1,l,1 do - val=val*256+byte(dump,i+n-1) - end - return val,i+l - end - end - local strip_function - strip_function=function(dump) - local count,offset=subint(dump,1,size) - local stripped,dirty=rep("\0",size),offset+count - offset=offset+count+int*2+4 - offset=offset+int+subint(dump,offset,int)*ins - count,offset=subint(dump,offset,int) - for n=1,count do - local t - t,offset=subint(dump,offset,1) - if t==1 then - offset=offset+1 - elseif t==4 then - offset=offset+size+subint(dump,offset,size) - elseif t==3 then - offset=offset+num - end - end - count,offset=subint(dump,offset,int) - stripped=stripped..sub(dump,dirty,offset-1) - for n=1,count do - local proto,off=strip_function(sub(dump,offset,-1)) - stripped,offset=stripped..proto,offset+off-1 - end - offset=offset+subint(dump,offset,int)*int+int - count,offset=subint(dump,offset,int) - for n=1,count do - offset=offset+subint(dump,offset,size)+size+int*2 - end - count,offset=subint(dump,offset,int) - for n=1,count do - offset=offset+subint(dump,offset,size)+size - end - stripped=stripped..rep("\0",int*3) - return stripped,offset - end - dump=sub(dump,1,12)..strip_function(sub(dump,13,-1)) - local after=#dump - local delta=register(name,before,after) - return dump,delta - end + return false,0 +end +function luautilities.loadedluacode(fullname,forcestrip,name) + name=name or fullname + local code,message + if environment.loadpreprocessedfile then + code,message=environment.loadpreprocessedfile(fullname) else - strip_code_pc=function(dump,name) - return dump,0 - end + code,message=loadfile(fullname) end - function luautilities.loadedluacode(fullname,forcestrip,name) - local code=environment.loadpreprocessedfile and environment.preprocessedloadfile(fullname) or loadfile(fullname) - if code then - code() + if code then + code() + else + report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message") + end + if forcestrip and luautilities.stripcode then + if type(forcestrip)=="function" then + forcestrip=forcestrip(fullname) end - if forcestrip and luautilities.stripcode then - if type(forcestrip)=="function" then - forcestrip=forcestrip(fullname) - end - if forcestrip then - local code,n=strip_code_pc(dump(code),name) - return load(code),n - elseif luautilities.alwaysstripcode then - return load(strip_code_pc(dump(code),name)) - else - return code,0 - end - elseif luautilities.alwaysstripcode then - return load(strip_code_pc(dump(code),name)) + if forcestrip or luautilities.alwaysstripcode then + register(name) + return load(dump(code,true)),0 else return code,0 end + elseif luautilities.alwaysstripcode then + register(name) + return load(dump(code,true)),0 + else + return code,0 end - function luautilities.strippedloadstring(code,forcestrip,name) - local n=0 - if (forcestrip and luautilities.stripcode) or luautilities.alwaysstripcode then - code=load(code) - if not code then - report_lua("fatal error in file %a",name) - end - code,n=strip_code_pc(dump(code),name) - end - return load(code),n +end +function luautilities.strippedloadstring(code,forcestrip,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 - local function stupidcompile(luafile,lucfile,strip) - local code=io.loaddata(luafile) - local n=0 - if code and code~="" then - code=load(code) - if not code then - report_lua("fatal error in file %a",luafile) - end - code=dump(code) - if strip then - code,n=strip_code_pc(code,luautilities.stripcode or luautilities.alwaysstripcode,luafile) - end - if code and code~="" then - io.savedata(lucfile,code) - end - end - return n + if forcestrip and luautilities.stripcode or luautilities.alwaysstripcode then + register(name) + return load(dump(code,true)),0 + else + return code,0 end - local luac_normal="texluac -o %q %q" - local luac_strip="texluac -s -o %q %q" - function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) - report_lua("compiling %a into %a",luafile,lucfile) - os.remove(lucfile) - local done=false - if strip~=false then - strip=true - end - if forcestupidcompile then - fallback=true - elseif strip then - done=os.spawn(format(luac_strip,lucfile,luafile))==0 - else - done=os.spawn(format(luac_normal,lucfile,luafile))==0 - end - if not done and fallback then - local n=stupidcompile(luafile,lucfile,strip) - if n>0 then - report_lua("%a dumped into %a (%i bytes stripped)",luafile,lucfile,n) - else - report_lua("%a dumped into %a (unstripped)",luafile,lucfile) - end - cleanup=false - done=true - end - if done and cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then +end +function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) + report_lua("compiling %a into %a",luafile,lucfile) + os.remove(lucfile) + local done=stupidcompile(luafile,lucfile,strip~=false) + if done then + report_lua("dumping %a into %a stripped",luafile,lucfile) + if cleanup==true and lfs.isfile(lucfile) and lfs.isfile(luafile) then report_lua("removing %a",luafile) os.remove(luafile) end - return done end - luautilities.loadstripped=loadstring + return done +end +function luautilities.loadstripped(...) + local l=load(...) + if l then + return load(dump(l,true)) + end end end -- closure @@ -2278,7 +2383,7 @@ local trace_template=false trackers.register("templates.trace",function(v) trace local report_template=logs.reporter("template") local tostring=tostring local format,sub=string.format,string.sub -local P,C,Cs,Carg,lpegmatch=lpeg.P,lpeg.C,lpeg.Cs,lpeg.Carg,lpeg.match +local P,C,Cs,Carg,lpegmatch,lpegpatterns=lpeg.P,lpeg.C,lpeg.Cs,lpeg.Carg,lpeg.match,lpeg.patterns local replacer local function replacekey(k,t,how,recursive) local v=t[k] @@ -2305,10 +2410,12 @@ local sqlescape=lpeg.replacer { { "\r\n","\\n" }, { "\r","\\n" }, } -local sqlquotedescape=lpeg.Cs(lpeg.Cc("'")*sqlescape*lpeg.Cc("'")) +local sqlquoted=lpeg.Cs(lpeg.Cc("'")*sqlescape*lpeg.Cc("'")) +lpegpatterns.sqlescape=sqlescape +lpegpatterns.sqlquoted=sqlquoted local escapers={ lua=function(s) - return sub(format("%q",s),2,-2) + return lpegmatch(luaescape,s) end, sql=function(s) return lpegmatch(sqlescape,s) @@ -2319,11 +2426,9 @@ local quotedescapers={ return format("%q",s) end, sql=function(s) - return lpegmatch(sqlquotedescape,s) + return lpegmatch(sqlquoted,s) end, } -lpeg.patterns.sqlescape=sqlescape -lpeg.patterns.sqlescape=sqlquotedescape local luaescaper=escapers.lua local quotedluaescaper=quotedescapers.lua local function replacekeyunquoted(s,t,how,recurse) @@ -2360,6 +2465,11 @@ local function replace(str,mapping,how,recurse) end end templates.replace=replace +function templates.replacer(str,how,recurse) + return function(mapping) + return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str + end +end function templates.load(filename,mapping,how,recurse) local data=io.loaddata(filename) or "" if mapping and next(mapping) then |