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