0938d56a7723aff450d9aecc573e1029dbdbbcc3
[rrdtool.git] / bindings / lua / compat-5.1r5 / compat-5.1.lua
1 --
2 -- Compat-5.1
3 -- Copyright Kepler Project 2004-2006 (http://www.keplerproject.org/compat)
4 -- According to Lua 5.1
5 -- $Id: compat-5.1.lua,v 1.22 2006/02/20 21:12:47 carregal Exp $
6 --
7
8 _COMPAT51 = "Compat-5.1 R5"
9
10 local LUA_DIRSEP = '/'
11 local LUA_OFSEP = '_'
12 local OLD_LUA_OFSEP = ''
13 local POF = 'luaopen_'
14 local LUA_PATH_MARK = '?'
15 local LUA_IGMARK = ':'
16
17 local assert, error, getfenv, ipairs, loadfile, loadlib, pairs, setfenv, setmetatable, type = assert, error, getfenv, ipairs, loadfile, loadlib, pairs, setfenv, setmetatable, type
18 local find, format, gfind, gsub, sub = string.find, string.format, string.gfind, string.gsub, string.sub
19
20 --
21 -- avoid overwriting the package table if it's already there
22 --
23 package = package or {}
24 local _PACKAGE = package
25
26 package.path = LUA_PATH or os.getenv("LUA_PATH") or
27              ("./?.lua;" ..
28               "/usr/local/share/lua/5.0/?.lua;" ..
29               "/usr/local/share/lua/5.0/?/?.lua;" ..
30               "/usr/local/share/lua/5.0/?/init.lua" )
31  
32 package.cpath = LUA_CPATH or os.getenv("LUA_CPATH") or
33              "./?.so;" ..
34              "./l?.so;" ..
35              "/usr/local/lib/lua/5.0/?.so;" ..
36              "/usr/local/lib/lua/5.0/l?.so"
37
38 --
39 -- make sure require works with standard libraries
40 --
41 package.loaded = package.loaded or {}
42 package.loaded.debug = debug
43 package.loaded.string = string
44 package.loaded.math = math
45 package.loaded.io = io
46 package.loaded.os = os
47 package.loaded.table = table 
48 package.loaded.base = _G
49 package.loaded.coroutine = coroutine
50 local _LOADED = package.loaded
51
52 --
53 -- avoid overwriting the package.preload table if it's already there
54 --
55 package.preload = package.preload or {}
56 local _PRELOAD = package.preload
57
58
59 --
60 -- looks for a file `name' in given path
61 --
62 local function findfile (name, pname)
63         name = gsub (name, "%.", LUA_DIRSEP)
64         local path = _PACKAGE[pname]
65         assert (type(path) == "string", format ("package.%s must be a string", pname))
66         for c in gfind (path, "[^;]+") do
67                 c = gsub (c, "%"..LUA_PATH_MARK, name)
68                 local f = io.open (c)
69                 if f then
70                         f:close ()
71                         return c
72                 end
73         end
74         return nil -- not found
75 end
76
77
78 --
79 -- check whether library is already loaded
80 --
81 local function loader_preload (name)
82         assert (type(name) == "string", format (
83                 "bad argument #1 to `require' (string expected, got %s)", type(name)))
84         assert (type(_PRELOAD) == "table", "`package.preload' must be a table")
85         return _PRELOAD[name]
86 end
87
88
89 --
90 -- Lua library loader
91 --
92 local function loader_Lua (name)
93         assert (type(name) == "string", format (
94                 "bad argument #1 to `require' (string expected, got %s)", type(name)))
95         local filename = findfile (name, "path")
96         if not filename then
97                 return false
98         end
99         local f, err = loadfile (filename)
100         if not f then
101                 error (format ("error loading module `%s' (%s)", name, err))
102         end
103         return f
104 end
105
106
107 local function mkfuncname (name)
108         name = gsub (name, "^.*%"..LUA_IGMARK, "")
109         name = gsub (name, "%.", LUA_OFSEP)
110         return POF..name
111 end
112
113 local function old_mkfuncname (name)
114         --name = gsub (name, "^.*%"..LUA_IGMARK, "")
115         name = gsub (name, "%.", OLD_LUA_OFSEP)
116         return POF..name
117 end
118
119 --
120 -- C library loader
121 --
122 local function loader_C (name)
123         assert (type(name) == "string", format (
124                 "bad argument #1 to `require' (string expected, got %s)", type(name)))
125         local filename = findfile (name, "cpath")
126         if not filename then
127                 return false
128         end
129         local funcname = mkfuncname (name)
130         local f, err = loadlib (filename, funcname)
131         if not f then
132                 funcname = old_mkfuncname (name)
133                 f, err = loadlib (filename, funcname)
134                 if not f then
135                         error (format ("error loading module `%s' (%s)", name, err))
136                 end
137         end
138         return f
139 end
140
141
142 local function loader_Croot (name)
143         local p = gsub (name, "^([^.]*).-$", "%1")
144         if p == "" then
145                 return
146         end
147         local filename = findfile (p, "cpath")
148         if not filename then
149                 return
150         end
151         local funcname = mkfuncname (name)
152         local f, err, where = loadlib (filename, funcname)
153         if f then
154                 return f
155         elseif where ~= "init" then
156                 error (format ("error loading module `%s' (%s)", name, err))
157         end
158 end
159
160 -- create `loaders' table
161 package.loaders = package.loaders or { loader_preload, loader_Lua, loader_C, loader_Croot, }
162 local _LOADERS = package.loaders
163
164
165 --
166 -- iterate over available loaders
167 --
168 local function load (name, loaders)
169         -- iterate over available loaders
170         assert (type (loaders) == "table", "`package.loaders' must be a table")
171         for i, loader in ipairs (loaders) do
172                 local f = loader (name)
173                 if f then
174                         return f
175                 end
176         end
177         error (format ("module `%s' not found", name))
178 end
179
180 -- sentinel
181 local sentinel = function () end
182
183 --
184 -- new require
185 --
186 function _G.require (modname)
187         assert (type(modname) == "string", format (
188                 "bad argument #1 to `require' (string expected, got %s)", type(name)))
189         local p = _LOADED[modname]
190         if p then -- is it there?
191                 if p == sentinel then
192                         error (format ("loop or previous error loading module '%s'", modname))
193                 end
194                 return p -- package is already loaded
195         end
196         local init = load (modname, _LOADERS)
197         _LOADED[modname] = sentinel
198         local actual_arg = _G.arg
199         _G.arg = { modname }
200         local res = init (modname)
201         if res then
202                 _LOADED[modname] = res
203         end
204         _G.arg = actual_arg
205         if _LOADED[modname] == sentinel then
206                 _LOADED[modname] = true
207         end
208         return _LOADED[modname]
209 end
210
211
212 -- findtable
213 local function findtable (t, f)
214         assert (type(f)=="string", "not a valid field name ("..tostring(f)..")")
215         local ff = f.."."
216         local ok, e, w = find (ff, '(.-)%.', 1)
217         while ok do
218                 local nt = rawget (t, w)
219                 if not nt then
220                         nt = {}
221                         t[w] = nt
222                 elseif type(t) ~= "table" then
223                         return sub (f, e+1)
224                 end
225                 t = nt
226                 ok, e, w = find (ff, '(.-)%.', e+1)
227         end
228         return t
229 end
230
231 --
232 -- new package.seeall function
233 --
234 function _PACKAGE.seeall (module)
235         local t = type(module)
236         assert (t == "table", "bad argument #1 to package.seeall (table expected, got "..t..")")
237         local meta = getmetatable (module)
238         if not meta then
239                 meta = {}
240                 setmetatable (module, meta)
241         end
242         meta.__index = _G
243 end
244
245
246 --
247 -- new module function
248 --
249 function _G.module (modname, ...)
250         local ns = _LOADED[modname]
251         if type(ns) ~= "table" then
252                 ns = findtable (_G, modname)
253                 if not ns then
254                         error (string.format ("name conflict for module '%s'", modname))
255                 end
256                 _LOADED[modname] = ns
257         end
258         if not ns._NAME then
259                 ns._NAME = modname
260                 ns._M = ns
261                 ns._PACKAGE = gsub (modname, "[^.]*$", "")
262         end
263         setfenv (2, ns)
264         for i, f in ipairs (arg) do
265                 f (ns)
266         end
267 end