diff options
author | Mike Pall <mike> | 2009-12-08 19:46:35 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2009-12-08 19:46:35 +0100 |
commit | 55b16959717084884fd4a0cbae6d19e3786c20c7 (patch) | |
tree | c8a07a43c13679751ed25a9d06796e9e7b2134a6 /src/lib_package.c | |
download | luajit-2.0.0-beta1.tar.gz luajit-2.0.0-beta1.tar.bz2 luajit-2.0.0-beta1.zip |
RELEASE LuaJIT-2.0.0-beta1v2.0.0-beta1
Diffstat (limited to 'src/lib_package.c')
-rw-r--r-- | src/lib_package.c | 508 |
1 files changed, 508 insertions, 0 deletions
diff --git a/src/lib_package.c b/src/lib_package.c new file mode 100644 index 00000000..69fa1db9 --- /dev/null +++ b/src/lib_package.c | |||
@@ -0,0 +1,508 @@ | |||
1 | /* | ||
2 | ** Package library. | ||
3 | ** Copyright (C) 2005-2009 Mike Pall. See Copyright Notice in luajit.h | ||
4 | ** | ||
5 | ** Major portions taken verbatim or adapted from the Lua interpreter. | ||
6 | ** Copyright (C) 1994-2008 Lua.org, PUC-Rio. See Copyright Notice in lua.h | ||
7 | */ | ||
8 | |||
9 | #define lib_package_c | ||
10 | #define LUA_LIB | ||
11 | |||
12 | #include "lua.h" | ||
13 | #include "lauxlib.h" | ||
14 | #include "lualib.h" | ||
15 | |||
16 | #include "lj_obj.h" | ||
17 | #include "lj_err.h" | ||
18 | #include "lj_lib.h" | ||
19 | |||
20 | /* ------------------------------------------------------------------------ */ | ||
21 | |||
22 | /* Error codes for ll_loadfunc. */ | ||
23 | #define PACKAGE_ERR_LIB 1 | ||
24 | #define PACKAGE_ERR_FUNC 2 | ||
25 | |||
26 | /* Redefined in platform specific part. */ | ||
27 | #define PACKAGE_LIB_FAIL "open" | ||
28 | #define setprogdir(L) ((void)0) | ||
29 | |||
30 | #if defined(LUA_DL_DLOPEN) | ||
31 | |||
32 | #include <dlfcn.h> | ||
33 | |||
34 | static void ll_unloadlib(void *lib) | ||
35 | { | ||
36 | dlclose(lib); | ||
37 | } | ||
38 | |||
39 | static void *ll_load(lua_State *L, const char *path) | ||
40 | { | ||
41 | void *lib = dlopen(path, RTLD_NOW); | ||
42 | if (lib == NULL) lua_pushstring(L, dlerror()); | ||
43 | return lib; | ||
44 | } | ||
45 | |||
46 | static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) | ||
47 | { | ||
48 | lua_CFunction f = (lua_CFunction)dlsym(lib, sym); | ||
49 | if (f == NULL) lua_pushstring(L, dlerror()); | ||
50 | return f; | ||
51 | } | ||
52 | |||
53 | #elif defined(LUA_DL_DLL) | ||
54 | |||
55 | #define WIN32_LEAN_AND_MEAN | ||
56 | #include <windows.h> | ||
57 | |||
58 | #undef setprogdir | ||
59 | |||
60 | static void setprogdir(lua_State *L) | ||
61 | { | ||
62 | char buff[MAX_PATH + 1]; | ||
63 | char *lb; | ||
64 | DWORD nsize = sizeof(buff); | ||
65 | DWORD n = GetModuleFileNameA(NULL, buff, nsize); | ||
66 | if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) { | ||
67 | luaL_error(L, "unable to get ModuleFileName"); | ||
68 | } else { | ||
69 | *lb = '\0'; | ||
70 | luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); | ||
71 | lua_remove(L, -2); /* remove original string */ | ||
72 | } | ||
73 | } | ||
74 | |||
75 | static void pusherror(lua_State *L) | ||
76 | { | ||
77 | DWORD error = GetLastError(); | ||
78 | char buffer[128]; | ||
79 | if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, | ||
80 | NULL, error, 0, buffer, sizeof(buffer), NULL)) | ||
81 | lua_pushstring(L, buffer); | ||
82 | else | ||
83 | lua_pushfstring(L, "system error %d\n", error); | ||
84 | } | ||
85 | |||
86 | static void ll_unloadlib(void *lib) | ||
87 | { | ||
88 | FreeLibrary((HINSTANCE)lib); | ||
89 | } | ||
90 | |||
91 | static void *ll_load(lua_State *L, const char *path) | ||
92 | { | ||
93 | HINSTANCE lib = LoadLibraryA(path); | ||
94 | if (lib == NULL) pusherror(L); | ||
95 | return lib; | ||
96 | } | ||
97 | |||
98 | static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) | ||
99 | { | ||
100 | lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); | ||
101 | if (f == NULL) pusherror(L); | ||
102 | return f; | ||
103 | } | ||
104 | |||
105 | #else | ||
106 | |||
107 | #undef PACKAGE_LIB_FAIL | ||
108 | #define PACKAGE_LIB_FAIL "absent" | ||
109 | |||
110 | #define DLMSG "dynamic libraries not enabled; check your Lua installation" | ||
111 | |||
112 | static void ll_unloadlib(void *lib) | ||
113 | { | ||
114 | (void)lib; | ||
115 | } | ||
116 | |||
117 | static void *ll_load(lua_State *L, const char *path) | ||
118 | { | ||
119 | (void)path; | ||
120 | lua_pushliteral(L, DLMSG); | ||
121 | return NULL; | ||
122 | } | ||
123 | |||
124 | static lua_CFunction ll_sym(lua_State *L, void *lib, const char *sym) | ||
125 | { | ||
126 | (void)lib; (void)sym; | ||
127 | lua_pushliteral(L, DLMSG); | ||
128 | return NULL; | ||
129 | } | ||
130 | #endif | ||
131 | |||
132 | /* ------------------------------------------------------------------------ */ | ||
133 | |||
134 | static void **ll_register(lua_State *L, const char *path) | ||
135 | { | ||
136 | void **plib; | ||
137 | lua_pushfstring(L, "LOADLIB: %s", path); | ||
138 | lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ | ||
139 | if (!lua_isnil(L, -1)) { /* is there an entry? */ | ||
140 | plib = (void **)lua_touserdata(L, -1); | ||
141 | } else { /* no entry yet; create one */ | ||
142 | lua_pop(L, 1); | ||
143 | plib = (void **)lua_newuserdata(L, sizeof(void *)); | ||
144 | *plib = NULL; | ||
145 | luaL_getmetatable(L, "_LOADLIB"); | ||
146 | lua_setmetatable(L, -2); | ||
147 | lua_pushfstring(L, "LOADLIB: %s", path); | ||
148 | lua_pushvalue(L, -2); | ||
149 | lua_settable(L, LUA_REGISTRYINDEX); | ||
150 | } | ||
151 | return plib; | ||
152 | } | ||
153 | |||
154 | static int ll_loadfunc(lua_State *L, const char *path, const char *sym) | ||
155 | { | ||
156 | void **reg = ll_register(L, path); | ||
157 | if (*reg == NULL) *reg = ll_load(L, path); | ||
158 | if (*reg == NULL) { | ||
159 | return PACKAGE_ERR_LIB; /* unable to load library */ | ||
160 | } else { | ||
161 | lua_CFunction f = ll_sym(L, *reg, sym); | ||
162 | if (f == NULL) | ||
163 | return PACKAGE_ERR_FUNC; /* unable to find function */ | ||
164 | lua_pushcfunction(L, f); | ||
165 | return 0; /* return function */ | ||
166 | } | ||
167 | } | ||
168 | |||
169 | static int lj_cf_package_loadlib(lua_State *L) | ||
170 | { | ||
171 | const char *path = luaL_checkstring(L, 1); | ||
172 | const char *init = luaL_checkstring(L, 2); | ||
173 | int stat = ll_loadfunc(L, path, init); | ||
174 | if (stat == 0) { /* no errors? */ | ||
175 | return 1; /* return the loaded function */ | ||
176 | } else { /* error; error message is on stack top */ | ||
177 | lua_pushnil(L); | ||
178 | lua_insert(L, -2); | ||
179 | lua_pushstring(L, (stat == PACKAGE_ERR_LIB) ? PACKAGE_LIB_FAIL : "init"); | ||
180 | return 3; /* return nil, error message, and where */ | ||
181 | } | ||
182 | } | ||
183 | |||
184 | static int lj_cf_package_unloadlib(lua_State *L) | ||
185 | { | ||
186 | void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); | ||
187 | if (*lib) ll_unloadlib(*lib); | ||
188 | *lib = NULL; /* mark library as closed */ | ||
189 | return 0; | ||
190 | } | ||
191 | |||
192 | /* ------------------------------------------------------------------------ */ | ||
193 | |||
194 | static int readable(const char *filename) | ||
195 | { | ||
196 | FILE *f = fopen(filename, "r"); /* try to open file */ | ||
197 | if (f == NULL) return 0; /* open failed */ | ||
198 | fclose(f); | ||
199 | return 1; | ||
200 | } | ||
201 | |||
202 | static const char *pushnexttemplate(lua_State *L, const char *path) | ||
203 | { | ||
204 | const char *l; | ||
205 | while (*path == *LUA_PATHSEP) path++; /* skip separators */ | ||
206 | if (*path == '\0') return NULL; /* no more templates */ | ||
207 | l = strchr(path, *LUA_PATHSEP); /* find next separator */ | ||
208 | if (l == NULL) l = path + strlen(path); | ||
209 | lua_pushlstring(L, path, (size_t)(l - path)); /* template */ | ||
210 | return l; | ||
211 | } | ||
212 | |||
213 | static const char *findfile(lua_State *L, const char *name, | ||
214 | const char *pname) | ||
215 | { | ||
216 | const char *path; | ||
217 | name = luaL_gsub(L, name, ".", LUA_DIRSEP); | ||
218 | lua_getfield(L, LUA_ENVIRONINDEX, pname); | ||
219 | path = lua_tostring(L, -1); | ||
220 | if (path == NULL) | ||
221 | luaL_error(L, LUA_QL("package.%s") " must be a string", pname); | ||
222 | lua_pushliteral(L, ""); /* error accumulator */ | ||
223 | while ((path = pushnexttemplate(L, path)) != NULL) { | ||
224 | const char *filename; | ||
225 | filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); | ||
226 | lua_remove(L, -2); /* remove path template */ | ||
227 | if (readable(filename)) /* does file exist and is readable? */ | ||
228 | return filename; /* return that file name */ | ||
229 | lua_pushfstring(L, "\n\tno file " LUA_QS, filename); | ||
230 | lua_remove(L, -2); /* remove file name */ | ||
231 | lua_concat(L, 2); /* add entry to possible error message */ | ||
232 | } | ||
233 | return NULL; /* not found */ | ||
234 | } | ||
235 | |||
236 | static void loaderror(lua_State *L, const char *filename) | ||
237 | { | ||
238 | luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", | ||
239 | lua_tostring(L, 1), filename, lua_tostring(L, -1)); | ||
240 | } | ||
241 | |||
242 | static int lj_cf_package_loader_lua(lua_State *L) | ||
243 | { | ||
244 | const char *filename; | ||
245 | const char *name = luaL_checkstring(L, 1); | ||
246 | filename = findfile(L, name, "path"); | ||
247 | if (filename == NULL) return 1; /* library not found in this path */ | ||
248 | if (luaL_loadfile(L, filename) != 0) | ||
249 | loaderror(L, filename); | ||
250 | return 1; /* library loaded successfully */ | ||
251 | } | ||
252 | |||
253 | static const char *mkfuncname(lua_State *L, const char *modname) | ||
254 | { | ||
255 | const char *funcname; | ||
256 | const char *mark = strchr(modname, *LUA_IGMARK); | ||
257 | if (mark) modname = mark + 1; | ||
258 | funcname = luaL_gsub(L, modname, ".", "_"); | ||
259 | funcname = lua_pushfstring(L, "luaopen_%s", funcname); | ||
260 | lua_remove(L, -2); /* remove 'gsub' result */ | ||
261 | return funcname; | ||
262 | } | ||
263 | |||
264 | static int lj_cf_package_loader_c(lua_State *L) | ||
265 | { | ||
266 | const char *funcname; | ||
267 | const char *name = luaL_checkstring(L, 1); | ||
268 | const char *filename = findfile(L, name, "cpath"); | ||
269 | if (filename == NULL) return 1; /* library not found in this path */ | ||
270 | funcname = mkfuncname(L, name); | ||
271 | if (ll_loadfunc(L, filename, funcname) != 0) | ||
272 | loaderror(L, filename); | ||
273 | return 1; /* library loaded successfully */ | ||
274 | } | ||
275 | |||
276 | static int lj_cf_package_loader_croot(lua_State *L) | ||
277 | { | ||
278 | const char *funcname; | ||
279 | const char *filename; | ||
280 | const char *name = luaL_checkstring(L, 1); | ||
281 | const char *p = strchr(name, '.'); | ||
282 | int stat; | ||
283 | if (p == NULL) return 0; /* is root */ | ||
284 | lua_pushlstring(L, name, (size_t)(p - name)); | ||
285 | filename = findfile(L, lua_tostring(L, -1), "cpath"); | ||
286 | if (filename == NULL) return 1; /* root not found */ | ||
287 | funcname = mkfuncname(L, name); | ||
288 | if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { | ||
289 | if (stat != PACKAGE_ERR_FUNC) loaderror(L, filename); /* real error */ | ||
290 | lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, | ||
291 | name, filename); | ||
292 | return 1; /* function not found */ | ||
293 | } | ||
294 | return 1; | ||
295 | } | ||
296 | |||
297 | static int lj_cf_package_loader_preload(lua_State *L) | ||
298 | { | ||
299 | const char *name = luaL_checkstring(L, 1); | ||
300 | lua_getfield(L, LUA_ENVIRONINDEX, "preload"); | ||
301 | if (!lua_istable(L, -1)) | ||
302 | luaL_error(L, LUA_QL("package.preload") " must be a table"); | ||
303 | lua_getfield(L, -1, name); | ||
304 | if (lua_isnil(L, -1)) /* not found? */ | ||
305 | lua_pushfstring(L, "\n\tno field package.preload['%s']", name); | ||
306 | return 1; | ||
307 | } | ||
308 | |||
309 | /* ------------------------------------------------------------------------ */ | ||
310 | |||
311 | static const int sentinel_ = 0; | ||
312 | #define sentinel ((void *)&sentinel_) | ||
313 | |||
314 | static int lj_cf_package_require(lua_State *L) | ||
315 | { | ||
316 | const char *name = luaL_checkstring(L, 1); | ||
317 | int i; | ||
318 | lua_settop(L, 1); /* _LOADED table will be at index 2 */ | ||
319 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | ||
320 | lua_getfield(L, 2, name); | ||
321 | if (lua_toboolean(L, -1)) { /* is it there? */ | ||
322 | if (lua_touserdata(L, -1) == sentinel) /* check loops */ | ||
323 | luaL_error(L, "loop or previous error loading module " LUA_QS, name); | ||
324 | return 1; /* package is already loaded */ | ||
325 | } | ||
326 | /* else must load it; iterate over available loaders */ | ||
327 | lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); | ||
328 | if (!lua_istable(L, -1)) | ||
329 | luaL_error(L, LUA_QL("package.loaders") " must be a table"); | ||
330 | lua_pushliteral(L, ""); /* error message accumulator */ | ||
331 | for (i = 1; ; i++) { | ||
332 | lua_rawgeti(L, -2, i); /* get a loader */ | ||
333 | if (lua_isnil(L, -1)) | ||
334 | luaL_error(L, "module " LUA_QS " not found:%s", | ||
335 | name, lua_tostring(L, -2)); | ||
336 | lua_pushstring(L, name); | ||
337 | lua_call(L, 1, 1); /* call it */ | ||
338 | if (lua_isfunction(L, -1)) /* did it find module? */ | ||
339 | break; /* module loaded successfully */ | ||
340 | else if (lua_isstring(L, -1)) /* loader returned error message? */ | ||
341 | lua_concat(L, 2); /* accumulate it */ | ||
342 | else | ||
343 | lua_pop(L, 1); | ||
344 | } | ||
345 | lua_pushlightuserdata(L, sentinel); | ||
346 | lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ | ||
347 | lua_pushstring(L, name); /* pass name as argument to module */ | ||
348 | lua_call(L, 1, 1); /* run loaded module */ | ||
349 | if (!lua_isnil(L, -1)) /* non-nil return? */ | ||
350 | lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ | ||
351 | lua_getfield(L, 2, name); | ||
352 | if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ | ||
353 | lua_pushboolean(L, 1); /* use true as result */ | ||
354 | lua_pushvalue(L, -1); /* extra copy to be returned */ | ||
355 | lua_setfield(L, 2, name); /* _LOADED[name] = true */ | ||
356 | } | ||
357 | return 1; | ||
358 | } | ||
359 | |||
360 | /* ------------------------------------------------------------------------ */ | ||
361 | |||
362 | static void setfenv(lua_State *L) | ||
363 | { | ||
364 | lua_Debug ar; | ||
365 | if (lua_getstack(L, 1, &ar) == 0 || | ||
366 | lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ | ||
367 | lua_iscfunction(L, -1)) | ||
368 | luaL_error(L, LUA_QL("module") " not called from a Lua function"); | ||
369 | lua_pushvalue(L, -2); | ||
370 | lua_setfenv(L, -2); | ||
371 | lua_pop(L, 1); | ||
372 | } | ||
373 | |||
374 | static void dooptions(lua_State *L, int n) | ||
375 | { | ||
376 | int i; | ||
377 | for (i = 2; i <= n; i++) { | ||
378 | lua_pushvalue(L, i); /* get option (a function) */ | ||
379 | lua_pushvalue(L, -2); /* module */ | ||
380 | lua_call(L, 1, 0); | ||
381 | } | ||
382 | } | ||
383 | |||
384 | static void modinit(lua_State *L, const char *modname) | ||
385 | { | ||
386 | const char *dot; | ||
387 | lua_pushvalue(L, -1); | ||
388 | lua_setfield(L, -2, "_M"); /* module._M = module */ | ||
389 | lua_pushstring(L, modname); | ||
390 | lua_setfield(L, -2, "_NAME"); | ||
391 | dot = strrchr(modname, '.'); /* look for last dot in module name */ | ||
392 | if (dot == NULL) dot = modname; else dot++; | ||
393 | /* set _PACKAGE as package name (full module name minus last part) */ | ||
394 | lua_pushlstring(L, modname, (size_t)(dot - modname)); | ||
395 | lua_setfield(L, -2, "_PACKAGE"); | ||
396 | } | ||
397 | |||
398 | static int lj_cf_package_module(lua_State *L) | ||
399 | { | ||
400 | const char *modname = luaL_checkstring(L, 1); | ||
401 | int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ | ||
402 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | ||
403 | lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ | ||
404 | if (!lua_istable(L, -1)) { /* not found? */ | ||
405 | lua_pop(L, 1); /* remove previous result */ | ||
406 | /* try global variable (and create one if it does not exist) */ | ||
407 | if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) | ||
408 | lj_err_callerv(L, LJ_ERR_BADMODN, modname); | ||
409 | lua_pushvalue(L, -1); | ||
410 | lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ | ||
411 | } | ||
412 | /* check whether table already has a _NAME field */ | ||
413 | lua_getfield(L, -1, "_NAME"); | ||
414 | if (!lua_isnil(L, -1)) { /* is table an initialized module? */ | ||
415 | lua_pop(L, 1); | ||
416 | } else { /* no; initialize it */ | ||
417 | lua_pop(L, 1); | ||
418 | modinit(L, modname); | ||
419 | } | ||
420 | lua_pushvalue(L, -1); | ||
421 | setfenv(L); | ||
422 | dooptions(L, loaded - 1); | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | static int lj_cf_package_seeall(lua_State *L) | ||
427 | { | ||
428 | luaL_checktype(L, 1, LUA_TTABLE); | ||
429 | if (!lua_getmetatable(L, 1)) { | ||
430 | lua_createtable(L, 0, 1); /* create new metatable */ | ||
431 | lua_pushvalue(L, -1); | ||
432 | lua_setmetatable(L, 1); | ||
433 | } | ||
434 | lua_pushvalue(L, LUA_GLOBALSINDEX); | ||
435 | lua_setfield(L, -2, "__index"); /* mt.__index = _G */ | ||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | /* ------------------------------------------------------------------------ */ | ||
440 | |||
441 | #define AUXMARK "\1" | ||
442 | |||
443 | static void setpath(lua_State *L, const char *fieldname, const char *envname, | ||
444 | const char *def) | ||
445 | { | ||
446 | const char *path = getenv(envname); | ||
447 | if (path == NULL) { | ||
448 | lua_pushstring(L, def); | ||
449 | } else { | ||
450 | path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, | ||
451 | LUA_PATHSEP AUXMARK LUA_PATHSEP); | ||
452 | luaL_gsub(L, path, AUXMARK, def); | ||
453 | lua_remove(L, -2); | ||
454 | } | ||
455 | setprogdir(L); | ||
456 | lua_setfield(L, -2, fieldname); | ||
457 | } | ||
458 | |||
459 | static const luaL_Reg package_lib[] = { | ||
460 | { "loadlib", lj_cf_package_loadlib }, | ||
461 | { "seeall", lj_cf_package_seeall }, | ||
462 | { NULL, NULL } | ||
463 | }; | ||
464 | |||
465 | static const luaL_Reg package_global[] = { | ||
466 | { "module", lj_cf_package_module }, | ||
467 | { "require", lj_cf_package_require }, | ||
468 | { NULL, NULL } | ||
469 | }; | ||
470 | |||
471 | static const lua_CFunction package_loaders[] = | ||
472 | { | ||
473 | lj_cf_package_loader_preload, | ||
474 | lj_cf_package_loader_lua, | ||
475 | lj_cf_package_loader_c, | ||
476 | lj_cf_package_loader_croot, | ||
477 | NULL | ||
478 | }; | ||
479 | |||
480 | LUALIB_API int luaopen_package(lua_State *L) | ||
481 | { | ||
482 | int i; | ||
483 | luaL_newmetatable(L, "_LOADLIB"); | ||
484 | lua_pushcfunction(L, lj_cf_package_unloadlib); | ||
485 | lua_setfield(L, -2, "__gc"); | ||
486 | luaL_register(L, LUA_LOADLIBNAME, package_lib); | ||
487 | lua_pushvalue(L, -1); | ||
488 | lua_replace(L, LUA_ENVIRONINDEX); | ||
489 | lua_createtable(L, sizeof(package_loaders)/sizeof(package_loaders[0])-1, 0); | ||
490 | for (i = 0; package_loaders[i] != NULL; i++) { | ||
491 | lua_pushcfunction(L, package_loaders[i]); | ||
492 | lua_rawseti(L, -2, i+1); | ||
493 | } | ||
494 | lua_setfield(L, -2, "loaders"); | ||
495 | setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); | ||
496 | setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); | ||
497 | lua_pushliteral(L, LUA_PATH_CONFIG); | ||
498 | lua_setfield(L, -2, "config"); | ||
499 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 16); | ||
500 | lua_setfield(L, -2, "loaded"); | ||
501 | lua_newtable(L); | ||
502 | lua_setfield(L, -2, "preload"); | ||
503 | lua_pushvalue(L, LUA_GLOBALSINDEX); | ||
504 | luaL_register(L, NULL, package_global); | ||
505 | lua_pop(L, 1); | ||
506 | return 1; | ||
507 | } | ||
508 | |||