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
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 setexitcode = lua.setexitcode or status.setexitcode or function() end
45
46local function start_run()
47 if logs.start_run then
48 logs.start_run()
49 end
50 for i=1,#startactions do
51 startactions[i]()
52 end
53end
54
55local function stop_run(badrun)
56 for i=1,#stopactions do
57 stopactions[i]()
58 end
59 local quit = logs.finalactions()
60 if trace_job_status then
61 statistics.show()
62 end
63 if trace_tex_status then
64 logs.newline()
65 for k, v in table.sortedhash(status.list()) do
66 if type(v) ~= "table" then
67 report_tex("%S=%S",k,v)
68 end
69 end
70 end
71 if quit then
72 setexitcode(1)
73 if type(quit) == "table" then
74 logs.newline()
75 report_tex("quitting due to: %, t",quit)
76 logs.newline()
77 end
78 elseif badrun and badrun > 0 then
79 setexitcode(1)
80 end
81 if logs.stop_run then
82 logs.stop_run()
83 end
84end
85
86
87
88function callbacks.functions.start_page_number()
89 synctex.start()
90 logs.start_page_number()
91end
92
93function callbacks.functions.stop_page_number()
94 logs.stop_page_number()
95 for i=1,#pageactions do
96 pageactions[i]()
97 end
98 synctex.stop()
99end
100
101local function pre_dump_actions()
102 for i=1,#dumpactions do
103 dumpactions[i]()
104 end
105 lua.finalizeinitex(trace_lua_dump and report_lua or nil)
106end
107
108local function wrapup_synctex()
109 synctex.wrapup()
110end
111
112
113
114local sequencers = utilities.sequencers
115local appendgroup = sequencers.appendgroup
116local appendaction = sequencers.appendaction
117local wrapupactions = sequencers.new { }
118local cleanupactions = sequencers.new { }
119
120appendgroup(wrapupactions,"system")
121appendgroup(wrapupactions,"user")
122
123appendgroup(cleanupactions,"system")
124appendgroup(cleanupactions,"user")
125
126local function wrapup_run(someerror)
127 local runner = wrapupactions.runner
128 if runner then
129 runner(someerror)
130 end
131end
132
133local function cleanup_run()
134 local runner = cleanupactions.runner
135 if runner then
136 runner()
137 end
138end
139
140function luatex.wrapup(action)
141 appendaction(wrapupactions,"user",action)
142end
143
144function luatex.cleanup(action)
145 appendaction(cleanupactions,"user",action)
146end
147
148function luatex.abort()
149 cleanup_run()
150 setexitcode(1)
151 osexit(1)
152end
153
154appendaction(wrapupactions,"system",synctex.wrapup)
155
156
157
158callbacks.register("start_run", start_run, "actions performed at the beginning of a run")
159callbacks.register("stop_run", stop_run, "actions performed at the end of a run")
160callbacks.register("pre_dump", pre_dump_actions, "lua related finalizers called before we dump the format")
161callbacks.register("wrapup_run", wrapup_run, "actions performed after closing files")
162
163
164
165local tempfiles = { }
166
167function luatex.registertempfile(name,extrasuffix,keep)
168 if extrasuffix then
169 name = name .. ".mkiv-tmp"
170 end
171 if trace_temp_files and not tempfiles[name] then
172 if keep then
173 report_tempfiles("%s temporary file %a","registering",name)
174 else
175 report_tempfiles("%s temporary file %a","unregistering",name)
176 end
177 end
178 tempfiles[name] = keep or false
179 return name
180end
181
182function luatex.cleanuptempfiles()
183 for name, keep in next, tempfiles do
184 if not keep then
185 if trace_temp_files then
186 report_tempfiles("%s temporary file %a","removing",name)
187 end
188 os.remove(name)
189 end
190 end
191 tempfiles = { }
192end
193
194luatex.registerstopactions(luatex.cleanuptempfiles)
195
196
197
198
199local report_open = logs.reporter("open source")
200local report_close = logs.reporter("close source")
201local report_load = logs.reporter("load resource")
202
203local level = 0
204local total = 0
205local stack = { }
206
207function luatex.currentfile()
208 return stack[#stack] or tex.jobname
209end
210
211function luatex.currentlevel()
212 return level
213end
214
215function luatex.currenttotal()
216 return total
217end
218
219local enabled = true directives.register("system.reportfiles", function(v) enabled = v end)
220
221local function report_start(name,rest)
222 if enabled then
223 if rest then
224
225 if name ~= 1 then
226 insert(stack,false)
227 return
228 end
229 name = rest
230 end
231 if find(name,"virtual://",1,true) then
232 insert(stack,false)
233 else
234 insert(stack,name)
235 total = total + 1
236 level = level + 1
237
238 report_open("level %i, order %i, name %a",level,total,name or "?")
239 synctex.setfilename(name)
240 end
241 end
242end
243
244local function report_stop()
245 if enabled then
246 local name = remove(stack)
247 if name then
248
249 report_close("level %i, order %i, name %a",level,total,name or "?")
250 level = level - 1
251 name = stack[#stack]
252
253 if name then
254 synctex.setfilename(name)
255 end
256 end
257 end
258end
259
260callbacks.register("start_file",report_start,"report opening of a file")
261callbacks.register("stop_file", report_stop, "report closing of a file")
262
263
264
265
266
267
268
269
270
271local report = logs.reporter("csname overload")
272local reported = { }
273
274callbacks.register("handle_overload", function(fatal,overload,csname,flags)
275 if not reported[csname] then
276 logs.newline()
277 local readstate = status.readstate
278 local filename = readstate.filename
279 local linenumber = readstate.linenumber
280 local flags = tokens.flags and tokens.flags(csname) or { }
281 if filename and linenumber then
282 report("%s, protection level %i, control sequence %a, properties '% t', file %a, line %i",
283 fatal and "fatal error" or "warning",overload,csname,flags,filename,linenumber)
284 else
285 report("%s, protection level %i, control sequence %a, properties '% t'",
286 fatal and "fatal error" or "warning",overload,csname,flags)
287 end
288 reported[csname] = true
289 logs.newline()
290 if fatal then
291 cleanup_run()
292 setexitcode(1)
293 osexit(1)
294 end
295 end
296end,"handle primitive and macro overload protection")
297
298
299
300if environment.initex then
301
302 luatex.registerdumpactions(statistics.showmemory)
303
304end
305 |