You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

267 lines
6.2 KiB

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