efl/src/scripts/elua/core/module.lua

127 lines
3.2 KiB
Lua

-- elua module system
local M = {}
local cutil = select(2, ...)
local preload = {
ffi = package.preload["ffi"],
cutil = function() return cutil end
}
local loaded = {
}
M.loaded = loaded
M.preload = preload
for k, v in pairs(package.loaded) do loaded[k] = v end
M.path = "./?.lua;./?/init.lua"
M.cpath = ""
M.apath = "./?.lua"
local loadlib = package.loadlib
local cloader_load = function(soname, modname)
local hyp = modname:find("%-")
if hyp then modname = modname:sub(hyp + 1) end
local f, err = loadlib(soname, "luaopen_" .. (modname:gsub("%.", "_")))
if not f then
error("error loading module '" .. modname .. "' from file '"
.. fname .. "':\n" .. err, 3)
end
return f
end
local loaders = {
function(modname)
local v = preload[modname]
if not v then
return ("\no field preload['%s']"):format(modname)
end
return v
end,
function(modname)
local fname, err = package.searchpath(modname, M.path)
if not fname then return err end
local f, err = loadfile(fname)
if not f then
error("error loading module '" .. modname .. "' from file '"
.. fname .. "':\n" .. err, 2)
end
return f
end,
function(modname)
local fname, err = package.searchpath(modname, M.cpath)
if not fname then return err end
local hyp = modname:find("%-")
if hyp then modname = modname:sub(hyp + 1) end
return cloader_load(fname, modname)
end,
function(modname)
local rootname, dot = modname, modname:find("%.")
if dot then
rootname = rootname:sub(dot + 1)
end
local fname, err = package.searchpath(rootname, M.cpath)
if not fname then return err end
return cloader_load(fname, modname)
end
}
M.loaders = loaders
local find_loader = function(modname, env)
env = env or _G
local err = { ("module '%s' not found\n"):format(modname) }
for i = 1, #loaders do
local v = loaders[i](modname)
if type(v) == "function" then
local status, ret = pcall(function() return setfenv(v, env) end)
return status and ret or v
elseif type(v) == "string" then
err[#err + 1] = v
end
end
return nil, table.concat(err)
end
M.require = function(modname, ...)
local v = loaded[modname]
if v ~= nil then return v end
local loader, err = find_loader(modname)
if not loader then error(err, 2) end
local ret = loader(modname, ...)
if ret ~= nil then
loaded[modname] = ret
return ret
elseif loaded[modname] == nil then
loaded[modname] = true
return true
end
return loaded[modname]
end
M.load_app = function(appname)
local fname, err = package.searchpath(appname, M.apath)
if not fname then return nil, err end
local f, err = loadfile(fname)
if not f then return nil, err end
return f
end
M.preload = preload
M.loaded = loaded
-- register require
M.path, M.apath = (...)(M.require, M.load_app, M.path, M.apath)
M.config = package.config
M.searchpath = package.searchpath
M.loadlib = package.loadlib
_G["require"] = M.require
_G["package"] = M
return M