summaryrefslogtreecommitdiff
path: root/tex/context/base/data-lua.lua
diff options
context:
space:
mode:
Diffstat (limited to 'tex/context/base/data-lua.lua')
-rw-r--r--tex/context/base/data-lua.lua263
1 files changed, 146 insertions, 117 deletions
diff --git a/tex/context/base/data-lua.lua b/tex/context/base/data-lua.lua
index 906a611ee..fec5856ea 100644
--- a/tex/context/base/data-lua.lua
+++ b/tex/context/base/data-lua.lua
@@ -6,167 +6,196 @@ if not modules then modules = { } end modules ['data-lua'] = {
license = "see context related readme files"
}
--- some loading stuff ... we might move this one to slot 2 depending
--- on the developments (the loaders must not trigger kpse); we could
--- of course use a more extensive lib path spec
+-- We overload the regular loader. We do so because we operate mostly in
+-- tds and use our own loader code. Alternatively we could use a more
+-- extensive definition of package.path and package.cpath but even then
+-- we're not done. Also, we now have better tracing.
+--
+-- -- local mylib = require("libtest")
+-- -- local mysql = require("luasql.mysql")
-local trace_locating = false trackers.register("resolvers.locating", function(v) trace_locating = v end)
+local concat = table.concat
+
+local trace_libraries = false
+
+trackers.register("resolvers.libraries", function(v) trace_libraries = v end)
+trackers.register("resolvers.locating", function(v) trace_libraries = v end)
local report_libraries = logs.reporter("resolvers","libraries")
local gsub, insert = string.gsub, table.insert
+local P, Cs, lpegmatch = lpeg.P, lpeg.Cs, lpeg.match
local unpack = unpack or table.unpack
+local is_readable = file.is_readable
local resolvers, package = resolvers, package
-local libformats = { 'luatexlibs', 'tex', 'texmfscripts', 'othertextfiles' } -- 'luainputs'
-local clibformats = { 'lib' }
+local libsuffixes = { 'tex', 'lua' }
+local clibsuffixes = { 'lib' }
+local libformats = { 'TEXINPUTS', 'LUAINPUTS' }
+local clibformats = { 'CLUAINPUTS' }
+
+local libpaths = nil
+local clibpaths = nil
+local libhash = { }
+local clibhash = { }
+local libextras = { }
+local clibextras = { }
-local _path_, libpaths, _cpath_, clibpaths
+local pattern = Cs(P("!")^0 / "" * (P("/") * P(-1) / "/" + P("/")^1 / "/" + 1)^0)
-function package.libpaths()
- if not _path_ or package.path ~= _path_ then
- _path_ = package.path
- libpaths = file.splitpath(_path_,";")
+local function cleanpath(path) --hm, don't we have a helper for this?
+ return resolvers.resolve(lpegmatch(pattern,path))
+end
+
+local function getlibpaths()
+ if not libpaths then
+ libpaths = { }
+ for i=1,#libformats do
+ local paths = resolvers.expandedpathlistfromvariable(libformats[i])
+ for i=1,#paths do
+ local path = cleanpath(paths[i])
+ if not libhash[path] then
+ libpaths[#libpaths+1] = path
+ libhash[path] = true
+ end
+ end
+ end
end
return libpaths
end
-function package.clibpaths()
- if not _cpath_ or package.cpath ~= _cpath_ then
- _cpath_ = package.cpath
- clibpaths = file.splitpath(_cpath_,";")
+local function getclibpaths()
+ if not clibpaths then
+ clibpaths = { }
+ for i=1,#clibformats do
+ local paths = resolvers.expandedpathlistfromvariable(clibformats[i])
+ for i=1,#paths do
+ local path = cleanpath(paths[i])
+ if not clibhash[path] then
+ clibpaths[#clibpaths+1] = path
+ clibhash[path] = true
+ end
+ end
+ end
end
return clibpaths
end
-local function thepath(...)
- local t = { ... } t[#t+1] = "?.lua"
- local path = file.join(unpack(t))
- if trace_locating then
- report_libraries("! appending '%s' to 'package.path'",path)
+package.libpaths = getlibpaths
+package.clibpaths = getclibpaths
+
+function package.extralibpath(...)
+ local paths = { ... }
+ for i=1,#paths do
+ local path = cleanpath(paths[i])
+ if not libhash[path] then
+ if trace_libraries then
+ report_libraries("! extra lua path '%s'",path)
+ end
+ libextras[#libextras+1] = path
+ libpaths[#libpaths +1] = path
+ end
end
- return path
end
-local p_libpaths, a_libpaths = { }, { }
-
-function package.appendtolibpath(...)
- insert(a_libpath,thepath(...))
+function package.extraclibpath(...)
+ local paths = { ... }
+ for i=1,#paths do
+ local path = cleanpath(paths[i])
+ if not clibhash[path] then
+ if trace_libraries then
+ report_libraries("! extra lib path '%s'",path)
+ end
+ clibextras[#clibextras+1] = path
+ clibpaths[#clibpaths +1] = path
+ end
+ end
end
-function package.prependtolibpath(...)
- insert(p_libpaths,1,thepath(...))
+if not package.loaders[-2] then
+ -- use package-path and package-cpath
+ package.loaders[-2] = package.loaders[2]
end
--- beware, we need to return a loadfile result !
+local function loadedaslib(resolved,rawname)
+ return package.loadlib(resolved,"luaopen_" .. gsub(rawname,"%.","_"))
+end
-local function loaded(libpaths,name,simple)
- for i=1,#libpaths do -- package.path, might become option
- local libpath = libpaths[i]
- local resolved = gsub(libpath,"%?",simple)
- if trace_locating then -- more detail
- report_libraries("! checking for '%s' on 'package.path': '%s' => '%s'",simple,libpath,resolved)
- end
- if file.is_readable(resolved) then
- if trace_locating then
- report_libraries("! lib '%s' located via 'package.path': '%s'",name,resolved)
- end
- return loadfile(resolved)
- end
+local function loadedbylua(name)
+ if trace_libraries then
+ report_libraries("! locating %q using normal loader",name)
end
+ local resolved = package.loaders[-2](name)
end
-package.loaders[2] = function(name) -- was [#package.loaders+1]
- if file.suffix(name) == "" then
- name = file.addsuffix(name,"lua") -- maybe a list
- if trace_locating then -- mode detail
- report_libraries("! locating '%s' with forced suffix",name)
- end
- else
- if trace_locating then -- mode detail
- report_libraries("! locating '%s'",name)
- end
+local function loadedbyformat(name,rawname,suffixes,islib)
+ if trace_libraries then
+ report_libraries("! locating %q as %q using formats %q",rawname,name,concat(suffixes))
end
- for i=1,#libformats do
- local format = libformats[i]
+ for i=1,#suffixes do -- so we use findfile and not a lookup loop
+ local format = suffixes[i]
local resolved = resolvers.findfile(name,format) or ""
- if trace_locating then -- mode detail
- report_libraries("! checking for '%s' using 'libformat path': '%s'",name,format)
+ if trace_libraries then
+ report_libraries("! checking for %q' using format %q",name,format)
end
if resolved ~= "" then
- if trace_locating then
- report_libraries("! lib '%s' located via environment: '%s'",name,resolved)
+ if trace_libraries then
+ report_libraries("! lib %q located on %q",name,resolved)
end
- return loadfile(resolved)
- end
- end
- -- libpaths
- local libpaths, clibpaths = package.libpaths(), package.clibpaths()
- local simple = gsub(name,"%.lua$","")
- local simple = gsub(simple,"%.","/")
- local resolved = loaded(p_libpaths,name,simple) or loaded(libpaths,name,simple) or loaded(a_libpaths,name,simple)
- if resolved then
- return resolved
- end
- --
- local libname = file.addsuffix(simple,os.libsuffix)
- for i=1,#clibformats do
- -- better have a dedicated loop
- local format = clibformats[i]
- local paths = resolvers.expandedpathlistfromvariable(format)
- for p=1,#paths do
- local path = paths[p]
- local resolved = file.join(path,libname)
- if trace_locating then -- mode detail
- report_libraries("! checking for '%s' using 'clibformat path': '%s'",libname,path)
- end
- if file.is_readable(resolved) then
- if trace_locating then
- report_libraries("! lib '%s' located via 'clibformat': '%s'",libname,resolved)
- end
- return package.loadlib(resolved,name)
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
end
end
end
- for i=1,#clibpaths do -- package.path, might become option
- local libpath = clibpaths[i]
- local resolved = gsub(libpath,"?",simple)
- if trace_locating then -- more detail
- report_libraries("! checking for '%s' on 'package.cpath': '%s'",simple,libpath)
+end
+
+local function loadedbypath(name,rawname,paths,islib,what)
+ if trace_libraries then
+ report_libraries("! locating %q as %q on %q paths",rawname,name,what)
+ end
+ for p=1,#paths do
+ local path = paths[p]
+ local resolved = file.join(path,name)
+ if trace_libraries then -- mode detail
+ report_libraries("! checking for %q using %q path %q",name,what,path)
end
- if file.is_readable(resolved) then
- if trace_locating then
- report_libraries("! lib '%s' located via 'package.cpath': '%s'",name,resolved)
+ if is_readable(resolved) then
+ if trace_libraries then
+ report_libraries("! lib %q located on %q",name,resolved)
+ end
+ if islib then
+ return loadedaslib(resolved,rawname)
+ else
+ return loadfile(resolved)
end
- return package.loadlib(resolved,name)
- end
- end
- -- just in case the distribution is messed up
- if trace_loading then -- more detail
- report_libraries("! checking for '%s' using 'luatexlibs': '%s'",name)
- end
- local resolved = resolvers.findfile(file.basename(name),'luatexlibs') or ""
- if resolved ~= "" then
- if trace_locating then
- report_libraries("! lib '%s' located by basename via environment: '%s'",name,resolved)
end
- return loadfile(resolved)
end
- if trace_locating then
- report_libraries('? unable to locate lib: %s',name)
- end
--- return "unable to locate " .. name
end
-resolvers.loadlualib = require
-
--- -- -- --
+local function notloaded(name)
+ if trace_libraries then
+ report_libraries("? unable to locate library %q",name)
+ end
+end
-package.obsolete = package.obsolete or { }
+package.loaders[2] = function(name)
+ local thename = gsub(name,"%.","/")
+ local luaname = file.addsuffix(thename,"lua")
+ local libname = file.addsuffix(thename,os.libsuffix)
+ return
+ loadedbyformat(luaname,name,libsuffixes, false)
+ or loadedbyformat(libname,name,clibsuffixes, true)
+ or loadedbypath (luaname,name,getlibpaths (),false,"lua")
+ or loadedbypath (luaname,name,getclibpaths(),false,"lua")
+ or loadedbypath (libname,name,getclibpaths(),true, "lib")
+ or loadedbylua (name)
+ or notloaded (name)
+end
-package.append_libpath = appendtolibpath -- will become obsolete
-package.prepend_libpath = prependtolibpath -- will become obsolete
+-- package.loaders[3] = nil
+-- package.loaders[4] = nil
-package.obsolete.append_libpath = appendtolibpath -- will become obsolete
-package.obsolete.prepend_libpath = prependtolibpath -- will become obsolete
+resolvers.loadlualib = require