1if not modules then modules = { } end modules ['trac-set'] = {
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
9
10
11local type, next, tostring, tonumber = type, next, tostring, tonumber
12local print = print
13local concat, sortedhash = table.concat, table.sortedhash
14local formatters, find, lower, gsub, topattern = string.formatters, string.find, string.lower, string.gsub, string.topattern
15local is_boolean = string.is_boolean
16local settings_to_hash = utilities.parsers.settings_to_hash
17local allocate = utilities.storage.allocate
18
19utilities = utilities or { }
20local utilities = utilities
21
22local setters = utilities.setters or { }
23utilities.setters = setters
24
25local data = { }
26
27
28
29
30
31
32
33local trace_initialize = false
34local frozen = true
35
36local function initialize_setter(filename,name,values)
37 local setter = data[name]
38 if setter then
39
40 local data = setter.data
41 if data then
42 for key, newvalue in sortedhash(values) do
43 local newvalue = is_boolean(newvalue,newvalue,true)
44 local functions = data[key]
45 if functions then
46 local oldvalue = functions.value
47 if functions.frozen then
48 if trace_initialize then
49 setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue)
50 end
51 elseif #functions > 0 and not oldvalue then
52
53 if trace_initialize then
54 setter.report("%s: %a is %s to %a",filename,key,"set",newvalue)
55 end
56 for i=1,#functions do
57 functions[i](newvalue)
58 end
59 functions.value = newvalue
60 functions.frozen = functions.frozen or frozen
61 else
62 if trace_initialize then
63 setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue)
64 end
65 end
66 else
67
68
69 functions = { default = newvalue, frozen = frozen }
70 data[key] = functions
71 if trace_initialize then
72 setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue)
73 end
74 end
75 end
76 return true
77 end
78 end
79end
80
81
82
83local function set(t,what,newvalue)
84 local data = t.data
85 if data and not data.frozen then
86 local done = t.done
87 if type(what) == "string" then
88 what = settings_to_hash(what)
89 end
90 if type(what) ~= "table" then
91 return
92 end
93 if not done then
94 done = { }
95 t.done = done
96 end
97 for w, value in sortedhash(what) do
98 if value == "" then
99 value = newvalue
100 elseif not value then
101 value = false
102 else
103 value = is_boolean(value,value,true)
104 end
105 w = topattern(w,true,true)
106 for name, functions in sortedhash(data) do
107 if done[name] then
108
109 elseif find(name,w) then
110 done[name] = true
111 for i=1,#functions do
112 functions[i](value)
113 end
114 functions.value = value
115 end
116 end
117 end
118 end
119end
120
121local function reset(t)
122 local data = t.data
123 if data and not data.frozen then
124 for name, functions in sortedthash(data) do
125 for i=1,#functions do
126 functions[i](false)
127 end
128 functions.value = false
129 end
130 end
131end
132
133local function enable(t,what)
134 set(t,what,true)
135end
136
137local function disable(t,what)
138 local data = t.data
139 if not what or what == "" then
140 t.done = { }
141 reset(t)
142 else
143 set(t,what,false)
144 end
145end
146
147local function register_setter(t,what,...)
148 local data = t.data
149 what = lower(what)
150 local functions = data[what]
151 if not functions then
152 functions = { }
153 data[what] = functions
154 if trace_initialize then
155 t.report("defining %a",what)
156 end
157 end
158 local default = functions.default
159 for i=1,select("#",...) do
160 local fnc = select(i,...)
161 local typ = type(fnc)
162 if typ == "string" then
163 if trace_initialize then
164 t.report("coupling %a to %a",what,fnc)
165 end
166 local s = fnc
167 fnc = function(value) set(t,s,value) end
168 elseif typ == "table" then
169 functions.values = fnc
170 fnc = nil
171 elseif typ ~= "function" then
172 fnc = nil
173 end
174 if fnc then
175 functions[#functions+1] = fnc
176
177
178 local value = functions.value or default
179 if value ~= nil then
180 fnc(value)
181 functions.value = value
182 end
183 end
184 end
185 return false
186end
187
188local function enable_setter(t,what)
189 local e = t.enable
190 t.enable, t.done = enable, { }
191 set(t,what,true)
192 enable(t,what)
193 t.enable, t.done = e, { }
194end
195
196local function disable_setter(t,what)
197 local e = t.disable
198 t.disable, t.done = disable, { }
199 disable(t,what)
200 t.disable, t.done = e, { }
201end
202
203local function reset_setter(t)
204 t.done = { }
205 reset(t)
206end
207
208local function list_setter(t)
209 local list = table.sortedkeys(t.data)
210 local user, system = { }, { }
211 for l=1,#list do
212 local what = list[l]
213 if find(what,"^%*") then
214 system[#system+1] = what
215 else
216 user[#user+1] = what
217 end
218 end
219 return user, system
220end
221
222local function show_setter(t,pattern)
223 local list = list_setter(t)
224 t.report()
225 for k=1,#list do
226 local name = list[k]
227 if not pattern or find(name,pattern) then
228 local functions = t.data[name]
229 if functions then
230 local value = functions.value
231 local default = functions.default
232 local values = functions.values
233 local modules = #functions
234 if default == nil then
235 default = "unset"
236 elseif type(default) == "table" then
237 default = concat(default,"|")
238 else
239 default = tostring(default)
240 end
241 if value == nil then
242 value = "unset"
243 elseif type(value) == "table" then
244 value = concat(value,"|")
245 else
246 value = tostring(value)
247 end
248 t.report(name)
249 t.report(" modules : %i",modules)
250 t.report(" default : %s",default)
251 t.report(" value : %s",value)
252 if values then
253 local v = { } for i=1,#values do v[i] = tostring(values[i]) end
254 t.report(" values : % t",v)
255 end
256 t.report()
257 end
258 end
259 end
260end
261
262
263
264
265
266
267function setters.report(setter,fmt,...)
268 if fmt then
269 print(formatters["%-15s : %s"](setter.name,formatters[fmt](...)))
270 else
271 print("")
272 end
273end
274
275local function setter_default(setter,name)
276 local d = setter.data[name]
277 return d and d.default
278end
279
280local function setter_value(setter,name)
281 local d = setter.data[name]
282 return d and (d.value or d.default)
283end
284
285local function setter_values(setter,name)
286 local d = setter.data[name]
287 return d and d.values
288end
289
290local function new_setter(name)
291 local setter
292 setter = {
293 data = allocate(),
294 name = name,
295 report = function(...) setters.report (setter,...) end,
296 enable = function(...) enable_setter (setter,...) end,
297 disable = function(...) disable_setter (setter,...) end,
298 reset = function(...) reset_setter (setter,...) end,
299 register = function(...) register_setter(setter,...) end,
300 list = function(...) return list_setter (setter,...) end,
301 show = function(...) show_setter (setter,...) end,
302 default = function(...) return setter_default (setter,...) end,
303 value = function(...) return setter_value (setter,...) end,
304 values = function(...) return setter_values (setter,...) end,
305 }
306 data[name] = setter
307 return setter
308end
309
310setters.enable = enable_setter
311setters.disable = disable_setter
312
313setters.register = register_setter
314setters.list = list_setter
315setters.show = show_setter
316setters.reset = reset_setter
317setters.new = new_setter
318setters.initialize = initialize_setter
319
320trackers = new_setter("trackers")
321directives = new_setter("directives")
322experiments = new_setter("experiments")
323
324local t_enable, t_disable = trackers .enable, trackers .disable
325local d_enable, d_disable = directives .enable, directives .disable
326local e_enable, e_disable = experiments.enable, experiments.disable
327
328
329
330
331local trace_directives = false local trace_directives = false trackers.register("system.directives", function(v) trace_directives = v end)
332local trace_experiments = false local trace_experiments = false trackers.register("system.experiments", function(v) trace_experiments = v end)
333
334function directives.enable(...)
335 if trace_directives then
336 directives.report("enabling: % t",{...})
337 end
338 d_enable(...)
339end
340
341function directives.disable(...)
342 if trace_directives then
343 directives.report("disabling: % t",{...})
344 end
345 d_disable(...)
346end
347
348function experiments.enable(...)
349 if trace_experiments then
350 experiments.report("enabling: % t",{...})
351 end
352 e_enable(...)
353end
354
355function experiments.disable(...)
356 if trace_experiments then
357 experiments.report("disabling: % t",{...})
358 end
359 e_disable(...)
360end
361
362
363
364directives.register("system.nostatistics", function(v)
365 if statistics then
366 statistics.enable = not v
367 else
368
369 end
370end)
371
372directives.register("system.nolibraries", function(v)
373 if libraries then
374 libraries = nil
375 else
376
377 end
378end)
379
380
381
382if environment then
383
384
385
386
387
388 local engineflags = environment.engineflags
389
390 if engineflags then
391 local list = engineflags["c:trackers"] or engineflags["trackers"]
392 if type(list) == "string" then
393 initialize_setter("commandline flags","trackers",settings_to_hash(list))
394
395 end
396 local list = engineflags["c:directives"] or engineflags["directives"]
397 if type(list) == "string" then
398 initialize_setter("commandline flags","directives", settings_to_hash(list))
399
400 end
401 end
402
403end
404
405
406
407if texconfig then
408
409
410
411 local function set(k,v)
412 local v = tonumber(v)
413 if v then
414 texconfig[k] = v
415 end
416 end
417
418 directives.register("luatex.expanddepth", function(v) set("expand_depth",v) end)
419 directives.register("luatex.hashextra", function(v) set("hash_extra",v) end)
420 directives.register("luatex.nestsize", function(v) set("nest_size",v) end)
421 directives.register("luatex.maxinopen", function(v) set("max_in_open",v) end)
422 directives.register("luatex.maxprintline", function(v) set("max_print_line",v) end)
423 directives.register("luatex.maxstrings", function(v) set("max_strings",v) end)
424 directives.register("luatex.paramsize", function(v) set("param_size",v) end)
425 directives.register("luatex.savesize", function(v) set("save_size",v) end)
426 directives.register("luatex.stacksize", function(v) set("stack_size",v) end)
427
428end
429
430
431
432local data = table.setmetatableindex("table")
433
434updaters = {
435 register = function(what,f)
436 local d = data[what]
437 d[#d+1] = f
438 end,
439 apply = function(what,...)
440 local d = data[what]
441 for i=1,#d do
442 d[i](...)
443 end
444 end,
445}
446 |