summaryrefslogtreecommitdiff
path: root/luatexbase-modutils.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'luatexbase-modutils.dtx')
-rw-r--r--luatexbase-modutils.dtx149
1 files changed, 38 insertions, 111 deletions
diff --git a/luatexbase-modutils.dtx b/luatexbase-modutils.dtx
index 0907fe3..f962fcf 100644
--- a/luatexbase-modutils.dtx
+++ b/luatexbase-modutils.dtx
@@ -202,10 +202,11 @@ See source file '\inFileName' for details.
% |date| with the same format as above. Optional fields |version| (number or
% string) and |description| may be used if present. Other fields are ignored.
%
-% If a date was required and a date is declared, then a warning is issued if
-% the required date is strictly newer than the declared date. A list of loaded
-% modules and their associated information is kept, and used to check the date
-% without reloading the module (since |require()| won't relaod it anyway).
+% If a date was required, then a warning is issued if the required date is
+% strictly newer than the declared date (or if no date was declared). A list
+% of loaded modules and their associated information is kept, and used to
+% check the date without reloading the module (since |require()| won't reload
+% it anyway) if a module is required several times.
%
% \begin{qcode}
% luatexbase.module_error(\meta{name}, \meta{message}, ...)
@@ -219,6 +220,10 @@ See source file '\inFileName' for details.
% done, you may still use |\n| as usual for that, and the name of the package
% will be prepended to each output line.
%
+% Note that |module_error| raises an actual Lua error with |error()|, which
+% currently means a call stack will be dumped. While this may not look pretty,
+% at least it provides useful information for tracking the error down.
+%
% \begin{qcode}
% local err, warn, info = luatexbase.errwarinf(\meta{name})
% local err, warn, info = luatexbase.provides_module(\meta{name})
@@ -465,62 +470,28 @@ module("luatexbase", package.seeall)
% \subsection{Internal functions and data}
%
% Tables holding informations about the modules loaded and the versions
-% required.
+% required. Keys are module names and values are the info tables as passed
+% to |provides_module()|.
%
% \begin{macrocode}
local modules = modules or {}
-local requiredversions = {}
% \end{macrocode}
%
-% Convert a date in YYYY/MM/DD format into a number
+% Convert a date in YYYY/MM/DD format into a number.
%
% \begin{macrocode}
-local function datetonumber(date)
+local function date_to_int(date)
numbers = string.gsub(date, "(%d+)/(%d+)/(%d+)", "%1%2%3")
return tonumber(numbers)
end
% \end{macrocode}
%
-% Say if a string is a date in YYYY//MM/DD format.
-%
-% \begin{macrocode}
-local function isdate(date)
- for _, _ in string.gmatch(date, "%d+/%d+/%d+") do
- return true
- end
- return false
-end
-% \end{macrocode}
-%
-% Parse a version into a table indicating a type (date or number), a
-% numeric version and the original version string.
-%
-% \begin{macrocode}
-local date, number = 1, 2
-local function parse_version(version)
- if isdate(version) then
- return {type = date, version = datetonumber(version), orig = version}
- else
- return {type = number, version = tonumber(version), orig = version}
- end
-end
-% \end{macrocode}
-%
% \subsubsection{Error, warning and info function for modules}
%
-% Here are the reporting functions for the modules. For errors, Lua's
-% |error()| is used. For now, the error reports look less good than with
-% \tex's |\errmessage|, but hopefully it will be improved in future
-% versions of \luatex.\footnote{Actually, \luatex 0.61 and higher provides
-% |tex.error| but it's less usefull, since only the current line in the
-% TeX file is reported.} We could invoke |\errmessage| using |tex.sprint()|,
-% but it may cause problems on the \tex end,\footnote{Eg, it will not work
-% inside an \cs{edef}.} and moreover |error()| will still be used by Lua
-% for other errors, so it makes messages more consistent.
-%
-% An internal function is used for error messages, so that the calling
-% level (last argument of |error()| remains constant using either
-% |module_error()| or a custom version as return by |errwarinf()|.
+% Here are the reporting functions for the modules. An internal function is
+% used for error messages, so that the calling level (last argument of
+% |error()| remains constant using either |module_error()| or a custom
+% version as return by |errwarinf()|.
%
% \begin{macrocode}
local function msg_format(msg_type, mod_name, ...)
@@ -536,7 +507,7 @@ function module_error(mod, ...)
end
% \end{macrocode}
%
-% Split the lines explicitely in order not to depend on the value of
+% Split the lines explicitly in order not to depend on the value of
% |\newlinechar|.
%
% \begin{macrocode}
@@ -571,80 +542,37 @@ local err, warn = errwarinf('luatexbase.modutils')
%
% \subsubsection{module loading and providing functions}
%
-% Load a module without version checking.
+% Load a module with mandatory name checking and optional version checking.
%
% \begin{macrocode}
-local function use_module(name)
+function require_module(name, req_date)
require(name)
- if not modules[name] then
- warn("Module didn't properly identified itself: %s", name)
- end
-end
-% \end{macrocode}
-%
-% Load a module with optional version checking.
-%
-% \begin{macrocode}
-function require_module(name, version)
- if not version then
- use_module(name)
- return
- end
- luaversion = parse_version(version)
- if modules[name] then
- if luaversion.type == date then
- if datetonumber(modules[name].date) < luaversion.version then
- err("found module `%s' loaded in version %s, "
- .."but version %s was required",
- name, modules[name].date, version)
- end
- else
- if modules[name].version < luaversion.version then
- err("found module `%s' loaded in version %.02f, "
- .."but version %s was required",
- name, modules[name].version, version)
- end
+ local info = modules[name]
+ if not info then
+ warn("module '%s' was not properly identified", name)
+ elseif version then
+ if not (info.date and date_to_int(info.date) > date_to_int(req_date))
+ then
+ warn("module '%s' required in version '%s'\n"
+ .. "but found in version '%s'", name, req_date, info.date)
end
- else
- requiredversions[name] = luaversion
- use_module(name)
end
end
% \end{macrocode}
%
% Provide identification information for a module. As a bonus, custom
-% reporting functions are returned.
+% reporting functions are returned. No need to do any check here,
+% everything done in |require_module()|.
%
% \begin{macrocode}
-function provides_module(mod)
- if not mod then
- err('cannot provide nil module')
- return
- end
- if not mod.version or not mod.name or not mod.date
- or not mod.description then
- err("invalid module registered: "
- .."fields name, version, date and description are mandatory")
- return
- end
- requiredversion = requiredversions[mod.name]
- if requiredversion then
- if requiredversion.type == date
- and requiredversion.version > datetonumber(mod.date) then
- err("loading module %s in version %s, "
- .."but version %s was required",
- mod.name, mod.date, requiredversion.orig)
- elseif requiredversion.type == number
- and requiredversion.version > mod.version then
- err("loading module %s in version %.02f, "
- .."but version %s was required",
- mod.name, mod.version, requiredversion.orig)
- end
+function provides_module(info)
+ if not (info and info.name) then
+ err('provides_module: missing information')
end
- modules[mod.name] = mod
- texio.write_nl('log', string.format("Lua module: %s %s v%.02f %s\n",
- mod.name, mod.date, mod.version, mod.description))
- return errwarinf(mod.name)
+ texio.write_nl('log', string.format("Lua module: %s %s %s %s\n",
+ info.name, info.date or '', info.version or '', info.description or ''))
+ modules[info.name] = info
+ return errwarinf(info.name)
end
% \end{macrocode}
%
@@ -669,8 +597,7 @@ info('It works!\nOh, rly?\nYeah rly!')
% \end{macrocode}
%
% We just check that the package loads properly, under both LaTeX and Plain
-% TeX. Anyway, the test files of other modules using this one already are a
-% test\dots
+% TeX, is able to load and identify the above dummy module.
%
% \begin{macrocode}
%<testplain>\input luatexbase-modutils.sty