summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua
diff options
context:
space:
mode:
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.lua704
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("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+P(1))^0)
-lpeg.patterns.texescape=Cs((C(S("#$%\\{}"))/"\\%1"+P(1))^0)
+patterns.xmlescape=Cs((P("<")/"&lt;"+P(">")/"&gt;"+P("&")/"&amp;"+P('"')/"&quot;"+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