summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/luatex/lualibs
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-07-24 21:47:53 +0000
committerKarl Berry <karl@freefriends.org>2013-07-24 21:47:53 +0000
commit42402bd9b4a14a3cc7c774c866fda4e419b9a4ee (patch)
tree33c0f31fffd538789552de57988c635997391606 /Master/texmf-dist/tex/luatex/lualibs
parent2ca350121961af1d06876475b5c661ebc41993e6 (diff)
lualibs (24jul13)
git-svn-id: svn://tug.org/texlive/trunk@31280 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/luatex/lualibs')
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua183
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-dir.lua3
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-extended-merged.lua704
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua4
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-file.lua26
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-io.lua1
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-lpeg.lua121
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua18
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua2
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua390
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua29
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-util-dim.lua32
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua16
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua325
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-util-prs.lua18
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua28
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua415
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tpl.lua30
-rw-r--r--Master/texmf-dist/tex/luatex/lualibs/lualibs.lua4
20 files changed, 1183 insertions, 1170 deletions
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
index fa28547b71f..ec738c2918f 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic-merged.lua
@@ -1,6 +1,6 @@
-- merged file : lualibs-basic-merged.lua
-- parent file : lualibs-basic.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
@@ -361,6 +361,7 @@ if not modules then modules={} end modules ['l-lpeg']={
license="see context related readme files"
}
lpeg=require("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
local floor=math.floor
@@ -376,13 +377,22 @@ patterns.anything=anything
patterns.endofstring=endofstring
patterns.beginofstring=alwaysmatched
patterns.alwaysmatched=alwaysmatched
-local digit,sign=R('09'),S('+-')
+local sign=S('+-')
+local zero=P('0')
+local digit=R('09')
+local octdigit=R("07")
+local lowercase=R("az")
+local uppercase=R("AZ")
+local underscore=P("_")
+local hexdigit=digit+lowercase+uppercase
local cr,lf,crlf=P("\r"),P("\n"),P("\r\n")
local newline=crlf+S("\r\n")
local escaped=P("\\")*anything
local squote=P("'")
local dquote=P('"')
local space=P(" ")
+local period=P(".")
+local comma=P(",")
local utfbom_32_be=P('\000\000\254\255')
local utfbom_32_le=P('\255\254\000\000')
local utfbom_16_be=P('\255\254')
@@ -421,23 +431,8 @@ local stripper=spacer^0*C((spacer^0*nonspacer^1)^0)
local collapser=Cs(spacer^0/""*nonspacer^0*((spacer^0/" "*nonspacer^1)^0))
patterns.stripper=stripper
patterns.collapser=collapser
-patterns.digit=digit
-patterns.sign=sign
-patterns.cardinal=sign^0*digit^1
-patterns.integer=sign^0*digit^1
-patterns.unsigned=digit^0*P('.')*digit^1
-patterns.float=sign^0*patterns.unsigned
-patterns.cunsigned=digit^0*P(',')*digit^1
-patterns.cfloat=sign^0*patterns.cunsigned
-patterns.number=patterns.float+patterns.integer
-patterns.cnumber=patterns.cfloat+patterns.integer
-patterns.oct=P("0")*R("07")^1
-patterns.octal=patterns.oct
-patterns.HEX=P("0x")*R("09","AF")^1
-patterns.hex=P("0x")*R("09","af")^1
-patterns.hexadecimal=P("0x")*R("09","AF","af")^1
-patterns.lowercase=R("az")
-patterns.uppercase=R("AZ")
+patterns.lowercase=lowercase
+patterns.uppercase=uppercase
patterns.letter=patterns.lowercase+patterns.uppercase
patterns.space=space
patterns.tab=P("\t")
@@ -445,12 +440,12 @@ patterns.spaceortab=patterns.space+patterns.tab
patterns.newline=newline
patterns.emptyline=newline^1
patterns.equal=P("=")
-patterns.comma=P(",")
-patterns.commaspacer=P(",")*spacer^0
-patterns.period=P(".")
+patterns.comma=comma
+patterns.commaspacer=comma*spacer^0
+patterns.period=period
patterns.colon=P(":")
patterns.semicolon=P(";")
-patterns.underscore=P("_")
+patterns.underscore=underscore
patterns.escaped=escaped
patterns.squote=squote
patterns.dquote=dquote
@@ -463,10 +458,29 @@ patterns.unspacer=((patterns.spacer^1)/"")^0
patterns.singlequoted=squote*patterns.nosquote*squote
patterns.doublequoted=dquote*patterns.nodquote*dquote
patterns.quoted=patterns.doublequoted+patterns.singlequoted
-patterns.propername=R("AZ","az","__")*R("09","AZ","az","__")^0*P(-1)
+patterns.digit=digit
+patterns.octdigit=octdigit
+patterns.hexdigit=hexdigit
+patterns.sign=sign
+patterns.cardinal=digit^1
+patterns.integer=sign^-1*digit^1
+patterns.unsigned=digit^0*period*digit^1
+patterns.float=sign^-1*patterns.unsigned
+patterns.cunsigned=digit^0*comma*digit^1
+patterns.cfloat=sign^-1*patterns.cunsigned
+patterns.number=patterns.float+patterns.integer
+patterns.cnumber=patterns.cfloat+patterns.integer
+patterns.oct=zero*octdigit^1
+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.propername=(uppercase+lowercase+underscore)*(uppercase+lowercase+underscore+digit)^0*endofstring
patterns.somecontent=(anything-newline-space)^1
patterns.beginline=#(1-newline)
-patterns.longtostring=Cs(whitespace^0/""*nonwhitespace^0*((whitespace^0/" "*(patterns.quoted+nonwhitespace)^1)^0))
+patterns.longtostring=Cs(whitespace^0/""*((patterns.quoted+nonwhitespace^1+whitespace^1/""*(P(-1)+Cc(" ")))^0))
local function anywhere(pattern)
return P { P(pattern)+1*V(1) }
end
@@ -638,7 +652,7 @@ function lpeg.replacer(one,two,makefunction,isutf)
return pattern
end
end
-function lpeg.finder(lst,makefunction)
+function lpeg.finder(lst,makefunction)
local pattern
if type(lst)=="table" then
pattern=P(false)
@@ -667,8 +681,8 @@ local splitters_f,splitters_s={},{}
function lpeg.firstofsplit(separator)
local splitter=splitters_f[separator]
if not splitter then
- separator=P(separator)
- splitter=C((1-separator)^0)
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)
splitters_f[separator]=splitter
end
return splitter
@@ -676,12 +690,31 @@ end
function lpeg.secondofsplit(separator)
local splitter=splitters_s[separator]
if not splitter then
- separator=P(separator)
- splitter=(1-separator)^0*separator*C(anything^0)
+ local pattern=P(separator)
+ splitter=(1-pattern)^0*pattern*C(anything^0)
splitters_s[separator]=splitter
end
return splitter
end
+local splitters_s,splitters_p={},{}
+function lpeg.beforesuffix(separator)
+ local splitter=splitters_s[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=C((1-pattern)^0)*pattern*endofstring
+ splitters_s[separator]=splitter
+ end
+ return splitter
+end
+function lpeg.afterprefix(separator)
+ local splitter=splitters_p[separator]
+ if not splitter then
+ local pattern=P(separator)
+ splitter=pattern*C(anything^0)
+ splitters_p[separator]=splitter
+ end
+ return splitter
+end
function lpeg.balancer(left,right)
left,right=P(left),P(right)
return P { left*((1-left-right)+V(1))^0*right }
@@ -913,9 +946,6 @@ end
function lpeg.times(pattern,n)
return P(nextstep(n,2^16,{ "start",["1"]=pattern }))
end
-local digit=R("09")
-local period=P(".")
-local zero=P("0")
local trailingzeros=zero^0*-digit
local case_1=period*trailingzeros/""
local case_2=period*(digit-trailingzeros)^1*(trailingzeros/"")
@@ -1303,6 +1333,7 @@ local noquotes,hexify,handle,reduce,compact,inline,functions
local reserved=table.tohash {
'and','break','do','else','elseif','end','false','for','function','if',
'in','local','nil','not','or','repeat','return','then','true','until','while',
+ 'NaN','goto',
}
local function simple_table(t)
if #t>0 then
@@ -1322,12 +1353,12 @@ local function simple_table(t)
else
tt[nt]=tostring(v)
end
- elseif tv=="boolean" then
- nt=nt+1
- tt[nt]=tostring(v)
elseif tv=="string" then
nt=nt+1
tt[nt]=format("%q",v)
+ elseif tv=="boolean" then
+ nt=nt+1
+ tt[nt]=v and "true" or "false"
else
tt=nil
break
@@ -1360,7 +1391,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s[%q]={",depth,name))
end
elseif tn=="boolean" then
- handle(format("%s[%s]={",depth,tostring(name)))
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
else
handle(format("%s{",depth))
end
@@ -1384,21 +1415,21 @@ local function do_serialize(root,name,depth,level,indexed)
for i=1,#sk do
local k=sk[i]
local v=root[k]
- local t,tk=type(v),type(k)
+ local tv,tk=type(v),type(k)
if compact and first and tk=="number" and k>=first and k<=last then
- if t=="number" then
+ if tv=="number" then
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
handle(format("%s %s,",depth,v))
end
- elseif t=="string" then
+ elseif tv=="string" then
if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
end
- elseif t=="table" then
+ elseif tv=="table" then
if not next(v) then
handle(format("%s {},",depth))
elseif inline then
@@ -1411,11 +1442,11 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1,true)
end
- elseif t=="boolean" then
- handle(format("%s %s,",depth,tostring(v)))
- elseif t=="function" then
+ elseif tv=="boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv=="function" then
if functions then
- handle(format('%s load(%q),',depth,dump(v)))
+ handle(format('%s load(%q),',depth,dump(v)))
else
handle(format('%s "function",',depth))
end
@@ -1426,7 +1457,7 @@ local function do_serialize(root,name,depth,level,indexed)
if false then
handle(format("%s __p__=nil,",depth))
end
- elseif t=="number" then
+ elseif tv=="number" then
if tk=="number" then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
@@ -1435,9 +1466,9 @@ local function do_serialize(root,name,depth,level,indexed)
end
elseif tk=="boolean" then
if hexify then
- handle(format("%s [%s]=0x%04X,",depth,tostring(k),v))
+ handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v))
else
- handle(format("%s [%s]=%s,",depth,tostring(k),v))
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
end
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
@@ -1452,7 +1483,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]=%s,",depth,k,v))
end
end
- elseif t=="string" then
+ elseif tv=="string" then
if reduce and tonumber(v) then
if tk=="number" then
if hexify then
@@ -1461,7 +1492,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v))
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%s,",depth,k,v))
else
@@ -1475,14 +1506,14 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,v))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,tostring(k),v))
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s [%q]=%q,",depth,k,v))
end
end
- elseif t=="table" then
+ elseif tv=="table" then
if not next(v) then
if tk=="number" then
if hexify then
@@ -1491,7 +1522,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={},",depth,k))
end
elseif tk=="boolean" then
- handle(format("%s [%s]={},",depth,tostring(k)))
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={},",depth,k))
else
@@ -1507,7 +1538,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
elseif tk=="boolean" then
- handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", ")))
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
else
@@ -1519,21 +1550,21 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1)
end
- elseif t=="boolean" then
+ elseif tv=="boolean" then
if tk=="number" then
if hexify then
- handle(format("%s [0x%04X]=%s,",depth,k,tostring(v)))
+ handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false"))
else
- handle(format("%s [%s]=%s,",depth,k,tostring(v)))
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v)))
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,tostring(v)))
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
else
- handle(format("%s [%q]=%s,",depth,k,tostring(v)))
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
- elseif t=="function" then
+ elseif tv=="function" then
if functions then
local f=getinfo(v).what=="C" and dump(dummy) or dump(v)
if tk=="number" then
@@ -1543,7 +1574,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=load(%q),",depth,k,f))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=load(%q),",depth,tostring(k),f))
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=load(%q),",depth,k,f))
else
@@ -1558,7 +1589,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
elseif tk=="boolean" then
- handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v)))
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,tostring(v)))
else
@@ -2167,6 +2198,7 @@ local function readall(f)
return f:read('*all')
else
local done=f:seek("set",0)
+ local step
if size<1024*1024 then
step=1024*1024
elseif size>16*1024*1024 then
@@ -2562,10 +2594,11 @@ if not os.times then
}
end
end
-os.gettimeofday=os.gettimeofday or os.clock
-local startuptime=os.gettimeofday()
+local gettimeofday=os.gettimeofday or os.clock
+os.gettimeofday=gettimeofday
+local startuptime=gettimeofday()
function os.runtime()
- return os.gettimeofday()-startuptime
+ return gettimeofday()-startuptime
end
os.resolvers=os.resolvers or {}
local resolvers=os.resolvers
@@ -3013,17 +3046,24 @@ end
function file.joinpath(tab,separator)
return tab and concat(tab,separator or io.pathseparator)
end
+local someslash=S("\\/")
local stripper=Cs(P(fwslash)^0/""*reslasher)
-local isnetwork=fwslash*fwslash*(1-fwslash)+(1-fwslash-colon)^1*colon
+local isnetwork=someslash*someslash*(1-someslash)+(1-fwslash-colon)^1*colon
local isroot=fwslash^1*-1
local hasroot=fwslash^1
+local reslasher=lpeg.replacer(S("\\/"),"/")
local deslasher=lpeg.replacer(S("\\/")^1,"/")
function file.join(...)
local lst={... }
local one=lst[1]
if lpegmatch(isnetwork,one) then
+ local one=lpegmatch(reslasher,one)
local two=lpegmatch(deslasher,concat(lst,"/",2))
- return one.."/"..two
+ if lpegmatch(hasroot,two) then
+ return one..two
+ else
+ return one.."/"..two
+ end
elseif lpegmatch(isroot,one) then
local two=lpegmatch(deslasher,concat(lst,"/",2))
if lpegmatch(hasroot,two) then
@@ -3040,7 +3080,9 @@ end
local drivespec=R("az","AZ")^1*colon
local anchors=fwslash+drivespec
local untouched=periods+(1-period)^1*P(-1)
-local splitstarter=(Cs(drivespec*(bwslash/"/"+fwslash)^0)+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
+local mswindrive=Cs(drivespec*(bwslash/"/"+fwslash)^0)
+local mswinuncpath=(bwslash+fwslash)*(bwslash+fwslash)*Cc("//")
+local splitstarter=(mswindrive+mswinuncpath+Cc(false))*Ct(lpeg.splitat(S("/\\")^1))
local absolute=fwslash
function file.collapsepath(str,anchor)
if not str then
@@ -3419,9 +3461,8 @@ if onwindows then
str=str.."/"..s
end
end
- local first,middle,last
local drive=false
- first,middle,last=match(str,"^(//)(//*)(.*)$")
+ local first,middle,last=match(str,"^(//)(//*)(.*)$")
if first then
else
first,last=match(str,"^(//)/*(.-)$")
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
index 5f6bc0fbc77..07719b20b4e 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-basic.lua
@@ -7,7 +7,7 @@
-- lualibs.dtx (with options: `basic')
-- This is a generated file.
--
--- Copyright (C) 2009 by PRAGMA ADE / ConTeXt Development Team
+-- Copyright (C) 2009--2013 by PRAGMA ADE / ConTeXt Development Team
--
-- See ConTeXt's mreadme.pdf for the license.
--
@@ -27,7 +27,7 @@ local loadmodule = lualibs.loadmodule
local lualibs_basic_module = {
name = "lualibs-basic",
version = 2.00,
- date = "2013/05/18",
+ date = "2013/07/23",
description = "ConTeXt Lua libraries -- basic collection.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-dir.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-dir.lua
index 3d0576eeb58..e47de603126 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-dir.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-dir.lua
@@ -273,9 +273,8 @@ if onwindows then
str = str .. "/" .. s
end
end
- local first, middle, last
local drive = false
- first, middle, last = match(str,"^(//)(//*)(.*)$")
+ local first, middle, last = match(str,"^(//)(//*)(.*)$")
if first then
-- empty network path == local path
else
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
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
index 5029c88cb1f..be659e162e0 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-extended.lua
@@ -7,7 +7,7 @@
-- lualibs.dtx (with options: `extended')
-- This is a generated file.
--
--- Copyright (C) 2009 by PRAGMA ADE / ConTeXt Development Team
+-- Copyright (C) 2009--2013 by PRAGMA ADE / ConTeXt Development Team
--
-- See ConTeXt's mreadme.pdf for the license.
--
@@ -28,7 +28,7 @@ lualibs = lualibs or { }
local lualibs_extended_module = {
name = "lualibs-extended",
version = 2.00,
- date = "2013/05/18",
+ date = "2013/07/23",
description = "ConTeXt Lua libraries -- extended collection.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-file.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-file.lua
index a64ee86564c..ebb2b39f4a2 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-file.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-file.lua
@@ -368,11 +368,14 @@ function file.joinpath(tab,separator) -- table
return tab and concat(tab,separator or io.pathseparator) -- can have trailing //
end
+local someslash = S("\\/")
local stripper = Cs(P(fwslash)^0/"" * reslasher)
-local isnetwork = fwslash * fwslash * (1-fwslash) + (1-fwslash-colon)^1 * colon
+local isnetwork = someslash * someslash * (1-someslash)
+ + (1-fwslash-colon)^1 * colon
local isroot = fwslash^1 * -1
local hasroot = fwslash^1
+local reslasher = lpeg.replacer(S("\\/"),"/")
local deslasher = lpeg.replacer(S("\\/")^1,"/")
-- If we have a network or prefix then there is a change that we end up with two
@@ -386,8 +389,13 @@ function file.join(...)
local lst = { ... }
local one = lst[1]
if lpegmatch(isnetwork,one) then
+ local one = lpegmatch(reslasher,one)
local two = lpegmatch(deslasher,concat(lst,"/",2))
- return one .. "/" .. two
+ if lpegmatch(hasroot,two) then
+ return one .. two
+ else
+ return one .. "/" .. two
+ end
elseif lpegmatch(isroot,one) then
local two = lpegmatch(deslasher,concat(lst,"/",2))
if lpegmatch(hasroot,two) then
@@ -412,6 +420,8 @@ end
-- print(file.join("http://a","/y"))
-- print(file.join("http:///a","/y"))
-- print(file.join("//nas-1","/y"))
+-- print(file.join("//nas-1/a/b/c","/y"))
+-- print(file.join("\\\\nas-1\\a\\b\\c","\\y"))
-- The previous one fails on "a.b/c" so Taco came up with a split based
-- variant. After some skyping we got it sort of compatible with the old
@@ -421,9 +431,14 @@ end
-- finds were replaced by lpegs.
local drivespec = R("az","AZ")^1 * colon
-local anchors = fwslash + drivespec
-local untouched = periods + (1-period)^1 * P(-1)
-local splitstarter = (Cs(drivespec * (bwslash/"/" + fwslash)^0) + Cc(false)) * Ct(lpeg.splitat(S("/\\")^1))
+local anchors = fwslash
+ + drivespec
+local untouched = periods
+ + (1-period)^1 * P(-1)
+local mswindrive = Cs(drivespec * (bwslash/"/" + fwslash)^0)
+local mswinuncpath = (bwslash + fwslash) * (bwslash + fwslash) * Cc("//")
+local splitstarter = (mswindrive + mswinuncpath + Cc(false))
+ * Ct(lpeg.splitat(S("/\\")^1))
local absolute = fwslash
function file.collapsepath(str,anchor) -- anchor: false|nil, true, "."
@@ -490,6 +505,7 @@ end
-- test("a/./b/..") test("a/aa/../b/bb") test("a/.././././b/..") test("a/./././b/..")
-- test("a/b/c/../..") test("./a/b/c/../..") test("a/b/c/../..")
-- test("./a")
+-- test([[\\a.b.c\d\e]])
local validchars = R("az","09","AZ","--","..")
local pattern_a = lpeg.replacer(1-validchars)
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-io.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-io.lua
index 06e1fb5efc8..e3a443be8c0 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-io.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-io.lua
@@ -35,6 +35,7 @@ local function readall(f)
return f:read('*all')
else
local done = f:seek("set",0)
+ local step
if size < 1024*1024 then
step = 1024 * 1024
elseif size > 16*1024*1024 then
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-lpeg.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-lpeg.lua
index 323c73b6967..b33df96b7d9 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-lpeg.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-lpeg.lua
@@ -13,6 +13,19 @@ if not modules then modules = { } end modules ['l-lpeg'] = {
lpeg = require("lpeg")
+-- The latest lpeg doesn't have print any more, and even the new ones are not
+-- available by default (only when debug mode is enabled), which is a pitty as
+-- as it helps bailign down bottlenecks. Performance seems comparable, although
+--
+-- local p = lpeg.C(lpeg.P(1)^0 * lpeg.P(-1))
+-- local a = string.rep("123",10)
+-- lpeg.match(p,a)
+--
+-- is nearly 20% slower and also still suboptimal (i.e. a match that runs from
+-- begin to end, one of the cases where string matchers win).
+
+if not lpeg.print then function lpeg.print(...) print(lpeg.pcode(...)) end end
+
-- tracing (only used when we encounter a problem in integration of lpeg in luatex)
-- some code will move to unicode and string
@@ -79,13 +92,22 @@ patterns.endofstring = endofstring
patterns.beginofstring = alwaysmatched
patterns.alwaysmatched = alwaysmatched
-local digit, sign = R('09'), S('+-')
+local sign = S('+-')
+local zero = P('0')
+local digit = R('09')
+local octdigit = R("07")
+local lowercase = R("az")
+local uppercase = R("AZ")
+local underscore = P("_")
+local hexdigit = digit + lowercase + uppercase
local cr, lf, crlf = P("\r"), P("\n"), P("\r\n")
local newline = crlf + S("\r\n") -- cr + lf
local escaped = P("\\") * anything
local squote = P("'")
local dquote = P('"')
local space = P(" ")
+local period = P(".")
+local comma = P(",")
local utfbom_32_be = P('\000\000\254\255')
local utfbom_32_le = P('\255\254\000\000')
@@ -137,29 +159,14 @@ patterns.nonwhitespace = nonwhitespace
local stripper = spacer^0 * C((spacer^0 * nonspacer^1)^0) -- from example by roberto
------ collapser = Cs(spacer^0/"" * ((spacer^1 * P(-1) / "") + (spacer^1/" ") + P(1))^0)
+----- collapser = Cs(spacer^0/"" * ((spacer^1 * endofstring / "") + (spacer^1/" ") + P(1))^0)
local collapser = Cs(spacer^0/"" * nonspacer^0 * ((spacer^0/" " * nonspacer^1)^0))
patterns.stripper = stripper
patterns.collapser = collapser
-patterns.digit = digit
-patterns.sign = sign
-patterns.cardinal = sign^0 * digit^1
-patterns.integer = sign^0 * digit^1
-patterns.unsigned = digit^0 * P('.') * digit^1
-patterns.float = sign^0 * patterns.unsigned
-patterns.cunsigned = digit^0 * P(',') * digit^1
-patterns.cfloat = sign^0 * patterns.cunsigned
-patterns.number = patterns.float + patterns.integer
-patterns.cnumber = patterns.cfloat + patterns.integer
-patterns.oct = P("0") * R("07")^1
-patterns.octal = patterns.oct
-patterns.HEX = P("0x") * R("09","AF")^1
-patterns.hex = P("0x") * R("09","af")^1
-patterns.hexadecimal = P("0x") * R("09","AF","af")^1
-patterns.lowercase = R("az")
-patterns.uppercase = R("AZ")
+patterns.lowercase = lowercase
+patterns.uppercase = uppercase
patterns.letter = patterns.lowercase + patterns.uppercase
patterns.space = space
patterns.tab = P("\t")
@@ -167,12 +174,12 @@ patterns.spaceortab = patterns.space + patterns.tab
patterns.newline = newline
patterns.emptyline = newline^1
patterns.equal = P("=")
-patterns.comma = P(",")
-patterns.commaspacer = P(",") * spacer^0
-patterns.period = P(".")
+patterns.comma = comma
+patterns.commaspacer = comma * spacer^0
+patterns.period = period
patterns.colon = P(":")
patterns.semicolon = P(";")
-patterns.underscore = P("_")
+patterns.underscore = underscore
patterns.escaped = escaped
patterns.squote = squote
patterns.dquote = dquote
@@ -187,12 +194,38 @@ patterns.singlequoted = squote * patterns.nosquote * squote
patterns.doublequoted = dquote * patterns.nodquote * dquote
patterns.quoted = patterns.doublequoted + patterns.singlequoted
-patterns.propername = R("AZ","az","__") * R("09","AZ","az", "__")^0 * P(-1)
+patterns.digit = digit
+patterns.octdigit = octdigit
+patterns.hexdigit = hexdigit
+patterns.sign = sign
+patterns.cardinal = digit^1
+patterns.integer = sign^-1 * digit^1
+patterns.unsigned = digit^0 * period * digit^1
+patterns.float = sign^-1 * patterns.unsigned
+patterns.cunsigned = digit^0 * comma * digit^1
+patterns.cfloat = sign^-1 * patterns.cunsigned
+patterns.number = patterns.float + patterns.integer
+patterns.cnumber = patterns.cfloat + patterns.integer
+patterns.oct = zero * octdigit^1
+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.propername = (uppercase + lowercase + underscore) * (uppercase + lowercase + underscore + digit)^0 * endofstring
patterns.somecontent = (anything - newline - space)^1 -- (utf8char - newline - space)^1
patterns.beginline = #(1-newline)
-patterns.longtostring = Cs(whitespace^0/"" * nonwhitespace^0 * ((whitespace^0/" " * (patterns.quoted + nonwhitespace)^1)^0))
+patterns.longtostring = Cs(whitespace^0/"" * ((patterns.quoted + nonwhitespace^1 + whitespace^1/"" * (P(-1) + Cc(" ")))^0))
local function anywhere(pattern) --slightly adapted from website
return P { P(pattern) + 1 * V(1) }
@@ -421,7 +454,7 @@ function lpeg.replacer(one,two,makefunction,isutf) -- in principle we should sor
end
end
-function lpeg.finder(lst,makefunction)
+function lpeg.finder(lst,makefunction) -- beware: slower than find with 'patternless finds'
local pattern
if type(lst) == "table" then
pattern = P(false)
@@ -456,8 +489,8 @@ local splitters_f, splitters_s = { }, { }
function lpeg.firstofsplit(separator) -- always return value
local splitter = splitters_f[separator]
if not splitter then
- separator = P(separator)
- splitter = C((1 - separator)^0)
+ local pattern = P(separator)
+ splitter = C((1 - pattern)^0)
splitters_f[separator] = splitter
end
return splitter
@@ -466,13 +499,35 @@ end
function lpeg.secondofsplit(separator) -- nil if not split
local splitter = splitters_s[separator]
if not splitter then
- separator = P(separator)
- splitter = (1 - separator)^0 * separator * C(anything^0)
+ local pattern = P(separator)
+ splitter = (1 - pattern)^0 * pattern * C(anything^0)
splitters_s[separator] = splitter
end
return splitter
end
+local splitters_s, splitters_p = { }, { }
+
+function lpeg.beforesuffix(separator) -- nil if nothing but empty is ok
+ local splitter = splitters_s[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = C((1 - pattern)^0) * pattern * endofstring
+ splitters_s[separator] = splitter
+ end
+ return splitter
+end
+
+function lpeg.afterprefix(separator) -- nil if nothing but empty is ok
+ local splitter = splitters_p[separator]
+ if not splitter then
+ local pattern = P(separator)
+ splitter = pattern * C(anything^0)
+ splitters_p[separator] = splitter
+ end
+ return splitter
+end
+
function lpeg.balancer(left,right)
left, right = P(left), P(right)
return P { left * ((1 - left - right) + V(1))^0 * right }
@@ -832,9 +887,9 @@ end
-- moved here (before util-str)
-local digit = R("09")
-local period = P(".")
-local zero = P("0")
+----- digit = R("09")
+----- period = P(".")
+----- zero = P("0")
local trailingzeros = zero^0 * -digit -- suggested by Roberto R
local case_1 = period * trailingzeros / ""
local case_2 = period * (digit - trailingzeros)^1 * (trailingzeros / "")
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua
index 05ca0acdc6a..a4c0ac82085 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-os.lua
@@ -172,19 +172,21 @@ if not os.times then -- ?
end
end
-os.gettimeofday = os.gettimeofday or os.clock
-local startuptime = os.gettimeofday()
+local gettimeofday = os.gettimeofday or os.clock
+os.gettimeofday = gettimeofday
+
+local startuptime = gettimeofday()
function os.runtime()
- return os.gettimeofday() - startuptime
+ return gettimeofday() - startuptime
end
---~ print(os.gettimeofday()-os.time())
---~ os.sleep(1.234)
---~ print (">>",os.runtime())
---~ print(os.date("%H:%M:%S",os.gettimeofday()))
---~ print(os.date("%H:%M:%S",os.time()))
+-- print(os.gettimeofday()-os.time())
+-- os.sleep(1.234)
+-- print (">>",os.runtime())
+-- print(os.date("%H:%M:%S",os.gettimeofday()))
+-- print(os.date("%H:%M:%S",os.time()))
-- no need for function anymore as we have more clever code and helpers now
-- this metatable trickery might as well disappear
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua
index 77c076cc53e..9b079b00a50 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-string.lua
@@ -91,6 +91,8 @@ end
local pattern = P(" ")^0 * P(-1)
+-- patterns.onlyspaces = pattern
+
function string.is_empty(str)
if str == "" then
return true
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua
index 9a1b97fff78..11cb66bef1e 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-table.lua
@@ -16,6 +16,9 @@ local lpegmatch, patterns = lpeg.match, lpeg.patterns
local floor = math.floor
-- extra functions, some might go (when not used)
+--
+-- we could serialize using %a but that won't work well is in the code we mostly use
+-- floats and as such we get unequality e.g. in version comparisons
local stripper = patterns.stripper
@@ -343,6 +346,7 @@ local noquotes, hexify, handle, reduce, compact, inline, functions
local reserved = table.tohash { -- intercept a language inconvenience: no reserved words as key
'and', 'break', 'do', 'else', 'elseif', 'end', 'false', 'for', 'function', 'if',
'in', 'local', 'nil', 'not', 'or', 'repeat', 'return', 'then', 'true', 'until', 'while',
+ 'NaN', 'goto',
}
local function simple_table(t)
@@ -363,12 +367,12 @@ local function simple_table(t)
else
tt[nt] = tostring(v) -- tostring not needed
end
- elseif tv == "boolean" then
- nt = nt + 1
- tt[nt] = tostring(v)
elseif tv == "string" then
nt = nt + 1
tt[nt] = format("%q",v)
+ elseif tv == "boolean" then
+ nt = nt + 1
+ tt[nt] = v and "true" or "false"
else
tt = nil
break
@@ -394,7 +398,8 @@ end
-- todo: %g faster on numbers than %s
--- we can speed this up with repeaters and formatters (is indeed faster)
+-- we can speed this up with repeaters and formatters but we haven't defined them
+-- yet
local propername = patterns.propername -- was find(name,"^%a[%w%_]*$")
@@ -420,7 +425,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s[%q]={",depth,name))
end
elseif tn == "boolean" then
- handle(format("%s[%s]={",depth,tostring(name)))
+ handle(format("%s[%s]={",depth,name and "true" or "false"))
else
handle(format("%s{",depth))
end
@@ -456,21 +461,21 @@ local function do_serialize(root,name,depth,level,indexed)
--~ if v == root then
-- circular
--~ else
- local t, tk = type(v), type(k)
+ local tv, tk = type(v), type(k)
if compact and first and tk == "number" and k >= first and k <= last then
- if t == "number" then
+ if tv == "number" then
if hexify then
handle(format("%s 0x%04X,",depth,v))
else
handle(format("%s %s,",depth,v)) -- %.99g
end
- elseif t == "string" then
+ elseif tv == "string" then
if reduce and tonumber(v) then
handle(format("%s %s,",depth,v))
else
handle(format("%s %q,",depth,v))
end
- elseif t == "table" then
+ elseif tv == "table" then
if not next(v) then
handle(format("%s {},",depth))
elseif inline then -- and #t > 0
@@ -483,11 +488,11 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1,true)
end
- elseif t == "boolean" then
- handle(format("%s %s,",depth,tostring(v)))
- elseif t == "function" then
+ elseif tv == "boolean" then
+ handle(format("%s %s,",depth,v and "true" or "false"))
+ elseif tv == "function" then
if functions then
- handle(format('%s load(%q),',depth,dump(v)))
+ handle(format('%s load(%q),',depth,dump(v))) -- maybe strip
else
handle(format('%s "function",',depth))
end
@@ -498,7 +503,7 @@ local function do_serialize(root,name,depth,level,indexed)
if false then
handle(format("%s __p__=nil,",depth))
end
- elseif t == "number" then
+ elseif tv == "number" then
if tk == "number" then
if hexify then
handle(format("%s [0x%04X]=0x%04X,",depth,k,v))
@@ -507,9 +512,9 @@ local function do_serialize(root,name,depth,level,indexed)
end
elseif tk == "boolean" then
if hexify then
- handle(format("%s [%s]=0x%04X,",depth,tostring(k),v))
+ handle(format("%s [%s]=0x%04X,",depth,k and "true" or "false",v))
else
- handle(format("%s [%s]=%s,",depth,tostring(k),v)) -- %.99g
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v)) -- %.99g
end
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
if hexify then
@@ -524,7 +529,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%q]=%s,",depth,k,v)) -- %.99g
end
end
- elseif t == "string" then
+ elseif tv == "string" then
if reduce and tonumber(v) then
if tk == "number" then
if hexify then
@@ -533,7 +538,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%s,",depth,k,v))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),v))
+ handle(format("%s [%s]=%s,",depth,k and "true" or "false",v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%s,",depth,k,v))
else
@@ -547,14 +552,14 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,v))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=%q,",depth,tostring(k),v))
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",v))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,v))
else
handle(format("%s [%q]=%q,",depth,k,v))
end
end
- elseif t == "table" then
+ elseif tv == "table" then
if not next(v) then
if tk == "number" then
if hexify then
@@ -563,7 +568,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={},",depth,k))
end
elseif tk == "boolean" then
- handle(format("%s [%s]={},",depth,tostring(k)))
+ handle(format("%s [%s]={},",depth,k and "true" or "false"))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={},",depth,k))
else
@@ -579,7 +584,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]={ %s },",depth,k,concat(st,", ")))
end
elseif tk == "boolean" then
- handle(format("%s [%s]={ %s },",depth,tostring(k),concat(st,", ")))
+ handle(format("%s [%s]={ %s },",depth,k and "true" or "false",concat(st,", ")))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s={ %s },",depth,k,concat(st,", ")))
else
@@ -591,24 +596,24 @@ local function do_serialize(root,name,depth,level,indexed)
else
do_serialize(v,k,depth,level+1)
end
- elseif t == "boolean" then
+ elseif tv == "boolean" then
if tk == "number" then
if hexify then
- handle(format("%s [0x%04X]=%s,",depth,k,tostring(v)))
+ handle(format("%s [0x%04X]=%s,",depth,k,v and "true" or "false"))
else
- handle(format("%s [%s]=%s,",depth,k,tostring(v)))
+ handle(format("%s [%s]=%s,",depth,k,v and "true" or "false"))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=%s,",depth,tostring(k),tostring(v)))
+ handle(format("%s [%s]=%s,",depth,tostring(k),v and "true" or "false"))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
- handle(format("%s %s=%s,",depth,k,tostring(v)))
+ handle(format("%s %s=%s,",depth,k,v and "true" or "false"))
else
- handle(format("%s [%q]=%s,",depth,k,tostring(v)))
+ handle(format("%s [%q]=%s,",depth,k,v and "true" or "false"))
end
- elseif t == "function" then
+ elseif tv == "function" then
if functions then
- local f = getinfo(v).what == "C" and dump(dummy) or dump(v)
- -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v)
+ local f = getinfo(v).what == "C" and dump(dummy) or dump(v) -- maybe strip
+ -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v) -- maybe strip
if tk == "number" then
if hexify then
handle(format("%s [0x%04X]=load(%q),",depth,k,f))
@@ -616,7 +621,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=load(%q),",depth,k,f))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=load(%q),",depth,tostring(k),f))
+ handle(format("%s [%s]=load(%q),",depth,k and "true" or "false",f))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=load(%q),",depth,k,f))
else
@@ -631,7 +636,7 @@ local function do_serialize(root,name,depth,level,indexed)
handle(format("%s [%s]=%q,",depth,k,tostring(v)))
end
elseif tk == "boolean" then
- handle(format("%s [%s]=%q,",depth,tostring(k),tostring(v)))
+ handle(format("%s [%s]=%q,",depth,k and "true" or "false",tostring(v)))
elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
handle(format("%s %s=%q,",depth,k,tostring(v)))
else
@@ -713,321 +718,10 @@ local function serialize(_handle,root,name,specification) -- handle wins
handle("}")
end
--- -- This is some 20% faster than using format (because formatters are much faster) but
--- -- of course, inlining the format using .. is then again faster .. anyway, as we do
--- -- some pretty printing as well there is not that much to gain unless we make a 'fast'
--- -- ugly variant as well. But, we would have to move the formatter to l-string then.
-
--- local formatters = string.formatters
-
--- local function do_serialize(root,name,level,indexed)
--- if level > 0 then
--- if indexed then
--- handle(formatters["%w{"](level))
--- else
--- local tn = type(name)
--- if tn == "number" then
--- if hexify then
--- handle(formatters["%w[%04H]={"](level,name))
--- else
--- handle(formatters["%w[%s]={"](level,name))
--- end
--- elseif tn == "string" then
--- if noquotes and not reserved[name] and lpegmatch(propername,name) then
--- handle(formatters["%w%s={"](level,name))
--- else
--- handle(formatters["%w[%q]={"](level,name))
--- end
--- elseif tn == "boolean" then
--- handle(formatters["%w[%S]={"](level,name))
--- else
--- handle(formatters["%w{"](level))
--- end
--- end
--- end
--- -- we could check for k (index) being number (cardinal)
--- if root and next(root) then
--- -- local first, last = nil, 0 -- #root cannot be trusted here (will be ok in 5.2 when ipairs is gone)
--- -- if compact then
--- -- -- NOT: for k=1,#root do (we need to quit at nil)
--- -- for k,v in ipairs(root) do -- can we use next?
--- -- if not first then first = k end
--- -- last = last + 1
--- -- end
--- -- end
--- local first, last = nil, 0
--- if compact then
--- 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
--- end
--- local sk = sortedkeys(root)
--- for i=1,#sk do
--- local k = sk[i]
--- local v = root[k]
--- --~ if v == root then
--- -- circular
--- --~ else
--- local t, tk = type(v), type(k)
--- if compact and first and tk == "number" and k >= first and k <= last then
--- if t == "number" then
--- if hexify then
--- handle(formatters["%w %04H,"](level,v))
--- else
--- handle(formatters["%w %s,"](level,v)) -- %.99g
--- end
--- elseif t == "string" then
--- if reduce and tonumber(v) then
--- handle(formatters["%w %s,"](level,v))
--- else
--- handle(formatters["%w %q,"](level,v))
--- end
--- elseif t == "table" then
--- if not next(v) then
--- handle(formatters["%w {},"](level))
--- elseif inline then -- and #t > 0
--- local st = simple_table(v)
--- if st then
--- handle(formatters["%w { %, t },"](level,st))
--- else
--- do_serialize(v,k,level+1,true)
--- end
--- else
--- do_serialize(v,k,level+1,true)
--- end
--- elseif t == "boolean" then
--- handle(formatters["%w %S,"](level,v))
--- elseif t == "function" then
--- if functions then
--- handle(formatters['%w load(%q),'](level,dump(v)))
--- else
--- handle(formatters['%w "function",'](level))
--- end
--- else
--- handle(formatters["%w %Q,"](level,v))
--- end
--- elseif k == "__p__" then -- parent
--- if false then
--- handle(formatters["%w __p__=nil,"](level))
--- end
--- elseif t == "number" then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%04H,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%s,"](level,k,v)) -- %.99g
--- end
--- elseif tk == "boolean" then
--- if hexify then
--- handle(formatters["%w [%S]=%04H,"](level,k,v))
--- else
--- handle(formatters["%w [%S]=%s,"](level,k,v)) -- %.99g
--- end
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- if hexify then
--- handle(formatters["%w %s=%04H,"](level,k,v))
--- else
--- handle(formatters["%w %s=%s,"](level,k,v)) -- %.99g
--- end
--- else
--- if hexify then
--- handle(formatters["%w [%q]=%04H,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%s,"](level,k,v)) -- %.99g
--- end
--- end
--- elseif t == "string" then
--- if reduce and tonumber(v) then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%s,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%s,"](level,k,v))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=%s,"](level,k,v))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=%s,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%s,"](level,k,v))
--- end
--- else
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%q,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%q,"](level,k,v))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=%q,"](level,k,v))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=%q,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%q,"](level,k,v))
--- end
--- end
--- elseif t == "table" then
--- if not next(v) then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]={},"](level,k))
--- else
--- handle(formatters["%w [%s]={},"](level,k))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]={},"](level,k))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s={},"](level,k))
--- else
--- handle(formatters["%w [%q]={},"](level,k))
--- end
--- elseif inline then
--- local st = simple_table(v)
--- if st then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]={ %, t },"](level,k,st))
--- else
--- handle(formatters["%w [%s]={ %, t },"](level,k,st))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]={ %, t },"](level,k,st))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s={ %, t },"](level,k,st))
--- else
--- handle(formatters["%w [%q]={ %, t },"](level,k,st))
--- end
--- else
--- do_serialize(v,k,level+1)
--- end
--- else
--- do_serialize(v,k,level+1)
--- end
--- elseif t == "boolean" then
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%S,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%S,"](level,k,v))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=%S,"](level,k,v))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=%S,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%S,"](level,k,v))
--- end
--- elseif t == "function" then
--- if functions then
--- local f = getinfo(v).what == "C" and dump(dummy) or dump(v)
--- -- local f = getinfo(v).what == "C" and dump(function(...) return v(...) end) or dump(v)
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=load(%q),"](level,k,f))
--- else
--- handle(formatters["%w [%s]=load(%q),"](level,k,f))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=load(%q),"](level,k,f))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=load(%q),"](level,k,f))
--- else
--- handle(formatters["%w [%q]=load(%q),"](level,k,f))
--- end
--- end
--- else
--- if tk == "number" then
--- if hexify then
--- handle(formatters["%w [%04H]=%Q,"](level,k,v))
--- else
--- handle(formatters["%w [%s]=%Q,"](level,k,v))
--- end
--- elseif tk == "boolean" then
--- handle(formatters["%w [%S]=%Q,"](level,k,v))
--- elseif noquotes and not reserved[k] and lpegmatch(propername,k) then
--- handle(formatters["%w %s=%Q,"](level,k,v))
--- else
--- handle(formatters["%w [%q]=%Q,"](level,k,v))
--- end
--- end
--- --~ end
--- end
--- end
--- if level > 0 then
--- handle(formatters["%w}"](level))
--- end
--- end
-
--- local function serialize(_handle,root,name,specification) -- handle wins
--- local tname = type(name)
--- if type(specification) == "table" then
--- noquotes = specification.noquotes
--- hexify = specification.hexify
--- handle = _handle or specification.handle or print
--- reduce = specification.reduce or false
--- functions = specification.functions
--- compact = specification.compact
--- inline = specification.inline and compact
--- if functions == nil then
--- functions = true
--- end
--- if compact == nil then
--- compact = true
--- end
--- if inline == nil then
--- inline = compact
--- end
--- else
--- noquotes = false
--- hexify = false
--- handle = _handle or print
--- reduce = false
--- compact = true
--- inline = true
--- functions = true
--- end
--- if tname == "string" then
--- if name == "return" then
--- handle("return {")
--- else
--- handle(name .. "={")
--- end
--- elseif tname == "number" then
--- if hexify then
--- handle(format("[0x%04X]={",name))
--- else
--- handle("[" .. name .. "]={")
--- end
--- elseif tname == "boolean" then
--- if name then
--- handle("return {")
--- else
--- handle("{")
--- end
--- else
--- handle("t={")
--- end
--- if root then
--- -- The dummy access will initialize a table that has a delayed initialization
--- -- using a metatable. (maybe explicitly test for metatable)
--- if getmetatable(root) then -- todo: make this an option, maybe even per subtable
--- local dummy = root._w_h_a_t_e_v_e_r_
--- root._w_h_a_t_e_v_e_r_ = nil
--- end
--- -- Let's forget about empty tables.
--- if next(root) then
--- do_serialize(root,name,0)
--- end
--- end
--- handle("}")
--- end
+-- A version with formatters is some 20% faster than using format (because formatters are
+-- much faster) but of course, inlining the format using .. is then again faster .. anyway,
+-- as we do some pretty printing as well there is not that much to gain unless we make a
+-- 'fast' ugly variant as well. But, we would have to move the formatter to l-string then.
-- name:
--
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua
index eefc15a6f7e..79cbdba3f2a 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-trac-inf.lua
@@ -11,20 +11,24 @@ if not modules then modules = { } end modules ['trac-inf'] = {
-- get warnings about assignments. This is more efficient than using rawset
-- and rawget.
-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 -- should go in environment
-statistics = statistics or { }
-local statistics = statistics
+local setmetatableindex = table.setmetatableindex
+local serialize = table.serialize
+local formatters = string.formatters
-statistics.enable = true
-statistics.threshold = 0.01
+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
@@ -178,6 +182,19 @@ function statistics.timed(action)
report("total runtime: %s",elapsedtime("run"))
end
+-- goodie
+
+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
+
-- where, not really the best spot for this:
commands = commands or { }
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-dim.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-dim.lua
index 47b2706b736..69061495f94 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-dim.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-dim.lua
@@ -22,6 +22,8 @@ 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
+
--this might become another namespace
number = number or { }
@@ -137,7 +139,7 @@ capture takes place.</p>
--ldx]]--
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)) -- tonumber is new
@@ -376,10 +378,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 -- to be considered: round
else
- k = value/unit
+ k = 0
end
known[a] = k
a = k
@@ -412,16 +414,16 @@ function string.todimen(str) -- maybe use tex.sp when available
end
end
---~ local known = { }
-
---~ function string.todimen(str) -- maybe use tex.sp
---~ local k = known[str]
---~ if not k then
---~ k = tex.sp(str)
---~ known[str] = k
---~ end
---~ return k
---~ end
+-- local known = { }
+--
+-- function string.todimen(str) -- maybe use tex.sp
+-- local k = known[str]
+-- if not k then
+-- k = tex.sp(str)
+-- known[str] = k
+-- end
+-- return k
+-- end
stringtodimen = string.todimen -- local variable defined earlier
@@ -439,7 +441,7 @@ probably use a hash instead of a one-element table.</p>
--ldx]]--
function number.percent(n,d) -- will be cleaned up once luatex 0.30 is out
- d = d or tex.hsize
+ d = d or texget("hsize")
if type(d) == "string" then
d = stringtodimen(d)
end
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
index 29587cd3834..bbe25d89df8 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-jsn.lua
@@ -42,8 +42,20 @@ 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 = {
+ -- ["\\"] = "\\", -- lua will escape these
+ -- ["/"] = "/", -- no need to escape this one
+ ["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) -- if not found then P(1) is returned i.e. the to be escaped char
+
+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)
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua
index f3be9dcd261..e1dcdc94d57 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-lua.lua
@@ -41,291 +41,100 @@ luautilities.suffixes = {
-- environment.loadpreprocessedfile can be set to a preprocessor
-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
+ strippedchunks[#strippedchunks+1] = name
+ luautilities.nofstrippedchunks = luautilities.nofstrippedchunks + 1
+end
- -- quite subtle ... doing this wrong incidentally can give more bytes
-
- function luautilities.loadedluacode(fullname,forcestrip,name)
- -- quite subtle ... doing this wrong incidentally can give more bytes
- name = name or fullname
- local code = environment.loadpreprocessedfile and environment.loadpreprocessedfile(fullname) or loadfile(fullname)
+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
- end
- end
-
- function luautilities.strippedloadstring(code,forcestrip,name) -- not executed
- 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) -- defaults: cleanup=false strip=true
- 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))
+ 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
+end
-else
-
- -- The next function was posted by Peter Cawley on the lua list and strips line
- -- number information etc. from the bytecode data blob. We only apply this trick
- -- when we store data tables. Stripping makes the compressed format file about
- -- 1MB smaller (and uncompressed we save at least 6MB).
- --
- -- You can consider this feature an experiment, so it might disappear. There is
- -- no noticeable gain in runtime although the memory footprint should be somewhat
- -- smaller (and the file system has a bit less to deal with).
- --
- -- Begin of borrowed code ... works for Lua 5.1 which LuaTeX currently uses ...
+-- quite subtle ... doing this wrong incidentally can give more bytes
- 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
+function luautilities.loadedluacode(fullname,forcestrip,name)
+ -- quite subtle ... doing this wrong incidentally can give more bytes
+ name = name or fullname
+ local code, message
+ if environment.loadpreprocessedfile then
+ code, message = environment.loadpreprocessedfile(fullname)
+ else
+ code, message = loadfile(fullname)
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
-
+ if code then
+ code()
else
-
- strip_code_pc = function(dump,name)
- return dump, 0
- end
-
+ report_lua("loading of file %a failed:\n\t%s",fullname,message or "no message")
end
-
- -- ... end of borrowed code.
-
- -- quite subtle ... doing this wrong incidentally can give more bytes
-
- function luautilities.loadedluacode(fullname,forcestrip,name)
- -- quite subtle ... doing this wrong incidentally can give more bytes
- local code = environment.loadpreprocessedfile and environment.preprocessedloadfile(fullname) or loadfile(fullname)
- if code then
- code()
+ 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
+end
- function luautilities.strippedloadstring(code,forcestrip,name) -- not executed
- 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
+function luautilities.strippedloadstring(code,forcestrip,name) -- not executed
+ 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) -- last one is reported
- 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 -- not yet executes
+ else
+ return code, 0
end
+end
- local luac_normal = "texluac -o %q %q"
- local luac_strip = "texluac -s -o %q %q"
-
- function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
- 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 -- better see how bad it is
- done = true -- hm
- end
- if done and cleanup == true and lfs.isfile(lucfile) and lfs.isfile(luafile) then
+function luautilities.compile(luafile,lucfile,cleanup,strip,fallback) -- defaults: cleanup=false strip=true
+ 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
+ return done
+end
- luautilities.loadstripped = loadstring
-
+function luautilities.loadstripped(...)
+ local l = load(...)
+ if l then
+ return load(dump(l,true))
+ end
end
-- local getmetatable, type = getmetatable, type
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-prs.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-prs.lua
index 9d2ffcc3ee7..7fe1e703b7b 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-prs.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-prs.lua
@@ -9,8 +9,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 { }
@@ -409,7 +410,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
@@ -590,3 +591,16 @@ end
-- }
--
-- inspect(utilities.parsers.mergehashes(t,"aa, bb, cc"))
+
+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
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua
index 4890a11d606..13e1e092241 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-str.lua
@@ -195,12 +195,14 @@ end
-- points %p number (scaled points)
-- basepoints %b number (scaled points)
-- table concat %...t table
+-- table concat %{.}t table
-- serialize %...T sequenced (no nested tables)
+-- serialize %{.}T sequenced (no nested tables)
-- boolean (logic) %l boolean
-- BOOLEAN %L boolean
-- whitespace %...w
-- automatic %...a 'whatever' (string, table, ...)
--- automatic %...a "whatever" (string, table, ...)
+-- automatic %...A "whatever" (string, table, ...)
local n = 0
@@ -298,7 +300,7 @@ setmetatable(arguments, { __index =
})
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)
-- we've split all cases as then we can optimize them (let's omit the fuzzy u)
@@ -337,7 +339,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
@@ -608,8 +610,8 @@ local builder = Cs { "start",
["b"] = (prefix_any * P("b")) / format_b, -- %b => 12.342bp / maybe: B (and more units)
["t"] = (prefix_tab * P("t")) / format_t, -- %t => concat
["T"] = (prefix_tab * P("T")) / format_T, -- %t => sequenced
- ["l"] = (prefix_tab * P("l")) / format_l, -- %l => boolean
- ["L"] = (prefix_tab * P("L")) / format_L, -- %L => BOOLEAN
+ ["l"] = (prefix_any * P("l")) / format_l, -- %l => boolean
+ ["L"] = (prefix_any * P("L")) / format_L, -- %L => BOOLEAN
["I"] = (prefix_any * P("I")) / format_I, -- %I => signed integer
--
["w"] = (prefix_any * P("w")) / format_w, -- %w => n spaces (optional prefix is added)
@@ -618,7 +620,7 @@ local builder = Cs { "start",
["a"] = (prefix_any * P("a")) / format_a, -- %a => '...' (forces tostring)
["A"] = (prefix_any * P("A")) / format_A, -- %A => "..." (forces tostring)
--
- ["*"] = Cs(((1-P("%"))^1 + P("%%")/"%%%%")^1) / format_rest, -- rest (including %%)
+ ["*"] = Cs(((1-P("%"))^1 + P("%%")/"%%")^1) / format_rest, -- rest (including %%)
--
["!"] = Carg(2) * prefix_any * P("!") * C((1-P("!"))^1) * P("!") / format_extension,
}
@@ -733,11 +735,17 @@ strings.formatters.add = add
-- registered in the default instance (should we fall back on this one?)
-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) -- maybe also \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]])
+-- escaping by lpeg is faster for strings without quotes, slower on a string with quotes, but
+-- faster again when other q-escapables are found (the ones we don't need to escape)
+
+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]])
-- -- yes or no:
--
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua
index a47c0cb77fd..f18c719e420 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tab.lua
@@ -15,7 +15,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(".")
@@ -293,100 +293,65 @@ function tables.encapsulate(core,capsule,protect)
end
end
-local function fastserialize(t,r,outer) -- no mixes
- 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)
+-- best keep [%q] keys (as we have some in older applications i.e. saving user data
+
+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) -- so prefix should contain the = | not sorted
+
+ local r = { prefix or "return" }
+ local m = 1
+
+ local function fastserialize(t,outer) -- no mixes
+ 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
-
--- local f_hashed_string = formatters["[%q]=%q,"]
--- local f_hashed_number = formatters["[%q]=%s,"]
--- local f_hashed_table = formatters["[%q]="]
--- local f_hashed_true = formatters["[%q]=true,"]
--- local f_hashed_false = formatters["[%q]=false,"]
---
--- local f_indexed_string = formatters["%q,"]
--- local f_indexed_number = formatters["%s,"]
--- ----- f_indexed_true = formatters["true,"]
--- ----- f_indexed_false = formatters["false,"]
---
--- local function fastserialize(t,r,outer) -- no mixes
--- 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] = f_indexed_string(v)
--- elseif tv == "number" then
--- r[#r+1] = f_indexed_number(v)
--- elseif tv == "table" then
--- fastserialize(v,r)
--- elseif tv == "boolean" then
--- -- r[#r+1] = v and f_indexed_true(k) or f_indexed_false(k)
--- r[#r+1] = v and "true," or "false,"
--- end
--- end
--- else
--- for k, v in next, t do
--- local tv = type(v)
--- if tv == "string" then
--- r[#r+1] = f_hashed_string(k,v)
--- elseif tv == "number" then
--- r[#r+1] = f_hashed_number(k,v)
--- elseif tv == "table" then
--- r[#r+1] = f_hashed_table(k)
--- fastserialize(v,r)
--- elseif tv == "boolean" then
--- r[#r+1] = v and f_hashed_true(k) or f_hashed_false(k)
--- end
--- end
--- end
--- if outer then
--- r[#r+1] = "}"
--- else
--- r[#r+1] = "},"
--- end
--- return r
--- end
-function table.fastserialize(t,prefix) -- so prefix should contain the =
- return concat(fastserialize(t,{ prefix or "return" },true))
+ return concat(fastserialize(t,true))
end
function table.deserialize(str)
@@ -422,10 +387,14 @@ function table.load(filename,loader)
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,...)) -- no frozen table.serialize
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) -- maybe less memory (intermediate concat)
local r = { }
local l = { }
for i=1,#t do
@@ -433,28 +402,30 @@ 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) -- only { { a=2 }, {a=3} }
+function table.drop(t,slow) -- only { { a=2 }, {a=3} } -- for special cases
if #t == 0 then
return "return { }"
elseif slow == true then
@@ -464,6 +435,9 @@ function table.drop(t,slow) -- only { { a=2 }, {a=3} }
end
end
+-- inspect(table.drop({ { a=2 }, {a=3} }))
+-- inspect(table.drop({ { a=2 }, {a=3} },true))
+
function table.autokey(t,k)
local v = { }
t[k] = v
@@ -491,3 +465,244 @@ function table.twowaymapper(t)
return t
end
+-- The next version is somewhat faster, although in practice one will seldom
+-- serialize a lot using this one. Often the above variants are more efficient.
+-- If we would really need this a lot, we could hash q keys.
+
+-- char-def.lua : 0.53 -> 0.38
+-- husayni.tma : 0.28 -> 0.19
+
+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["}"]
+
+----- f_string = formatters["%q"]
+
+local spaces = utilities.strings.newrepeater(" ")
+
+local serialize = table.serialize -- the extensive one, the one we started with
+
+function table.serialize(root,name,specification)
+
+ if type(specification) == "table" then
+ return serialize(root,name,specification) -- the original one
+ 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) -- f_string(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
+ -- we could check for k (index) being number (cardinal)
+ 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) -- inline fast version?
+ 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
+ -- The dummy access will initialize a table that has a delayed initialization
+ -- using a metatable. (maybe explicitly test for metatable)
+ if getmetatable(root) then -- todo: make this an option, maybe even per subtable
+ local dummy = root._w_h_a_t_e_v_e_r_
+ root._w_h_a_t_e_v_e_r_ = nil
+ end
+ -- Let's forget about empty tables.
+ 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
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tpl.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tpl.lua
index 7a6abefd692..e0c405a42de 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tpl.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs-util-tpl.lua
@@ -18,7 +18,7 @@ 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
-- todo: make installable template.new
@@ -52,7 +52,10 @@ local sqlescape = lpeg.replacer {
-- { "\t", "\\t" },
}
-local sqlquotedescape = lpeg.Cs(lpeg.Cc("'") * sqlescape * lpeg.Cc("'"))
+local sqlquoted = lpeg.Cs(lpeg.Cc("'") * sqlescape * lpeg.Cc("'"))
+
+lpegpatterns.sqlescape = sqlescape
+lpegpatterns.sqlquoted = sqlquoted
-- escapeset : \0\1\2\3\4\5\6\7\8\9\10\11\12\13\14\15\16\17\18\19\20\21\22\23\24\25\26\27\28\29\30\31\"\\\127
-- test string: [[1\0\31test23"\\]] .. string.char(19) .. "23"
@@ -78,9 +81,16 @@ local sqlquotedescape = lpeg.Cs(lpeg.Cc("'") * sqlescape * lpeg.Cc("'"))
-- P(1)
-- )^0)
+-- local xmlescape = lpegpatterns.xmlescape
+-- local texescape = lpegpatterns.texescape
+-- local luaescape = lpegpatterns.luaescape
+-- local sqlquoted = lpegpatterns.sqlquoted
+-- local luaquoted = lpegpatterns.luaquoted
+
local escapers = {
lua = function(s)
- return sub(format("%q",s),2,-2)
+ -- return sub(format("%q",s),2,-2)
+ return lpegmatch(luaescape,s)
end,
sql = function(s)
return lpegmatch(sqlescape,s)
@@ -89,16 +99,14 @@ local escapers = {
local quotedescapers = {
lua = function(s)
+ -- return lpegmatch(luaquoted,s)
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
@@ -151,6 +159,14 @@ end
templates.replace = replace
+function templates.replacer(str,how,recurse) -- reads nicer
+ return function(mapping)
+ return lpegmatch(replacer,str,1,mapping,how or "lua",recurse or false) or str
+ end
+end
+
+-- local cmd = templates.replacer([[foo %bar%]]) print(cmd { bar = "foo" })
+
function templates.load(filename,mapping,how,recurse)
local data = io.loaddata(filename) or ""
if mapping and next(mapping) then
diff --git a/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua b/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua
index 5e4d818e93f..9240f1b1c79 100644
--- a/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua
+++ b/Master/texmf-dist/tex/luatex/lualibs/lualibs.lua
@@ -7,7 +7,7 @@
-- lualibs.dtx (with options: `lualibs')
-- This is a generated file.
--
--- Copyright (C) 2009 by PRAGMA ADE / ConTeXt Development Team
+-- Copyright (C) 2009--2013 by PRAGMA ADE / ConTeXt Development Team
--
-- See ConTeXt's mreadme.pdf for the license.
--
@@ -23,7 +23,7 @@ lualibs = lualibs or { }
lualibs.module_info = {
name = "lualibs",
version = 2.00,
- date = "2013/05/18",
+ date = "2013/07/23",
description = "ConTeXt Lua standard libraries.",
author = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux & Philipp Gesang",
copyright = "PRAGMA ADE / ConTeXt Development Team",