compat-5.1.lua (6391B)
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