From 48c4609c92a6e0cbbbd8c5e894d2e11b081e032f Mon Sep 17 00:00:00 2001 From: Marius Date: Mon, 26 Nov 2012 19:00:25 +0200 Subject: beta 2012.11.26 13:31 --- scripts/context/lua/mtx-context.lua | 21 +- scripts/context/lua/mtx-profile.lua | 35 +- scripts/context/lua/mtxrun.lua | 62 +++- scripts/context/stubs/mswin/mtxrun.lua | 62 +++- scripts/context/stubs/unix/mtxrun | 62 +++- tex/context/base/char-ini.lua | 10 +- tex/context/base/colo-ini.lua | 6 - tex/context/base/cont-new.mkii | 2 +- tex/context/base/cont-new.mkiv | 4 +- tex/context/base/context-version.pdf | Bin 4152 -> 4149 bytes tex/context/base/context-version.png | Bin 40647 -> 40624 bytes tex/context/base/context.mkii | 2 +- tex/context/base/context.mkiv | 2 +- tex/context/base/data-ini.lua | 8 +- tex/context/base/file-job.lua | 2 +- tex/context/base/font-chk.lua | 1 + tex/context/base/grph-inc.lua | 23 +- tex/context/base/l-io.lua | 18 + tex/context/base/l-lpeg.lua | 6 +- tex/context/base/luat-cbk.lua | 4 +- tex/context/base/luat-cod.mkiv | 25 +- tex/context/base/m-timing.mkiv | 2 +- tex/context/base/meta-ini.mkiv | 12 +- tex/context/base/mtx-context-timing.tex | 2 +- tex/context/base/node-fin.lua | 3 +- tex/context/base/node-ref.lua | 143 +++++-- tex/context/base/node-tra.lua | 55 +++ tex/context/base/phys-dim.lua | 3 +- tex/context/base/spac-ver.lua | 413 +++++++++++---------- tex/context/base/status-files.pdf | Bin 24539 -> 24569 bytes tex/context/base/status-lua.pdf | Bin 198711 -> 198842 bytes tex/context/base/trac-inf.lua | 17 +- tex/context/base/trac-tim.lua | 58 +-- tex/context/base/util-tab.lua | 13 +- tex/generic/context/luatex/luatex-fonts-merged.lua | 26 +- 35 files changed, 698 insertions(+), 404 deletions(-) diff --git a/scripts/context/lua/mtx-context.lua b/scripts/context/lua/mtx-context.lua index f33363a0d..698a6f142 100644 --- a/scripts/context/lua/mtx-context.lua +++ b/scripts/context/lua/mtx-context.lua @@ -518,6 +518,7 @@ function scripts.context.run(ctxdata,filename) local a_purgeresult = getargument("purgeresult") local a_global = getargument("global") local a_timing = getargument("timing") + local a_profile = getargument("profile") local a_batchmode = getargument("batchmode") local a_nonstopmode = getargument("nonstopmode") local a_once = getargument("once") @@ -626,6 +627,22 @@ function scripts.context.run(ctxdata,filename) report("warning: synctex is enabled") -- can add upto 5% runtime end -- + if not a_timing then + -- okay + elseif c_flags.usemodule then + c_flags.usemodule = format("timing,%s",c_flags.usemodule) + else + c_flags.usemodule = "timing" + end + -- + if not a_profile then + -- okay + elseif c_flags.directives then + c_flags.directives = format("system.profile,%s",c_flags.directives) + else + c_flags.directives = "system.profile" + end + -- -- kindofrun: 1:first run, 2:successive run, 3:once, 4:last of maxruns -- for currentrun=1,maxnofruns do @@ -1371,10 +1388,6 @@ elseif getargument("runs") then multipass_nofruns = tonumber(getargument("runs")) or nil end -if getargument("profile") then - os.setenv("MTX_PROFILE_RUN","YES") -end - if getargument("run") then scripts.context.timed(scripts.context.autoctx) elseif getargument("make") then diff --git a/scripts/context/lua/mtx-profile.lua b/scripts/context/lua/mtx-profile.lua index 74e1d1538..35cf1fc47 100644 --- a/scripts/context/lua/mtx-profile.lua +++ b/scripts/context/lua/mtx-profile.lua @@ -41,33 +41,28 @@ function scripts.profiler.analyze(filename) if f then local times, counts, calls = { }, { }, { } local totalruntime, totalcount, totalcalls = 0, 0, 0 - while true do - local line = f:read() - if line then - local stacklevel, filename, functionname, linenumber, currentline, localtime, totaltime = line:match("^(%d+)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)") - if not filename then - -- next - elseif filename == "=[C]" then - if not functionname:find("^%(") then - calls[functionname] = (calls[functionname] or 0) + 1 - end - else - local filename = filename:match("^@(.*)$") - if filename then - local fi = times[filename] - if not fi then fi = { } times[filename] = fi end - fi[functionname] = (fi[functionname] or 0) + tonumber(localtime) - counts[functionname] = (counts[functionname] or 0) + 1 - end + for line in f:lines() do + local stacklevel, filename, functionname, linenumber, currentline, localtime, totaltime = line:match("^(%d+)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)\t(.-)") + if not filename then + -- next + elseif filename == "=[C]" then + if not functionname:find("^%(") then + calls[functionname] = (calls[functionname] or 0) + 1 end else - break + local filename = filename:match("^@(.*)$") + if filename then + local fi = times[filename] + if not fi then fi = { } times[filename] = fi end + fi[functionname] = (fi[functionname] or 0) + tonumber(localtime) + counts[functionname] = (counts[functionname] or 0) + 1 + end end end f:close() print("") local loaded = { } - sortedtable.sortedkeys(times) + local sorted = table.sortedkeys(times) for i=1,#sorted do local filename = sorted[i] local functions = times[filename] diff --git a/scripts/context/lua/mtxrun.lua b/scripts/context/lua/mtxrun.lua index 403f2ba63..0d977b57e 100644 --- a/scripts/context/lua/mtxrun.lua +++ b/scripts/context/lua/mtxrun.lua @@ -1318,8 +1318,10 @@ patterns.digit = digit patterns.sign = sign patterns.cardinal = sign^0 * digit^1 patterns.integer = sign^0 * digit^1 -patterns.float = sign^0 * digit^0 * P('.') * digit^1 -patterns.cfloat = sign^0 * digit^0 * P(',') * 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 @@ -2345,6 +2347,24 @@ end if not io.i_limiter then function io.i_limiter() end end -- dummy so we can test safely if not io.o_limiter then function io.o_limiter() end end -- dummy so we can test safely +-- This works quite ok: +-- +-- function io.piped(command,writer) +-- local pipe = io.popen(command) +-- -- for line in pipe:lines() do +-- -- print(line) +-- -- end +-- while true do +-- local line = pipe:read(1) +-- if not line then +-- break +-- elseif line ~= "\n" then +-- writer(line) +-- end +-- end +-- return pipe:close() -- ok, status, (error)code +-- end + end -- of closure @@ -4780,6 +4800,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, loadstring = type, next, rawset, tonumber, loadstring local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs +local serialize = table.serialize -- function tables.definetable(target) -- defines undefined tables -- local composed, t, n = nil, { }, 0 @@ -4958,7 +4979,7 @@ function tables.encapsulate(core,capsule,protect) end end -local function serialize(t,r,outer) -- no mixes +local function fastserialize(t,r,outer) -- no mixes r[#r+1] = "{" local n = #t if n > 0 then @@ -4970,7 +4991,7 @@ local function serialize(t,r,outer) -- no mixes elseif tv == "number" then r[#r+1] = format("%s,",v) elseif tv == "table" then - serialize(v,r) + fastserialize(v,r) elseif tv == "boolean" then r[#r+1] = format("%s,",tostring(v)) end @@ -4984,7 +5005,7 @@ local function serialize(t,r,outer) -- no mixes r[#r+1] = format("[%q]=%s,",k,v) elseif tv == "table" then r[#r+1] = format("[%q]=",k) - serialize(v,r) + fastserialize(v,r) elseif tv == "boolean" then r[#r+1] = format("[%q]=%s,",k,tostring(v)) end @@ -4999,7 +5020,7 @@ local function serialize(t,r,outer) -- no mixes end function table.fastserialize(t,prefix) -- so prefix should contain the = - return concat(serialize(t,{ prefix or "return" },true)) + return concat(fastserialize(t,{ prefix or "return" },true)) end function table.deserialize(str) @@ -5034,6 +5055,10 @@ function table.load(filename) end end +function table.save(filename,t,n,...) + io.savedata(filename,serialize(t,n == nil and true or n,...)) +end + local function slowdrop(t) local r = { } local l = { } @@ -6338,10 +6363,16 @@ statistics = statistics or { } local statistics = statistics statistics.enable = true -statistics.threshold = 0.05 +statistics.threshold = 0.01 local statusinfo, n, registered, timers = { }, 0, { }, { } +table.setmetatableindex(timers,function(t,k) + local v = { timing = 0, loadtime = 0 } + t[k] = v + return v +end) + local function hastiming(instance) return instance and timers[instance] end @@ -6352,14 +6383,7 @@ end local function starttiming(instance) local timer = timers[instance or "notimer"] - if not timer then - timer = { } - timers[instance or "notimer"] = timer - end - local it = timer.timing - if not it then - it = 0 - end + local it = timer.timing or 0 if it == 0 then timer.starttime = clock() if not timer.loadtime then @@ -12152,9 +12176,11 @@ resolvers.settrace(osgetenv("MTX_INPUT_TRACE")) -- todo: --- if profiler and osgetenv("MTX_PROFILE_RUN") == "YES" then --- profiler.start("luatex-profile.log") --- end +if profiler then + directives.register("system.profile",function() + profiler.start("luatex-profile.log") + end) +end -- a forward definition diff --git a/scripts/context/stubs/mswin/mtxrun.lua b/scripts/context/stubs/mswin/mtxrun.lua index 403f2ba63..0d977b57e 100644 --- a/scripts/context/stubs/mswin/mtxrun.lua +++ b/scripts/context/stubs/mswin/mtxrun.lua @@ -1318,8 +1318,10 @@ patterns.digit = digit patterns.sign = sign patterns.cardinal = sign^0 * digit^1 patterns.integer = sign^0 * digit^1 -patterns.float = sign^0 * digit^0 * P('.') * digit^1 -patterns.cfloat = sign^0 * digit^0 * P(',') * 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 @@ -2345,6 +2347,24 @@ end if not io.i_limiter then function io.i_limiter() end end -- dummy so we can test safely if not io.o_limiter then function io.o_limiter() end end -- dummy so we can test safely +-- This works quite ok: +-- +-- function io.piped(command,writer) +-- local pipe = io.popen(command) +-- -- for line in pipe:lines() do +-- -- print(line) +-- -- end +-- while true do +-- local line = pipe:read(1) +-- if not line then +-- break +-- elseif line ~= "\n" then +-- writer(line) +-- end +-- end +-- return pipe:close() -- ok, status, (error)code +-- end + end -- of closure @@ -4780,6 +4800,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, loadstring = type, next, rawset, tonumber, loadstring local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs +local serialize = table.serialize -- function tables.definetable(target) -- defines undefined tables -- local composed, t, n = nil, { }, 0 @@ -4958,7 +4979,7 @@ function tables.encapsulate(core,capsule,protect) end end -local function serialize(t,r,outer) -- no mixes +local function fastserialize(t,r,outer) -- no mixes r[#r+1] = "{" local n = #t if n > 0 then @@ -4970,7 +4991,7 @@ local function serialize(t,r,outer) -- no mixes elseif tv == "number" then r[#r+1] = format("%s,",v) elseif tv == "table" then - serialize(v,r) + fastserialize(v,r) elseif tv == "boolean" then r[#r+1] = format("%s,",tostring(v)) end @@ -4984,7 +5005,7 @@ local function serialize(t,r,outer) -- no mixes r[#r+1] = format("[%q]=%s,",k,v) elseif tv == "table" then r[#r+1] = format("[%q]=",k) - serialize(v,r) + fastserialize(v,r) elseif tv == "boolean" then r[#r+1] = format("[%q]=%s,",k,tostring(v)) end @@ -4999,7 +5020,7 @@ local function serialize(t,r,outer) -- no mixes end function table.fastserialize(t,prefix) -- so prefix should contain the = - return concat(serialize(t,{ prefix or "return" },true)) + return concat(fastserialize(t,{ prefix or "return" },true)) end function table.deserialize(str) @@ -5034,6 +5055,10 @@ function table.load(filename) end end +function table.save(filename,t,n,...) + io.savedata(filename,serialize(t,n == nil and true or n,...)) +end + local function slowdrop(t) local r = { } local l = { } @@ -6338,10 +6363,16 @@ statistics = statistics or { } local statistics = statistics statistics.enable = true -statistics.threshold = 0.05 +statistics.threshold = 0.01 local statusinfo, n, registered, timers = { }, 0, { }, { } +table.setmetatableindex(timers,function(t,k) + local v = { timing = 0, loadtime = 0 } + t[k] = v + return v +end) + local function hastiming(instance) return instance and timers[instance] end @@ -6352,14 +6383,7 @@ end local function starttiming(instance) local timer = timers[instance or "notimer"] - if not timer then - timer = { } - timers[instance or "notimer"] = timer - end - local it = timer.timing - if not it then - it = 0 - end + local it = timer.timing or 0 if it == 0 then timer.starttime = clock() if not timer.loadtime then @@ -12152,9 +12176,11 @@ resolvers.settrace(osgetenv("MTX_INPUT_TRACE")) -- todo: --- if profiler and osgetenv("MTX_PROFILE_RUN") == "YES" then --- profiler.start("luatex-profile.log") --- end +if profiler then + directives.register("system.profile",function() + profiler.start("luatex-profile.log") + end) +end -- a forward definition diff --git a/scripts/context/stubs/unix/mtxrun b/scripts/context/stubs/unix/mtxrun index 403f2ba63..0d977b57e 100644 --- a/scripts/context/stubs/unix/mtxrun +++ b/scripts/context/stubs/unix/mtxrun @@ -1318,8 +1318,10 @@ patterns.digit = digit patterns.sign = sign patterns.cardinal = sign^0 * digit^1 patterns.integer = sign^0 * digit^1 -patterns.float = sign^0 * digit^0 * P('.') * digit^1 -patterns.cfloat = sign^0 * digit^0 * P(',') * 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 @@ -2345,6 +2347,24 @@ end if not io.i_limiter then function io.i_limiter() end end -- dummy so we can test safely if not io.o_limiter then function io.o_limiter() end end -- dummy so we can test safely +-- This works quite ok: +-- +-- function io.piped(command,writer) +-- local pipe = io.popen(command) +-- -- for line in pipe:lines() do +-- -- print(line) +-- -- end +-- while true do +-- local line = pipe:read(1) +-- if not line then +-- break +-- elseif line ~= "\n" then +-- writer(line) +-- end +-- end +-- return pipe:close() -- ok, status, (error)code +-- end + end -- of closure @@ -4780,6 +4800,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, loadstring = type, next, rawset, tonumber, loadstring local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs +local serialize = table.serialize -- function tables.definetable(target) -- defines undefined tables -- local composed, t, n = nil, { }, 0 @@ -4958,7 +4979,7 @@ function tables.encapsulate(core,capsule,protect) end end -local function serialize(t,r,outer) -- no mixes +local function fastserialize(t,r,outer) -- no mixes r[#r+1] = "{" local n = #t if n > 0 then @@ -4970,7 +4991,7 @@ local function serialize(t,r,outer) -- no mixes elseif tv == "number" then r[#r+1] = format("%s,",v) elseif tv == "table" then - serialize(v,r) + fastserialize(v,r) elseif tv == "boolean" then r[#r+1] = format("%s,",tostring(v)) end @@ -4984,7 +5005,7 @@ local function serialize(t,r,outer) -- no mixes r[#r+1] = format("[%q]=%s,",k,v) elseif tv == "table" then r[#r+1] = format("[%q]=",k) - serialize(v,r) + fastserialize(v,r) elseif tv == "boolean" then r[#r+1] = format("[%q]=%s,",k,tostring(v)) end @@ -4999,7 +5020,7 @@ local function serialize(t,r,outer) -- no mixes end function table.fastserialize(t,prefix) -- so prefix should contain the = - return concat(serialize(t,{ prefix or "return" },true)) + return concat(fastserialize(t,{ prefix or "return" },true)) end function table.deserialize(str) @@ -5034,6 +5055,10 @@ function table.load(filename) end end +function table.save(filename,t,n,...) + io.savedata(filename,serialize(t,n == nil and true or n,...)) +end + local function slowdrop(t) local r = { } local l = { } @@ -6338,10 +6363,16 @@ statistics = statistics or { } local statistics = statistics statistics.enable = true -statistics.threshold = 0.05 +statistics.threshold = 0.01 local statusinfo, n, registered, timers = { }, 0, { }, { } +table.setmetatableindex(timers,function(t,k) + local v = { timing = 0, loadtime = 0 } + t[k] = v + return v +end) + local function hastiming(instance) return instance and timers[instance] end @@ -6352,14 +6383,7 @@ end local function starttiming(instance) local timer = timers[instance or "notimer"] - if not timer then - timer = { } - timers[instance or "notimer"] = timer - end - local it = timer.timing - if not it then - it = 0 - end + local it = timer.timing or 0 if it == 0 then timer.starttime = clock() if not timer.loadtime then @@ -12152,9 +12176,11 @@ resolvers.settrace(osgetenv("MTX_INPUT_TRACE")) -- todo: --- if profiler and osgetenv("MTX_PROFILE_RUN") == "YES" then --- profiler.start("luatex-profile.log") --- end +if profiler then + directives.register("system.profile",function() + profiler.start("luatex-profile.log") + end) +end -- a forward definition diff --git a/tex/context/base/char-ini.lua b/tex/context/base/char-ini.lua index 6e14982c7..70e893b2c 100644 --- a/tex/context/base/char-ini.lua +++ b/tex/context/base/char-ini.lua @@ -717,7 +717,15 @@ characters.activeoffset = 0x10000 -- there will be remapped in that byte range -- entities.gt = utfchar(characters.activeoffset + utfbyte(">")) -- end --- some day we will make a table +-- -- some day we will make a table .. not that many calls to utfchar +-- +-- local utfchar = utf.char +-- local utfbyte = utf.byte +-- local utfbytes = { } +-- local utfchars = { } +-- +-- table.setmetatableindex(utfbytes,function(t,k) local v= utfchar(k) t[k] = v return v end) +-- table.setmetatableindex(utfchars,function(t,k) local v= utfbyte(k) t[k] = v return v end) local function utfstring(s) if type(s) == "table" then diff --git a/tex/context/base/colo-ini.lua b/tex/context/base/colo-ini.lua index e08f3d387..51f66025e 100644 --- a/tex/context/base/colo-ini.lua +++ b/tex/context/base/colo-ini.lua @@ -428,9 +428,6 @@ function colors.definemultitonecolor(name,multispec,colorspec,selfspec) if max > 0 then nn = concat(nn,'_') local parent = gsub(lower(nn),"[^%d%a%.]+","_") ---~ if max == 2 and (not colorspec or colorspec == "") then ---~ colors.defineduocolor(parent,pp[1],l_color[dd[1]],pp[2],l_color[dd[2]],true,true) ---~ elseif (not colorspec or colorspec == "") then if not colorspec or colorspec == "" then local cc = { } for i=1,max do cc[i] = l_color[dd[i]] end colors.definemixcolor(parent,pp,cc,global,freeze) -- can become local @@ -442,11 +439,8 @@ function colors.definemultitonecolor(name,multispec,colorspec,selfspec) end local cp = attributes_list[a_color][parent] dd, pp = concat(dd,','), concat(pp,',') ---~ print(name,multispec,colorspec,selfspec) ---~ print(parent,max,cp) if cp then do_registerspotcolor(parent, name, cp, "", max, dd, pp) ---~ do_registermultitonecolor(parent, name, cp, "", max, dd, pp) -- done in previous ... check it definecolor(name, register_color(name, 'spot', parent, max, dd, pp), true) local t = settings_to_hash_strict(selfspec) if t and t.a and t.t then diff --git a/tex/context/base/cont-new.mkii b/tex/context/base/cont-new.mkii index 1156b3e27..d5f90c684 100644 --- a/tex/context/base/cont-new.mkii +++ b/tex/context/base/cont-new.mkii @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.11.23 17:35} +\newcontextversion{2012.11.26 13:31} %D This file is loaded at runtime, thereby providing an %D excellent place for hacks, patches, extensions and new diff --git a/tex/context/base/cont-new.mkiv b/tex/context/base/cont-new.mkiv index 06127c68b..10fba7f40 100644 --- a/tex/context/base/cont-new.mkiv +++ b/tex/context/base/cont-new.mkiv @@ -11,7 +11,7 @@ %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. -\newcontextversion{2012.11.23 17:35} +\newcontextversion{2012.11.26 13:31} %D This file is loaded at runtime, thereby providing an excellent place for %D hacks, patches, extensions and new features. @@ -20,6 +20,8 @@ \writestatus\m!system{beware: some patches loaded from cont-new.mkiv} +% \attribute152\zerocount : marks ... lots of sweeps so best early in list + %D Maybe: \unexpanded\def\tightvbox{\dowithnextbox{\dp\nextbox\zeropoint\box\nextbox}\vbox} diff --git a/tex/context/base/context-version.pdf b/tex/context/base/context-version.pdf index d17c41110..f8855c59a 100644 Binary files a/tex/context/base/context-version.pdf and b/tex/context/base/context-version.pdf differ diff --git a/tex/context/base/context-version.png b/tex/context/base/context-version.png index 43687ee49..db92e1e14 100644 Binary files a/tex/context/base/context-version.png and b/tex/context/base/context-version.png differ diff --git a/tex/context/base/context.mkii b/tex/context/base/context.mkii index 9520ff3ff..a083e5911 100644 --- a/tex/context/base/context.mkii +++ b/tex/context/base/context.mkii @@ -20,7 +20,7 @@ %D your styles an modules. \edef\contextformat {\jobname} -\edef\contextversion{2012.11.23 17:35} +\edef\contextversion{2012.11.26 13:31} %D For those who want to use this: diff --git a/tex/context/base/context.mkiv b/tex/context/base/context.mkiv index 3f6175d13..afe46d69c 100644 --- a/tex/context/base/context.mkiv +++ b/tex/context/base/context.mkiv @@ -25,7 +25,7 @@ %D up and the dependencies are more consistent. \edef\contextformat {\jobname} -\edef\contextversion{2012.11.23 17:35} +\edef\contextversion{2012.11.26 13:31} %D For those who want to use this: diff --git a/tex/context/base/data-ini.lua b/tex/context/base/data-ini.lua index 773490785..a952a29bd 100644 --- a/tex/context/base/data-ini.lua +++ b/tex/context/base/data-ini.lua @@ -227,9 +227,11 @@ resolvers.settrace(osgetenv("MTX_INPUT_TRACE")) -- todo: --- if profiler and osgetenv("MTX_PROFILE_RUN") == "YES" then --- profiler.start("luatex-profile.log") --- end +if profiler then + directives.register("system.profile",function() + profiler.start("luatex-profile.log") + end) +end -- a forward definition diff --git a/tex/context/base/file-job.lua b/tex/context/base/file-job.lua index 6be901a9f..fda4f27da 100644 --- a/tex/context/base/file-job.lua +++ b/tex/context/base/file-job.lua @@ -771,7 +771,7 @@ function document.getargument(key,default) -- commands end function document.getfilename(i) -- commands - context(document.files[i] or "") + context(document.files[tonumber(i)] or "") end function commands.getcommandline() -- has to happen at the tex end in order to expand diff --git a/tex/context/base/font-chk.lua b/tex/context/base/font-chk.lua index 7536a3e09..4bedf7ace 100644 --- a/tex/context/base/font-chk.lua +++ b/tex/context/base/font-chk.lua @@ -169,6 +169,7 @@ local function addmissingsymbols(tfmdata) -- we can have an alternative with rul width = size*fake.width, height = size*fake.height, depth = size*fake.depth, + -- bah .. low level pdf ... should be a rule or plugged in commands = { { "special", "pdf: " .. format(package,scale,scale,r,g,b,r,g,b,fake.code) } } } cache[hash] = char diff --git a/tex/context/base/grph-inc.lua b/tex/context/base/grph-inc.lua index 57b726909..ee59de508 100644 --- a/tex/context/base/grph-inc.lua +++ b/tex/context/base/grph-inc.lua @@ -65,6 +65,27 @@ local report_inclusion = logs.reporter("graphics","inclusion") local context, img = context, img +local maxdimen = 2^30-1 + +function img.check(figure) + if figure then + local width = figure.width + local height = figure.height + if height > width then + if height > maxdimen then + figure.height = maxdimen + figure.width = width * maxdimen/height + report_inclusion("limiting natural dimensions of %q (height)",figure.filename or "?") + end + elseif width > maxdimen then + figure.width = maxdimen + figure.height = height * maxdimen/width + report_inclusion("limiting natural dimensions of %q (width)",figure.filename or "?") + end + return figure + end +end + --- some extra img functions --- can become luat-img.lua local imgkeys = img.keys() @@ -970,7 +991,7 @@ function checkers.generic(data) } codeinjections.setfigurecolorspace(data,figure) codeinjections.setfiguremask(data,figure) - figure = figure and img.scan(figure) or false + figure = figure and img.check(img.scan(figure)) or false local f, d = codeinjections.setfigurealternative(data,figure) figure, data = f or figure, d or data figures_loaded[hash] = figure diff --git a/tex/context/base/l-io.lua b/tex/context/base/l-io.lua index 3456001b7..ec628b5e0 100644 --- a/tex/context/base/l-io.lua +++ b/tex/context/base/l-io.lua @@ -336,3 +336,21 @@ end if not io.i_limiter then function io.i_limiter() end end -- dummy so we can test safely if not io.o_limiter then function io.o_limiter() end end -- dummy so we can test safely + +-- This works quite ok: +-- +-- function io.piped(command,writer) +-- local pipe = io.popen(command) +-- -- for line in pipe:lines() do +-- -- print(line) +-- -- end +-- while true do +-- local line = pipe:read(1) +-- if not line then +-- break +-- elseif line ~= "\n" then +-- writer(line) +-- end +-- end +-- return pipe:close() -- ok, status, (error)code +-- end diff --git a/tex/context/base/l-lpeg.lua b/tex/context/base/l-lpeg.lua index 55c520691..819a1b9ab 100644 --- a/tex/context/base/l-lpeg.lua +++ b/tex/context/base/l-lpeg.lua @@ -120,8 +120,10 @@ patterns.digit = digit patterns.sign = sign patterns.cardinal = sign^0 * digit^1 patterns.integer = sign^0 * digit^1 -patterns.float = sign^0 * digit^0 * P('.') * digit^1 -patterns.cfloat = sign^0 * digit^0 * P(',') * 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 diff --git a/tex/context/base/luat-cbk.lua b/tex/context/base/luat-cbk.lua index c4f0aba02..6c37307ca 100644 --- a/tex/context/base/luat-cbk.lua +++ b/tex/context/base/luat-cbk.lua @@ -137,7 +137,7 @@ function callbacks.register(name,func,freeze) end return frozen_callback(name) elseif freeze then - frozen[name] = (type(freeze) == "string" and freeze) or "registered" + frozen[name] = type(freeze) == "string" and freeze or "registered" end if delayed[name] and environment.initex then return nil @@ -154,7 +154,7 @@ function callback.register(name,func) -- original return frozen_callback(name) end -function callbacks.push(name, func) +function callbacks.push(name,func) if not frozen[name] then local sn = stack[name] if not sn then diff --git a/tex/context/base/luat-cod.mkiv b/tex/context/base/luat-cod.mkiv index 034ab0613..9f0f9e6a8 100644 --- a/tex/context/base/luat-cod.mkiv +++ b/tex/context/base/luat-cod.mkiv @@ -49,14 +49,23 @@ % we can drop the \zerocount as it's default -\def\ctxdirectlua {\directlua\zerocount} -\def\ctxlatelua {\latelua \zerocount} -\def\ctxsprint #1{\directlua\zerocount{tex.sprint(tex.ctxcatcodes,#1)}} % saves tokens -\def\ctxwrite #1{\directlua\zerocount{tex.write(#1)}} % saves tokens -\def\ctxcommand #1{\directlua\zerocount{commands.#1}} % saves tokens -\def\ctxdirectcommand#1{\directlua\zerocount{commands.#1}} % saves tokens -\def\ctxlatecommand #1{\latelua \zerocount{commands.#1}} % saves tokens -\def\ctxreport #1{\directlua\zerocount{logs.writer[[#1]]}} +% \def\ctxdirectlua {\directlua\zerocount} +% \def\ctxlatelua {\latelua \zerocount} +% \def\ctxsprint #1{\directlua\zerocount{tex.sprint(tex.ctxcatcodes,#1)}} % saves tokens +% \def\ctxwrite #1{\directlua\zerocount{tex.write(#1)}} % saves tokens +% \def\ctxcommand #1{\directlua\zerocount{commands.#1}} % saves tokens +% \def\ctxdirectcommand#1{\directlua\zerocount{commands.#1}} % saves tokens +% \def\ctxlatecommand #1{\latelua \zerocount{commands.#1}} % saves tokens +% \def\ctxreport #1{\directlua\zerocount{logs.writer[[#1]]}} + +\let\ctxdirectlua \directlua +\let\ctxlatelua \latelua +\def\ctxsprint #1{\directlua{tex.sprint(tex.ctxcatcodes,#1)}} % saves tokens +\def\ctxwrite #1{\directlua{tex.write(#1)}} % saves tokens +\def\ctxcommand #1{\directlua{commands.#1}} % saves tokens +\def\ctxdirectcommand#1{\directlua{commands.#1}} % saves tokens +\def\ctxlatecommand #1{\latelua {commands.#1}} % saves tokens +\def\ctxreport #1{\directlua{logs.writer[[#1]]}} %D Take your choice \unknown diff --git a/tex/context/base/m-timing.mkiv b/tex/context/base/m-timing.mkiv index 62d2ad91b..18646cfae 100644 --- a/tex/context/base/m-timing.mkiv +++ b/tex/context/base/m-timing.mkiv @@ -37,7 +37,7 @@ local progress = moduledata.progress function progress.show(filename,parameters,nodes,other) - for n, name in pairs(parameters or progress.parameters(filename)) do + for n, name in pairs(parameters or progress.parameters()) do context.ShowNamedUsage(filename or progress.defaultfilename,name,other or "") end for n, name in pairs(nodes or progress.nodes(filename)) do diff --git a/tex/context/base/meta-ini.mkiv b/tex/context/base/meta-ini.mkiv index e188794ea..d0045fe14 100644 --- a/tex/context/base/meta-ini.mkiv +++ b/tex/context/base/meta-ini.mkiv @@ -570,8 +570,8 @@ \def\meta_unique_graphic#1#2% {\meta_begin_graphic_group{#1}% \setupMPvariables[\currentMPgraphicname][#2]% - %\getvalue{\??mpgraphic\currentMPgraphicname}\empty - \getvalue{\??mpgraphic#1}\empty + \getvalue{\??mpgraphic\currentMPgraphicname}\empty + %\getvalue{\??mpgraphic#1}\empty \meta_end_graphic_group} \def\meta_handle_use_graphic#1#2#3% @@ -623,8 +623,8 @@ \def\meta_use_graphic#1#2% {\meta_begin_graphic_group{#1}% \doifsomething{#2}{\setupMPvariables[\currentMPgraphicname][#2]}% - %\getvalue{\??mpgraphic\currentMPgraphicname}\empty - \getvalue{\??mpgraphic#1}\empty + \getvalue{\??mpgraphic\currentMPgraphicname}\empty + %\getvalue{\??mpgraphic#1}\empty \meta_end_graphic_group} \let\reuseMPgraphic \useMPgraphic % we can save a setup here if needed @@ -660,8 +660,8 @@ {\meta_begin_graphic_group{#1}% \let\overlaystamp\overlaypagestamp \setupMPvariables[\m_meta_page_prefix:\currentMPgraphicname][#2]% prefix is new here -% \getvalue{\??mpgraphic\m_meta_page_prefix:\currentMPgraphicname}{}% - \getvalue{\??mpgraphic\m_meta_page_prefix:#1}{}% + \getvalue{\??mpgraphic\m_meta_page_prefix:\currentMPgraphicname}{}% + %\getvalue{\??mpgraphic\m_meta_page_prefix:#1}{}% \meta_end_graphic_group} %D One way of defining a stamp is: diff --git a/tex/context/base/mtx-context-timing.tex b/tex/context/base/mtx-context-timing.tex index 1bc5b4776..2fd9cb807 100644 --- a/tex/context/base/mtx-context-timing.tex +++ b/tex/context/base/mtx-context-timing.tex @@ -28,7 +28,7 @@ style=\tt] \setupfootertexts - [\getdocumentfilename{1}-luatex-progress.lut -- \pagenumber] + [\getdocumentfilename{1}-luatex-progress.lut \emdash\ \pagenumber] \setupcolors [state=start] diff --git a/tex/context/base/node-fin.lua b/tex/context/base/node-fin.lua index e0830de61..506fc724f 100644 --- a/tex/context/base/node-fin.lua +++ b/tex/context/base/node-fin.lua @@ -84,7 +84,7 @@ end local function process_attribute(head,plugin) -- head,attribute,enabled,initializer,resolver,processor,finalizer local namespace = plugin.namespace if namespace.enabled ~= false then -- this test will go away - starttiming(attributes) + starttiming(attributes) -- in principle we could delegate this to the main caller local done, used, ok = false, nil, false local attribute = namespace.attribute or numbers[plugin.name] -- todo: plugin.attribute local processor = plugin.processor @@ -579,7 +579,6 @@ local function selective(namespace,attribute,head,inheritance,default) -- two at return head, done end - states.selective = selective -- Ideally the next one should be merged with the previous but keeping it separate is diff --git a/tex/context/base/node-ref.lua b/tex/context/base/node-ref.lua index 33d27e0ec..7e7b3be3b 100644 --- a/tex/context/base/node-ref.lua +++ b/tex/context/base/node-ref.lua @@ -205,6 +205,65 @@ end -- skip is somewhat messy +-- local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main +-- if head then +-- local current, first, last, firstdir, reference = head, nil, nil, nil, nil +-- pardir = pardir or "===" +-- txtdir = txtdir or "===" +-- while current do +-- local id = current.id +-- local r = has_attribute(current,attribute) +-- if id == hlist_code or id == vlist_code then +-- -- somehow reference is true so the following fails (second one not done) in +-- -- test \goto{test}[page(2)] test \gotobox{test}[page(2)] +-- -- so let's wait till this fails again +-- -- if not reference and r and (not skip or r > skip) then -- > or ~= +-- if r and (not skip or r > skip) then -- > or ~= +-- inject_list(id,current,r,make,stack,pardir,txtdir) +-- end +-- if r then +-- done[r] = (done[r] or 0) + 1 +-- end +-- local list = current.list +-- if list then +-- local _ +-- current.list, _, pardir, txtdir = inject_areas(list,attribute,make,stack,done,r or skip or 0,current,pardir,txtdir) +-- end +-- if r then +-- done[r] = done[r] - 1 +-- end +-- elseif id == whatsit_code then +-- local subtype = current.subtype +-- if subtype == localpar_code then +-- pardir = current.dir +-- elseif subtype == dir_code then +-- txtdir = current.dir +-- end +-- elseif id == glue_code and current.subtype == leftskip_code then -- any glue at the left? +-- -- +-- elseif not r then +-- -- just go on, can be kerns +-- elseif not reference then +-- reference, first, last, firstdir = r, current, current, txtdir +-- elseif r == reference then +-- last = current +-- elseif (done[reference] or 0) == 0 then -- or id == glue_code and current.subtype == right_skip_code +-- if not skip or r > skip then -- maybe no > test +-- head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) +-- reference, first, last, firstdir = nil, nil, nil, nil +-- end +-- else +-- reference, first, last, firstdir = r, current, current, txtdir +-- end +-- current = current.next +-- end +-- if reference and (done[reference] or 0) == 0 then +-- head = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) +-- end +-- end +-- return head, true, pardir, txtdir +-- end + local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,txtdir) -- main if head then local current, first, last, firstdir, reference = head, nil, nil, nil, nil @@ -212,12 +271,12 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx txtdir = txtdir or "===" while current do local id = current.id - local r = has_attribute(current,attribute) if id == hlist_code or id == vlist_code then --- somehow reference is true so the following fails (second one not done) in --- test \goto{test}[page(2)] test \gotobox{test}[page(2)] --- so let's wait till this fails again --- if not reference and r and (not skip or r > skip) then -- > or ~= + local r = has_attribute(current,attribute) + -- somehow reference is true so the following fails (second one not done) in + -- test \goto{test}[page(2)] test \gotobox{test}[page(2)] + -- so let's wait till this fails again + -- if not reference and r and (not skip or r > skip) then -- > or ~= if r and (not skip or r > skip) then -- > or ~= inject_list(id,current,r,make,stack,pardir,txtdir) end @@ -241,19 +300,22 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx end elseif id == glue_code and current.subtype == leftskip_code then -- any glue at the left? -- - elseif not r then - -- just go on, can be kerns - elseif not reference then - reference, first, last, firstdir = r, current, current, txtdir - elseif r == reference then - last = current - elseif (done[reference] or 0) == 0 then -- or id == glue_code and current.subtype == right_skip_code - if not skip or r > skip then -- maybe no > test - head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) - reference, first, last, firstdir = nil, nil, nil, nil - end else - reference, first, last, firstdir = r, current, current, txtdir + local r = has_attribute(current,attribute) + if not r then + -- just go on, can be kerns + elseif not reference then + reference, first, last, firstdir = r, current, current, txtdir + elseif r == reference then + last = current + elseif (done[reference] or 0) == 0 then -- or id == glue_code and current.subtype == right_skip_code + if not skip or r > skip then -- maybe no > test + head, current = inject_range(head,first,last,reference,make,stack,parent,pardir,firstdir) + reference, first, last, firstdir = nil, nil, nil, nil + end + else + reference, first, last, firstdir = r, current, current, txtdir + end end current = current.next end @@ -264,6 +326,37 @@ local function inject_areas(head,attribute,make,stack,done,skip,parent,pardir,tx return head, true, pardir, txtdir end +-- local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) -- singular ! +-- if head then +-- pardir = pardir or "===" +-- txtdir = txtdir or "===" +-- local current = head +-- while current do +-- local id = current.id +-- local r = has_attribute(current,attribute) +-- if id == hlist_code or id == vlist_code then +-- if r and not done[r] then +-- done[r] = true +-- inject_list(id,current,r,make,stack,pardir,txtdir) +-- end +-- current.list = inject_area(current.list,attribute,make,stack,done,current,pardir,txtdir) +-- elseif id == whatsit_code then +-- local subtype = current.subtype +-- if subtype == localpar_code then +-- pardir = current.dir +-- elseif subtype == dir_code then +-- txtdir = current.dir +-- end +-- elseif r and not done[r] then +-- done[r] = true +-- head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir) +-- end +-- current = current.next +-- end +-- end +-- return head, true +-- end + local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) -- singular ! if head then pardir = pardir or "===" @@ -271,13 +364,16 @@ local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) local current = head while current do local id = current.id - local r = has_attribute(current,attribute) if id == hlist_code or id == vlist_code then + local r = has_attribute(current,attribute) if r and not done[r] then done[r] = true inject_list(id,current,r,make,stack,pardir,txtdir) end - current.list = inject_area(current.list,attribute,make,stack,done,current,pardir,txtdir) + local list = current.list + if list then + current.list = inject_area(list,attribute,make,stack,done,current,pardir,txtdir) + end elseif id == whatsit_code then local subtype = current.subtype if subtype == localpar_code then @@ -285,9 +381,12 @@ local function inject_area(head,attribute,make,stack,done,parent,pardir,txtdir) elseif subtype == dir_code then txtdir = current.dir end - elseif r and not done[r] then - done[r] = true - head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir) + else + local r = has_attribute(current,attribute) + if r and not done[r] then + done[r] = true + head, current = inject_range(head,current,current,r,make,stack,parent,pardir,txtdir) + end end current = current.next end diff --git a/tex/context/base/node-tra.lua b/tex/context/base/node-tra.lua index 7d5630eaa..1d7a19896 100644 --- a/tex/context/base/node-tra.lua +++ b/tex/context/base/node-tra.lua @@ -16,6 +16,7 @@ local concat = table.concat local format, match, gmatch, concat, rep = string.format, string.match, string.gmatch, table.concat, string.rep local lpegmatch = lpeg.match local write_nl = texio.write_nl +local clock = os.gettimeofday or os.clock -- should go in environment local report_nodes = logs.reporter("nodes","tracing") @@ -799,3 +800,57 @@ nodes.visualizers = { } function nodes.visualizers.handler(head) return head, false end + +-- also moved here + +local snapshots = { } +nodes.snapshots = snapshots + +local nodeusage = nodepool.usage + +local lasttime = clock() +local samples = { } +local parameters = { + "cs_count", + "dyn_used", + "elapsed_time", + "luabytecode_bytes", + "luastate_bytes", + "max_buf_stack", + "obj_ptr", + "pdf_mem_ptr", + "pdf_mem_size", + "pdf_os_cntr", +-- "pool_ptr", -- obsolete + "str_ptr", +} + +function snapshots.takesample(comment) + local c = clock() + local t = { + elapsed_time = c - lasttime, + node_memory = nodeusage(), + comment = comment, + } + for i=1,#parameters do + local parameter = parameters[i] + local ps = status[parameter] + if ps then + t[parameter] = ps + end + end + samples[#samples+1] = t + lasttime = c +end + +function snapshots.getsamples() + return samples -- one return value ! +end + +function snapshots.resetsamples() + samples = { } +end + +function snapshots.getparameters() + return parameters +end diff --git a/tex/context/base/phys-dim.lua b/tex/context/base/phys-dim.lua index 88a522195..ee5298c96 100644 --- a/tex/context/base/phys-dim.lua +++ b/tex/context/base/phys-dim.lua @@ -91,7 +91,6 @@ local powerdigits = plus * C(digits) / context.digitspowerplus + minus * C(digits) / context.digitspowerminus + C(digits) / context.digitspower - local ddigitspace = digitspace / "" / context.digitsspace local ddigit = digits / context.digitsdigit local dsemicomma = semicolon / "" / context.digitsseparatorspace @@ -438,6 +437,8 @@ local short_units = { -- I'm not sure about casing -- a = "ampere", A = "ampere", + min = "minute", + [utfchar(0x2103)] = "celsius", [utfchar(0x2109)] = "fahrenheit", } diff --git a/tex/context/base/spac-ver.lua b/tex/context/base/spac-ver.lua index c02789547..696635bfc 100644 --- a/tex/context/base/spac-ver.lua +++ b/tex/context/base/spac-ver.lua @@ -889,7 +889,7 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end if trace then trace_info("start analyzing",where,what) end while current do - local id, subtype = current.id, current.subtype + local id = current.id if id == hlist_code or id == vlist_code then -- needs checking, why so many calls if snap then @@ -943,246 +943,249 @@ local function collapser(head,where,what,trace,snap,a_snapmethod) -- maybe also end flush("kern") current = current.next - elseif id ~= glue_code then - flush("something else") - current = current.next - elseif subtype == userskip_code then - local sc = has_attribute(current,a_skipcategory) -- has no default, no unset (yet) - local so = has_attribute(current,a_skiporder ) or 1 -- has 1 default, no unset (yet) - local sp = has_attribute(current,a_skippenalty ) -- has no default, no unset (yet) - if sp and sc == penalty then - if not penalty_data then - penalty_data = sp - elseif penalty_order < so then - penalty_order, penalty_data = so, sp - elseif penalty_order == so and sp > penalty_data then - penalty_data = sp - end - if trace then trace_skip('penalty in skip',sc,so,sp,current) end - head, current = remove_node(head, current, true) - elseif not sc then -- if not sc then - if glue_data then - if trace then trace_done("flush",glue_data) end - head = insert_node_before(head,current,glue_data) - if trace then trace_natural("natural",current) end - current = current.next - else - -- not look back across head - local previous = current.prev - if previous and previous.id == glue_code and previous.subtype == userskip_code then - local ps = previous.spec - if ps.writable then - local cs = current.spec - if cs.writable and ps.stretch_order == 0 and ps.shrink_order == 0 and cs.stretch_order == 0 and cs.shrink_order == 0 then - local pw, pp, pm = ps.width, ps.stretch, ps.shrink - local cw, cp, cm = cs.width, cs.stretch, cs.shrink - -- ps = writable_spec(previous) -- no writable needed here - -- ps.width, ps.stretch, ps.shrink = pw + cw, pp + cp, pm + cm - previous.spec = new_gluespec(pw + cw, pp + cp, pm + cm) -- else topskip can disappear - if trace then trace_natural("removed",current) end - head, current = remove_node(head, current, true) - -- current = previous - if trace then trace_natural("collapsed",previous) end - -- current = current.next + elseif id == glue_code then + local subtype = current.subtype + if subtype == userskip_code then + local sc = has_attribute(current,a_skipcategory) -- has no default, no unset (yet) + local so = has_attribute(current,a_skiporder ) or 1 -- has 1 default, no unset (yet) + local sp = has_attribute(current,a_skippenalty ) -- has no default, no unset (yet) + if sp and sc == penalty then + if not penalty_data then + penalty_data = sp + elseif penalty_order < so then + penalty_order, penalty_data = so, sp + elseif penalty_order == so and sp > penalty_data then + penalty_data = sp + end + if trace then trace_skip('penalty in skip',sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif not sc then -- if not sc then + if glue_data then + if trace then trace_done("flush",glue_data) end + head = insert_node_before(head,current,glue_data) + if trace then trace_natural("natural",current) end + current = current.next + else + -- not look back across head + local previous = current.prev + if previous and previous.id == glue_code and previous.subtype == userskip_code then + local ps = previous.spec + if ps.writable then + local cs = current.spec + if cs.writable and ps.stretch_order == 0 and ps.shrink_order == 0 and cs.stretch_order == 0 and cs.shrink_order == 0 then + local pw, pp, pm = ps.width, ps.stretch, ps.shrink + local cw, cp, cm = cs.width, cs.stretch, cs.shrink + -- ps = writable_spec(previous) -- no writable needed here + -- ps.width, ps.stretch, ps.shrink = pw + cw, pp + cp, pm + cm + previous.spec = new_gluespec(pw + cw, pp + cp, pm + cm) -- else topskip can disappear + if trace then trace_natural("removed",current) end + head, current = remove_node(head, current, true) + -- current = previous + if trace then trace_natural("collapsed",previous) end + -- current = current.next + else + if trace then trace_natural("filler",current) end + current = current.next + end else - if trace then trace_natural("filler",current) end + if trace then trace_natural("natural (no prev spec)",current) end current = current.next end else - if trace then trace_natural("natural (no prev spec)",current) end + if trace then trace_natural("natural (no prev)",current) end current = current.next end - else - if trace then trace_natural("natural (no prev)",current) end - current = current.next end - end - glue_order, glue_data = 0, nil - elseif sc == disable then - ignore_following = true - if trace then trace_skip("disable",sc,so,sp,current) end - head, current = remove_node(head, current, true) - elseif sc == together then - keep_together = true - if trace then trace_skip("together",sc,so,sp,current) end - head, current = remove_node(head, current, true) - elseif sc == nowhite then - ignore_whitespace = true - head, current = remove_node(head, current, true) - elseif sc == discard then - if trace then trace_skip("discard",sc,so,sp,current) end - head, current = remove_node(head, current, true) - elseif ignore_following then - if trace then trace_skip("disabled",sc,so,sp,current) end - head, current = remove_node(head, current, true) - elseif not glue_data then - if trace then trace_skip("assign",sc,so,sp,current) end - glue_order = so - head, current, glue_data = remove_node(head, current) - elseif glue_order < so then - if trace then trace_skip("force",sc,so,sp,current) end - glue_order = so - free_glue_node(glue_data) - head, current, glue_data = remove_node(head, current) - elseif glue_order == so then - -- is now exclusive, maybe support goback as combi, else why a set - if sc == largest then - local cs, gs = current.spec, glue_data.spec - local cw, gw = cs.width, gs.width - if cw > gw then - if trace then trace_skip('largest',sc,so,sp,current) end + glue_order, glue_data = 0, nil + elseif sc == disable then + ignore_following = true + if trace then trace_skip("disable",sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif sc == together then + keep_together = true + if trace then trace_skip("together",sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif sc == nowhite then + ignore_whitespace = true + head, current = remove_node(head, current, true) + elseif sc == discard then + if trace then trace_skip("discard",sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif ignore_following then + if trace then trace_skip("disabled",sc,so,sp,current) end + head, current = remove_node(head, current, true) + elseif not glue_data then + if trace then trace_skip("assign",sc,so,sp,current) end + glue_order = so + head, current, glue_data = remove_node(head, current) + elseif glue_order < so then + if trace then trace_skip("force",sc,so,sp,current) end + glue_order = so + free_glue_node(glue_data) + head, current, glue_data = remove_node(head, current) + elseif glue_order == so then + -- is now exclusive, maybe support goback as combi, else why a set + if sc == largest then + local cs, gs = current.spec, glue_data.spec + local cw, gw = cs.width, gs.width + if cw > gw then + if trace then trace_skip('largest',sc,so,sp,current) end + free_glue_node(glue_data) -- also free spec + head, current, glue_data = remove_node(head, current) + else + if trace then trace_skip('remove smallest',sc,so,sp,current) end + head, current = remove_node(head, current, true) + end + elseif sc == goback then + if trace then trace_skip('goback',sc,so,sp,current) end free_glue_node(glue_data) -- also free spec head, current, glue_data = remove_node(head, current) + elseif sc == force then + -- last one counts, some day we can provide an accumulator and largest etc + -- but not now + if trace then trace_skip('force',sc,so,sp,current) end + free_glue_node(glue_data) -- also free spec + head, current, glue_data = remove_node(head, current) + elseif sc == penalty then + -- ? ? ? ? + if trace then trace_skip('penalty',sc,so,sp,current) end + free_glue_node(glue_data) -- also free spec + glue_data = nil + head, current = remove_node(head, current, true) + elseif sc == add then + if trace then trace_skip('add',sc,so,sp,current) end + -- local old, new = glue_data.spec, current.spec + local old, new = writable_spec(glue_data), current.spec + old.width = old.width + new.width + old.stretch = old.stretch + new.stretch + old.shrink = old.shrink + new.shrink + -- toto: order + head, current = remove_node(head, current, true) else - if trace then trace_skip('remove smallest',sc,so,sp,current) end + if trace then trace_skip("unknown",sc,so,sp,current) end head, current = remove_node(head, current, true) end - elseif sc == goback then - if trace then trace_skip('goback',sc,so,sp,current) end - free_glue_node(glue_data) -- also free spec - head, current, glue_data = remove_node(head, current) - elseif sc == force then - -- last one counts, some day we can provide an accumulator and largest etc - -- but not now - if trace then trace_skip('force',sc,so,sp,current) end - free_glue_node(glue_data) -- also free spec - head, current, glue_data = remove_node(head, current) - elseif sc == penalty then - -- ? ? ? ? - if trace then trace_skip('penalty',sc,so,sp,current) end - free_glue_node(glue_data) -- also free spec - glue_data = nil - head, current = remove_node(head, current, true) - elseif sc == add then - if trace then trace_skip('add',sc,so,sp,current) end - -- local old, new = glue_data.spec, current.spec - local old, new = writable_spec(glue_data), current.spec - old.width = old.width + new.width - old.stretch = old.stretch + new.stretch - old.shrink = old.shrink + new.shrink - -- toto: order - head, current = remove_node(head, current, true) else if trace then trace_skip("unknown",sc,so,sp,current) end head, current = remove_node(head, current, true) end - else - if trace then trace_skip("unknown",sc,so,sp,current) end - head, current = remove_node(head, current, true) - end - if sc == force then - force_glue = true - end - elseif subtype == lineskip_code then - if snap then - local s = has_attribute(current,a_snapmethod) - if s and s ~= 0 then - set_attribute(current,a_snapmethod,0) - if current.spec.writable then - local spec = writable_spec(current) - spec.width = 0 - if trace_vsnapping then - report_snapper("lineskip set to zero") + if sc == force then + force_glue = true + end + elseif subtype == lineskip_code then + if snap then + local s = has_attribute(current,a_snapmethod) + if s and s ~= 0 then + set_attribute(current,a_snapmethod,0) + if current.spec.writable then + local spec = writable_spec(current) + spec.width = 0 + if trace_vsnapping then + report_snapper("lineskip set to zero") + end end + else + if trace then trace_skip("lineskip",sc,so,sp,current) end + flush("lineskip") end else if trace then trace_skip("lineskip",sc,so,sp,current) end flush("lineskip") end - else - if trace then trace_skip("lineskip",sc,so,sp,current) end - flush("lineskip") - end - current = current.next - elseif subtype == baselineskip_code then - if snap then - local s = has_attribute(current,a_snapmethod) - if s and s ~= 0 then - set_attribute(current,a_snapmethod,0) - if current.spec.writable then - local spec = writable_spec(current) - spec.width = 0 - if trace_vsnapping then - report_snapper("baselineskip set to zero") + current = current.next + elseif subtype == baselineskip_code then + if snap then + local s = has_attribute(current,a_snapmethod) + if s and s ~= 0 then + set_attribute(current,a_snapmethod,0) + if current.spec.writable then + local spec = writable_spec(current) + spec.width = 0 + if trace_vsnapping then + report_snapper("baselineskip set to zero") + end end + else + if trace then trace_skip("baselineskip",sc,so,sp,current) end + flush("baselineskip") end else if trace then trace_skip("baselineskip",sc,so,sp,current) end flush("baselineskip") end - else - if trace then trace_skip("baselineskip",sc,so,sp,current) end - flush("baselineskip") - end - current = current.next - elseif subtype == parskip_code then - -- parskip always comes later - if ignore_whitespace then - if trace then trace_natural("ignored parskip",current) end - head, current = remove_node(head, current, true) - elseif glue_data then - local ps, gs = current.spec, glue_data.spec - if ps.writable and gs.writable and ps.width > gs.width then - glue_data.spec = copy_node(ps) - if trace then trace_natural("taking parskip",current) end + current = current.next + elseif subtype == parskip_code then + -- parskip always comes later + if ignore_whitespace then + if trace then trace_natural("ignored parskip",current) end + head, current = remove_node(head, current, true) + elseif glue_data then + local ps, gs = current.spec, glue_data.spec + if ps.writable and gs.writable and ps.width > gs.width then + glue_data.spec = copy_node(ps) + if trace then trace_natural("taking parskip",current) end + else + if trace then trace_natural("removed parskip",current) end + end + head, current = remove_node(head, current, true) else - if trace then trace_natural("removed parskip",current) end + if trace then trace_natural("honored parskip",current) end + head, current, glue_data = remove_node(head, current) end - head, current = remove_node(head, current, true) - else - if trace then trace_natural("honored parskip",current) end - head, current, glue_data = remove_node(head, current) - end - elseif subtype == topskip_code or subtype == splittopskip_code then - if snap then - local s = has_attribute(current,a_snapmethod) - if s and s ~= 0 then - set_attribute(current,a_snapmethod,0) - local sv = snapmethods[s] - local w, cw = snap_topskip(current,sv) - if trace_vsnapping then - report_snapper("topskip snapped from %s to %s for '%s'",w,cw,where) + elseif subtype == topskip_code or subtype == splittopskip_code then + if snap then + local s = has_attribute(current,a_snapmethod) + if s and s ~= 0 then + set_attribute(current,a_snapmethod,0) + local sv = snapmethods[s] + local w, cw = snap_topskip(current,sv) + if trace_vsnapping then + report_snapper("topskip snapped from %s to %s for '%s'",w,cw,where) + end + else + if trace then trace_skip("topskip",sc,so,sp,current) end + flush("topskip") end else if trace then trace_skip("topskip",sc,so,sp,current) end flush("topskip") end - else - if trace then trace_skip("topskip",sc,so,sp,current) end - flush("topskip") - end - current = current.next - elseif subtype == abovedisplayskip_code then - -- - if trace then trace_skip("above display skip (normal)",sc,so,sp,current) end - flush("above display skip (normal)") - current = current.next - -- - elseif subtype == belowdisplayskip_code then - -- - if trace then trace_skip("below display skip (normal)",sc,so,sp,current) end - flush("below display skip (normal)") - current = current.next - -- - elseif subtype == abovedisplayshortskip_code then - -- - if trace then trace_skip("above display skip (short)",sc,so,sp,current) end - flush("above display skip (short)") - current = current.next - -- - elseif subtype == belowdisplayshortskip_code then - -- - if trace then trace_skip("below display skip (short)",sc,so,sp,current) end - flush("below display skip (short)") - current = current.next - -- - else -- other glue - if snap and trace_vsnapping and current.spec.writable and current.spec.width ~= 0 then - report_snapper("%s of %s (kept)",skipcodes[subtype],current.spec.width) - --~ current.spec.width = 0 + current = current.next + elseif subtype == abovedisplayskip_code then + -- + if trace then trace_skip("above display skip (normal)",sc,so,sp,current) end + flush("above display skip (normal)") + current = current.next + -- + elseif subtype == belowdisplayskip_code then + -- + if trace then trace_skip("below display skip (normal)",sc,so,sp,current) end + flush("below display skip (normal)") + current = current.next + -- + elseif subtype == abovedisplayshortskip_code then + -- + if trace then trace_skip("above display skip (short)",sc,so,sp,current) end + flush("above display skip (short)") + current = current.next + -- + elseif subtype == belowdisplayshortskip_code then + -- + if trace then trace_skip("below display skip (short)",sc,so,sp,current) end + flush("below display skip (short)") + current = current.next + -- + else -- other glue + if snap and trace_vsnapping and current.spec.writable and current.spec.width ~= 0 then + report_snapper("%s of %s (kept)",skipcodes[subtype],current.spec.width) + --~ current.spec.width = 0 + end + if trace then trace_skip(format("some glue (%s)",subtype),sc,so,sp,current) end + flush("some glue") + current = current.next end - if trace then trace_skip(format("some glue (%s)",subtype),sc,so,sp,current) end - flush("some glue") + else + flush("something else") current = current.next end end diff --git a/tex/context/base/status-files.pdf b/tex/context/base/status-files.pdf index 83936aba1..ddafd2831 100644 Binary files a/tex/context/base/status-files.pdf and b/tex/context/base/status-files.pdf differ diff --git a/tex/context/base/status-lua.pdf b/tex/context/base/status-lua.pdf index 736cc36fc..fac4e063e 100644 Binary files a/tex/context/base/status-lua.pdf and b/tex/context/base/status-lua.pdf differ diff --git a/tex/context/base/trac-inf.lua b/tex/context/base/trac-inf.lua index 6ba3d348e..699e2b668 100644 --- a/tex/context/base/trac-inf.lua +++ b/tex/context/base/trac-inf.lua @@ -19,10 +19,16 @@ statistics = statistics or { } local statistics = statistics statistics.enable = true -statistics.threshold = 0.05 +statistics.threshold = 0.01 local statusinfo, n, registered, timers = { }, 0, { }, { } +table.setmetatableindex(timers,function(t,k) + local v = { timing = 0, loadtime = 0 } + t[k] = v + return v +end) + local function hastiming(instance) return instance and timers[instance] end @@ -33,14 +39,7 @@ end local function starttiming(instance) local timer = timers[instance or "notimer"] - if not timer then - timer = { } - timers[instance or "notimer"] = timer - end - local it = timer.timing - if not it then - it = 0 - end + local it = timer.timing or 0 if it == 0 then timer.starttime = clock() if not timer.loadtime then diff --git a/tex/context/base/trac-tim.lua b/tex/context/base/trac-tim.lua index adc8e01b5..66ac518bb 100644 --- a/tex/context/base/trac-tim.lua +++ b/tex/context/base/trac-tim.lua @@ -11,60 +11,33 @@ local concat, sort = table.concat, table.sort local next, tonumber = next, tonumber moduledata = moduledata or { } -moduledata.progress = moduledata.progress or { } -local progress = moduledata.progress +local progress = moduledata.progress or { } +moduledata.progress = progress +progress.parameters = nodes.snapshots.getparameters progress.defaultfilename = ((tex and tex.jobname) or "whatever") .. "-luatex-progress" -local params = { - "cs_count", - "dyn_used", - "elapsed_time", - "luabytecode_bytes", - "luastate_bytes", - "max_buf_stack", - "obj_ptr", - "pdf_mem_ptr", - "pdf_mem_size", - "pdf_os_cntr", --- "pool_ptr", -- obsolete - "str_ptr", -} - -- storage -local last = os.clock() -local data = { } - -function progress.save(name) - io.savedata((name or progress.defaultfilename) .. ".lut",table.serialize(data,true)) - data = { } +function progress.store() + nodes.snapshots.takesample() end -function progress.store() - local c = os.clock() - local t = { - elapsed_time = c - last, - node_memory = nodes.pool.usage(), - } - for k, v in next, params do - if status[v] then t[v] = status[v] end - end - data[#data+1] = t - last = c +function progress.save(name) + table.save((name or progress.defaultfilename) .. ".lut",nodes.snapshots.getsamples()) + nodes.snapshots.resetsamples() end -- conversion -local processed = { } +local processed = { } +local parameters = progress.parameters() local function convert(name) name = name ~= "" and name or progress.defaultfilename if not processed[name] then local names, top, bot, pages, paths, keys = { }, { }, { }, 0, { }, { } - local data = io.loaddata(name .. ".lut") - if data then data = loadstring(data) end - if data then data = data() end + local data = table.load(name .. ".lut") if data then pages = #data if pages > 1 then @@ -109,12 +82,12 @@ local function convert(name) delta = factor/delta end for k=1,#s do - s[k] = "(" .. k .. "," .. (s[k]-b)*delta .. ")" + s[k] = format("(%s,%s)",k,(s[k]-b)*delta) end paths[tagname] = concat(s,"--") end - for _, tag in next, params do - path(tag) + for i=1,#parameters do + path(parameters[i]) end for tag, _ in next, keys do path("node_memory",tag) @@ -157,6 +130,3 @@ function progress.nodes(name) return convert(name).names or { } end -function progress.parameters(name) - return params -- shared -end diff --git a/tex/context/base/util-tab.lua b/tex/context/base/util-tab.lua index c1cedf9bb..cd6826983 100644 --- a/tex/context/base/util-tab.lua +++ b/tex/context/base/util-tab.lua @@ -15,6 +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, loadstring = type, next, rawset, tonumber, loadstring local lpegmatch, P, Cs = lpeg.match, lpeg.P, lpeg.Cs +local serialize = table.serialize -- function tables.definetable(target) -- defines undefined tables -- local composed, t, n = nil, { }, 0 @@ -193,7 +194,7 @@ function tables.encapsulate(core,capsule,protect) end end -local function serialize(t,r,outer) -- no mixes +local function fastserialize(t,r,outer) -- no mixes r[#r+1] = "{" local n = #t if n > 0 then @@ -205,7 +206,7 @@ local function serialize(t,r,outer) -- no mixes elseif tv == "number" then r[#r+1] = format("%s,",v) elseif tv == "table" then - serialize(v,r) + fastserialize(v,r) elseif tv == "boolean" then r[#r+1] = format("%s,",tostring(v)) end @@ -219,7 +220,7 @@ local function serialize(t,r,outer) -- no mixes r[#r+1] = format("[%q]=%s,",k,v) elseif tv == "table" then r[#r+1] = format("[%q]=",k) - serialize(v,r) + fastserialize(v,r) elseif tv == "boolean" then r[#r+1] = format("[%q]=%s,",k,tostring(v)) end @@ -234,7 +235,7 @@ local function serialize(t,r,outer) -- no mixes end function table.fastserialize(t,prefix) -- so prefix should contain the = - return concat(serialize(t,{ prefix or "return" },true)) + return concat(fastserialize(t,{ prefix or "return" },true)) end function table.deserialize(str) @@ -269,6 +270,10 @@ function table.load(filename) end end +function table.save(filename,t,n,...) + io.savedata(filename,serialize(t,n == nil and true or n,...)) +end + local function slowdrop(t) local r = { } local l = { } diff --git a/tex/generic/context/luatex/luatex-fonts-merged.lua b/tex/generic/context/luatex/luatex-fonts-merged.lua index 9bd7f8297..9367a1527 100644 --- a/tex/generic/context/luatex/luatex-fonts-merged.lua +++ b/tex/generic/context/luatex/luatex-fonts-merged.lua @@ -1,6 +1,6 @@ -- merged file : luatex-fonts-merged.lua -- parent file : luatex-fonts.lua --- merge date : 11/23/12 17:35:57 +-- merge date : 11/26/12 13:31:26 do -- begin closure to overcome local limits and interference @@ -1294,8 +1294,10 @@ patterns.digit = digit patterns.sign = sign patterns.cardinal = sign^0 * digit^1 patterns.integer = sign^0 * digit^1 -patterns.float = sign^0 * digit^0 * P('.') * digit^1 -patterns.cfloat = sign^0 * digit^0 * P(',') * 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 @@ -2991,6 +2993,24 @@ end if not io.i_limiter then function io.i_limiter() end end -- dummy so we can test safely if not io.o_limiter then function io.o_limiter() end end -- dummy so we can test safely +-- This works quite ok: +-- +-- function io.piped(command,writer) +-- local pipe = io.popen(command) +-- -- for line in pipe:lines() do +-- -- print(line) +-- -- end +-- while true do +-- local line = pipe:read(1) +-- if not line then +-- break +-- elseif line ~= "\n" then +-- writer(line) +-- end +-- end +-- return pipe:close() -- ok, status, (error)code +-- end + end -- closure do -- begin closure to overcome local limits and interference -- cgit v1.2.3