luat-run.lua /size: 9 Kb    last modification: 2021-10-28 13:50
1if not modules then modules = { } end modules ['luat-run'] = {
2    version   = 1.001,
3    comment   = "companion to luat-lib.mkiv",
4    author    = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
5    copyright = "PRAGMA ADE / ConTeXt Development Team",
6    license   = "see context related readme files"
7}
8
9local next = next
10local find = string.find
11local insert, remove = table.insert, table.remove
12local osexit = os.exit
13
14-- trace_job_status is also controlled by statistics.enable that is set via the directive system.nostatistics
15
16local trace_lua_dump   = false  trackers.register("system.dump",      function(v) trace_lua_dump   = v end)
17local trace_temp_files = false  trackers.register("system.tempfiles", function(v) trace_temp_files = v end)
18local trace_job_status = true   trackers.register("system.jobstatus", function(v) trace_job_status = v end)
19local trace_tex_status = false  trackers.register("system.texstatus", function(v) trace_tex_status = v end)
20
21local report_lua       = logs.reporter("system","lua")
22local report_tex       = logs.reporter("system","status")
23local report_tempfiles = logs.reporter("resolvers","tempfiles")
24
25luatex        = luatex or { }
26local luatex  = luatex
27local synctex = luatex.synctex
28
29if not synctex then
30    synctex        = table.setmetatableindex(function() return function() end end)
31    luatex.synctex = synctex
32end
33
34local startactions = { }
35local stopactions  = { }
36local dumpactions  = { }
37local pageactions  = { }
38
39function luatex.registerstartactions(...) insert(startactions, ...) end
40function luatex.registerstopactions (...) insert(stopactions,  ...) end
41function luatex.registerdumpactions (...) insert(dumpactions,  ...) end
42function luatex.registerpageactions (...) insert(pageactions,  ...) end
43
44local function start_run()
45    if logs.start_run then
46        logs.start_run()
47    end
48 -- logs.report("engine","%s version %s, format id %s",LUATEXENGINE,LUATEXVERSION,LUATEXFORMATID)
49    for i=1,#startactions do
50        startactions[i]()
51    end
52end
53
54local function stop_run()
55    for i=1,#stopactions do
56        stopactions[i]()
57    end
58    local quit = logs.finalactions()
59    if trace_job_status then
60        statistics.show()
61    end
62    if trace_tex_status then
63        logs.newline()
64        for k, v in table.sortedhash(status.list()) do
65            if type(v) ~= "table" then
66                report_tex("%S=%S",k,v)
67            end
68        end
69    end
70    if quit then
71        local setexitcode = lua.setexitcode or status.setexitcode
72        if setexitcode then
73            setexitcode(1)
74            if type(quit) == "table" then
75                logs.newline()
76                report_tex("quitting due to: %, t",quit)
77                logs.newline()
78            end
79        end
80    end
81    if logs.stop_run then
82        logs.stop_run()
83    end
84end
85
86local function start_shipout_page()
87    synctex.start()
88    logs.start_page_number()
89end
90
91local function stop_shipout_page()
92    logs.stop_page_number()
93    for i=1,#pageactions do
94        pageactions[i]()
95    end
96    synctex.stop()
97end
98
99local function report_output_pages()
100end
101
102local function report_output_log()
103end
104
105local function pre_dump_actions()
106    for i=1,#dumpactions do
107        dumpactions[i]()
108    end
109    lua.finalizeinitex(trace_lua_dump and report_lua or nil)
110end
111
112local function wrapup_synctex()
113    synctex.wrapup()
114end
115
116-- For Taco ...
117
118local sequencers     = utilities.sequencers
119local appendgroup    = sequencers.appendgroup
120local appendaction   = sequencers.appendaction
121local wrapupactions  = sequencers.new { }
122local cleanupactions = sequencers.new { }
123
124appendgroup(wrapupactions,"system")
125appendgroup(wrapupactions,"user")
126
127appendgroup(cleanupactions,"system")
128appendgroup(cleanupactions,"user")
129
130local function wrapup_run(someerror)
131    local runner = wrapupactions.runner
132    if runner then
133        runner(someerror) -- we could use the error flag in lmtx
134    end
135end
136
137local function cleanup_run()
138    local runner = cleanupactions.runner
139    if runner then
140        runner()
141    end
142end
143
144function luatex.wrapup(action)
145    appendaction(wrapupactions,"user",action)
146end
147
148function luatex.cleanup(action)
149    appendaction(cleanupactions,"user",action)
150end
151
152function luatex.abort()
153    cleanup_run()
154    osexit(1)
155end
156
157appendaction(wrapupactions,"system",synctex.wrapup)
158
159-- this can be done later
160
161callbacks.register('start_run',               start_run,           "actions performed at the beginning of a run")
162callbacks.register('stop_run',                stop_run,            "actions performed at the end of a run")
163
164---------.register('show_open',               show_open,           "actions performed when opening a file")
165---------.register('show_close',              show_close,          "actions performed when closing a file")
166
167callbacks.register('report_output_pages',     report_output_pages, "actions performed when reporting pages")
168callbacks.register('report_output_log',       report_output_log,   "actions performed when reporting log file")
169
170---------.register('start_page_number',       start_shipout_page,  "actions performed at the beginning of a shipout")
171---------.register('stop_page_number',        stop_shipout_page,   "actions performed at the end of a shipout")
172
173callbacks.register('start_page_number',       function() end,      "actions performed at the beginning of a shipout")
174callbacks.register('stop_page_number',        function() end,      "actions performed at the end of a shipout")
175
176callbacks.register('process_input_buffer',    false,               "actions performed when reading data")
177callbacks.register('process_output_buffer',   false,               "actions performed when writing data")
178
179callbacks.register("pre_dump",                pre_dump_actions,    "lua related finalizers called before we dump the format") -- comes after \everydump
180
181-- finish_synctex might go away (move to wrapup_run)
182
183callbacks.register("finish_synctex",          wrapup_synctex,      "rename temporary synctex file")
184callbacks.register('wrapup_run',              wrapup_run,          "actions performed after closing files")
185
186-- temp hack for testing:
187
188callbacks.functions.start_page_number = start_shipout_page
189callbacks.functions.stop_page_number  = stop_shipout_page
190
191-- an example:
192
193local tempfiles = { }
194
195function luatex.registertempfile(name,extrasuffix,keep) -- namespace might change
196    if extrasuffix then
197        name = name .. ".mkiv-tmp" -- maybe just .tmp
198    end
199    if trace_temp_files and not tempfiles[name] then
200        if keep then
201            report_tempfiles("%s temporary file %a","registering",name)
202        else
203            report_tempfiles("%s temporary file %a","unregistering",name)
204        end
205    end
206    tempfiles[name] = keep or false
207    return name
208end
209
210function luatex.cleanuptempfiles()
211    for name, keep in next, tempfiles do
212        if not keep then
213            if trace_temp_files then
214                report_tempfiles("%s temporary file %a","removing",name)
215            end
216            os.remove(name)
217        end
218    end
219    tempfiles = { }
220end
221
222luatex.registerstopactions(luatex.cleanuptempfiles)
223
224-- Reporting filenames has been simplified since lmtx because we don't need  the
225-- traditional () {} <> etc methods (read: that directive option was never chosen).
226
227local report_open  = logs.reporter("open source")
228local report_close = logs.reporter("close source")
229local report_load  = logs.reporter("load resource")
230
231local register     = callbacks.register
232
233local level = 0
234local total = 0
235local stack = { }
236
237function luatex.currentfile()
238    return stack[#stack] or tex.jobname
239end
240
241local function report_start(name,rest)
242    if rest then
243        -- luatex
244        if name ~= 1 then
245            insert(stack,false)
246            return
247        end
248        name = rest
249    end
250    if find(name,"virtual://",1,true) then
251        insert(stack,false)
252    else
253        insert(stack,name)
254        total = total + 1
255        level = level + 1
256     -- report_open("%i > %i > %s",level,total,name or "?")
257        report_open("level %i, order %i, name %a",level,total,name or "?")
258        synctex.setfilename(name)
259    end
260end
261
262local function report_stop()
263    local name = remove(stack)
264    if name then
265     -- report_close("%i > %i > %s",level,total,name or "?")
266        report_close("level %i, order %i, name %a",level,total,name or "?")
267        level = level - 1
268        synctex.setfilename(stack[#stack] or tex.jobname)
269    end
270end
271
272local function report_none()
273end
274
275register("start_file",report_start)
276register("stop_file", report_stop)
277
278directives.register("system.reportfiles", function(v)
279    if v then
280        register("start_file",report_start)
281        register("stop_file", report_stop)
282    else
283        register("start_file",report_none)
284        register("stop_file", report_none)
285    end
286end)
287
288-- start_run doesn't work
289
290-- luatex.registerstartactions(function()
291--     if environment.arguments.sandbox then
292--         sandbox.enable()
293--     end
294-- end)
295
296local report   = logs.reporter("csname overload")
297local reported = { }
298
299callback.register("handle_overload", function(fatal,overload,csname,flags)
300    if not reported[csname] then
301        logs.newline()
302        local readstate  = status.readstate
303        local filename   = readstate.filename
304        local linenumber = readstate.linenumber
305        local flags      = tokens.flags and tokens.flags(csname) or { }
306        if filename and linenumber then
307            report("%s, protection level %i, control sequence %a, properties '% t', file %a, line %i",
308                fatal and "fatal error" or "warning",overload,csname,flags,filename,linenumber)
309        else
310            report("%s, protection level %i, control sequence %a, properties '% t'",
311                fatal and "fatal error" or "warning",overload,csname,flags)
312        end
313        reported[csname] = true
314        logs.newline()
315        if fatal then
316            cleanup_run()
317            osexit(1)
318        end
319    end
320end)
321
322-- bonus
323
324if environment.initex then
325
326    luatex.registerdumpactions(statistics.showmemory)
327
328end
329