trac-deb.lua /size: 15 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
trac-deb
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to trac-deb.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
-- This is an old mechanism, a result of some experiments in the early days of
10
-- luatex and mkiv, but still nice anyway.
11 12
local
status
=
status
13 14
local
tonumber
,
tostring
,
type
=
tonumber
,
tostring
,
type
15
local
format
,
concat
,
match
,
find
,
gsub
=
string
.
format
,
table
.
concat
,
string
.
match
,
string
.
find
,
string
.
gsub
16
local
lpegmatch
=
lpeg
.
match
17 18
-- maybe tracers -> tracers.tex (and tracers.lua for current debugger)
19 20
----- report_tex = logs.reporter("tex error")
21
----- report_lua = logs.reporter("lua error")
22
local
report_nl
=
logs
.
newline
23
local
report_str
=
logs
.
writer
24 25
tracers
=
tracers
or
{
}
26
local
tracers
=
tracers
27 28
tracers
.
lists
=
{
}
29
local
lists
=
tracers
.
lists
30 31
tracers
.
strings
=
{
}
32
local
strings
=
tracers
.
strings
33 34
local
texgetdimen
=
tex
.
getdimen
35
local
texgettoks
=
tex
.
gettoks
36
local
texgetcount
=
tex
.
getcount
37
local
texgethelp
=
tex
.
gethelptext
or
function
(
)
end
38
local
fatalerror
=
tex
.
fatalerror
39 40
local
implement
=
interfaces
.
implement
41 42
-- this is used in lmx files but needs to be redone
43 44
strings
.
undefined
=
"
undefined
"
45 46
function
tracers
.
dimen
(
name
)
47
local
d
=
texgetdimen
(
name
)
48
return
d
and
number
.
topoints
(
d
)
or
strings
.
undefined
49
end
50 51
function
tracers
.
count
(
name
)
52
return
texgetcount
(
name
)
or
strings
.
undefined
53
end
54 55
function
tracers
.
toks
(
name
,
limit
)
56
local
t
=
texgettoks
(
name
)
57
return
t
and
string
.
limit
(
t
,
tonumber
(
limit
)
or
40
)
or
strings
.
undefined
58
end
59 60
function
tracers
.
primitive
(
name
)
61
return
tex
[
name
]
or
strings
.
undefined
62
end
63 64
lists
.
scratch
=
{
65
0
,
2
,
4
,
6
,
8
66
}
67 68
lists
.
internals
=
{
69
'
p:hsize
'
,
'
p:parindent
'
,
'
p:leftskip
'
,
'
p:rightskip
'
,
70
'
p:vsize
'
,
'
p:parskip
'
,
'
p:baselineskip
'
,
'
p:lineskip
'
,
'
p:topskip
'
71
}
72 73
lists
.
context
=
{
74
'
d:lineheight
'
,
75
'
c:realpageno
'
,
'
c:userpageno
'
,
'
c:pageno
'
,
'
c:subpageno
'
76
}
77 78
local
types
=
{
79
[
'
d
'
]
=
tracers
.
dimen
,
80
[
'
c
'
]
=
tracers
.
count
,
81
[
'
t
'
]
=
tracers
.
toks
,
82
[
'
p
'
]
=
tracers
.
primitive
83
}
84 85
local
splitboth
=
lpeg
.
splitat
(
"
:
"
)
86 87
function
tracers
.
type
(
csname
)
88
local
tag
,
name
=
lpegmatch
(
splitboth
,
csname
)
89
return
tag
or
"
"
90
end
91 92
function
tracers
.
name
(
csname
)
93
local
tag
,
name
=
lpegmatch
(
splitboth
,
csname
)
94
return
name
or
csname
95
end
96 97
function
tracers
.
cs
(
csname
)
98
local
tag
,
name
=
lpegmatch
(
splitboth
,
csname
)
99
if
name
and
types
[
tag
]
then
100
return
types
[
tag
]
(
name
)
101
else
102
return
tracers
.
primitive
(
csname
)
103
end
104
end
105 106
function
tracers
.
knownlist
(
name
)
107
local
l
=
lists
[
name
]
108
return
l
and
#
l
>
0
109
end
110 111
local
savedluaerror
=
nil
112
local
usescitelexer
=
nil
113
local
quitonerror
=
true
114 115
local
function
errorreporter
(
luaerror
)
116
local
category
=
luaerror
and
"
lua error
"
or
"
tex error
"
117
local
report
=
logs
.
reporter
(
category
)
118
logs
.
enable
(
category
)
119
return
report
120
end
121 122
function
tracers
.
showlines
(
filename
,
linenumber
,
offset
,
luaerrorline
)
123
local
data
=
io
.
loaddata
(
filename
)
124
if
not
data
or
data
=
=
"
"
then
125
local
hash
=
url
.
hashed
(
filename
)
126
if
not
hash
.
noscheme
then
127
local
ok
,
d
,
n
=
resolvers
.
loaders
.
byscheme
(
hash
.
scheme
,
filename
)
128
if
ok
and
n
>
0
then
129
data
=
d
130
end
131
end
132
end
133
local
scite
=
usescitelexer
and
require
(
"
util-sci
"
)
134
if
scite
then
135
return
utilities
.
scite
.
tohtml
(
data
,
"
tex
"
,
linenumber
or
true
,
false
)
136
else
137
local
lines
=
data
and
string
.
splitlines
(
data
)
138
if
lines
and
#
lines
>
0
then
139
if
luaerrorline
and
luaerrorline
>
0
then
140
-- lua error: linenumber points to last line
141
local
start
=
"
\\startluacode
"
142
local
stop
=
"
\\stopluacode
"
143
local
n
=
linenumber
144
for
i
=
n
,
1
,
-1
do
145
local
line
=
lines
[
i
]
146
if
not
line
then
147
break
148
elseif
find
(
line
,
start
)
then
149
n
=
i
+
luaerrorline
-
1
150
if
n
<
=
linenumber
then
151
linenumber
=
n
152
end
153
break
154
end
155
end
156
end
157
offset
=
tonumber
(
offset
)
or
10
158
linenumber
=
tonumber
(
linenumber
)
or
10
159
local
start
=
math
.
max
(
linenumber
-
offset
,
1
)
160
local
stop
=
math
.
min
(
linenumber
+
offset
,
#
lines
)
161
if
stop
>
#
lines
then
162
return
"
<linenumber past end of file>
"
163
else
164
local
result
,
fmt
=
{
}
,
"
%
"
.
.
#
tostring
(
stop
)
.
.
"
d %s %s
"
165
for
n
=
start
,
stop
do
166
result
[
#
result
+
1
]
=
format
(
fmt
,
n
,
n
=
=
linenumber
and
"
>>
"
or
"
"
,
lines
[
n
]
)
167
end
168
return
concat
(
result
,
"
\n
"
)
169
end
170
else
171
return
"
<empty file>
"
172
end
173
end
174
end
175 176
-- this will work ok in >=0.79
177 178
-- todo: last tex error has ! prepended
179
-- todo: some nested errors have two line numbers
180
-- todo: collect errorcontext in string (after code cleanup)
181
-- todo: have a separate status.lualinenumber
182 183
-- todo: \starttext bla \blank[foo] bla \stoptext
184 185
local
nop
=
function
(
)
end
186
local
resetmessages
=
status
.
resetmessages
or
nop
187 188
local
function
processerror
(
offset
)
189
-- print("[[ last tex error: " .. tostring(status.lasterrorstring or "<unset>") .. " ]]")
190
-- print("[[ last lua error: " .. tostring(status.lastluaerrorstring or "<unset>") .. " ]]")
191
-- print("[[ last warning : " .. tostring(status.lastwarningstring or "<unset>") .. " ]]")
192
-- print("[[ last location : " .. tostring(status.lastwarninglocation or "<unset>") .. " ]]")
193
-- print("[[ last context : " .. tostring(status.lasterrorcontext or "<unset>") .. " ]]")
194 195
local
filename
=
status
.
filename
196
local
linenumber
=
tonumber
(
status
.
linenumber
)
or
0
197
local
lastcontext
=
status
.
lasterrorcontext
198
local
lasttexerror
=
status
.
lasterrorstring
or
"
?
"
199
local
lastluaerror
=
status
.
lastluaerrorstring
or
"
?
"
-- lasttexerror
200
local
luaerrorline
=
match
(
lastluaerror
,
[[
lua%]?:.-(%d+)
]]
)
or
(
lastluaerror
and
find
(
lastluaerror
,
"
?:0:
"
,
1
,
true
)
and
0
)
201
local
lastmpserror
=
match
(
lasttexerror
,
[[
^.-mp%serror:%s*(.*)$
]]
)
202
resetmessages
(
)
203
lastluaerror
=
gsub
(
lastluaerror
,
"
%[\\directlua%]
"
,
"
[ctxlua]
"
)
204
tracers
.
printerror
{
205
filename
=
filename
,
206
linenumber
=
linenumber
,
207
offset
=
tonumber
(
offset
)
or
10
,
208
lasttexerror
=
lasttexerror
,
209
lastmpserror
=
lastmpserror
,
210
lastluaerror
=
lastluaerror
,
-- can be the same as lasttexerror
211
luaerrorline
=
luaerrorline
,
212
lastcontext
=
lastcontext
,
213
lasttexhelp
=
tex
.
gethelptext
and
tex
.
gethelptext
(
)
or
nil
,
214
}
215
end
216 217
-- so one can overload the printer if (really) needed
218 219
if
fatalerror
then
220
callback
.
register
(
"
terminal_input
"
,
function
(
what
)
221
processerror
(
)
222
if
what
=
=
"
*
"
then
223
fatalerror
(
"
some kind of input expected, file ends too soon, quitting now
"
)
224
else
225
fatalerror
(
"
bad input, quitting now
"
)
226
end
227
end
)
228
else
229
-- tex.print("\\nonstopmode")
230
end
231 232
directives
.
register
(
"
system.quitonerror
"
,
function
(
v
)
233
quitonerror
=
toboolean
(
v
)
234
-- tex.print("\\errorstopmode")
235
end
)
236 237
directives
.
register
(
"
system.usescitelexer
"
,
function
(
v
)
238
usescitelexer
=
toboolean
(
v
)
239
end
)
240 241
local
busy
=
false
242 243
function
tracers
.
printerror
(
specification
)
244
if
not
busy
then
245
busy
=
true
246
local
filename
=
specification
.
filename
247
local
linenumber
=
specification
.
linenumber
248
local
lasttexerror
=
specification
.
lasttexerror
249
local
lastmpserror
=
specification
.
lastmpserror
250
local
lastluaerror
=
specification
.
lastluaerror
251
local
lastcontext
=
specification
.
lasterrorcontext
252
local
luaerrorline
=
specification
.
luaerrorline
253
local
errortype
=
specification
.
errortype
254
local
offset
=
specification
.
offset
255
local
report
=
errorreporter
(
luaerrorline
)
256
if
not
filename
then
257
report
(
"
error not related to input file:
"
)
258
report
(
"
tex: %s
"
,
lasttexerror
or
"
-
"
)
259
report
(
"
lua: %s
"
,
lastluaerror
or
"
-
"
)
260
report
(
"
mps: %s
"
,
lastmpserror
or
"
-
"
)
261
elseif
type
(
filename
)
=
=
"
number
"
then
262
report
(
"
error on line %s of filehandle %s: %s ...
"
,
linenumber
,
lasttexerror
)
263
else
264
report_nl
(
)
265
if
luaerrorline
then
266
if
linenumber
=
=
0
or
not
filename
or
filename
=
=
"
"
then
267
print
(
"
\nfatal lua error:\n\n
"
,
lastluaerror
,
"
\n
"
)
268
luatex
.
abort
(
)
269
return
270
else
271
report
(
"
lua error on line %s in file %s:\n\n%s
"
,
linenumber
,
filename
,
lastluaerror
)
272
end
273
elseif
lastmpserror
then
274
report
(
"
mp error on line %s in file %s:\n\n%s
"
,
linenumber
,
filename
,
lastmpserror
)
275
else
276
report
(
"
tex error on line %s in file %s: %s
"
,
linenumber
,
filename
,
lasttexerror
)
277
if
lastcontext
then
278
report_nl
(
)
279
report_str
(
lastcontext
)
280
report_nl
(
)
281
elseif
tex
.
show_context
then
282
report_nl
(
)
283
tex
.
show_context
(
)
284
end
285
if
lastluaerror
and
not
match
(
lastluaerror
,
"
^%s*[%?]*%s*$
"
)
then
286
print
(
"
\nlua error:\n\n
"
,
lastluaerror
,
"
\n
"
)
287
quitonerror
=
true
288
end
289
end
290
report_nl
(
)
291
report_str
(
tracers
.
showlines
(
filename
,
linenumber
,
offset
,
tonumber
(
luaerrorline
)
)
)
292
report_nl
(
)
293
end
294
local
errname
=
file
.
addsuffix
(
tex
.
jobname
.
.
"
-error
"
,
"
log
"
)
295
if
quitonerror
then
296
table
.
save
(
errname
,
specification
)
297
local
help
=
specification
.
lasttexhelp
298
if
help
and
#
help
>
0
then
299
report_nl
(
)
300
report_str
(
help
)
301
report_nl
(
)
302
report_nl
(
)
303
end
304
luatex
.
abort
(
)
305
end
306
busy
=
false
307
end
308
end
309 310
luatex
.
wrapup
(
function
(
)
os
.
remove
(
file
.
addsuffix
(
tex
.
jobname
.
.
"
-error
"
,
"
log
"
)
)
end
)
311 312
local
function
processwarning
(
offset
)
313
local
lastwarning
=
status
.
lastwarningstring
or
"
?
"
314
local
lastlocation
=
status
.
lastwarningtag
or
"
?
"
315
resetmessages
(
)
316
tracers
.
printwarning
{
317
lastwarning
=
lastwarning
,
318
lastlocation
=
lastlocation
,
319
}
320
end
321 322
function
tracers
.
printwarning
(
specification
)
323
logs
.
report
(
"
luatex warning
"
,
"
%s: %s
"
,
specification
.
lastlocation
,
specification
.
lastwarning
)
324
end
325 326
directives
.
register
(
"
system.errorcontext
"
,
function
(
v
)
327
local
register
=
callback
.
register
328
if
v
then
329
register
(
'
show_error_message
'
,
nop
)
330
register
(
'
show_warning_message
'
,
function
(
)
processwarning
(
v
)
end
)
331
register
(
'
show_error_hook
'
,
function
(
)
processerror
(
v
)
end
)
332
register
(
'
show_lua_error_hook
'
,
function
(
)
processerror
(
v
)
end
)
333
else
334
register
(
'
show_error_message
'
,
nil
)
335
register
(
'
show_error_hook
'
,
nil
)
336
register
(
'
show_warning_message
'
,
nil
)
337
register
(
'
show_lua_error_hook
'
,
nil
)
338
end
339
end
)
340 341
-- this might move
342 343
lmx
=
lmx
or
{
}
344 345
lmx
.
htmfile
=
function
(
name
)
return
environment
.
jobname
.
.
"
-status.html
"
end
346
lmx
.
lmxfile
=
function
(
name
)
return
resolvers
.
findfile
(
name
,
'
tex
'
)
end
347 348
local
function
reportback
(
lmxname
,
default
,
variables
)
349
if
lmxname
=
=
false
then
350
return
variables
351
else
352
local
name
=
lmx
.
show
(
type
(
lmxname
)
=
=
"
string
"
and
lmxname
or
default
,
variables
)
353
if
name
then
354
logs
.
report
(
"
context report
"
,
"
file: %s
"
,
name
)
355
end
356
end
357
end
358 359
function
lmx
.
showdebuginfo
(
lmxname
)
360
local
variables
=
{
361
[
'
title
'
]
=
'
ConTeXt Debug Information
'
,
362
[
'
color-background-one
'
]
=
lmx
.
get
(
'
color-background-green
'
)
,
363
[
'
color-background-two
'
]
=
lmx
.
get
(
'
color-background-blue
'
)
,
364
}
365
reportback
(
lmxname
,
"
context-debug.lmx
"
,
variables
)
366
end
367 368
local
function
showerror
(
lmxname
)
369
local
filename
,
linenumber
,
errorcontext
=
status
.
filename
,
tonumber
(
status
.
linenumber
)
or
0
,
"
"
370
if
not
filename
then
371
filename
,
errorcontext
=
'
unknown
'
,
'
error in filename
'
372
elseif
type
(
filename
)
=
=
"
number
"
then
373
filename
,
errorcontext
=
format
(
"
<read %s>
"
,
filename
)
,
'
unknown error
'
374
else
375
errorcontext
=
tracers
.
showlines
(
filename
,
linenumber
,
offset
)
376
end
377
local
variables
=
{
378
[
'
title
'
]
=
'
ConTeXt Error Information
'
,
379
[
'
errormessage
'
]
=
status
.
lasterrorstring
,
380
[
'
linenumber
'
]
=
linenumber
,
381
[
'
color-background-one
'
]
=
lmx
.
get
(
'
color-background-yellow
'
)
,
382
[
'
color-background-two
'
]
=
lmx
.
get
(
'
color-background-purple
'
)
,
383
[
'
filename
'
]
=
filename
,
384
[
'
errorcontext
'
]
=
errorcontext
,
385
}
386
reportback
(
lmxname
,
"
context-error.lmx
"
,
variables
)
387
luatex
.
abort
(
)
388
end
389 390
lmx
.
showerror
=
showerror
391 392
function
lmx
.
overloaderror
(
v
)
393
if
v
=
=
"
scite
"
then
394
usescitelexer
=
true
395
end
396
callback
.
register
(
'
show_error_hook
'
,
function
(
)
showerror
(
)
end
)
-- prevents arguments being passed
397
callback
.
register
(
'
show_lua_error_hook
'
,
function
(
)
showerror
(
)
end
)
-- prevents arguments being passed
398
end
399 400
directives
.
register
(
"
system.showerror
"
,
lmx
.
overloaderror
)
401 402
-- local debugger = utilities.debugger
403
--
404
-- local function trace_calls(n)
405
-- debugger.enable()
406
-- luatex.registerstopactions(function()
407
-- debugger.disable()
408
-- debugger.savestats(tex.jobname .. "-luacalls.log",tonumber(n))
409
-- end)
410
-- trace_calls = function() end
411
-- end
412
--
413
-- directives.register("system.tracecalls", function(n)
414
-- trace_calls(n)
415
-- end) -- indirect is needed for nilling
416 417
-- Obsolete ... not that usefull as normally one runs from an editor and
418
-- when run unattended it makes no sense either.
419 420
-- local editor = [[scite "-open:%filename%" -goto:%linenumber%]]
421
--
422
-- directives.register("system.editor",function(v)
423
-- editor = v
424
-- end)
425
--
426
-- callback.register("call_edit",function(filename,linenumber)
427
-- if editor then
428
-- editor = gsub(editor,"%%s",filename)
429
-- editor = gsub(editor,"%%d",linenumber)
430
-- editor = gsub(editor,"%%filename%%",filename)
431
-- editor = gsub(editor,"%%linenumber%%",linenumber)
432
-- logs.report("system","starting editor: %s",editor)
433
-- os.execute(editor)
434
-- end
435
-- end)
436 437
local
implement
=
interfaces
.
implement
438 439
implement
{
name
=
"
showtrackers
"
,
actions
=
trackers
.
show
}
440
implement
{
name
=
"
enabletrackers
"
,
actions
=
trackers
.
enable
,
arguments
=
"
string
"
}
441
implement
{
name
=
"
disabletrackers
"
,
actions
=
trackers
.
disable
,
arguments
=
"
string
"
}
442
implement
{
name
=
"
resettrackers
"
,
actions
=
trackers
.
reset
}
443 444
implement
{
name
=
"
showdirectives
"
,
actions
=
directives
.
show
}
445
implement
{
name
=
"
enabledirectives
"
,
actions
=
directives
.
enable
,
arguments
=
"
string
"
}
446
implement
{
name
=
"
disabledirectives
"
,
actions
=
directives
.
disable
,
arguments
=
"
string
"
}
447 448
implement
{
name
=
"
showexperiments
"
,
actions
=
experiments
.
show
}
449
implement
{
name
=
"
enableexperiments
"
,
actions
=
experiments
.
enable
,
arguments
=
"
string
"
}
450
implement
{
name
=
"
disableexperiments
"
,
actions
=
experiments
.
disable
,
arguments
=
"
string
"
}
451 452
implement
{
name
=
"
showdebuginfo
"
,
actions
=
lmx
.
showdebuginfo
}
453
implement
{
name
=
"
overloaderror
"
,
actions
=
lmx
.
overloaderror
}
454
implement
{
name
=
"
showlogcategories
"
,
actions
=
logs
.
show
}
455 456
local
debugger
=
utilities
.
debugger
457 458
directives
.
register
(
"
system.profile
"
,
function
(
n
)
459
luatex
.
registerstopactions
(
function
(
)
460
debugger
.
disable
(
)
461
debugger
.
savestats
(
"
luatex-profile.log
"
,
tonumber
(
n
)
or
0
)
462
report_nl
(
)
463
logs
.
report
(
"
system
"
,
"
profiler stopped, log saved in %a
"
,
"
luatex-profile.log
"
)
464
report_nl
(
)
465
end
)
466
logs
.
report
(
"
system
"
,
"
profiler started
"
)
467
debugger
.
enable
(
)
468
end
)
469