2 -- Copyright (C) 2008-2009 Matthew Wild
3 -- Copyright (C) 2008-2009 Waqas Hussain
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
8 -- Based on Kepler Compat-5.1 code
9 -- Copyright Kepler Project 2004-2006 (http://www.keplerproject.org/compat)
10 -- $Id: compat-5.1.lua,v 1.22 2006/02/20 21:12:47 carregal Exp $
13 local LUA_DIRSEP = '/'
15 local OLD_LUA_OFSEP = ''
16 local POF = 'luaopen_'
17 local LUA_PATH_MARK = '?'
18 local LUA_IGMARK = ':'
20 local assert, error, getfenv, ipairs, loadfile, loadlib, pairs, setfenv, setmetatable, type = assert, error, getfenv, ipairs, loadfile, loadlib, pairs, setfenv, setmetatable, type
21 local find, format, gfind, gsub, sub = string.find, string.format, string.gfind, string.gsub, string.sub
23 if package.nonglobal_module then return; end
24 package.nonglobal_module = true;
26 local _PACKAGE = package
27 local _LOADED = package.loaded
28 local _PRELOAD = package.preload
31 -- looks for a file `name' in given path
33 local function findfile (name, pname)
34 name = gsub (name, "%.", LUA_DIRSEP)
35 local path = _PACKAGE[pname]
36 assert (type(path) == "string", format ("package.%s must be a string", pname))
37 for c in gfind (path, "[^;]+") do
38 c = gsub (c, "%"..LUA_PATH_MARK, name)
45 return nil -- not found
50 -- check whether library is already loaded
52 local function loader_preload (name)
53 assert (type(name) == "string", format (
54 "bad argument #1 to `require' (string expected, got %s)", type(name)))
55 assert (type(_PRELOAD) == "table", "`package.preload' must be a table")
63 local function loader_Lua (name)
64 assert (type(name) == "string", format (
65 "bad argument #1 to `require' (string expected, got %s)", type(name)))
66 local filename = findfile (name, "path")
70 local f, err = loadfile (filename)
72 error (format ("error loading module `%s' (%s)", name, err))
78 local function mkfuncname (name)
79 name = gsub (name, "^.*%"..LUA_IGMARK, "")
80 name = gsub (name, "%.", LUA_OFSEP)
84 local function old_mkfuncname (name)
85 --name = gsub (name, "^.*%"..LUA_IGMARK, "")
86 name = gsub (name, "%.", OLD_LUA_OFSEP)
93 local function loader_C (name)
94 assert (type(name) == "string", format (
95 "bad argument #1 to `require' (string expected, got %s)", type(name)))
96 local filename = findfile (name, "cpath")
100 local funcname = mkfuncname (name)
101 local f, err = loadlib (filename, funcname)
103 funcname = old_mkfuncname (name)
104 f, err = loadlib (filename, funcname)
106 error (format ("error loading module `%s' (%s)", name, err))
113 local function loader_Croot (name)
114 local p = gsub (name, "^([^.]*).-$", "%1")
118 local filename = findfile (p, "cpath")
122 local funcname = mkfuncname (name)
123 local f, err, where = loadlib (filename, funcname)
126 elseif where ~= "init" then
127 error (format ("error loading module `%s' (%s)", name, err))
131 -- create `loaders' table
132 package.loaders = package.loaders or { loader_preload, loader_Lua, loader_C, loader_Croot, }
133 local _LOADERS = package.loaders
137 -- iterate over available loaders
139 local function load (name, loaders)
140 -- iterate over available loaders
141 assert (type (loaders) == "table", "`package.loaders' must be a table")
142 for i, loader in ipairs (loaders) do
143 local f = loader (name)
148 error (format ("module `%s' not found", name))
152 local sentinel = function () end
154 local old_require = _G.require;
156 local current_env = nil;
157 function _G.require(modname)
158 --table.insert(dep_path, modname);
159 --if getfenv(2) == getfenv(0) --[[and rawget(_G, "__locked")]] then
160 -- print("**** Uh-oh, require called from locked global env at "..table.concat(dep_path, "->"), debug.traceback());
162 if not current_env and rawget(_G, "__locked") then
163 _G.prosody.unlock_globals();
166 local old_current_env;
167 old_current_env, current_env = current_env, getfenv(2);
168 local ok, ret = pcall(old_require, modname);
169 current_env = old_current_env;
170 if not current_env and rawget(_G, "__locked") == false then
171 _G.prosody.lock_globals();
173 --table.remove(dep_path);
174 if not ok then error(ret, 0); end
180 local function findtable (t, f)
181 assert (type(f)=="string", "not a valid field name ("..tostring(f)..")")
183 local ok, e, w = find (ff, '(.-)%.', 1)
185 local nt = rawget (t, w)
189 elseif type(t) ~= "table" then
193 ok, e, w = find (ff, '(.-)%.', e+1)
199 -- new package.seeall function
201 function _PACKAGE.seeall (module)
202 local t = type(module)
203 assert (t == "table", "bad argument #1 to package.seeall (table expected, got "..t..")")
204 local meta = getmetatable (module)
207 setmetatable (module, meta)
214 -- new module function
216 function _G.module (modname, ...)
217 local ns = _LOADED[modname];
218 if type(ns) ~= "table" then
219 --if not current_env then
220 -- print("module outside require for "..modname.." at "..debug.traceback());
222 ns = findtable (current_env or getfenv(2), modname);
224 error (string.format ("name conflict for module '%s'", modname))
226 _LOADED[modname] = ns
231 ns._PACKAGE = gsub (modname, "[^.]*$", "")
234 for i, f in ipairs (arg) do