1if not modules then modules = { } end modules ['cont-run'] = {
2 version = 1.001,
3 comment = "companion to cont-yes.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
9
10
11
12
13local type, tostring = type, tostring
14
15local report_sandbox = logs.reporter("sandbox","call")
16local report_system = logs.reporter("system")
17local fastserialize = table.fastserialize
18local quoted = string.quoted
19local possiblepath = sandbox.possiblepath
20
21local context = context
22local implement = interfaces.implement
23
24local texset = tex.set
25
26local qualified = { }
27local writeable = { }
28local readable = { }
29local blocked = { }
30local trace_files = false
31local trace_calls = false
32local nofcalls = 0
33local nofrejected = 0
34local logfilename = "sandbox.log"
35
36local function registerstats()
37 statistics.register("sandboxing", function()
38 if trace_files then
39 return string.format("%i calls, %i rejected, logdata in '%s'",nofcalls,nofrejected,logfilename)
40 else
41 return string.format("%i calls, %i rejected",nofcalls,nofrejected)
42 end
43 end)
44 registerstats = false
45end
46
47local function logsandbox(details)
48 local comment = details.comment
49 local result = details.result
50 local arguments = details.arguments
51 for i=1,#arguments do
52 local argument = arguments[i]
53 local t = type(argument)
54 if t == "string" then
55 arguments[i] = quoted(argument)
56 if trace_files and possiblepath(argument) then
57 local q = qualified[argument]
58 if q then
59 local c = q[comment]
60 if c then
61 local r = c[result]
62 if r then
63 c[result] = r + 1
64 else
65 c[result] = r
66 end
67 else
68 q[comment] = {
69 [result] = 1
70 }
71 end
72 else
73 qualified[argument] = {
74 [comment] = {
75 [result] = 1
76 }
77 }
78 end
79 end
80 elseif t == "table" then
81 arguments[i] = fastserialize(argument)
82 else
83 arguments[i] = tostring(argument)
84 end
85 end
86 if trace_calls then
87 report_sandbox("%s(%,t) => %l",details.comment,arguments,result)
88 end
89 nofcalls = nofcalls + 1
90 if not result then
91 nofrejected = nofrejected + 1
92 end
93end
94
95local ioopen = sandbox.original(io.open)
96
97local function logsandboxfiles(name,what,asked,okay)
98
99 if not okay then
100 blocked [asked] = blocked [asked] or 0 + 1
101 elseif what == "*" or what == "w" then
102 writeable[asked] = writeable[asked] or 0 + 1
103 else
104 readable [asked] = readable [asked] or 0 + 1
105 end
106end
107
108function sandbox.logcalls()
109 if not trace_calls then
110 trace_calls = true
111 sandbox.setlogger(logsandbox)
112 if registerstats then
113 registerstats()
114 end
115 end
116end
117
118function sandbox.logfiles()
119 if not trace_files then
120 trace_files = true
121 sandbox.setlogger(logsandbox)
122 sandbox.setfilenamelogger(logsandboxfiles)
123 luatex.registerstopactions(function()
124 table.save(logfilename,{
125 calls = {
126 nofcalls = nofcalls,
127 nofrejected = nofrejected,
128 filenames = qualified,
129 },
130 checkednames = {
131 readable = readable,
132 writeable = writeable,
133 blocked = blocked,
134 },
135 })
136 end)
137 if registerstats then
138 registerstats()
139 end
140 end
141end
142
143trackers.register("sandbox.tracecalls",sandbox.logcalls)
144trackers.register("sandbox.tracefiles",sandbox.logfiles)
145
146local sandboxing = environment.arguments.sandbox
147local debugging = environment.arguments.debug
148
149if sandboxing then
150
151 report_system("enabling sandbox")
152
153 sandbox.enable()
154
155 if type(sandboxing) == "string" then
156 sandboxing = utilities.parsers.settings_to_hash(sandboxing)
157 if sandboxing.calls then
158 sandbox.logcalls()
159 end
160 if sandboxing.files then
161 sandbox.logfiles()
162 end
163 end
164
165
166
167
168
169
170
171 context [[\let\primitive\relax\let\normalprimitive\relax]]
172
173 debug = {
174 traceback = debug.traceback,
175 }
176
177 package.loaded.debug = debug
178
179elseif debugging then
180
181
182
183else
184
185 debug = {
186 traceback = debug.traceback,
187 getinfo = debug.getinfo,
188 sethook = debug.sethook,
189 }
190
191 package.loaded.debug = debug
192
193end
194
195local function setoverloadmode(overloadmode)
196 if overloadmode == "warning" then
197 overloadmode = 3
198 elseif overloadmode == "error" then
199 overloadmode = 4
200 else
201 overloadmode = tonumber(overloadmode)
202 end
203 if overloadmode then
204 texset("overloadmode",overloadmode)
205 end
206end
207
208directives.register("overloadmode", setoverloadmode)
209
210local function processjob()
211
212 tokens.setters.macro("processjob","","permanent")
213
214 environment.initializefilenames()
215
216 local arguments = environment.arguments
217 local suffix = environment.suffix
218 local filename = environment.filename
219
220 environment.lmtxmode = CONTEXTLMTXMODE
221
222
223
224
225
226if arguments.directives then
227 directives.enable(arguments.directives)
228end
229
230 if arguments.nosynctex then
231 luatex.synctex.setup {
232 state = interfaces.variables.never,
233 }
234 elseif arguments.synctex then
235 luatex.synctex.setup {
236 state = interfaces.variables.start,
237 method = interfaces.variables.max,
238 }
239 end
240
241 logs.registerfinalactions(function()
242 logs.pushtarget("log")
243 statistics.showusage("finish")
244 logs.poptarget()
245 end)
246
247 setoverloadmode(arguments.overloadmode)
248
249 if not filename or filename == "" then
250
251 elseif suffix == "svg" or arguments.forcesvg then
252
253 report_system("processing svg output: %s",filename)
254
255 context.starttext()
256 context.startTEXpage()
257 context.externalfigure ( { filename }, { conversion = "mp" } )
258 context.stopTEXpage()
259 context.stoptext()
260
261 elseif suffix == "xml" or arguments.forcexml then
262
263
264
265
266
267 report_system("processing as xml: %s",filename)
268
269 context.starttext()
270 context.xmlprocess("main",filename,"")
271 context.stoptext()
272
273 elseif suffix == "cld" or arguments.forcecld then
274
275 report_system("processing as cld: %s",filename)
276
277 context.runfile(filename)
278
279 elseif suffix == "lua" or arguments.forcelua then
280
281
282
283
284 report_system("processing as lua: %s",filename)
285
286 context.starttext()
287 context.ctxlua(string.format('dofile("%s")',filename))
288 context.stoptext()
289
290 elseif suffix == "mp" or arguments.forcemp then
291
292 report_system("processing as metapost: %s",filename)
293
294 context.starttext()
295 context.processMPfigurefile(filename)
296 context.stoptext()
297
298
299
300
301
302
303
304
305
306
307 elseif suffix == "mps" or arguments.forcemps then
308
309 report_system("processing metapost output: %s",filename)
310
311 context.starttext()
312 context.startTEXpage()
313 context.externalfigure { filename }
314 context.stopTEXpage()
315 context.stoptext()
316
317 else
318
319
320
321
322
323 if type(arguments.forceinput) == "string" then
324 filename = arguments.forceinput or filename
325 end
326 context.input(filename)
327
328
329 end
330
331 context.finishjob()
332
333end
334
335implement {
336 name = "processjob",
337
338 public = true,
339 onlyonce = true,
340 actions = processjob,
341}
342
343texconfig.firstline = "\\processjob "
344 |