summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--lualibs-basic.lua1
-rw-r--r--lualibs-file.lua18
-rw-r--r--lualibs-lua.lua256
-rw-r--r--lualibs-package.lua338
5 files changed, 354 insertions, 261 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1fcf771
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,2 @@
+testing/*
+*-merged.lua
diff --git a/lualibs-basic.lua b/lualibs-basic.lua
index 883ae5f..cf8d6ea 100644
--- a/lualibs-basic.lua
+++ b/lualibs-basic.lua
@@ -31,6 +31,7 @@ end
if loaded == false then
loadmodule("lualibs-lua.lua")
+ loadmodule("lualibs-package.lua")
loadmodule("lualibs-lpeg.lua")
loadmodule("lualibs-function.lua")
loadmodule("lualibs-string.lua")
diff --git a/lualibs-file.lua b/lualibs-file.lua
index af86f93..29416ca 100644
--- a/lualibs-file.lua
+++ b/lualibs-file.lua
@@ -62,7 +62,7 @@ elseif not lfs.isfile then
end
local insert, concat = table.insert, table.concat
-local match = string.match
+local match, find = string.match, string.find
local lpegmatch = lpeg.match
local getcurrentdir, attributes = lfs.currentdir, lfs.attributes
local checkedsplit = string.checkedsplit
@@ -410,11 +410,11 @@ local untouched = periods + (1-period)^1 * P(-1)
local splitstarter = (Cs(drivespec * (bwslash/"/" + fwslash)^0) + Cc(false)) * Ct(lpeg.splitat(S("/\\")^1))
local absolute = fwslash
-function file.collapsepath(str,anchor)
+function file.collapsepath(str,anchor) -- anchor: false|nil, true, "."
if not str then
return
end
- if anchor and not lpegmatch(anchors,str) then
+ if anchor == true and not lpegmatch(anchors,str) then
str = getcurrentdir() .. "/" .. str
end
if str == "" or str =="." then
@@ -455,12 +455,17 @@ function file.collapsepath(str,anchor)
elseif lpegmatch(absolute,str) then
return "/" .. concat(newelements,'/')
else
- return concat(newelements, '/')
+ newelements = concat(newelements, '/')
+ if anchor == "." and find(str,"^%./") then
+ return "./" .. newelements
+ else
+ return newelements
+ end
end
end
--- local function test(str)
--- print(string.format("%-20s %-15s %-15s",str,file.collapsepath(str),file.collapsepath(str,true)))
+-- local function test(str,...)
+-- print(string.format("%-20s %-15s %-30s %-20s",str,file.collapsepath(str),file.collapsepath(str,true),file.collapsepath(str,".")))
-- end
-- test("a/b.c/d") test("b.c/d") test("b.c/..")
-- test("/") test("c:/..") test("sys://..")
@@ -468,6 +473,7 @@ end
-- test("a") test("./a") test("/a") test("a/../..")
-- test("a/./b/..") test("a/aa/../b/bb") test("a/.././././b/..") test("a/./././b/..")
-- test("a/b/c/../..") test("./a/b/c/../..") test("a/b/c/../..")
+-- test("./a")
local validchars = R("az","09","AZ","--","..")
local pattern_a = lpeg.replacer(1-validchars)
diff --git a/lualibs-lua.lua b/lualibs-lua.lua
index 5181640..fc05afa 100644
--- a/lualibs-lua.lua
+++ b/lualibs-lua.lua
@@ -6,7 +6,7 @@ if not modules then modules = { } end modules ['l-lua'] = {
license = "see context related readme files"
}
--- compatibility hacks ... try to avoid usage
+-- compatibility hacksand helpers
local major, minor = string.match(_VERSION,"^[^%d]+(%d+)%.(%d+).*$")
@@ -148,257 +148,3 @@ function optionalrequire(...)
return result
end
end
-
--- Code moved from data-lua and changed into a plug-in.
-
--- 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 type = type
-local gsub, format = string.gsub, string.format
-
-local package = package
-local searchers = package.searchers or package.loaders
-
-local libpaths = nil
-local clibpaths = nil
-local libhash = { }
-local clibhash = { }
-local libextras = { }
-local clibextras = { }
-
--- dummies
-
-local filejoin = file and file.join or function(path,name) return path .. "/" .. name end
-local isreadable = file and file.is_readable or function(name) local f = io.open(name) if f then f:close() return true end end
-local addsuffix = file and file.addsuffix or function(name,suffix) return name .. "." .. suffix end
-
---
-
-local function cleanpath(path) -- hm, don't we have a helper for this?
- return path
-end
-
-local helpers = package.helpers or {
- libpaths = function() return { } end,
- clibpaths = function() return { } end,
- cleanpath = cleanpath,
- trace = false,
- report = function(...) print(format(...)) end,
-}
-package.helpers = helpers
-
-local function getlibpaths()
- return libpaths or helpers.libpaths(libhash)
-end
-
-local function getclibpaths()
- return clibpaths or helpers.clibpaths(clibhash)
-end
-
-package.libpaths = getlibpaths
-package.clibpaths = getclibpaths
-
-local function addpath(what,paths,extras,hash,...)
- local pathlist = { ... }
- local cleanpath = helpers.cleanpath
- local trace = helpers.trace
- local report = helpers.report
- --
- local function add(path)
- local path = cleanpath(path)
- if not hash[path] then
- if trace then
- report("extra %s path: %s",what,path)
- end
- paths [#paths +1] = path
- extras[#extras+1] = path
- end
- end
- --
- for p=1,#pathlist do
- local path = pathlist[p]
- if type(path) == "table" then
- for i=1,#path do
- add(path[i])
- end
- else
- add(path)
- end
- end
- return paths, extras
-end
-
-function package.extralibpath(...)
- libpaths, libextras = addpath("lua", getlibpaths(), libextras, libhash,...)
-end
-
-function package.extraclibpath(...)
- clibpaths, clibextras = addpath("lib",getclibpaths(),clibextras,clibhash,...)
-end
-
--- function package.extralibpath(...)
--- libpaths = getlibpaths()
--- local pathlist = { ... }
--- local cleanpath = helpers.cleanpath
--- local trace = helpers.trace
--- local report = helpers.report
--- --
--- local function add(path)
--- local path = cleanpath(path)
--- if not libhash[path] then
--- if trace then
--- report("extra lua path: %s",path)
--- end
--- libextras[#libextras+1] = path
--- libpaths [#libpaths +1] = path
--- end
--- end
--- --
--- for p=1,#pathlist do
--- local path = pathlist[p]
--- if type(path) == "table" then
--- for i=1,#path do
--- add(path[i])
--- end
--- else
--- add(path)
--- end
--- end
--- end
-
--- function package.extraclibpath(...)
--- clibpaths = getclibpaths()
--- local pathlist = { ... }
--- local cleanpath = helpers.cleanpath
--- local trace = helpers.trace
--- local report = helpers.report
--- --
--- local function add(path)
--- local path = cleanpath(path)
--- if not clibhash[path] then
--- if trace then
--- report("extra lib path: %s",path)
--- end
--- clibextras[#clibextras+1] = path
--- clibpaths [#clibpaths +1] = path
--- end
--- end
--- --
--- for p=1,#pathlist do
--- local path = pathlist[p]
--- if type(path) == "table" then
--- for i=1,#path do
--- add(path[i])
--- end
--- else
--- add(path)
--- end
--- end
--- end
-
-if not searchers[-2] then
- -- use package-path and package-cpath
- searchers[-2] = searchers[2]
-end
-
-searchers[2] = function(name)
- return helpers.loaded(name)
-end
-
-searchers[3] = nil -- get rid of the built in one
-
-local function loadedaslib(resolved,rawname)
- -- local init = "luaopen_" .. string.match(rawname,".-([^%.]+)$")
- local init = "luaopen_"..gsub(rawname,"%.","_")
- if helpers.trace then
- helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
- end
- return package.loadlib(resolved,init)
-end
-
-local function loadedbylua(name)
- if helpers.trace then
- helpers.report("locating '%s' using normal loader",name)
- end
- return true, searchers[-2](name) -- the original
-end
-
-local function loadedbypath(name,rawname,paths,islib,what)
- local trace = helpers.trace
- local report = helpers.report
- if trace then
- report("locating '%s' as '%s' on '%s' paths",rawname,name,what)
- end
- for p=1,#paths do
- local path = paths[p]
- local resolved = filejoin(path,name)
- if trace then -- mode detail
- report("checking for '%s' using '%s' path '%s'",name,what,path)
- end
- if isreadable(resolved) then
- if trace then
- report("lib '%s' located on '%s'",name,resolved)
- end
- if islib then
- return true, loadedaslib(resolved,rawname)
- else
- return true, loadfile(resolved)
- end
- end
- end
-end
-
-local function notloaded(name)
- if helpers.trace then
- helpers.report("unable to locate library '%s'",name)
- end
-end
-
-helpers.loadedaslib = loadedaslib
-helpers.loadedbylua = loadedbylua
-helpers.loadedbypath = loadedbypath
-helpers.notloaded = notloaded
-
--- alternatively we could set the package.searchers
-
-function helpers.loaded(name)
- local thename = gsub(name,"%.","/")
- local luaname = addsuffix(thename,"lua")
- local libname = addsuffix(thename,os.libsuffix or "so") -- brrr
- local libpaths = getlibpaths()
- local clibpaths = getclibpaths()
- local done, result = loadedbypath(luaname,name,libpaths,false,"lua")
- if done then
- return result
- end
- local done, result = loadedbypath(luaname,name,clibpaths,false,"lua")
- if done then
- return result
- end
- local done, result = loadedbypath(libname,name,clibpaths,true,"lib")
- if done then
- return result
- end
- local done, result = loadedbylua(name)
- if done then
- return result
- end
- return notloaded(name)
-end
-
-function helpers.unload(name)
- if helpers.trace then
- if package.loaded[name] then
- helpers.report("unloading library '%s', %s",name,"done")
- else
- helpers.report("unloading library '%s', %s",name,"not loaded")
- end
- end
- package.loaded[name] = nil
-end
diff --git a/lualibs-package.lua b/lualibs-package.lua
new file mode 100644
index 0000000..7b82fa5
--- /dev/null
+++ b/lualibs-package.lua
@@ -0,0 +1,338 @@
+if not modules then modules = { } end modules ['l-package'] = {
+ version = 1.001,
+ comment = "companion to luat-lib.mkiv",
+ author = "Hans Hagen, PRAGMA-ADE, Hasselt NL",
+ copyright = "PRAGMA ADE / ConTeXt Development Team",
+ license = "see context related readme files"
+}
+
+-- Code moved from data-lua and changed into a plug-in.
+
+-- 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 type = type
+local gsub, format = string.gsub, string.format
+
+local P, S, Cs, lpegmatch = lpeg.P, lpeg.S, lpeg.Cs, lpeg.match
+
+local package = package
+local searchers = package.searchers or package.loaders
+
+-- dummies
+
+local filejoin = file and file.join or function(path,name) return path .. "/" .. name end
+local isreadable = file and file.is_readable or function(name) local f = io.open(name) if f then f:close() return true end end
+local addsuffix = file and file.addsuffix or function(name,suffix) return name .. "." .. suffix end
+
+--
+
+-- local separator, concatinator, placeholder, pathofexecutable, ignorebefore = string.match(package.config,"(.-)\n(.-)\n(.-)\n(.-)\n(.-)\n")
+--
+-- local config = {
+-- separator = separator, -- \ or /
+-- concatinator = concatinator, -- ;
+-- placeholder = placeholder, -- ? becomes name
+-- pathofexecutable = pathofexecutable, -- ! becomes executables dir (on windows)
+-- ignorebefore = ignorebefore, -- - remove all before this when making lua_open
+-- }
+
+--
+
+local function cleanpath(path) -- hm, don't we have a helper for this?
+ return path
+end
+
+local pattern = Cs((((1-S("\\/"))^0 * (S("\\/")^1/"/"))^0 * (P(".")^1/"/"+P(1))^1) * -1)
+
+local function lualibfile(name)
+ return lpegmatch(pattern,name) or name
+end
+
+local helpers = package.helpers or {
+ cleanpath = cleanpath,
+ lualibfile = lualibfile,
+ trace = false,
+ report = function(...) print(format(...)) end,
+ builtin = {
+ ["preload table"] = searchers[1], -- special case, built-in libs
+ ["path specification"] = searchers[2],
+ ["cpath specification"] = searchers[3],
+ ["all in one fallback"] = searchers[4], -- special case, combined libs
+ },
+ methods = {
+ },
+ sequence = {
+ "already loaded",
+ "preload table",
+ "lua extra list",
+ "lib extra list",
+ "path specification",
+ "cpath specification",
+ "all in one fallback",
+ "not loaded",
+ }
+}
+
+package.helpers = helpers
+
+local methods = helpers.methods
+local builtin = helpers.builtin
+
+-- extra tds/ctx paths
+
+local extraluapaths = { }
+local extralibpaths = { }
+local luapaths = nil -- delayed
+local libpaths = nil -- delayed
+
+local function getextraluapaths()
+ return extraluapaths
+end
+
+local function getextralibpaths()
+ return extralibpaths
+end
+
+local function getluapaths()
+ luapaths = luapaths or file.splitpath(package.path, ";")
+ return luapaths
+end
+
+local function getlibpaths()
+ libpaths = libpaths or file.splitpath(package.cpath, ";")
+ return libpaths
+end
+
+package.luapaths = getluapaths
+package.libpaths = getlibpaths
+package.extraluapaths = getextraluapaths
+package.extralibpaths = getextralibpaths
+
+local hashes = {
+ lua = { },
+ lib = { },
+}
+
+local function registerpath(tag,what,target,...)
+ local pathlist = { ... }
+ local cleanpath = helpers.cleanpath
+ local trace = helpers.trace
+ local report = helpers.report
+ local hash = hashes[what]
+ --
+ local function add(path)
+ local path = cleanpath(path)
+ if not hash[path] then
+ target[#target+1] = path
+ hash[path] = true
+ if trace then
+ report("registered %s path %s: %s",tag,#target,path)
+ end
+ else
+ if trace then
+ report("duplicate %s path: %s",tag,path)
+ end
+ end
+ end
+ --
+ for p=1,#pathlist do
+ local path = pathlist[p]
+ if type(path) == "table" then
+ for i=1,#path do
+ add(path[i])
+ end
+ else
+ add(path)
+ end
+ end
+ return paths
+end
+
+helpers.registerpath = registerpath
+
+function package.extraluapath(...)
+ registerpath("extra lua","lua",extraluapaths,...)
+end
+
+function package.extralibpath(...)
+ registerpath("extra lib","lib",extralibpaths,...)
+end
+
+-- lib loader (used elsewhere)
+
+local function loadedaslib(resolved,rawname) -- todo: strip all before first -
+ -- local init = "luaopen_" .. string.match(rawname,".-([^%.]+)$")
+ local init = "luaopen_"..gsub(rawname,"%.","_")
+ if helpers.trace then
+ helpers.report("calling loadlib with '%s' with init '%s'",resolved,init)
+ end
+ return package.loadlib(resolved,init)
+end
+
+helpers.loadedaslib = loadedaslib
+
+-- wrapped and new loaders
+
+local function loadedbypath(name,rawname,paths,islib,what)
+ local trace = helpers.trace
+ local report = helpers.report
+ if trace then
+ report("locating '%s' as '%s' on '%s' paths",rawname,name,what)
+ end
+ for p=1,#paths do
+ local path = paths[p]
+ local resolved = filejoin(path,name)
+ if trace then -- mode detail
+ report("checking '%s' using '%s' path '%s'",name,what,path)
+ end
+ if isreadable(resolved) then
+ if trace then
+ report("'%s' located on '%s'",name,resolved)
+ end
+ local result = nil
+ if islib then
+ result = loadedaslib(resolved,rawname)
+ else
+ result = loadfile(resolved)
+ end
+ if result then
+ result()
+ end
+ return true, result
+ end
+ end
+end
+
+helpers.loadedbypath = loadedbypath
+
+-- alternatively we could set the package.searchers
+
+methods["already loaded"] = function(name)
+ local result = package.loaded[name]
+ if result then
+ return true, result
+ end
+end
+
+methods["preload table"] = function(name)
+ local result = builtin["preload table"](name)
+ if type(result) == "function" then
+ return true, result
+ end
+end
+
+methods["lua extra list"] = function(name)
+ local thename = lualibfile(name)
+ local luaname = addsuffix(thename,"lua")
+ local luapaths = getextraluapaths()
+ local done, result = loadedbypath(luaname,name,luapaths,false,"lua")
+ if done then
+ return true, result
+ end
+end
+
+methods["lib extra list"] = function(name)
+ local thename = lualibfile(name)
+ local libname = addsuffix(thename,os.libsuffix)
+ local libpaths = getextralibpaths()
+ local done, result = loadedbypath(libname,name,libpaths,true,"lib")
+ if done then
+ return true, result
+ end
+end
+
+local shown = false
+
+methods["path specification"] = function(name)
+ if not shown and helpers.trace then
+ local luapaths = getluapaths() -- triggers list building
+ if #luapaths > 0 then
+ helpers.report("using %s built in lua paths",#luapaths)
+ else
+ helpers.report("no built in lua paths defined")
+ end
+ shown = true
+ end
+ local result = builtin["path specification"](name)
+ if type(result) == "function" then
+ return true, result()
+ end
+end
+
+local shown = false
+
+methods["cpath specification"] = function(name)
+ if not shown and helpers.trace then
+ local libpaths = getlibpaths() -- triggers list building
+ if #libpaths > 0 then
+ helpers.report("using %s built in lib paths",#libpaths)
+ else
+ helpers.report("no built in lib paths defined")
+ end
+ shown = true
+ end
+ local result = builtin["cpath specification"](name)
+ if type(result) == "function" then
+ return true, result()
+ end
+end
+
+methods["all in one fallback"] = function(name)
+ local result = builtin["all in one fallback"](name)
+ if type(result) == "function" then
+ return true, result()
+ end
+end
+
+methods["not loaded"] = function(name)
+ if helpers.trace then
+ helpers.report("unable to locate '%s'",name)
+ end
+end
+
+function helpers.loaded(name)
+ local sequence = helpers.sequence
+ for i=1,#sequence do
+ local step = sequence[i]
+ if helpers.trace then
+ helpers.report("locating '%s' using method '%s'",name,step)
+ end
+ local done, result = methods[step](name)
+ if done then
+ if helpers.trace then
+ helpers.report("'%s' located via method '%s' returns '%s'",name,step,type(result))
+ end
+ if result then
+ package.loaded[name] = result
+ end
+ return result
+ end
+ end
+ return nil -- we must return a value
+end
+
+function helpers.unload(name)
+ if helpers.trace then
+ if package.loaded[name] then
+ helpers.report("unloading '%s', %s",name,"done")
+ else
+ helpers.report("unloading '%s', %s",name,"not loaded")
+ end
+ end
+ package.loaded[name] = nil -- does that work? is readable only, maybe we need our own hash
+end
+
+searchers[1] = nil
+searchers[2] = nil
+searchers[3] = nil
+searchers[4] = nil
+
+helpers.savedrequire = helpers.savedrequire or require
+
+require = helpers.loaded