trac-log.lua /size: 32 Kb    last modification: 2020-07-01 14:35
1
if
not
modules
then
modules
=
{
}
end
modules
[
'
trac-log
'
]
=
{
2
version
=
1
.
001
,
3
comment
=
"
companion to trac-log.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
-- In fact all writes could go through lua and we could write the console and
10
-- terminal handler in lua then. Ok, maybe it's slower then, so a no-go.
11 12
local
next
,
type
,
select
,
print
=
next
,
type
,
select
,
print
13
local
format
,
gmatch
,
find
=
string
.
format
,
string
.
gmatch
,
string
.
find
14
local
concat
,
insert
,
remove
=
table
.
concat
,
table
.
insert
,
table
.
remove
15
local
topattern
=
string
.
topattern
16
local
utfchar
=
utf
.
char
17
local
datetime
=
os
.
date
18
local
openfile
=
io
.
open
19 20
local
runningtex
=
tex
and
(
tex
.
jobname
or
tex
.
formatname
)
21
-- local write_nl = texio and texio.write_nl or print
22
-- local write = texio and texio.write or io.write
23 24
local
write_nl
=
runningtex
and
texio
and
texio
.
write_nl
or
print
25
local
write
=
runningtex
and
texio
and
texio
.
write
or
io
.
write
26 27
local
setmetatableindex
=
table
.
setmetatableindex
28
local
formatters
=
string
.
formatters
29
local
settings_to_hash
=
utilities
.
parsers
.
settings_to_hash
30
local
sortedkeys
=
table
.
sortedkeys
31 32
-- variant is set now
33 34
local
variant
=
"
default
"
35
-- local variant = "ansi"
36 37
-- todo: less categories, more subcategories (e.g. nodes)
38
-- todo: split into basics and ctx specific
39 40
--[[ldx-- 41<p>This is a prelude to a more extensive logging module. We no longer 42provide <l n='xml'/> based logging as parsing is relatively easy anyway.</p> 43--ldx]]
--
44 45
logs
=
logs
or
{
}
46
local
logs
=
logs
47 48
local
moreinfo
=
[[
49More information about ConTeXt and the tools that come with it can be found at: 50
]]
.
.
"
\n
"
.
.
[[
51maillist : ntg-context@ntg.nl / http://www.ntg.nl/mailman/listinfo/ntg-context 52webpage : http://www.pragma-ade.nl / http://tex.aanhet.net 53wiki : http://contextgarden.net 54
]]
55 56
-- -- we extend the formatters:
57
--
58
-- function utilities.strings.unichr(s) return "U+" .. format("%05X",s) .. " (" .. utfchar(s) .. ")" end
59
-- function utilities.strings.chruni(s) return utfchar(s) .. " (U+" .. format("%05X",s) .. ")" end
60
--
61
-- utilities.strings.formatters.add (
62
-- string.formatters, "unichr",
63
-- [[unichr(%s)]],
64
-- [[local unichr = utilities.strings.unichr]]
65
-- )
66
--
67
-- utilities.strings.formatters.add (
68
-- string.formatters, "chruni",
69
-- [[chruni(%s)]],
70
-- [[local chruni = utilities.strings.chruni]]
71
-- )
72 73
formatters
.
add
(
74
formatters
,
"
unichr
"
,
75
[[
"U+" .. format("%%05X",%s) .. " (" .. utfchar(%s) .. ")"
]]
76
)
77 78
formatters
.
add
(
79
formatters
,
"
chruni
"
,
80
[[
utfchar(%s) .. " (U+" .. format("%%05X",%s) .. ")"
]]
81
)
82 83
-- function utilities.strings.unichk(s) return s <= 0xFFFF and ("U+" .. format("%05X",s) .. " (" .. utfchar(s) .. ")") or ("U+" .. format("%05X",s)) end
84
-- function utilities.strings.chkuni(s) return s <= 0xFFFF and (utfchar(s) .. " (U+" .. format("%05X",s) .. ")") or ("U+" .. format("%05X",s)) end
85
--
86
-- utilities.strings.formatters.add (
87
-- string.formatters, "unichk",
88
-- [[unichk(%s)]],
89
-- [[local unichk = utilities.strings.unichk]]
90
-- )
91
--
92
-- utilities.strings.formatters.add (
93
-- string.formatters, "chkuni",
94
-- [[chkuni(%s)]],
95
-- [[local chkuni = utilities.strings.chkuni]]
96
-- )
97
--
98
-- print(formatters["Missing character %!chruni! in font."](234))
99
-- print(formatters["Missing character %!unichr! in font."](234))
100
-- print(formatters["Missing character %!chkuni! in font."](234))
101
-- print(formatters["Missing character %!unichk! in font."](234))
102 103
-- basic loggers
104 105
local
function
ignore
(
)
end
106 107
setmetatableindex
(
logs
,
function
(
t
,
k
)
t
[
k
]
=
ignore
;
return
ignore
end
)
108 109
local
report
,
subreport
,
status
,
settarget
,
setformats
,
settranslations
110 111
local
direct
,
subdirect
,
writer
,
pushtarget
,
poptarget
,
setlogfile
,
settimedlog
,
setprocessor
,
setformatters
,
newline
112 113
-- we use formatters but best check for % then because for simple messages but
114
-- we don't want this overhead for single messages (not that there are that
115
-- many; we could have a special weak table)
116 117
local
function
ansisupported
(
specification
)
118
if
specification
~
=
"
ansi
"
and
specification
~
=
"
ansilog
"
then
119
return
false
120
elseif
os
and
os
.
enableansi
then
121
return
os
.
enableansi
(
)
122
else
123
return
false
124
end
125
end
126 127
if
runningtex
and
texio
then
128 129
if
texio
.
setescape
then
130
texio
.
setescape
(
0
)
-- or (false)
131
end
132 133
if
arg
and
ansisupported
then
134
-- we're don't have environment.arguments yet
135
for
k
,
v
in
next
,
arg
do
-- k can be negative !
136
if
v
=
=
"
--ansi
"
or
v
=
=
"
--c:ansi
"
then
137
if
ansisupported
(
"
ansi
"
)
then
138
variant
=
"
ansi
"
139
end
140
break
141
elseif
v
=
=
"
--ansilog
"
or
v
=
=
"
--c:ansilog
"
then
142
if
ansisupported
(
"
ansilog
"
)
then
143
variant
=
"
ansilog
"
144
end
145
break
146
end
147
end
148
end
149 150
local
function
useluawrites
(
)
151 152
-- quick hack, awaiting speedup in engine (8 -> 6.4 sec for --make with console2)
153
-- still needed for luajittex .. luatex should not have that ^^ mess
154 155
local
texio_write_nl
=
texio
.
write_nl
156
local
texio_write
=
texio
.
write
157
local
io_write
=
io
.
write
158 159
write_nl
=
function
(
target
,
...
)
160
if
not
io_write
then
161
io_write
=
io
.
write
162
end
163
if
target
=
=
"
term and log
"
then
164
texio_write_nl
(
"
log
"
,
...
)
165
texio_write_nl
(
"
term
"
,
"
"
)
166
io_write
(
...
)
167
elseif
target
=
=
"
log
"
then
168
texio_write_nl
(
"
log
"
,
...
)
169
elseif
target
=
=
"
term
"
then
170
texio_write_nl
(
"
term
"
,
"
"
)
171
io_write
(
...
)
172
elseif
type
(
target
)
=
=
"
number
"
then
173
texio_write_nl
(
target
,
...
)
-- a tex output channel
174
elseif
target
~
=
"
none
"
then
175
texio_write_nl
(
"
log
"
,
target
,
...
)
176
texio_write_nl
(
"
term
"
,
"
"
)
177
io_write
(
target
,
...
)
178
end
179
end
180 181
write
=
function
(
target
,
...
)
182
if
not
io_write
then
183
io_write
=
io
.
write
184
end
185
if
target
=
=
"
term and log
"
then
186
texio_write
(
"
log
"
,
...
)
187
io_write
(
...
)
188
elseif
target
=
=
"
log
"
then
189
texio_write
(
"
log
"
,
...
)
190
elseif
target
=
=
"
term
"
then
191
io_write
(
...
)
192
elseif
type
(
target
)
=
=
"
number
"
then
193
texio_write
(
target
,
...
)
-- a tex output channel
194
elseif
target
~
=
"
none
"
then
195
texio_write
(
"
log
"
,
target
,
...
)
196
io_write
(
target
,
...
)
197
end
198
end
199 200
texio
.
write
=
write
201
texio
.
write_nl
=
write_nl
202 203
useluawrites
=
ignore
204 205
end
206 207
-- local format = string.formatter
208 209
local
whereto
=
"
both
"
210
local
target
=
nil
211
local
targets
=
nil
212 213
local
formats
=
table
.
setmetatableindex
(
"
self
"
)
214
local
translations
=
table
.
setmetatableindex
(
"
self
"
)
215 216
local
report_yes
,
subreport_yes
,
direct_yes
,
subdirect_yes
,
status_yes
217
local
report_nop
,
subreport_nop
,
direct_nop
,
subdirect_nop
,
status_nop
218 219
local
variants
=
{
220
default
=
{
221
formats
=
{
222
report_yes
=
formatters
[
"
%-15s > %s\n
"
]
,
223
report_nop
=
formatters
[
"
%-15s >\n
"
]
,
224
direct_yes
=
formatters
[
"
%-15s > %s
"
]
,
225
direct_nop
=
formatters
[
"
%-15s >
"
]
,
226
subreport_yes
=
formatters
[
"
%-15s > %s > %s\n
"
]
,
227
subreport_nop
=
formatters
[
"
%-15s > %s >\n
"
]
,
228
subdirect_yes
=
formatters
[
"
%-15s > %s > %s
"
]
,
229
subdirect_nop
=
formatters
[
"
%-15s > %s >
"
]
,
230
status_yes
=
formatters
[
"
%-15s : %s\n
"
]
,
231
status_nop
=
formatters
[
"
%-15s :\n
"
]
,
232
}
,
233
targets
=
{
234
logfile
=
"
log
"
,
235
log
=
"
log
"
,
236
file
=
"
log
"
,
237
console
=
"
term
"
,
238
terminal
=
"
term
"
,
239
both
=
"
term and log
"
,
240
}
,
241
}
,
242
ansi
=
{
243
formats
=
{
244
report_yes
=
formatters
[
"
%-15s > %s\n
"
]
,
245
report_nop
=
formatters
[
"
%-15s >\n
"
]
,
246
direct_yes
=
formatters
[
"
%-15s > %s
"
]
,
247
direct_nop
=
formatters
[
"
%-15s >
"
]
,
248
subreport_yes
=
formatters
[
"
%-15s > %s > %s\n
"
]
,
249
subreport_nop
=
formatters
[
"
%-15s > %s >\n
"
]
,
250
subdirect_yes
=
formatters
[
"
%-15s > %s > %s
"
]
,
251
subdirect_nop
=
formatters
[
"
%-15s > %s >
"
]
,
252
status_yes
=
formatters
[
"
%-15s : %s\n
"
]
,
253
status_nop
=
formatters
[
"
%-15s :\n
"
]
,
254
}
,
255
targets
=
{
256
logfile
=
"
none
"
,
257
log
=
"
none
"
,
258
file
=
"
none
"
,
259
console
=
"
term
"
,
260
terminal
=
"
term
"
,
261
both
=
"
term
"
,
262
}
,
263
}
264
}
265 266
variants
.
ansilog
=
{
267
formats
=
variants
.
ansi
.
formats
,
268
targets
=
variants
.
default
.
targets
,
269
}
270 271
logs
.
flush
=
io
.
flush
272 273
writer
=
function
(
...
)
274
write_nl
(
target
,
...
)
275
end
276 277
newline
=
function
(
)
278
write_nl
(
target
,
"
\n
"
)
279
end
280 281
report
=
function
(
a
,
b
,
c
,
...
)
282
if
c
~
=
nil
then
283
write_nl
(
target
,
report_yes
(
translations
[
a
]
,
formatters
[
formats
[
b
]
]
(
c
,
...
)
)
)
284
elseif
b
then
285
write_nl
(
target
,
report_yes
(
translations
[
a
]
,
formats
[
b
]
)
)
286
elseif
a
then
287
write_nl
(
target
,
report_nop
(
translations
[
a
]
)
)
288
else
289
write_nl
(
target
,
"
\n
"
)
290
end
291
end
292 293
direct
=
function
(
a
,
b
,
c
,
...
)
294
if
c
~
=
nil
then
295
return
direct_yes
(
translations
[
a
]
,
formatters
[
formats
[
b
]
]
(
c
,
...
)
)
296
elseif
b
then
297
return
direct_yes
(
translations
[
a
]
,
formats
[
b
]
)
298
elseif
a
then
299
return
direct_nop
(
translations
[
a
]
)
300
else
301
return
"
"
302
end
303
end
304 305
subreport
=
function
(
a
,
s
,
b
,
c
,
...
)
306
if
c
~
=
nil
then
307
write_nl
(
target
,
subreport_yes
(
translations
[
a
]
,
translations
[
s
]
,
formatters
[
formats
[
b
]
]
(
c
,
...
)
)
)
308
elseif
b
then
309
write_nl
(
target
,
subreport_yes
(
translations
[
a
]
,
translations
[
s
]
,
formats
[
b
]
)
)
310
elseif
a
then
311
write_nl
(
target
,
subreport_nop
(
translations
[
a
]
,
translations
[
s
]
)
)
312
else
313
write_nl
(
target
,
"
\n
"
)
314
end
315
end
316 317
subdirect
=
function
(
a
,
s
,
b
,
c
,
...
)
318
if
c
~
=
nil
then
319
return
subdirect_yes
(
translations
[
a
]
,
translations
[
s
]
,
formatters
[
formats
[
b
]
]
(
c
,
...
)
)
320
elseif
b
then
321
return
subdirect_yes
(
translations
[
a
]
,
translations
[
s
]
,
formats
[
b
]
)
322
elseif
a
then
323
return
subdirect_nop
(
translations
[
a
]
,
translations
[
s
]
)
324
else
325
return
"
"
326
end
327
end
328 329
status
=
function
(
a
,
b
,
c
,
...
)
330
if
c
~
=
nil
then
331
write_nl
(
target
,
status_yes
(
translations
[
a
]
,
formatters
[
formats
[
b
]
]
(
c
,
...
)
)
)
332
elseif
b
then
333
write_nl
(
target
,
status_yes
(
translations
[
a
]
,
formats
[
b
]
)
)
334
elseif
a
then
335
write_nl
(
target
,
status_nop
(
translations
[
a
]
)
)
336
else
337
write_nl
(
target
,
"
\n
"
)
338
end
339
end
340 341
settarget
=
function
(
askedwhereto
)
342
whereto
=
askedwhereto
or
whereto
or
"
both
"
343
target
=
targets
[
whereto
]
344
if
not
target
then
345
whereto
=
"
both
"
346
target
=
targets
[
whereto
]
347
end
348
if
target
=
=
"
term
"
or
target
=
=
"
term and log
"
then
349
logs
.
flush
=
io
.
flush
350
else
351
logs
.
flush
=
ignore
352
end
353
end
354 355
local
stack
=
{
}
356 357
pushtarget
=
function
(
newtarget
)
358
insert
(
stack
,
target
)
359
settarget
(
newtarget
)
360
end
361 362
poptarget
=
function
(
)
363
if
#
stack
>
0
then
364
settarget
(
remove
(
stack
)
)
365
end
366
end
367 368
setformats
=
function
(
f
)
369
formats
=
f
370
end
371 372
settranslations
=
function
(
t
)
373
translations
=
t
374
end
375 376
setprocessor
=
function
(
f
)
377
local
writeline
=
write_nl
378
write_nl
=
function
(
target
,
...
)
379
writeline
(
target
,
f
(
...
)
)
380
end
381
end
382 383
setformatters
=
function
(
specification
)
384
local
t
=
nil
385
local
f
=
nil
386
local
d
=
variants
.
default
387
if
not
specification
then
388
--
389
elseif
type
(
specification
)
=
=
"
table
"
then
390
t
=
specification
.
targets
391
f
=
specification
.
formats
or
specification
392
else
393
if
not
ansisupported
(
specification
)
then
394
specification
=
"
default
"
395
end
396
local
v
=
variants
[
specification
]
397
if
v
then
398
t
=
v
.
targets
399
f
=
v
.
formats
400
variant
=
specification
401
end
402
end
403
targets
=
t
or
d
.
targets
404
target
=
targets
[
whereto
]
or
target
405
if
f
then
406
d
=
d
.
formats
407
else
408
f
=
d
.
formats
409
d
=
f
410
end
411
setmetatableindex
(
f
,
d
)
412
report_yes
=
f
.
report_yes
413
report_nop
=
f
.
report_nop
414
subreport_yes
=
f
.
subreport_yes
415
subreport_nop
=
f
.
subreport_nop
416
direct_yes
=
f
.
direct_yes
417
direct_nop
=
f
.
direct_nop
418
subdirect_yes
=
f
.
subdirect_yes
419
subdirect_nop
=
f
.
subdirect_nop
420
status_yes
=
f
.
status_yes
421
status_nop
=
f
.
status_nop
422
if
variant
=
=
"
ansi
"
or
variant
=
=
"
ansilog
"
then
423
useluawrites
(
)
-- because tex escapes ^^, not needed in lmtx
424
end
425
settarget
(
whereto
)
426
end
427 428
setformatters
(
variant
)
429 430
setlogfile
=
ignore
431
settimedlog
=
ignore
432 433
-- settimedlog = function()
434
-- local localtime = os.localtime
435
-- local writeline = write_nl
436
-- write_nl = function(f,...)
437
-- writeline(f,localtime() .. " | " .. concat { ... })
438
-- end
439
-- settimedlog = ignore
440
-- end
441 442
else
443 444
local
report_yes
,
subreport_yes
,
status_yes
445
local
report_nop
,
subreport_nop
,
status_nop
446 447
local
variants
=
{
448
default
=
{
449
formats
=
{
450
report_yes
=
formatters
[
"
%-15s | %s
"
]
,
451
report_nop
=
formatters
[
"
%-15s |
"
]
,
452
subreport_yes
=
formatters
[
"
%-15s | %s | %s
"
]
,
453
subreport_nop
=
formatters
[
"
%-15s | %s |
"
]
,
454
status_yes
=
formatters
[
"
%-15s : %s\n
"
]
,
455
status_nop
=
formatters
[
"
%-15s :\n
"
]
,
456
}
,
457
}
,
458
ansi
=
{
459
formats
=
{
460
report_yes
=
formatters
[
"
%-15s | %s
"
]
,
461
report_nop
=
formatters
[
"
%-15s |
"
]
,
462
subreport_yes
=
formatters
[
"
%-15s | %s | %s
"
]
,
463
subreport_nop
=
formatters
[
"
%-15s | %s |
"
]
,
464
status_yes
=
formatters
[
"
%-15s : %s\n
"
]
,
465
status_nop
=
formatters
[
"
%-15s :\n
"
]
,
466
}
,
467
}
,
468
}
469 470
logs
.
flush
=
ignore
471 472
writer
=
function
(
s
)
473
write_nl
(
s
)
474
end
475 476
newline
=
function
(
)
477
write_nl
(
"
\n
"
)
478
end
479 480
report
=
function
(
a
,
b
,
c
,
...
)
481
if
c
then
482
write_nl
(
report_yes
(
a
,
formatters
[
b
]
(
c
,
...
)
)
)
483
elseif
b
then
484
write_nl
(
report_yes
(
a
,
b
)
)
485
elseif
a
then
486
write_nl
(
report_nop
(
a
)
)
487
else
488
write_nl
(
"
"
)
489
end
490
end
491 492
subreport
=
function
(
a
,
sub
,
b
,
c
,
...
)
493
if
c
then
494
write_nl
(
subreport_yes
(
a
,
sub
,
formatters
[
b
]
(
c
,
...
)
)
)
495
elseif
b
then
496
write_nl
(
subreport_yes
(
a
,
sub
,
b
)
)
497
elseif
a
then
498
write_nl
(
subreport_nop
(
a
,
sub
)
)
499
else
500
write_nl
(
"
"
)
501
end
502
end
503 504
status
=
function
(
a
,
b
,
c
,
...
)
-- not to be used in lua anyway
505
if
c
then
506
write_nl
(
status_yes
(
a
,
formatters
[
b
]
(
c
,
...
)
)
)
507
elseif
b
then
508
write_nl
(
status_yes
(
a
,
b
)
)
-- b can have %'s
509
elseif
a
then
510
write_nl
(
status_nop
(
a
)
)
511
else
512
write_nl
(
"
\n
"
)
513
end
514
end
515 516
direct
=
ignore
517
subdirect
=
ignore
518 519
settarget
=
ignore
520
pushtarget
=
ignore
521
poptarget
=
ignore
522
setformats
=
ignore
523
settranslations
=
ignore
524 525
setprocessor
=
function
(
f
)
526
local
writeline
=
write_nl
527
write_nl
=
function
(
s
)
528
writeline
(
f
(
s
)
)
529
end
530
end
531 532
setformatters
=
function
(
specification
)
533
local
f
=
nil
534
local
d
=
variants
.
default
535
if
specification
then
536
if
type
(
specification
)
=
=
"
table
"
then
537
f
=
specification
.
formats
or
specification
538
else
539
if
not
ansisupported
(
specification
)
then
540
specification
=
"
default
"
541
end
542
local
v
=
variants
[
specification
]
543
if
v
then
544
f
=
v
.
formats
545
end
546
end
547
end
548
if
f
then
549
d
=
d
.
formats
550
else
551
f
=
d
.
formats
552
d
=
f
553
end
554
setmetatableindex
(
f
,
d
)
555
report_yes
=
f
.
report_yes
556
report_nop
=
f
.
report_nop
557
subreport_yes
=
f
.
subreport_yes
558
subreport_nop
=
f
.
subreport_nop
559
status_yes
=
f
.
status_yes
560
status_nop
=
f
.
status_nop
561
end
562 563
setformatters
(
variant
)
564 565
setlogfile
=
function
(
name
,
keepopen
)
566
if
name
and
name
~
=
"
"
then
567
local
localtime
=
os
.
localtime
568
local
writeline
=
write_nl
569
if
keepopen
then
570
local
f
=
io
.
open
(
name
,
"
ab
"
)
571
write_nl
=
function
(
s
)
572
writeline
(
s
)
573
f
:
write
(
localtime
(
)
,
"
|
"
,
s
,
"
\n
"
)
574
end
575
else
576
write_nl
=
function
(
s
)
577
writeline
(
s
)
578
local
f
=
io
.
open
(
name
,
"
ab
"
)
579
f
:
write
(
localtime
(
)
,
"
|
"
,
s
,
"
\n
"
)
580
f
:
close
(
)
581
end
582
end
583
end
584
setlogfile
=
ignore
585
end
586 587
settimedlog
=
function
(
)
588
local
localtime
=
os
.
localtime
589
local
writeline
=
write_nl
590
write_nl
=
function
(
s
)
591
writeline
(
localtime
(
)
.
.
"
|
"
.
.
s
)
592
end
593
settimedlog
=
ignore
594
end
595 596
end
597 598
logs
.
report
=
report
599
logs
.
subreport
=
subreport
600
logs
.
status
=
status
601
logs
.
settarget
=
settarget
602
logs
.
pushtarget
=
pushtarget
603
logs
.
poptarget
=
poptarget
604
logs
.
setformats
=
setformats
605
logs
.
settranslations
=
settranslations
606 607
logs
.
setlogfile
=
setlogfile
608
logs
.
settimedlog
=
settimedlog
609
logs
.
setprocessor
=
setprocessor
610
logs
.
setformatters
=
setformatters
611 612
logs
.
direct
=
direct
613
logs
.
subdirect
=
subdirect
614
logs
.
writer
=
writer
615
logs
.
newline
=
newline
616 617
-- installer
618 619
-- todo: renew (un) locks when a new one is added and wildcard
620 621
local
data
=
{
}
622
local
states
=
nil
623
local
force
=
false
624 625
function
logs
.
reporter
(
category
,
subcategory
)
626
local
logger
=
data
[
category
]
627
if
not
logger
then
628
local
state
=
states
=
=
true
629
if
not
state
and
type
(
states
)
=
=
"
table
"
then
630
for
c
,
_
in
next
,
states
do
631
if
find
(
category
,
c
)
then
632
state
=
true
633
break
634
end
635
end
636
end
637
logger
=
{
638
reporters
=
{
}
,
639
state
=
state
,
640
}
641
data
[
category
]
=
logger
642
end
643
local
reporter
=
logger
.
reporters
[
subcategory
or
"
default
"
]
644
if
not
reporter
then
645
if
subcategory
then
646
reporter
=
function
(
...
)
647
if
force
or
not
logger
.
state
then
648
subreport
(
category
,
subcategory
,
...
)
649
end
650
end
651
logger
.
reporters
[
subcategory
]
=
reporter
652
else
653
local
tag
=
category
654
reporter
=
function
(
...
)
655
if
force
or
not
logger
.
state
then
656
report
(
category
,
...
)
657
end
658
end
659
logger
.
reporters
.
default
=
reporter
660
end
661
end
662
return
reporter
663
end
664 665
logs
.
new
=
logs
.
reporter
-- for old times sake
666 667
-- context specicific: this ends up in the macro stream
668 669
local
ctxreport
=
logs
.
writer
670 671
function
logs
.
setmessenger
(
m
)
672
ctxreport
=
m
673
end
674 675
function
logs
.
messenger
(
category
,
subcategory
)
676
-- we need to avoid catcode mess (todo: fast context)
677
if
subcategory
then
678
return
function
(
...
)
679
ctxreport
(
subdirect
(
category
,
subcategory
,
...
)
)
680
end
681
else
682
return
function
(
...
)
683
ctxreport
(
direct
(
category
,
...
)
)
684
end
685
end
686
end
687 688
-- so far
689 690
local
function
setblocked
(
category
,
value
)
-- v.state == value == true : disable
691
if
category
=
=
true
or
category
=
=
"
all
"
then
692
-- lock all
693
category
,
value
=
"
*
"
,
true
694
elseif
category
=
=
false
then
695
-- unlock all
696
category
,
value
=
"
*
"
,
false
697
elseif
value
=
=
nil
then
698
-- lock selective
699
value
=
true
700
end
701
if
category
=
=
"
*
"
then
702
states
=
value
703
for
k
,
v
in
next
,
data
do
704
v
.
state
=
value
705
end
706
else
707
alllocked
=
false
708
states
=
settings_to_hash
(
category
,
type
(
states
)
=
=
"
table
"
and
states
or
nil
)
709
for
c
in
next
,
states
do
710
local
v
=
data
[
c
]
711
if
v
then
712
v
.
state
=
value
713
else
714
c
=
topattern
(
c
,
true
,
true
)
715
for
k
,
v
in
next
,
data
do
716
if
find
(
k
,
c
)
then
717
v
.
state
=
value
718
end
719
end
720
end
721
end
722
end
723
end
724 725
function
logs
.
disable
(
category
,
value
)
726
setblocked
(
category
,
value
=
=
nil
and
true
or
value
)
727
end
728 729
function
logs
.
enable
(
category
)
730
setblocked
(
category
,
false
)
731
end
732 733
function
logs
.
categories
(
)
734
return
sortedkeys
(
data
)
735
end
736 737
function
logs
.
show
(
)
738
local
n
,
c
,
s
,
max
=
0
,
0
,
0
,
0
739
for
category
,
v
in
table
.
sortedpairs
(
data
)
do
740
n
=
n
+
1
741
local
state
=
v
.
state
742
local
reporters
=
v
.
reporters
743
local
nc
=
#
category
744
if
nc
>
c
then
745
c
=
nc
746
end
747
for
subcategory
,
_
in
next
,
reporters
do
748
local
ns
=
#
subcategory
749
if
ns
>
c
then
750
s
=
ns
751
end
752
local
m
=
nc
+
ns
753
if
m
>
max
then
754
max
=
m
755
end
756
end
757
local
subcategories
=
concat
(
sortedkeys
(
reporters
)
,
"
,
"
)
758
if
state
=
=
true
then
759
state
=
"
disabled
"
760
elseif
state
=
=
false
then
761
state
=
"
enabled
"
762
else
763
state
=
"
unknown
"
764
end
765
-- no new here
766
report
(
"
logging
"
,
"
category %a, subcategories %a, state %a
"
,
category
,
subcategories
,
state
)
767
end
768
report
(
"
logging
"
,
"
categories: %s, max category: %s, max subcategory: %s, max combined: %s
"
,
n
,
c
,
s
,
max
)
769
end
770 771
local
delayed_reporters
=
{
}
772 773
setmetatableindex
(
delayed_reporters
,
function
(
t
,
k
)
774
local
v
=
logs
.
reporter
(
k
.
name
)
775
t
[
k
]
=
v
776
return
v
777
end
)
778 779
function
utilities
.
setters
.
report
(
setter
,
...
)
780
delayed_reporters
[
setter
]
(
...
)
781
end
782 783
directives
.
register
(
"
logs.blocked
"
,
function
(
v
)
784
setblocked
(
v
,
true
)
785
end
)
786 787
directives
.
register
(
"
logs.target
"
,
function
(
v
)
788
settarget
(
v
)
789
end
)
790 791
-- tex specific loggers (might move elsewhere)
792 793
if
tex
then
794 795
local
report
=
logs
.
reporter
(
"
pages
"
)
-- not needed but saves checking when we grep for it
796
local
texgetcount
=
tex
and
tex
.
getcount
797 798
local
real
,
user
,
sub
=
0
,
0
,
0
799 800
function
logs
.
start_page_number
(
)
801
real
=
texgetcount
(
"
realpageno
"
)
802
user
=
texgetcount
(
"
userpageno
"
)
803
sub
=
texgetcount
(
"
subpageno
"
)
804
end
805 806
local
timing
=
false
807
local
lasttime
=
nil
808 809
trackers
.
register
(
"
pages.timing
"
,
function
(
v
)
-- only for myself (diagnostics)
810
timing
=
"
"
811
end
)
812 813
function
logs
.
stop_page_number
(
)
-- the first page can includes the initialization so we omit this in average
814
if
timing
then
815
local
elapsed
=
statistics
.
currenttime
(
statistics
)
816
local
average
,
page
817
if
not
lasttime
or
real
<
2
then
818
average
=
elapsed
819
page
=
elapsed
820
else
821
average
=
elapsed
/
(
real
-
1
)
822
page
=
elapsed
-
lasttime
823
end
824
lasttime
=
elapsed
825
timing
=
formatters
[
"
, total %0.03f, page %0.03f, average %0.03f
"
]
(
elapsed
,
page
,
average
)
826
end
827
if
real
<
=
0
then
828
report
(
"
flushing page%s
"
,
timing
)
829
elseif
user
<
=
0
then
830
report
(
"
flushing realpage %s%s
"
,
real
,
timing
)
831
elseif
sub
<
=
0
then
832
report
(
"
flushing realpage %s, userpage %s%s
"
,
real
,
user
,
timing
)
833
else
834
report
(
"
flushing realpage %s, userpage %s, subpage %s%s
"
,
real
,
user
,
sub
,
timing
)
835
end
836
logs
.
flush
(
)
837
end
838 839
end
840 841
-- we don't have show_open and show_close callbacks yet
842 843
----- report_files = logs.reporter("files")
844
local
nesting
=
0
845
local
verbose
=
false
846
local
hasscheme
=
url
.
hasscheme
847 848
-- there may be scripts out there using this:
849 850
local
simple
=
logs
.
reporter
(
"
comment
"
)
851 852
logs
.
simple
=
simple
853
logs
.
simpleline
=
simple
854 855
-- obsolete
856 857
logs
.
setprogram
=
ignore
-- obsolete
858
logs
.
extendbanner
=
ignore
-- obsolete
859
logs
.
reportlines
=
ignore
-- obsolete
860
logs
.
reportbanner
=
ignore
-- obsolete
861
logs
.
reportline
=
ignore
-- obsolete
862
logs
.
simplelines
=
ignore
-- obsolete
863
logs
.
help
=
ignore
-- obsolete
864 865
-- applications
866 867
-- local function reportlines(t,str)
868
-- if str then
869
-- for line in gmatch(str,"([^\n\r]*)[\n\r]") do
870
-- t.report(line)
871
-- end
872
-- end
873
-- end
874 875
local
Carg
,
C
,
lpegmatch
=
lpeg
.
Carg
,
lpeg
.
C
,
lpeg
.
match
876
local
p_newline
=
lpeg
.
patterns
.
newline
877 878
local
linewise
=
(
879
Carg
(
1
)
*
C
(
(
1
-
p_newline
)
^
1
)
/
function
(
t
,
s
)
t
.
report
(
s
)
end
880
+
Carg
(
1
)
*
p_newline
^
2
/
function
(
t
)
t
.
report
(
)
end
881
+
p_newline
882
)
^
1
883 884
local
function
reportlines
(
t
,
str
)
885
if
str
then
886
lpegmatch
(
linewise
,
str
,
1
,
t
)
887
end
888
end
889 890
local
function
reportbanner
(
t
)
891
local
banner
=
t
.
banner
892
if
banner
then
893
t
.
report
(
banner
)
894
t
.
report
(
)
895
end
896
end
897 898
local
function
reportversion
(
t
)
899
local
banner
=
t
.
banner
900
if
banner
then
901
t
.
report
(
banner
)
902
end
903
end
904 905
local
function
reporthelp
(
t
,
...
)
906
local
helpinfo
=
t
.
helpinfo
907
if
type
(
helpinfo
)
=
=
"
string
"
then
908
reportlines
(
t
,
helpinfo
)
909
elseif
type
(
helpinfo
)
=
=
"
table
"
then
910
for
i
=
1
,
select
(
"
#
"
,
...
)
do
911
reportlines
(
t
,
t
.
helpinfo
[
select
(
i
,
...
)
]
)
912
if
i
<
n
then
913
t
.
report
(
)
914
end
915
end
916
end
917
end
918 919
local
function
reportinfo
(
t
)
920
t
.
report
(
)
921
reportlines
(
t
,
t
.
moreinfo
)
922
end
923 924
local
function
reportexport
(
t
,
method
)
925
report
(
t
.
helpinfo
)
926
end
927 928
local
reporters
=
{
929
lines
=
reportlines
,
-- not to be overloaded
930
banner
=
reportbanner
,
931
version
=
reportversion
,
932
help
=
reporthelp
,
933
info
=
reportinfo
,
934
export
=
reportexport
,
935
}
936 937
local
exporters
=
{
938
-- empty
939
}
940 941
logs
.
reporters
=
reporters
942
logs
.
exporters
=
exporters
943 944
function
logs
.
application
(
t
)
945
--
946
local
arguments
=
environment
and
environment
.
arguments
947
if
arguments
then
948
local
ansi
=
arguments
.
ansi
or
arguments
.
ansilog
949
if
ansi
then
950
logs
.
setformatters
(
arguments
.
ansi
and
"
ansi
"
or
"
ansilog
"
)
951
end
952
end
953
--
954
t
.
name
=
t
.
name
or
"
unknown
"
955
t
.
banner
=
t
.
banner
956
t
.
moreinfo
=
moreinfo
957
t
.
report
=
logs
.
reporter
(
t
.
name
)
958
t
.
help
=
function
(
...
)
959
reporters
.
banner
(
t
)
960
reporters
.
help
(
t
,
...
)
961
reporters
.
info
(
t
)
962
end
963
t
.
export
=
function
(
...
)
964
reporters
.
export
(
t
,
...
)
965
end
966
t
.
identify
=
function
(
)
967
reporters
.
banner
(
t
)
968
end
969
t
.
version
=
function
(
)
970
reporters
.
version
(
t
)
971
end
972
return
t
973
end
974 975
-- somewhat special .. will be redone (already a better solution in place in lmx)
976 977
-- logging to a file
978 979
-- local syslogname = "oeps.xxx"
980
--
981
-- for i=1,10 do
982
-- logs.system(syslogname,"context","test","fonts","font %s recached due to newer version (%s)","blabla","123")
983
-- end
984 985
local
f_syslog
=
formatters
[
"
%s %s => %s => %s => %s\r
"
]
986 987
function
logs
.
system
(
whereto
,
process
,
jobname
,
category
,
fmt
,
arg
,
...
)
988
local
message
=
f_syslog
(
datetime
(
"
%d/%m/%y %H:%m:%S
"
)
,
process
,
jobname
,
category
,
arg
=
=
nil
and
fmt
or
format
(
fmt
,
arg
,
...
)
)
989
for
i
=
1
,
10
do
990
local
f
=
openfile
(
whereto
,
"
a
"
)
-- we can consider keeping the file open
991
if
f
then
992
f
:
write
(
message
)
993
f
:
close
(
)
994
break
995
else
996
sleep
(
0
.
1
)
997
end
998
end
999
end
1000 1001
local
report_system
=
logs
.
reporter
(
"
system
"
,
"
logs
"
)
1002 1003
function
logs
.
obsolete
(
old
,
new
)
1004
local
o
=
loadstring
(
"
return
"
.
.
new
)
(
)
1005
if
type
(
o
)
=
=
"
function
"
then
1006
return
function
(
...
)
1007
report_system
(
"
function %a is obsolete, use %a
"
,
old
,
new
)
1008
loadstring
(
old
.
.
"
=
"
.
.
new
.
.
"
return
"
.
.
old
)
(
)
(
...
)
1009
end
1010
elseif
type
(
o
)
=
=
"
table
"
then
1011
local
t
,
m
=
{
}
,
{
}
1012
m
.
__index
=
function
(
t
,
k
)
1013
report_system
(
"
table %a is obsolete, use %a
"
,
old
,
new
)
1014
m
.
__index
,
m
.
__newindex
=
o
,
o
1015
return
o
[
k
]
1016
end
1017
m
.
__newindex
=
function
(
t
,
k
,
v
)
1018
report_system
(
"
table %a is obsolete, use %a
"
,
old
,
new
)
1019
m
.
__index
,
m
.
__newindex
=
o
,
o
1020
o
[
k
]
=
v
1021
end
1022
if
libraries
then
1023
libraries
.
obsolete
[
old
]
=
t
-- true
1024
end
1025
setmetatable
(
t
,
m
)
1026
return
t
1027
end
1028
end
1029 1030
if
utilities
then
1031
utilities
.
report
=
report_system
1032
end
1033 1034
if
tex
and
tex
.
error
then
1035
function
logs
.
texerrormessage
(
...
)
-- for the moment we put this function here
1036
tex
.
error
(
format
(
...
)
)
1037
end
1038
else
1039
function
logs
.
texerrormessage
(
...
)
1040
print
(
format
(
...
)
)
1041
end
1042
end
1043 1044
-- this is somewhat slower but prevents out-of-order messages when print is mixed
1045
-- with texio.write
1046 1047
-- io.stdout:setvbuf('no')
1048
-- io.stderr:setvbuf('no')
1049 1050
-- windows: > nul 2>&1
1051
-- unix : > null 2>&1
1052 1053
if
package
.
helpers
.
report
then
1054
package
.
helpers
.
report
=
logs
.
reporter
(
"
package loader
"
)
-- when used outside mtxrun
1055
end
1056 1057
if
tex
then
1058 1059
local
finalactions
=
{
}
1060
local
fatalerrors
=
{
}
1061
local
possiblefatal
=
{
}
1062
local
loggingerrors
=
false
1063 1064
function
logs
.
loggingerrors
(
)
1065
return
loggingerrors
1066
end
1067 1068
directives
.
register
(
"
logs.errors
"
,
function
(
v
)
1069
loggingerrors
=
v
1070
if
type
(
v
)
=
=
"
string
"
then
1071
fatalerrors
=
settings_to_hash
(
v
)
1072
else
1073
fatalerrors
=
{
}
1074
end
1075
end
)
1076 1077
function
logs
.
registerfinalactions
(
...
)
1078
insert
(
finalactions
,
...
)
-- so we can force an order if needed
1079
end
1080 1081
local
what
=
nil
1082
local
report
=
nil
1083
local
state
=
nil
1084
local
target
=
nil
1085 1086
local
function
startlogging
(
t
,
r
,
w
,
s
)
1087
target
=
t
1088
state
=
force
1089
force
=
true
1090
report
=
type
(
r
)
=
=
"
function
"
and
r
or
logs
.
reporter
(
r
)
1091
what
=
w
1092
pushtarget
(
target
)
1093
newline
(
)
1094
if
s
then
1095
report
(
"
start %s: %s
"
,
what
,
s
)
1096
else
1097
report
(
"
start %s
"
,
what
)
1098
end
1099
if
target
=
=
"
logfile
"
then
1100
newline
(
)
1101
end
1102
return
report
1103
end
1104 1105
local
function
stoplogging
(
)
1106
if
target
=
=
"
logfile
"
then
1107
newline
(
)
1108
end
1109
report
(
"
stop %s
"
,
what
)
1110
if
target
=
=
"
logfile
"
then
1111
newline
(
)
1112
end
1113
poptarget
(
)
1114
state
=
oldstate
1115
end
1116 1117
function
logs
.
startfilelogging
(
...
)
1118
return
startlogging
(
"
logfile
"
,
...
)
1119
end
1120 1121
logs
.
stopfilelogging
=
stoplogging
1122 1123
local
done
=
false
1124 1125
function
logs
.
starterrorlogging
(
r
,
w
,
...
)
1126
if
not
done
then
1127
pushtarget
(
"
terminal
"
)
1128
newline
(
)
1129
logs
.
report
(
"
error logging
"
,
"
start possible issues
"
)
1130
poptarget
(
)
1131
done
=
true
1132
end
1133
if
fatalerrors
[
w
]
then
1134
possiblefatal
[
w
]
=
true
1135
end
1136
return
startlogging
(
"
terminal
"
,
r
,
w
,
...
)
1137
end
1138 1139
logs
.
stoperrorlogging
=
stoplogging
1140 1141
function
logs
.
finalactions
(
)
1142
if
#
finalactions
>
0
then
1143
for
i
=
1
,
#
finalactions
do
1144
finalactions
[
i
]
(
)
1145
end
1146
if
done
then
1147
pushtarget
(
"
terminal
"
)
1148
newline
(
)
1149
logs
.
report
(
"
error logging
"
,
"
stop possible issues
"
)
1150
poptarget
(
)
1151
end
1152
return
next
(
possiblefatal
)
and
sortedkeys
(
possiblefatal
)
or
false
1153
end
1154
end
1155 1156
end
1157