summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/context/base/trac-set.lua
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/tex/context/base/trac-set.lua')
-rw-r--r--Master/texmf-dist/tex/context/base/trac-set.lua205
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