diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/trac-set.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/trac-set.lua | 205 |
1 files changed, 124 insertions, 81 deletions
diff --git a/Master/texmf-dist/tex/context/base/trac-set.lua b/Master/texmf-dist/tex/context/base/trac-set.lua index bc0070eb42b..95fdc43b30f 100644 --- a/Master/texmf-dist/tex/context/base/trac-set.lua +++ b/Master/texmf-dist/tex/context/base/trac-set.lua @@ -6,19 +6,22 @@ if not modules then modules = { } end modules ['trac-set'] = { -- might become u license = "see context related readme files" } +-- maybe this should be util-set.lua + local type, next, tostring = type, next, tostring local concat = table.concat -local format, find, lower, gsub, escapedpattern = string.format, string.find, string.lower, string.gsub, string.escapedpattern +local format, find, lower, gsub, topattern = string.format, string.find, string.lower, string.gsub, string.topattern local is_boolean = string.is_boolean local settings_to_hash = utilities.parsers.settings_to_hash local allocate = utilities.storage.allocate utilities = utilities or { } local utilities = utilities -utilities.setters = utilities.setters or { } -local setters = utilities.setters -local data = { } -- maybe just local +local setters = utilities.setters or { } +utilities.setters = setters + +local data = { } -- We can initialize from the cnf file. This is sort of tricky as -- later defined setters also need to be initialized then. If set @@ -29,33 +32,41 @@ local trace_initialize = false -- only for testing during development function setters.initialize(filename,name,values) -- filename only for diagnostics local setter = data[name] if setter then + frozen = true -- don't permitoverload + -- trace_initialize = true local data = setter.data if data then - for key, value in next, values do - -- key = gsub(key,"_",".") - value = is_boolean(value,value) + for key, newvalue in next, values do + local newvalue = is_boolean(newvalue,newvalue) local functions = data[key] if functions then - if #functions > 0 and not functions.value then + local oldvalue = functions.value + if functions.frozen then + if trace_initialize then + setter.report("%s: %a is %s to %a",filename,key,"frozen",oldvalue) + end + elseif #functions > 0 and not oldvalue then +-- elseif #functions > 0 and oldvalue == nil then if trace_initialize then - setter.report("executing %s (%s -> %s)",key,filename,tostring(value)) + setter.report("%s: %a is %s to %a",filename,key,"set",newvalue) end for i=1,#functions do - functions[i](value) + functions[i](newvalue) end - functions.value = value + functions.value = newvalue + functions.frozen = functions.frozen or frozen else if trace_initialize then - setter.report("skipping %s (%s -> %s)",key,filename,tostring(value)) + setter.report("%s: %a is %s as %a",filename,key,"kept",oldvalue) end end else -- we do a simple preregistration i.e. not in the -- list as it might be an obsolete entry - functions = { default = value } + functions = { default = newvalue, frozen = frozen } data[key] = functions if trace_initialize then - setter.report("storing %s (%s -> %s)",key,filename,tostring(value)) + setter.report("%s: %a is %s to %a",filename,key,"defaulted",newvalue) end end end @@ -67,46 +78,52 @@ end -- user interface code local function set(t,what,newvalue) - local data, done = t.data, t.done - if type(what) == "string" then - what = settings_to_hash(what) -- inefficient but ok - end - if type(what) ~= "table" then - return - end - if not done then -- catch ... why not set? - done = { } - t.done = done - end - for w, value in next, what do - if value == "" then - value = newvalue - elseif not value then - value = false -- catch nil - else - value = is_boolean(value,value) + local data = t.data + if not data.frozen then + local done = t.done + if type(what) == "string" then + what = settings_to_hash(what) -- inefficient but ok end - w = "^" .. escapedpattern(w,true) .. "$" -- new: anchored - for name, functions in next, data do - if done[name] then - -- prevent recursion due to wildcards - elseif find(name,w) then - done[name] = true - for i=1,#functions do - functions[i](value) + if type(what) ~= "table" then + return + end + if not done then -- catch ... why not set? + done = { } + t.done = done + end + for w, value in next, what do + if value == "" then + value = newvalue + elseif not value then + value = false -- catch nil + else + value = is_boolean(value,value) + end + w = topattern(w,true,true) + for name, functions in next, data do + if done[name] then + -- prevent recursion due to wildcards + elseif find(name,w) then + done[name] = true + for i=1,#functions do + functions[i](value) + end + functions.value = value end - functions.value = value end end end end local function reset(t) - for name, functions in next, t.data do - for i=1,#functions do - functions[i](false) + local data = t.data + if not data.frozen then + for name, functions in next, data do + for i=1,#functions do + functions[i](false) + end + functions.value = false end - functions.value = false end end @@ -132,15 +149,16 @@ function setters.register(t,what,...) functions = { } data[what] = functions if trace_initialize then - t.report("defining %s",what) + t.report("defining %a",what) end end local default = functions.default -- can be set from cnf file - for _, fnc in next, { ... } do + for i=1,select("#",...) do + local fnc = select(i,...) local typ = type(fnc) if typ == "string" then if trace_initialize then - t.report("coupling %s to %s",what,fnc) + t.report("coupling %a to %a",what,fnc) end local s = fnc -- else wrong reference fnc = function(value) set(t,s,value) end @@ -205,7 +223,7 @@ function setters.show(t) local value, default, modules = functions.value, functions.default, #functions value = value == nil and "unset" or tostring(value) default = default == nil and "unset" or tostring(default) - t.report("%-30s modules: %2i default: %6s value: %6s",name,modules,default,value) + t.report("%-50s modules: %2i default: %-12s value: %-12s",name,modules,default,value) end end t.report() @@ -218,26 +236,33 @@ end local enable, disable, register, list, show = setters.enable, setters.disable, setters.register, setters.list, setters.show -local function report(setter,...) - local report = logs and logs.report - if report then - report(setter.name,...) - else -- fallback, as this module is loaded before the logger - write_nl(format("%-15s : %s\n",setter.name,format(...))) - end +function setters.report(setter,...) + print(format("%-15s : %s\n",setter.name,format(...))) +end + +local function default(setter,name) + local d = setter.data[name] + return d and d.default end -function setters.new(name) +local function value(setter,name) + local d = setter.data[name] + return d and (d.value or d.default) +end + +function setters.new(name) -- we could use foo:bar syntax (but not used that often) local setter -- we need to access it in setter itself setter = { data = allocate(), -- indexed, but also default and value fields name = name, - report = function(...) report (setter,...) end, - enable = function(...) enable (setter,...) end, - disable = function(...) disable (setter,...) end, - register = function(...) register(setter,...) end, - list = function(...) list (setter,...) end, - show = function(...) show (setter,...) end, + report = function(...) setters.report (setter,...) end, + enable = function(...) enable (setter,...) end, + disable = function(...) disable (setter,...) end, + register = function(...) register(setter,...) end, + list = function(...) list (setter,...) end, + show = function(...) show (setter,...) end, + default = function(...) return default (setter,...) end, + value = function(...) return value (setter,...) end, } data[name] = setter return setter @@ -247,9 +272,9 @@ trackers = setters.new("trackers") directives = setters.new("directives") experiments = setters.new("experiments") -local t_enable, t_disable, t_report = trackers .enable, trackers .disable, trackers .report -local d_enable, d_disable, d_report = directives .enable, directives .disable, directives .report -local e_enable, e_disable, e_report = experiments.enable, experiments.disable, experiments.report +local t_enable, t_disable = trackers .enable, trackers .disable +local d_enable, d_disable = directives .enable, directives .disable +local e_enable, e_disable = experiments.enable, experiments.disable -- nice trick: we overload two of the directives related functions with variants that -- do tracing (itself using a tracker) .. proof of concept @@ -259,28 +284,28 @@ local trace_experiments = false local trace_experiments = false trackers.regist function directives.enable(...) if trace_directives then - d_report("enabling: %s",concat({...}," ")) + directives.report("enabling: % t",{...}) end d_enable(...) end function directives.disable(...) if trace_directives then - d_report("disabling: %s",concat({...}," ")) + directives.report("disabling: % t",{...}) end d_disable(...) end function experiments.enable(...) if trace_experiments then - e_report("enabling: %s",concat({...}," ")) + experiments.report("enabling: % t",{...}) end e_enable(...) end function experiments.disable(...) if trace_experiments then - e_report("disabling: %s",concat({...}," ")) + experiments.report("disabling: % t",{...}) end e_disable(...) end @@ -288,26 +313,44 @@ end -- a useful example directives.register("system.nostatistics", function(v) - statistics.enable = not v + if statistics then + statistics.enable = not v + else + -- forget about it + end end) directives.register("system.nolibraries", function(v) - libraries = nil -- we discard this tracing for security + if libraries then + libraries = nil -- we discard this tracing for security + else + -- no libraries defined + end end) -- experiment -local flags = environment and environment.engineflags +if environment then -if flags then - if trackers and flags.trackers then - setters.initialize("flags","trackers", settings_to_hash(flags.trackers)) - -- t_enable(flags.trackers) - end - if directives and flags.directives then - setters.initialize("flags","directives", settings_to_hash(flags.directives)) - -- d_enable(flags.directives) + -- The engineflags are known earlier than environment.arguments but maybe we + -- need to handle them both as the later are parsed differently. The c: prefix + -- is used by mtx-context to isolate the flags from those that concern luatex. + + local engineflags = environment.engineflags + + if engineflags then + local list = engineflags["c:trackers"] or engineflags["trackers"] + if type(list) == "string" then + setters.initialize("commandline flags","trackers",settings_to_hash(list)) + -- t_enable(list) + end + local list = engineflags["c:directives"] or engineflags["directives"] + if type(list) == "string" then + setters.initialize("commandline flags","directives", settings_to_hash(list)) + -- d_enable(list) + end end + end -- here |