00001 /* 00002 ** $Id: loadlib.c,v 1.52.1.3 2008/08/06 13:29:28 roberto Exp $ 00003 ** Dynamic library loader for Lua 00004 ** See Copyright Notice in lua.h 00005 ** 00006 ** This module contains an implementation of loadlib for Unix systems 00007 ** that have dlfcn, an implementation for Darwin (Mac OS X), an 00008 ** implementation for Windows, and a stub for other systems. 00009 */ 00010 00011 00012 #include <stdlib.h> 00013 #include <string.h> 00014 00015 00016 #define loadlib_c 00017 #define LUA_LIB 00018 00019 #include "lua.h" 00020 00021 #include "lauxlib.h" 00022 #include "lualib.h" 00023 00024 00025 /* prefix for open functions in C libraries */ 00026 #define LUA_POF "luaopen_" 00027 00028 /* separator for open functions in C libraries */ 00029 #define LUA_OFSEP "_" 00030 00031 00032 #define LIBPREFIX "LOADLIB: " 00033 00034 #define POF LUA_POF 00035 #define LIB_FAIL "open" 00036 00037 00038 /* error codes for ll_loadfunc */ 00039 #define ERRLIB 1 00040 #define ERRFUNC 2 00041 00042 #define setprogdir(L) ((void)0) 00043 00044 00045 static void ll_unloadlib (void *lib); 00046 static void *ll_load (lua_State *L, const char *path); 00047 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); 00048 00049 00050 00051 #if defined(LUA_DL_DLOPEN) 00052 /* 00053 ** {======================================================================== 00054 ** This is an implementation of loadlib based on the dlfcn interface. 00055 ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, 00056 ** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least 00057 ** as an emulation layer on top of native functions. 00058 ** ========================================================================= 00059 */ 00060 00061 #include <dlfcn.h> 00062 00063 static void ll_unloadlib (void *lib) { 00064 dlclose(lib); 00065 } 00066 00067 00068 static void *ll_load (lua_State *L, const char *path) { 00069 void *lib = dlopen(path, RTLD_NOW); 00070 if (lib == NULL) lua_pushstring(L, dlerror()); 00071 return lib; 00072 } 00073 00074 00075 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 00076 lua_CFunction f = (lua_CFunction)dlsym(lib, sym); 00077 if (f == NULL) lua_pushstring(L, dlerror()); 00078 return f; 00079 } 00080 00081 /* }====================================================== */ 00082 00083 00084 00085 #elif defined(LUA_DL_DLL) 00086 /* 00087 ** {====================================================================== 00088 ** This is an implementation of loadlib for Windows using native functions. 00089 ** ======================================================================= 00090 */ 00091 00092 #include <windows.h> 00093 00094 00095 #undef setprogdir 00096 00097 static void setprogdir (lua_State *L) { 00098 char buff[MAX_PATH + 1]; 00099 char *lb; 00100 DWORD nsize = sizeof(buff)/sizeof(char); 00101 DWORD n = GetModuleFileNameA(NULL, buff, nsize); 00102 if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) 00103 luaL_error(L, "unable to get ModuleFileName"); 00104 else { 00105 *lb = '\0'; 00106 luaL_gsub(L, lua_tostring(L, -1), LUA_EXECDIR, buff); 00107 lua_remove(L, -2); /* remove original string */ 00108 } 00109 } 00110 00111 00112 static void pusherror (lua_State *L) { 00113 int error = GetLastError(); 00114 char buffer[128]; 00115 if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 00116 NULL, error, 0, buffer, sizeof(buffer), NULL)) 00117 lua_pushstring(L, buffer); 00118 else 00119 lua_pushfstring(L, "system error %d\n", error); 00120 } 00121 00122 static void ll_unloadlib (void *lib) { 00123 FreeLibrary((HINSTANCE)lib); 00124 } 00125 00126 00127 static void *ll_load (lua_State *L, const char *path) { 00128 HINSTANCE lib = LoadLibraryA(path); 00129 if (lib == NULL) pusherror(L); 00130 return lib; 00131 } 00132 00133 00134 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 00135 lua_CFunction f = (lua_CFunction)GetProcAddress((HINSTANCE)lib, sym); 00136 if (f == NULL) pusherror(L); 00137 return f; 00138 } 00139 00140 /* }====================================================== */ 00141 00142 00143 00144 #elif defined(LUA_DL_DYLD) 00145 /* 00146 ** {====================================================================== 00147 ** Native Mac OS X / Darwin Implementation 00148 ** ======================================================================= 00149 */ 00150 00151 #include <mach-o/dyld.h> 00152 00153 00154 /* Mac appends a `_' before C function names */ 00155 #undef POF 00156 #define POF "_" LUA_POF 00157 00158 00159 static void pusherror (lua_State *L) { 00160 const char *err_str; 00161 const char *err_file; 00162 NSLinkEditErrors err; 00163 int err_num; 00164 NSLinkEditError(&err, &err_num, &err_file, &err_str); 00165 lua_pushstring(L, err_str); 00166 } 00167 00168 00169 static const char *errorfromcode (NSObjectFileImageReturnCode ret) { 00170 switch (ret) { 00171 case NSObjectFileImageInappropriateFile: 00172 return "file is not a bundle"; 00173 case NSObjectFileImageArch: 00174 return "library is for wrong CPU type"; 00175 case NSObjectFileImageFormat: 00176 return "bad format"; 00177 case NSObjectFileImageAccess: 00178 return "cannot access file"; 00179 case NSObjectFileImageFailure: 00180 default: 00181 return "unable to load library"; 00182 } 00183 } 00184 00185 00186 static void ll_unloadlib (void *lib) { 00187 NSUnLinkModule((NSModule)lib, NSUNLINKMODULE_OPTION_RESET_LAZY_REFERENCES); 00188 } 00189 00190 00191 static void *ll_load (lua_State *L, const char *path) { 00192 NSObjectFileImage img; 00193 NSObjectFileImageReturnCode ret; 00194 /* this would be a rare case, but prevents crashing if it happens */ 00195 if(!_dyld_present()) { 00196 lua_pushliteral(L, "dyld not present"); 00197 return NULL; 00198 } 00199 ret = NSCreateObjectFileImageFromFile(path, &img); 00200 if (ret == NSObjectFileImageSuccess) { 00201 NSModule mod = NSLinkModule(img, path, NSLINKMODULE_OPTION_PRIVATE | 00202 NSLINKMODULE_OPTION_RETURN_ON_ERROR); 00203 NSDestroyObjectFileImage(img); 00204 if (mod == NULL) pusherror(L); 00205 return mod; 00206 } 00207 lua_pushstring(L, errorfromcode(ret)); 00208 return NULL; 00209 } 00210 00211 00212 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 00213 NSSymbol nss = NSLookupSymbolInModule((NSModule)lib, sym); 00214 if (nss == NULL) { 00215 lua_pushfstring(L, "symbol " LUA_QS " not found", sym); 00216 return NULL; 00217 } 00218 return (lua_CFunction)NSAddressOfSymbol(nss); 00219 } 00220 00221 /* }====================================================== */ 00222 00223 #elif defined(LUA_DL_RLIBRARY) 00224 00225 // This file needs to be compiled as C++ for this code to compile. 00226 00227 #include <e32std.h> 00228 00229 static void ll_unloadlib (void *lib) { 00230 RLibrary* library = static_cast<RLibrary*>(lib); 00231 library->Close(); 00232 delete library; 00233 } 00234 00235 00236 static void *ll_load (lua_State *L, const char *path) { 00237 RLibrary* library = new RLibrary; 00238 if (lib == NULL) lua_pushstring(L, "RLibrary alloc failed"); 00239 00240 TInt err = library->Load(TPtrC8(path)); 00241 if (err != KErrNone) lua_pushstring(L, "RLibrary::Load failed"); 00242 00243 return lib; 00244 } 00245 00246 00247 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 00248 // sym is an ordinal, we need to convert this to a number 00249 TLex8 lexer(sym); 00250 00251 TInt ordinal = 0; 00252 lexer.Val(ordinal); 00253 00254 RLibrary* library = static_cast<RLibrary*>(lib); 00255 lua_CFunction f = (lua_CFunction) library->Lookup(ordinal); 00256 if (f == NULL) lua_pushstring(L, "Function not at ordinal"); 00257 return f; 00258 } 00259 00260 #else 00261 /* 00262 ** {====================================================== 00263 ** Fallback for other systems 00264 ** ======================================================= 00265 */ 00266 00267 //#error dynamic libraries cannot be supported 00268 00269 #undef LIB_FAIL 00270 #define LIB_FAIL "absent" 00271 00272 00273 #define DLMSG "dynamic libraries not enabled; check your Lua installation" 00274 00275 00276 static void ll_unloadlib (void *lib) { 00277 (void)lib; /* to avoid warnings */ 00278 } 00279 00280 00281 static void *ll_load (lua_State *L, const char *path) { 00282 (void)path; /* to avoid warnings */ 00283 lua_pushliteral(L, DLMSG); 00284 return NULL; 00285 } 00286 00287 00288 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 00289 (void)lib; (void)sym; /* to avoid warnings */ 00290 lua_pushliteral(L, DLMSG); 00291 return NULL; 00292 } 00293 00294 /* }====================================================== */ 00295 #endif 00296 00297 00298 00299 static void **ll_register (lua_State *L, const char *path) { 00300 void **plib; 00301 lua_pushfstring(L, "%s%s", LIBPREFIX, path); 00302 lua_gettable(L, LUA_REGISTRYINDEX); /* check library in registry? */ 00303 if (!lua_isnil(L, -1)) /* is there an entry? */ 00304 plib = (void **)lua_touserdata(L, -1); 00305 else { /* no entry yet; create one */ 00306 lua_pop(L, 1); 00307 plib = (void **)lua_newuserdata(L, sizeof(const void *)); 00308 *plib = NULL; 00309 luaL_getmetatable(L, "_LOADLIB"); 00310 lua_setmetatable(L, -2); 00311 lua_pushfstring(L, "%s%s", LIBPREFIX, path); 00312 lua_pushvalue(L, -2); 00313 lua_settable(L, LUA_REGISTRYINDEX); 00314 } 00315 return plib; 00316 } 00317 00318 00319 /* 00320 ** __gc tag method: calls library's `ll_unloadlib' function with the lib 00321 ** handle 00322 */ 00323 static int gctm (lua_State *L) { 00324 void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB"); 00325 if (*lib) ll_unloadlib(*lib); 00326 *lib = NULL; /* mark library as closed */ 00327 return 0; 00328 } 00329 00330 00331 static int ll_loadfunc (lua_State *L, const char *path, const char *sym) { 00332 void **reg = ll_register(L, path); 00333 if (*reg == NULL) *reg = ll_load(L, path); 00334 if (*reg == NULL) 00335 return ERRLIB; /* unable to load library */ 00336 else { 00337 lua_CFunction f = ll_sym(L, *reg, sym); 00338 if (f == NULL) 00339 return ERRFUNC; /* unable to find function */ 00340 lua_pushcfunction(L, f); 00341 return 0; /* return function */ 00342 } 00343 } 00344 00345 00346 static int ll_loadlib (lua_State *L) { 00347 const char *path = luaL_checkstring(L, 1); 00348 const char *init = luaL_checkstring(L, 2); 00349 int stat = ll_loadfunc(L, path, init); 00350 if (stat == 0) /* no errors? */ 00351 return 1; /* return the loaded function */ 00352 else { /* error; error message is on stack top */ 00353 lua_pushnil(L); 00354 lua_insert(L, -2); 00355 lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); 00356 return 3; /* return nil, error message, and where */ 00357 } 00358 } 00359 00360 00361 00362 /* 00363 ** {====================================================== 00364 ** 'require' function 00365 ** ======================================================= 00366 */ 00367 00368 00369 static int readable (const char *filename) { 00370 FILE *f = fopen(filename, "r"); /* try to open file */ 00371 if (f == NULL) return 0; /* open failed */ 00372 fclose(f); 00373 return 1; 00374 } 00375 00376 00377 static const char *pushnexttemplate (lua_State *L, const char *path) { 00378 const char *l; 00379 while (*path == *LUA_PATHSEP) path++; /* skip separators */ 00380 if (*path == '\0') return NULL; /* no more templates */ 00381 l = strchr(path, *LUA_PATHSEP); /* find next separator */ 00382 if (l == NULL) l = path + strlen(path); 00383 lua_pushlstring(L, path, l - path); /* template */ 00384 return l; 00385 } 00386 00387 00388 static const char *findfile (lua_State *L, const char *name, 00389 const char *pname) { 00390 const char *path; 00391 name = luaL_gsub(L, name, ".", LUA_DIRSEP); 00392 lua_getfield(L, LUA_ENVIRONINDEX, pname); 00393 path = lua_tostring(L, -1); 00394 if (path == NULL) 00395 luaL_error(L, LUA_QL("package.%s") " must be a string", pname); 00396 lua_pushliteral(L, ""); /* error accumulator */ 00397 while ((path = pushnexttemplate(L, path)) != NULL) { 00398 const char *filename; 00399 filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name); 00400 lua_remove(L, -2); /* remove path template */ 00401 if (readable(filename)) /* does file exist and is readable? */ 00402 return filename; /* return that file name */ 00403 lua_pushfstring(L, "\n\tno file " LUA_QS, filename); 00404 lua_remove(L, -2); /* remove file name */ 00405 lua_concat(L, 2); /* add entry to possible error message */ 00406 } 00407 return NULL; /* not found */ 00408 } 00409 00410 00411 static void loaderror (lua_State *L, const char *filename) { 00412 luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s", 00413 lua_tostring(L, 1), filename, lua_tostring(L, -1)); 00414 } 00415 00416 00417 static int loader_Lua (lua_State *L) { 00418 const char *filename; 00419 const char *name = luaL_checkstring(L, 1); 00420 filename = findfile(L, name, "path"); 00421 if (filename == NULL) return 1; /* library not found in this path */ 00422 if (luaL_loadfile(L, filename) != 0) 00423 loaderror(L, filename); 00424 return 1; /* library loaded successfully */ 00425 } 00426 00427 00428 static const char *mkfuncname (lua_State *L, const char *modname) { 00429 const char *funcname; 00430 const char *mark = strchr(modname, *LUA_IGMARK); 00431 if (mark) modname = mark + 1; 00432 funcname = luaL_gsub(L, modname, ".", LUA_OFSEP); 00433 funcname = lua_pushfstring(L, POF"%s", funcname); 00434 lua_remove(L, -2); /* remove 'gsub' result */ 00435 return funcname; 00436 } 00437 00438 00439 static int loader_C (lua_State *L) { 00440 const char *funcname; 00441 const char *name = luaL_checkstring(L, 1); 00442 const char *filename = findfile(L, name, "cpath"); 00443 if (filename == NULL) return 1; /* library not found in this path */ 00444 funcname = mkfuncname(L, name); 00445 if (ll_loadfunc(L, filename, funcname) != 0) 00446 loaderror(L, filename); 00447 return 1; /* library loaded successfully */ 00448 } 00449 00450 00451 static int loader_Croot (lua_State *L) { 00452 const char *funcname; 00453 const char *filename; 00454 const char *name = luaL_checkstring(L, 1); 00455 const char *p = strchr(name, '.'); 00456 int stat; 00457 if (p == NULL) return 0; /* is root */ 00458 lua_pushlstring(L, name, p - name); 00459 filename = findfile(L, lua_tostring(L, -1), "cpath"); 00460 if (filename == NULL) return 1; /* root not found */ 00461 funcname = mkfuncname(L, name); 00462 if ((stat = ll_loadfunc(L, filename, funcname)) != 0) { 00463 if (stat != ERRFUNC) loaderror(L, filename); /* real error */ 00464 lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, 00465 name, filename); 00466 return 1; /* function not found */ 00467 } 00468 return 1; 00469 } 00470 00471 00472 static int loader_preload (lua_State *L) { 00473 const char *name = luaL_checkstring(L, 1); 00474 lua_getfield(L, LUA_ENVIRONINDEX, "preload"); 00475 if (!lua_istable(L, -1)) 00476 luaL_error(L, LUA_QL("package.preload") " must be a table"); 00477 lua_getfield(L, -1, name); 00478 if (lua_isnil(L, -1)) /* not found? */ 00479 lua_pushfstring(L, "\n\tno field package.preload['%s']", name); 00480 return 1; 00481 } 00482 00483 00484 static const int sentinel_ = 0; 00485 #define sentinel ((void *)&sentinel_) 00486 00487 00488 static int ll_require (lua_State *L) { 00489 const char *name = luaL_checkstring(L, 1); 00490 int i; 00491 lua_settop(L, 1); /* _LOADED table will be at index 2 */ 00492 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 00493 lua_getfield(L, 2, name); 00494 if (lua_toboolean(L, -1)) { /* is it there? */ 00495 if (lua_touserdata(L, -1) == sentinel) /* check loops */ 00496 luaL_error(L, "loop or previous error loading module " LUA_QS, name); 00497 return 1; /* package is already loaded */ 00498 } 00499 /* else must load it; iterate over available loaders */ 00500 lua_getfield(L, LUA_ENVIRONINDEX, "loaders"); 00501 if (!lua_istable(L, -1)) 00502 luaL_error(L, LUA_QL("package.loaders") " must be a table"); 00503 lua_pushliteral(L, ""); /* error message accumulator */ 00504 for (i=1; ; i++) { 00505 lua_rawgeti(L, -2, i); /* get a loader */ 00506 if (lua_isnil(L, -1)) 00507 luaL_error(L, "module " LUA_QS " not found:%s", 00508 name, lua_tostring(L, -2)); 00509 lua_pushstring(L, name); 00510 lua_call(L, 1, 1); /* call it */ 00511 if (lua_isfunction(L, -1)) /* did it find module? */ 00512 break; /* module loaded successfully */ 00513 else if (lua_isstring(L, -1)) /* loader returned error message? */ 00514 lua_concat(L, 2); /* accumulate it */ 00515 else 00516 lua_pop(L, 1); 00517 } 00518 lua_pushlightuserdata(L, sentinel); 00519 lua_setfield(L, 2, name); /* _LOADED[name] = sentinel */ 00520 lua_pushstring(L, name); /* pass name as argument to module */ 00521 lua_call(L, 1, 1); /* run loaded module */ 00522 if (!lua_isnil(L, -1)) /* non-nil return? */ 00523 lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ 00524 lua_getfield(L, 2, name); 00525 if (lua_touserdata(L, -1) == sentinel) { /* module did not set a value? */ 00526 lua_pushboolean(L, 1); /* use true as result */ 00527 lua_pushvalue(L, -1); /* extra copy to be returned */ 00528 lua_setfield(L, 2, name); /* _LOADED[name] = true */ 00529 } 00530 return 1; 00531 } 00532 00533 /* }====================================================== */ 00534 00535 00536 00537 /* 00538 ** {====================================================== 00539 ** 'module' function 00540 ** ======================================================= 00541 */ 00542 00543 00544 static void setfenv (lua_State *L) { 00545 lua_Debug ar; 00546 if (lua_getstack(L, 1, &ar) == 0 || 00547 lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ 00548 lua_iscfunction(L, -1)) 00549 luaL_error(L, LUA_QL("module") " not called from a Lua function"); 00550 lua_pushvalue(L, -2); 00551 lua_setfenv(L, -2); 00552 lua_pop(L, 1); 00553 } 00554 00555 00556 static void dooptions (lua_State *L, int n) { 00557 int i; 00558 for (i = 2; i <= n; i++) { 00559 lua_pushvalue(L, i); /* get option (a function) */ 00560 lua_pushvalue(L, -2); /* module */ 00561 lua_call(L, 1, 0); 00562 } 00563 } 00564 00565 00566 static void modinit (lua_State *L, const char *modname) { 00567 const char *dot; 00568 lua_pushvalue(L, -1); 00569 lua_setfield(L, -2, "_M"); /* module._M = module */ 00570 lua_pushstring(L, modname); 00571 lua_setfield(L, -2, "_NAME"); 00572 dot = strrchr(modname, '.'); /* look for last dot in module name */ 00573 if (dot == NULL) dot = modname; 00574 else dot++; 00575 /* set _PACKAGE as package name (full module name minus last part) */ 00576 lua_pushlstring(L, modname, dot - modname); 00577 lua_setfield(L, -2, "_PACKAGE"); 00578 } 00579 00580 00581 static int ll_module (lua_State *L) { 00582 const char *modname = luaL_checkstring(L, 1); 00583 int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ 00584 lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 00585 lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ 00586 if (!lua_istable(L, -1)) { /* not found? */ 00587 lua_pop(L, 1); /* remove previous result */ 00588 /* try global variable (and create one if it does not exist) */ 00589 if (luaL_findtable(L, LUA_GLOBALSINDEX, modname, 1) != NULL) 00590 return luaL_error(L, "name conflict for module " LUA_QS, modname); 00591 lua_pushvalue(L, -1); 00592 lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ 00593 } 00594 /* check whether table already has a _NAME field */ 00595 lua_getfield(L, -1, "_NAME"); 00596 if (!lua_isnil(L, -1)) /* is table an initialized module? */ 00597 lua_pop(L, 1); 00598 else { /* no; initialize it */ 00599 lua_pop(L, 1); 00600 modinit(L, modname); 00601 } 00602 lua_pushvalue(L, -1); 00603 setfenv(L); 00604 dooptions(L, loaded - 1); 00605 return 0; 00606 } 00607 00608 00609 static int ll_seeall (lua_State *L) { 00610 luaL_checktype(L, 1, LUA_TTABLE); 00611 if (!lua_getmetatable(L, 1)) { 00612 lua_createtable(L, 0, 1); /* create new metatable */ 00613 lua_pushvalue(L, -1); 00614 lua_setmetatable(L, 1); 00615 } 00616 lua_pushvalue(L, LUA_GLOBALSINDEX); 00617 lua_setfield(L, -2, "__index"); /* mt.__index = _G */ 00618 return 0; 00619 } 00620 00621 00622 /* }====================================================== */ 00623 00624 00625 00626 /* auxiliary mark (for internal use) */ 00627 #define AUXMARK "\1" 00628 00629 static void setpath (lua_State *L, const char *fieldname, const char *envname, 00630 const char *def) { 00631 const char *path = getenv(envname); 00632 if (path == NULL) /* no environment variable? */ 00633 lua_pushstring(L, def); /* use default */ 00634 else { 00635 /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ 00636 path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP, 00637 LUA_PATHSEP AUXMARK LUA_PATHSEP); 00638 luaL_gsub(L, path, AUXMARK, def); 00639 lua_remove(L, -2); 00640 } 00641 setprogdir(L); 00642 lua_setfield(L, -2, fieldname); 00643 } 00644 00645 00646 static const luaL_Reg pk_funcs[] = { 00647 {"loadlib", ll_loadlib}, 00648 {"seeall", ll_seeall}, 00649 {NULL, NULL} 00650 }; 00651 00652 00653 static const luaL_Reg ll_funcs[] = { 00654 {"module", ll_module}, 00655 {"require", ll_require}, 00656 {NULL, NULL} 00657 }; 00658 00659 00660 static const lua_CFunction loaders[] = 00661 {loader_preload, loader_Lua, loader_C, loader_Croot, NULL}; 00662 00663 00664 LUALIB_API int luaopen_package (lua_State *L) { 00665 int i; 00666 /* create new type _LOADLIB */ 00667 luaL_newmetatable(L, "_LOADLIB"); 00668 lua_pushcfunction(L, gctm); 00669 lua_setfield(L, -2, "__gc"); 00670 /* create `package' table */ 00671 luaL_register(L, LUA_LOADLIBNAME, pk_funcs); 00672 #if defined(LUA_COMPAT_LOADLIB) 00673 lua_getfield(L, -1, "loadlib"); 00674 lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); 00675 #endif 00676 lua_pushvalue(L, -1); 00677 lua_replace(L, LUA_ENVIRONINDEX); 00678 /* create `loaders' table */ 00679 lua_createtable(L, 0, sizeof(loaders)/sizeof(loaders[0]) - 1); 00680 /* fill it with pre-defined loaders */ 00681 for (i=0; loaders[i] != NULL; i++) { 00682 lua_pushcfunction(L, loaders[i]); 00683 lua_rawseti(L, -2, i+1); 00684 } 00685 lua_setfield(L, -2, "loaders"); /* put it in field `loaders' */ 00686 setpath(L, "path", LUA_PATH, LUA_PATH_DEFAULT); /* set field `path' */ 00687 setpath(L, "cpath", LUA_CPATH, LUA_CPATH_DEFAULT); /* set field `cpath' */ 00688 /* store config information */ 00689 lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATHSEP "\n" LUA_PATH_MARK "\n" 00690 LUA_EXECDIR "\n" LUA_IGMARK); 00691 lua_setfield(L, -2, "config"); 00692 /* set field `loaded' */ 00693 luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 2); 00694 lua_setfield(L, -2, "loaded"); 00695 /* set field `preload' */ 00696 lua_newtable(L); 00697 lua_setfield(L, -2, "preload"); 00698 lua_pushvalue(L, LUA_GLOBALSINDEX); 00699 luaL_register(L, NULL, ll_funcs); /* open lib into global table */ 00700 lua_pop(L, 1); 00701 return 1; /* return 'package' table */ 00702 } 00703
ContextLogger2—ContextLogger2 Logger Daemon Internals—Generated on Mon May 2 13:49:54 2011 by Doxygen 1.6.1