lua/loadlib.c

Go to the documentation of this file.
00001 /*
00002 ** $Id: loadlib.c,v 1.108 2011/12/12 16:34:03 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 Windows, and a stub for other
00008 ** systems.
00009 */
00010 
00011 
00012 /*
00013 ** if needed, includes windows header before everything else
00014 */
00015 #if defined(_WIN32)
00016 #include <windows.h>
00017 #endif
00018 
00019 
00020 #include <stdlib.h>
00021 #include <string.h>
00022 
00023 
00024 #define loadlib_c
00025 #define LUA_LIB
00026 
00027 #include "lua.h"
00028 
00029 #include "lauxlib.h"
00030 #include "lualib.h"
00031 
00032 
00033 /*
00034 ** LUA_PATH and LUA_CPATH are the names of the environment
00035 ** variables that Lua check to set its paths.
00036 */
00037 #if !defined(LUA_PATH)
00038 #define LUA_PATH    "LUA_PATH"
00039 #endif
00040 
00041 #if !defined(LUA_CPATH)
00042 #define LUA_CPATH   "LUA_CPATH"
00043 #endif
00044 
00045 #define LUA_PATHSUFFIX      "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
00046 
00047 #define LUA_PATHVERSION     LUA_PATH LUA_PATHSUFFIX
00048 #define LUA_CPATHVERSION    LUA_CPATH LUA_PATHSUFFIX
00049 
00050 /*
00051 ** LUA_PATH_SEP is the character that separates templates in a path.
00052 ** LUA_PATH_MARK is the string that marks the substitution points in a
00053 ** template.
00054 ** LUA_EXEC_DIR in a Windows path is replaced by the executable's
00055 ** directory.
00056 ** LUA_IGMARK is a mark to ignore all before it when building the
00057 ** luaopen_ function name.
00058 */
00059 #if !defined (LUA_PATH_SEP)
00060 #define LUA_PATH_SEP        ";"
00061 #endif
00062 #if !defined (LUA_PATH_MARK)
00063 #define LUA_PATH_MARK       "?"
00064 #endif
00065 #if !defined (LUA_EXEC_DIR)
00066 #define LUA_EXEC_DIR        "!"
00067 #endif
00068 #if !defined (LUA_IGMARK)
00069 #define LUA_IGMARK      "-"
00070 #endif
00071 
00072 
00073 /*
00074 ** LUA_CSUBSEP is the character that replaces dots in submodule names
00075 ** when searching for a C loader.
00076 ** LUA_LSUBSEP is the character that replaces dots in submodule names
00077 ** when searching for a Lua loader.
00078 */
00079 #if !defined(LUA_CSUBSEP)
00080 #define LUA_CSUBSEP     LUA_DIRSEP
00081 #endif
00082 
00083 #if !defined(LUA_LSUBSEP)
00084 #define LUA_LSUBSEP     LUA_DIRSEP
00085 #endif
00086 
00087 
00088 /* prefix for open functions in C libraries */
00089 #define LUA_POF     "luaopen_"
00090 
00091 /* separator for open functions in C libraries */
00092 #define LUA_OFSEP   "_"
00093 
00094 
00095 #define LIBPREFIX   "LOADLIB: "
00096 
00097 #define POF     LUA_POF
00098 #define LIB_FAIL    "open"
00099 
00100 
00101 /* error codes for ll_loadfunc */
00102 #define ERRLIB      1
00103 #define ERRFUNC     2
00104 
00105 #define setprogdir(L)       ((void)0)
00106 
00107 
00108 /*
00109 ** system-dependent functions
00110 */
00111 static void ll_unloadlib (void *lib);
00112 static void *ll_load (lua_State *L, const char *path, int seeglb);
00113 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
00114 
00115 
00116 
00117 #if defined(LUA_USE_DLOPEN)
00118 /*
00119 ** {========================================================================
00120 ** This is an implementation of loadlib based on the dlfcn interface.
00121 ** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD,
00122 ** NetBSD, AIX 4.2, HPUX 11, and  probably most other Unix flavors, at least
00123 ** as an emulation layer on top of native functions.
00124 ** =========================================================================
00125 */
00126 
00127 #include <dlfcn.h>
00128 
00129 static void ll_unloadlib (void *lib) {
00130   dlclose(lib);
00131 }
00132 
00133 
00134 static void *ll_load (lua_State *L, const char *path, int seeglb) {
00135   void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
00136   if (lib == NULL) lua_pushstring(L, dlerror());
00137   return lib;
00138 }
00139 
00140 
00141 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
00142   lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
00143   if (f == NULL) lua_pushstring(L, dlerror());
00144   return f;
00145 }
00146 
00147 /* }====================================================== */
00148 
00149 
00150 
00151 #elif defined(LUA_DL_DLL)
00152 /*
00153 ** {======================================================================
00154 ** This is an implementation of loadlib for Windows using native functions.
00155 ** =======================================================================
00156 */
00157 
00158 #undef setprogdir
00159 
00160 /*
00161 ** optional flags for LoadLibraryEx
00162 */
00163 #if !defined(LUA_LLE_FLAGS)
00164 #define LUA_LLE_FLAGS   0
00165 #endif
00166 
00167 
00168 static void setprogdir (lua_State *L) {
00169   char buff[MAX_PATH + 1];
00170   char *lb;
00171   DWORD nsize = sizeof(buff)/sizeof(char);
00172   DWORD n = GetModuleFileNameA(NULL, buff, nsize);
00173   if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
00174     luaL_error(L, "unable to get ModuleFileName");
00175   else {
00176     *lb = '\0';
00177     luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
00178     lua_remove(L, -2);  /* remove original string */
00179   }
00180 }
00181 
00182 
00183 static void pusherror (lua_State *L) {
00184   int error = GetLastError();
00185   char buffer[128];
00186   if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM,
00187       NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL))
00188     lua_pushstring(L, buffer);
00189   else
00190     lua_pushfstring(L, "system error %d\n", error);
00191 }
00192 
00193 static void ll_unloadlib (void *lib) {
00194   FreeLibrary((HMODULE)lib);
00195 }
00196 
00197 
00198 static void *ll_load (lua_State *L, const char *path, int seeglb) {
00199   HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
00200   (void)(seeglb);  /* not used: symbols are 'global' by default */
00201   if (lib == NULL) pusherror(L);
00202   return lib;
00203 }
00204 
00205 
00206 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
00207   lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
00208   if (f == NULL) pusherror(L);
00209   return f;
00210 }
00211 
00212 /* }====================================================== */
00213 
00214 
00215 #else
00216 /*
00217 ** {======================================================
00218 ** Fallback for other systems
00219 ** =======================================================
00220 */
00221 
00222 #undef LIB_FAIL
00223 #define LIB_FAIL    "absent"
00224 
00225 
00226 #define DLMSG   "dynamic libraries not enabled; check your Lua installation"
00227 
00228 
00229 static void ll_unloadlib (void *lib) {
00230   (void)(lib);  /* not used */
00231 }
00232 
00233 
00234 static void *ll_load (lua_State *L, const char *path, int seeglb) {
00235   (void)(path); (void)(seeglb);  /* not used */
00236   lua_pushliteral(L, DLMSG);
00237   return NULL;
00238 }
00239 
00240 
00241 static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
00242   (void)(lib); (void)(sym);  /* not used */
00243   lua_pushliteral(L, DLMSG);
00244   return NULL;
00245 }
00246 
00247 /* }====================================================== */
00248 #endif
00249 
00250 
00251 
00252 static void **ll_register (lua_State *L, const char *path) {
00253   void **plib;
00254   lua_pushfstring(L, "%s%s", LIBPREFIX, path);
00255   lua_gettable(L, LUA_REGISTRYINDEX);  /* check library in registry? */
00256   if (!lua_isnil(L, -1))  /* is there an entry? */
00257     plib = (void **)lua_touserdata(L, -1);
00258   else {  /* no entry yet; create one */
00259     lua_pop(L, 1);  /* remove result from gettable */
00260     plib = (void **)lua_newuserdata(L, sizeof(const void *));
00261     *plib = NULL;
00262     luaL_setmetatable(L, "_LOADLIB");
00263     lua_pushfstring(L, "%s%s", LIBPREFIX, path);
00264     lua_pushvalue(L, -2);
00265     lua_settable(L, LUA_REGISTRYINDEX);
00266   }
00267   return plib;
00268 }
00269 
00270 
00271 /*
00272 ** __gc tag method: calls library's `ll_unloadlib' function with the lib
00273 ** handle
00274 */
00275 static int gctm (lua_State *L) {
00276   void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
00277   if (*lib) ll_unloadlib(*lib);
00278   *lib = NULL;  /* mark library as closed */
00279   return 0;
00280 }
00281 
00282 
00283 static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
00284   void **reg = ll_register(L, path);
00285   if (*reg == NULL) *reg = ll_load(L, path, *sym == '*');
00286   if (*reg == NULL) return ERRLIB;  /* unable to load library */
00287   if (*sym == '*') {  /* loading only library (no function)? */
00288     lua_pushboolean(L, 1);  /* return 'true' */
00289     return 0;  /* no errors */
00290   }
00291   else {
00292     lua_CFunction f = ll_sym(L, *reg, sym);
00293     if (f == NULL)
00294       return ERRFUNC;  /* unable to find function */
00295     lua_pushcfunction(L, f);  /* else create new function */
00296     return 0;  /* no errors */
00297   }
00298 }
00299 
00300 
00301 static int ll_loadlib (lua_State *L) {
00302   const char *path = luaL_checkstring(L, 1);
00303   const char *init = luaL_checkstring(L, 2);
00304   int stat = ll_loadfunc(L, path, init);
00305   if (stat == 0)  /* no errors? */
00306     return 1;  /* return the loaded function */
00307   else {  /* error; error message is on stack top */
00308     lua_pushnil(L);
00309     lua_insert(L, -2);
00310     lua_pushstring(L, (stat == ERRLIB) ?  LIB_FAIL : "init");
00311     return 3;  /* return nil, error message, and where */
00312   }
00313 }
00314 
00315 
00316 
00317 /*
00318 ** {======================================================
00319 ** 'require' function
00320 ** =======================================================
00321 */
00322 
00323 
00324 static int readable (const char *filename) {
00325   FILE *f = fopen(filename, "r");  /* try to open file */
00326   if (f == NULL) return 0;  /* open failed */
00327   fclose(f);
00328   return 1;
00329 }
00330 
00331 
00332 static const char *pushnexttemplate (lua_State *L, const char *path) {
00333   const char *l;
00334   while (*path == *LUA_PATH_SEP) path++;  /* skip separators */
00335   if (*path == '\0') return NULL;  /* no more templates */
00336   l = strchr(path, *LUA_PATH_SEP);  /* find next separator */
00337   if (l == NULL) l = path + strlen(path);
00338   lua_pushlstring(L, path, l - path);  /* template */
00339   return l;
00340 }
00341 
00342 
00343 static const char *searchpath (lua_State *L, const char *name,
00344                                              const char *path,
00345                                              const char *sep,
00346                                              const char *dirsep) {
00347   luaL_Buffer msg;  /* to build error message */
00348   luaL_buffinit(L, &msg);
00349   if (*sep != '\0')  /* non-empty separator? */
00350     name = luaL_gsub(L, name, sep, dirsep);  /* replace it by 'dirsep' */
00351   while ((path = pushnexttemplate(L, path)) != NULL) {
00352     const char *filename = luaL_gsub(L, lua_tostring(L, -1),
00353                                      LUA_PATH_MARK, name);
00354     lua_remove(L, -2);  /* remove path template */
00355     if (readable(filename))  /* does file exist and is readable? */
00356       return filename;  /* return that file name */
00357     lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
00358     lua_remove(L, -2);  /* remove file name */
00359     luaL_addvalue(&msg);  /* concatenate error msg. entry */
00360   }
00361   luaL_pushresult(&msg);  /* create error message */
00362   return NULL;  /* not found */
00363 }
00364 
00365 
00366 static int ll_searchpath (lua_State *L) {
00367   const char *f = searchpath(L, luaL_checkstring(L, 1),
00368                                 luaL_checkstring(L, 2),
00369                                 luaL_optstring(L, 3, "."),
00370                                 luaL_optstring(L, 4, LUA_DIRSEP));
00371   if (f != NULL) return 1;
00372   else {  /* error message is on top of the stack */
00373     lua_pushnil(L);
00374     lua_insert(L, -2);
00375     return 2;  /* return nil + error message */
00376   }
00377 }
00378 
00379 
00380 static const char *findfile (lua_State *L, const char *name,
00381                                            const char *pname,
00382                                            const char *dirsep) {
00383   const char *path;
00384   lua_getfield(L, lua_upvalueindex(1), pname);
00385   path = lua_tostring(L, -1);
00386   if (path == NULL)
00387     luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
00388   return searchpath(L, name, path, ".", dirsep);
00389 }
00390 
00391 
00392 static int checkload (lua_State *L, int stat, const char *filename) {
00393   if (stat) {  /* module loaded successfully? */
00394     lua_pushstring(L, filename);  /* will be 2nd argument to module */
00395     return 2;  /* return open function and file name */
00396   }
00397   else
00398     return luaL_error(L, "error loading module " LUA_QS
00399                          " from file " LUA_QS ":\n\t%s",
00400                           lua_tostring(L, 1), filename, lua_tostring(L, -1));
00401 }
00402 
00403 
00404 static int searcher_Lua (lua_State *L) {
00405   const char *filename;
00406   const char *name = luaL_checkstring(L, 1);
00407   filename = findfile(L, name, "path", LUA_LSUBSEP);
00408   if (filename == NULL) return 1;  /* module not found in this path */
00409   return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
00410 }
00411 
00412 
00413 static int loadfunc (lua_State *L, const char *filename, const char *modname) {
00414   const char *funcname;
00415   const char *mark;
00416   modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
00417   mark = strchr(modname, *LUA_IGMARK);
00418   if (mark) {
00419     int stat;
00420     funcname = lua_pushlstring(L, modname, mark - modname);
00421     funcname = lua_pushfstring(L, POF"%s", funcname);
00422     stat = ll_loadfunc(L, filename, funcname);
00423     if (stat != ERRFUNC) return stat;
00424     modname = mark + 1;  /* else go ahead and try old-style name */
00425   }
00426   funcname = lua_pushfstring(L, POF"%s", modname);
00427   return ll_loadfunc(L, filename, funcname);
00428 }
00429 
00430 
00431 static int searcher_C (lua_State *L) {
00432   const char *name = luaL_checkstring(L, 1);
00433   const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
00434   if (filename == NULL) return 1;  /* module not found in this path */
00435   return checkload(L, (loadfunc(L, filename, name) == 0), filename);
00436 }
00437 
00438 
00439 static int searcher_Croot (lua_State *L) {
00440   const char *filename;
00441   const char *name = luaL_checkstring(L, 1);
00442   const char *p = strchr(name, '.');
00443   int stat;
00444   if (p == NULL) return 0;  /* is root */
00445   lua_pushlstring(L, name, p - name);
00446   filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
00447   if (filename == NULL) return 1;  /* root not found */
00448   if ((stat = loadfunc(L, filename, name)) != 0) {
00449     if (stat != ERRFUNC)
00450       return checkload(L, 0, filename);  /* real error */
00451     else {  /* open function not found */
00452       lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
00453                          name, filename);
00454       return 1;
00455     }
00456   }
00457   lua_pushstring(L, filename);  /* will be 2nd argument to module */
00458   return 2;
00459 }
00460 
00461 
00462 static int searcher_preload (lua_State *L) {
00463   const char *name = luaL_checkstring(L, 1);
00464   lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD");
00465   lua_getfield(L, -1, name);
00466   if (lua_isnil(L, -1))  /* not found? */
00467     lua_pushfstring(L, "\n\tno field package.preload['%s']", name);
00468   return 1;
00469 }
00470 
00471 
00472 static void findloader (lua_State *L, const char *name) {
00473   int i;
00474   luaL_Buffer msg;  /* to build error message */
00475   luaL_buffinit(L, &msg);
00476   lua_getfield(L, lua_upvalueindex(1), "searchers");  /* will be at index 3 */
00477   if (!lua_istable(L, 3))
00478     luaL_error(L, LUA_QL("package.searchers") " must be a table");
00479   /*  iterate over available seachers to find a loader */
00480   for (i = 1; ; i++) {
00481     lua_rawgeti(L, 3, i);  /* get a seacher */
00482     if (lua_isnil(L, -1)) {  /* no more searchers? */
00483       lua_pop(L, 1);  /* remove nil */
00484       luaL_pushresult(&msg);  /* create error message */
00485       luaL_error(L, "module " LUA_QS " not found:%s",
00486                     name, lua_tostring(L, -1));
00487     }
00488     lua_pushstring(L, name);
00489     lua_call(L, 1, 2);  /* call it */
00490     if (lua_isfunction(L, -2))  /* did it find a loader? */
00491       return;  /* module loader found */
00492     else if (lua_isstring(L, -2)) {  /* searcher returned error message? */
00493       lua_pop(L, 1);  /* remove extra return */
00494       luaL_addvalue(&msg);  /* concatenate error message */
00495     }
00496     else
00497       lua_pop(L, 2);  /* remove both returns */
00498   }
00499 }
00500 
00501 
00502 static int ll_require (lua_State *L) {
00503   const char *name = luaL_checkstring(L, 1);
00504   lua_settop(L, 1);  /* _LOADED table will be at index 2 */
00505   lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
00506   lua_getfield(L, 2, name);  /* _LOADED[name] */
00507   if (lua_toboolean(L, -1))  /* is it there? */
00508     return 1;  /* package is already loaded */
00509   /* else must load package */
00510   lua_pop(L, 1);  /* remove 'getfield' result */
00511   findloader(L, name);
00512   lua_pushstring(L, name);  /* pass name as argument to module loader */
00513   lua_insert(L, -2);  /* name is 1st argument (before search data) */
00514   lua_call(L, 2, 1);  /* run loader to load module */
00515   if (!lua_isnil(L, -1))  /* non-nil return? */
00516     lua_setfield(L, 2, name);  /* _LOADED[name] = returned value */
00517   lua_getfield(L, 2, name);
00518   if (lua_isnil(L, -1)) {   /* module did not set a value? */
00519     lua_pushboolean(L, 1);  /* use true as result */
00520     lua_pushvalue(L, -1);  /* extra copy to be returned */
00521     lua_setfield(L, 2, name);  /* _LOADED[name] = true */
00522   }
00523   return 1;
00524 }
00525 
00526 /* }====================================================== */
00527 
00528 
00529 
00530 /*
00531 ** {======================================================
00532 ** 'module' function
00533 ** =======================================================
00534 */
00535 #if defined(LUA_COMPAT_MODULE)
00536 
00537 /*
00538 ** changes the environment variable of calling function
00539 */
00540 static void set_env (lua_State *L) {
00541   lua_Debug ar;
00542   if (lua_getstack(L, 1, &ar) == 0 ||
00543       lua_getinfo(L, "f", &ar) == 0 ||  /* get calling function */
00544       lua_iscfunction(L, -1))
00545     luaL_error(L, LUA_QL("module") " not called from a Lua function");
00546   lua_pushvalue(L, -2);  /* copy new environment table to top */
00547   lua_setupvalue(L, -2, 1);
00548   lua_pop(L, 1);  /* remove function */
00549 }
00550 
00551 
00552 static void dooptions (lua_State *L, int n) {
00553   int i;
00554   for (i = 2; i <= n; i++) {
00555     if (lua_isfunction(L, i)) {  /* avoid 'calling' extra info. */
00556       lua_pushvalue(L, i);  /* get option (a function) */
00557       lua_pushvalue(L, -2);  /* module */
00558       lua_call(L, 1, 0);
00559     }
00560   }
00561 }
00562 
00563 
00564 static void modinit (lua_State *L, const char *modname) {
00565   const char *dot;
00566   lua_pushvalue(L, -1);
00567   lua_setfield(L, -2, "_M");  /* module._M = module */
00568   lua_pushstring(L, modname);
00569   lua_setfield(L, -2, "_NAME");
00570   dot = strrchr(modname, '.');  /* look for last dot in module name */
00571   if (dot == NULL) dot = modname;
00572   else dot++;
00573   /* set _PACKAGE as package name (full module name minus last part) */
00574   lua_pushlstring(L, modname, dot - modname);
00575   lua_setfield(L, -2, "_PACKAGE");
00576 }
00577 
00578 
00579 static int ll_module (lua_State *L) {
00580   const char *modname = luaL_checkstring(L, 1);
00581   int lastarg = lua_gettop(L);  /* last parameter */
00582   luaL_pushmodule(L, modname, 1);  /* get/create module table */
00583   /* check whether table already has a _NAME field */
00584   lua_getfield(L, -1, "_NAME");
00585   if (!lua_isnil(L, -1))  /* is table an initialized module? */
00586     lua_pop(L, 1);
00587   else {  /* no; initialize it */
00588     lua_pop(L, 1);
00589     modinit(L, modname);
00590   }
00591   lua_pushvalue(L, -1);
00592   set_env(L);
00593   dooptions(L, lastarg);
00594   return 1;
00595 }
00596 
00597 
00598 static int ll_seeall (lua_State *L) {
00599   luaL_checktype(L, 1, LUA_TTABLE);
00600   if (!lua_getmetatable(L, 1)) {
00601     lua_createtable(L, 0, 1); /* create new metatable */
00602     lua_pushvalue(L, -1);
00603     lua_setmetatable(L, 1);
00604   }
00605   lua_pushglobaltable(L);
00606   lua_setfield(L, -2, "__index");  /* mt.__index = _G */
00607   return 0;
00608 }
00609 
00610 #endif
00611 /* }====================================================== */
00612 
00613 
00614 
00615 /* auxiliary mark (for internal use) */
00616 #define AUXMARK     "\1"
00617 
00618 
00619 /*
00620 ** return registry.LUA_NOENV as a boolean
00621 */
00622 static int noenv (lua_State *L) {
00623   int b;
00624   lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
00625   b = lua_toboolean(L, -1);
00626   lua_pop(L, 1);  /* remove value */
00627   return b;
00628 }
00629 
00630 
00631 static void setpath (lua_State *L, const char *fieldname, const char *envname1,
00632                                    const char *envname2, const char *def) {
00633   const char *path = getenv(envname1);
00634   if (path == NULL)  /* no environment variable? */
00635     path = getenv(envname2);  /* try alternative name */
00636   if (path == NULL || noenv(L))  /* no environment variable? */
00637     lua_pushstring(L, def);  /* use default */
00638   else {
00639     /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
00640     path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
00641                               LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
00642     luaL_gsub(L, path, AUXMARK, def);
00643     lua_remove(L, -2);
00644   }
00645   setprogdir(L);
00646   lua_setfield(L, -2, fieldname);
00647 }
00648 
00649 
00650 static const luaL_Reg pk_funcs[] = {
00651   {"loadlib", ll_loadlib},
00652   {"searchpath", ll_searchpath},
00653 #if defined(LUA_COMPAT_MODULE)
00654   {"seeall", ll_seeall},
00655 #endif
00656   {NULL, NULL}
00657 };
00658 
00659 
00660 static const luaL_Reg ll_funcs[] = {
00661 #if defined(LUA_COMPAT_MODULE)
00662   {"module", ll_module},
00663 #endif
00664   {"require", ll_require},
00665   {NULL, NULL}
00666 };
00667 
00668 
00669 static const lua_CFunction searchers[] =
00670   {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL};
00671 
00672 
00673 LUAMOD_API int luaopen_package (lua_State *L) {
00674   int i;
00675   /* create new type _LOADLIB */
00676   luaL_newmetatable(L, "_LOADLIB");
00677   lua_pushcfunction(L, gctm);
00678   lua_setfield(L, -2, "__gc");
00679   /* create `package' table */
00680   luaL_newlib(L, pk_funcs);
00681   /* create 'searchers' table */
00682   lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0);
00683   /* fill it with pre-defined searchers */
00684   for (i=0; searchers[i] != NULL; i++) {
00685     lua_pushvalue(L, -2);  /* set 'package' as upvalue for all searchers */
00686     lua_pushcclosure(L, searchers[i], 1);
00687     lua_rawseti(L, -2, i+1);
00688   }
00689 #if defined(LUA_COMPAT_LOADERS)
00690   lua_pushvalue(L, -1);  /* make a copy of 'searchers' table */
00691   lua_setfield(L, -3, "loaders");  /* put it in field `loaders' */
00692 #endif
00693   lua_setfield(L, -2, "searchers");  /* put it in field 'searchers' */
00694   /* set field 'path' */
00695   setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT);
00696   /* set field 'cpath' */
00697   setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT);
00698   /* store config information */
00699   lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
00700                      LUA_EXEC_DIR "\n" LUA_IGMARK "\n");
00701   lua_setfield(L, -2, "config");
00702   /* set field `loaded' */
00703   luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED");
00704   lua_setfield(L, -2, "loaded");
00705   /* set field `preload' */
00706   luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD");
00707   lua_setfield(L, -2, "preload");
00708   lua_pushglobaltable(L);
00709   lua_pushvalue(L, -2);  /* set 'package' as upvalue for next lib */
00710   luaL_setfuncs(L, ll_funcs, 1);  /* open lib into global table */
00711   lua_pop(L, 1);  /* pop global table */
00712   return 1;  /* return 'package' table */
00713 }
00714 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Fri May 25 2012 01:03:04 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs