1dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 2dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** $Id: loadlib.c,v 1.111 2012/05/30 12:33:44 roberto Exp $ 3dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Dynamic library loader for Lua 4dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** See Copyright Notice in lua.h 5dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** 6dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** This module contains an implementation of loadlib for Unix systems 7dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** that have dlfcn, an implementation for Windows, and a stub for other 8dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** systems. 9dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 10dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 11dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 12dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 13dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** if needed, includes windows header before everything else 14dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 15dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if defined(_WIN32) 16dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <windows.h> 17dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 18dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 19dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 20dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <stdlib.h> 21dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <string.h> 22dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 23dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 24dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define loadlib_c 25dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_LIB 26dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 27dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lua.h" 28dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 29dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lauxlib.h" 30dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include "lualib.h" 31dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 32dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 33dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 34dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** LUA_PATH and LUA_CPATH are the names of the environment 35dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** variables that Lua check to set its paths. 36dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 37dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined(LUA_PATH) 38dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_PATH "LUA_PATH" 39dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 40dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 41dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined(LUA_CPATH) 42dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_CPATH "LUA_CPATH" 43dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 44dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 45dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 46dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 47dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX 48dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX 49dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 50dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 51dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** LUA_PATH_SEP is the character that separates templates in a path. 52dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** LUA_PATH_MARK is the string that marks the substitution points in a 53dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** template. 54dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** LUA_EXEC_DIR in a Windows path is replaced by the executable's 55dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** directory. 56dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** LUA_IGMARK is a mark to ignore all before it when building the 57dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** luaopen_ function name. 58dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 59dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined (LUA_PATH_SEP) 60dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_PATH_SEP ";" 61dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 62dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined (LUA_PATH_MARK) 63dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_PATH_MARK "?" 64dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 65dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined (LUA_EXEC_DIR) 66dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_EXEC_DIR "!" 67dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 68dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined (LUA_IGMARK) 69dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_IGMARK "-" 70dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 71dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 72dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 73dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 74dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** LUA_CSUBSEP is the character that replaces dots in submodule names 75dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** when searching for a C loader. 76dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** LUA_LSUBSEP is the character that replaces dots in submodule names 77dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** when searching for a Lua loader. 78dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 79dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined(LUA_CSUBSEP) 80dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_CSUBSEP LUA_DIRSEP 81dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 82dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 83dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined(LUA_LSUBSEP) 84dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_LSUBSEP LUA_DIRSEP 85dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 86dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 87dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 88dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* prefix for open functions in C libraries */ 89dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_POF "luaopen_" 90dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 91dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* separator for open functions in C libraries */ 92dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_OFSEP "_" 93dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 94dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 95dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* table (in the registry) that keeps handles for all loaded C libraries */ 96dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define CLIBS "_CLIBS" 97dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 98dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LIB_FAIL "open" 99dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 100dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 101dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* error codes for ll_loadfunc */ 102dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define ERRLIB 1 103dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define ERRFUNC 2 104dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 105dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define setprogdir(L) ((void)0) 106dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 107dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 108dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 109dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** system-dependent functions 110dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 111dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void ll_unloadlib (void *lib); 112dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void *ll_load (lua_State *L, const char *path, int seeglb); 113dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); 114dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 115dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 116dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 117dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if defined(LUA_USE_DLOPEN) 118dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 119dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {======================================================================== 120dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** This is an implementation of loadlib based on the dlfcn interface. 121dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, 122dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least 123dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** as an emulation layer on top of native functions. 124dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** ========================================================================= 125dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 126dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 127dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#include <dlfcn.h> 128dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 129dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void ll_unloadlib (void *lib) { 130dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com dlclose(lib); 131dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 132dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 133dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 134dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void *ll_load (lua_State *L, const char *path, int seeglb) { 135dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); 136dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lib == NULL) lua_pushstring(L, dlerror()); 137dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return lib; 138dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 139dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 140dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 141dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 142dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_CFunction f = (lua_CFunction)dlsym(lib, sym); 143dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (f == NULL) lua_pushstring(L, dlerror()); 144dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return f; 145dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 146dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 147dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */ 148dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 149dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 150dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 151dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#elif defined(LUA_DL_DLL) 152dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 153dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {====================================================================== 154dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** This is an implementation of loadlib for Windows using native functions. 155dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** ======================================================================= 156dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 157dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 158dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#undef setprogdir 159dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 160dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 161dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** optional flags for LoadLibraryEx 162dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 163dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if !defined(LUA_LLE_FLAGS) 164dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LUA_LLE_FLAGS 0 165dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 166dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 167dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 168dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void setprogdir (lua_State *L) { 169dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com char buff[MAX_PATH + 1]; 170dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com char *lb; 171dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com DWORD nsize = sizeof(buff)/sizeof(char); 172dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com DWORD n = GetModuleFileNameA(NULL, buff, nsize); 173dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) 174dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_error(L, "unable to get ModuleFileName"); 175dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 176dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com *lb = '\0'; 177dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); 178dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_remove(L, -2); /* remove original string */ 179dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 180dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 181dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 182dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 183dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void pusherror (lua_State *L) { 184dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int error = GetLastError(); 185dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com char buffer[128]; 186dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 187dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) 188dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushstring(L, buffer); 189dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else 190dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushfstring(L, "system error %d\n", error); 191dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 192dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 193dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void ll_unloadlib (void *lib) { 194dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com FreeLibrary((HMODULE)lib); 195dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 196dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 197dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 198dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void *ll_load (lua_State *L, const char *path, int seeglb) { 199dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); 200dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com (void)(seeglb); /* not used: symbols are 'global' by default */ 201dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lib == NULL) pusherror(L); 202dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return lib; 203dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 204dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 205dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 206dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 207dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); 208dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (f == NULL) pusherror(L); 209dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return f; 210dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 211dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 212dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */ 213dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 214dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 215dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#else 216dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 217dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {====================================================== 218dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** Fallback for other systems 219dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** ======================================================= 220dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 221dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 222dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#undef LIB_FAIL 223dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define LIB_FAIL "absent" 224dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 225dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 226dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define DLMSG "dynamic libraries not enabled; check your Lua installation" 227dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 228dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 229dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void ll_unloadlib (void *lib) { 230dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com (void)(lib); /* not used */ 231dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 232dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 233dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 234dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void *ll_load (lua_State *L, const char *path, int seeglb) { 235dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com (void)(path); (void)(seeglb); /* not used */ 236dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushliteral(L, DLMSG); 237dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return NULL; 238dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 239dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 240dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 241dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 242dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com (void)(lib); (void)(sym); /* not used */ 243dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushliteral(L, DLMSG); 244dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return NULL; 245dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 246dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 247dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */ 248dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 249dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 250dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 251dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void *ll_checkclib (lua_State *L, const char *path) { 252dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com void *plib; 253dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); 254dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, -1, path); 255dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ 256dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 2); /* pop CLIBS table and 'plib' */ 257dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return plib; 258dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 259dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 260dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 261dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void ll_addtoclib (lua_State *L, const char *path, void *plib) { 262dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); 263dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushlightuserdata(L, plib); 264dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -1); 265dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -3, path); /* CLIBS[path] = plib */ 266dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ 267dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); /* pop CLIBS table */ 268dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 269dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 270dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 271dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 272dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib 273dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** handles in list CLIBS 274dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 275dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int gctm (lua_State *L) { 276dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int n = luaL_len(L, 1); 277dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (; n >= 1; n--) { /* for each handle, in reverse order */ 278dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ 279dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ll_unloadlib(lua_touserdata(L, -1)); 280dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); /* pop handle */ 281dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 282dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 0; 283dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 284dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 285dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 286dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int ll_loadfunc (lua_State *L, const char *path, const char *sym) { 287dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com void *reg = ll_checkclib(L, path); /* check loaded C libraries */ 288dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (reg == NULL) { /* must load library? */ 289dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com reg = ll_load(L, path, *sym == '*'); 290dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (reg == NULL) return ERRLIB; /* unable to load library */ 291dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com ll_addtoclib(L, path, reg); 292dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 293dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (*sym == '*') { /* loading only library (no function)? */ 294dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushboolean(L, 1); /* return 'true' */ 295dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 0; /* no errors */ 296dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 297dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 298dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_CFunction f = ll_sym(L, reg, sym); 299dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (f == NULL) 300dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return ERRFUNC; /* unable to find function */ 301dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushcfunction(L, f); /* else create new function */ 302dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 0; /* no errors */ 303dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 304dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 305dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 306dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 307dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int ll_loadlib (lua_State *L) { 308dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *path = luaL_checkstring(L, 1); 309dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *init = luaL_checkstring(L, 2); 310dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int stat = ll_loadfunc(L, path, init); 311dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (stat == 0) /* no errors? */ 312dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; /* return the loaded function */ 313dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { /* error; error message is on stack top */ 314dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushnil(L); 315dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_insert(L, -2); 316dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); 317dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 3; /* return nil, error message, and where */ 318dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 319dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 320dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 321dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 322dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 323dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 324dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {====================================================== 325dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** 'require' function 326dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** ======================================================= 327dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 328dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 329dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 330dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int readable (const char *filename) { 331dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com FILE *f = fopen(filename, "r"); /* try to open file */ 332dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (f == NULL) return 0; /* open failed */ 333dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com fclose(f); 334dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; 335dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 336dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 337dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 338dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *pushnexttemplate (lua_State *L, const char *path) { 339dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *l; 340dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com while (*path == *LUA_PATH_SEP) path++; /* skip separators */ 341dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (*path == '\0') return NULL; /* no more templates */ 342dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com l = strchr(path, *LUA_PATH_SEP); /* find next separator */ 343dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (l == NULL) l = path + strlen(path); 344dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushlstring(L, path, l - path); /* template */ 345dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return l; 346dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 347dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 348dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 349dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *searchpath (lua_State *L, const char *name, 350dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *path, 351dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *sep, 352dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *dirsep) { 353dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_Buffer msg; /* to build error message */ 354dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_buffinit(L, &msg); 355dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (*sep != '\0') /* non-empty separator? */ 356dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ 357dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com while ((path = pushnexttemplate(L, path)) != NULL) { 358dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *filename = luaL_gsub(L, lua_tostring(L, -1), 359dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com LUA_PATH_MARK, name); 360dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_remove(L, -2); /* remove path template */ 361dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (readable(filename)) /* does file exist and is readable? */ 362dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return filename; /* return that file name */ 363dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushfstring(L, "\n\tno file " LUA_QS, filename); 364dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_remove(L, -2); /* remove file name */ 365dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_addvalue(&msg); /* concatenate error msg. entry */ 366dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 367dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_pushresult(&msg); /* create error message */ 368dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return NULL; /* not found */ 369dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 370dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 371dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 372dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int ll_searchpath (lua_State *L) { 373dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *f = searchpath(L, luaL_checkstring(L, 1), 374dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_checkstring(L, 2), 375dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_optstring(L, 3, "."), 376dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_optstring(L, 4, LUA_DIRSEP)); 377dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (f != NULL) return 1; 378dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { /* error message is on top of the stack */ 379dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushnil(L); 380dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_insert(L, -2); 381dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 2; /* return nil + error message */ 382dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 383dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 384dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 385dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 386dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const char *findfile (lua_State *L, const char *name, 387dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *pname, 388dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *dirsep) { 389dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *path; 390dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, lua_upvalueindex(1), pname); 391dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com path = lua_tostring(L, -1); 392dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (path == NULL) 393dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_error(L, LUA_QL("package.%s") " must be a string", pname); 394dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return searchpath(L, name, path, ".", dirsep); 395dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 396dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 397dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 398dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int checkload (lua_State *L, int stat, const char *filename) { 399dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (stat) { /* module loaded successfully? */ 400dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushstring(L, filename); /* will be 2nd argument to module */ 401dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 2; /* return open function and file name */ 402dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 403dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else 404dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return luaL_error(L, "error loading module " LUA_QS 405dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com " from file " LUA_QS ":\n\t%s", 406dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_tostring(L, 1), filename, lua_tostring(L, -1)); 407dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 408dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 409dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 410dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int searcher_Lua (lua_State *L) { 411dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *filename; 412dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name = luaL_checkstring(L, 1); 413dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com filename = findfile(L, name, "path", LUA_LSUBSEP); 414dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (filename == NULL) return 1; /* module not found in this path */ 415dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); 416dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 417dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 418dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 419dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int loadfunc (lua_State *L, const char *filename, const char *modname) { 420dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *funcname; 421dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *mark; 422dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com modname = luaL_gsub(L, modname, ".", LUA_OFSEP); 423dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com mark = strchr(modname, *LUA_IGMARK); 424dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (mark) { 425dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int stat; 426dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com funcname = lua_pushlstring(L, modname, mark - modname); 427dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com funcname = lua_pushfstring(L, LUA_POF"%s", funcname); 428dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com stat = ll_loadfunc(L, filename, funcname); 429dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (stat != ERRFUNC) return stat; 430dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com modname = mark + 1; /* else go ahead and try old-style name */ 431dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 432dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com funcname = lua_pushfstring(L, LUA_POF"%s", modname); 433dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return ll_loadfunc(L, filename, funcname); 434dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 435dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 436dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 437dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int searcher_C (lua_State *L) { 438dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name = luaL_checkstring(L, 1); 439dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); 440dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (filename == NULL) return 1; /* module not found in this path */ 441dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return checkload(L, (loadfunc(L, filename, name) == 0), filename); 442dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 443dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 444dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 445dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int searcher_Croot (lua_State *L) { 446dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *filename; 447dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name = luaL_checkstring(L, 1); 448dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *p = strchr(name, '.'); 449dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int stat; 450dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (p == NULL) return 0; /* is root */ 451dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushlstring(L, name, p - name); 452dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); 453dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (filename == NULL) return 1; /* root not found */ 454dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if ((stat = loadfunc(L, filename, name)) != 0) { 455dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (stat != ERRFUNC) 456dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return checkload(L, 0, filename); /* real error */ 457dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { /* open function not found */ 458dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, 459dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com name, filename); 460dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; 461dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 462dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 463dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushstring(L, filename); /* will be 2nd argument to module */ 464dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 2; 465dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 466dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 467dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 468dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int searcher_preload (lua_State *L) { 469dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name = luaL_checkstring(L, 1); 470dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); 471dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, -1, name); 472dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lua_isnil(L, -1)) /* not found? */ 473dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushfstring(L, "\n\tno field package.preload['%s']", name); 474dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; 475dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 476dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 477dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 478dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void findloader (lua_State *L, const char *name) { 479dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int i; 480dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_Buffer msg; /* to build error message */ 481dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_buffinit(L, &msg); 482dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ 483dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (!lua_istable(L, 3)) 484dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_error(L, LUA_QL("package.searchers") " must be a table"); 485dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* iterate over available searchers to find a loader */ 486dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (i = 1; ; i++) { 487dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_rawgeti(L, 3, i); /* get a searcher */ 488dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lua_isnil(L, -1)) { /* no more searchers? */ 489dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); /* remove nil */ 490dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_pushresult(&msg); /* create error message */ 491dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_error(L, "module " LUA_QS " not found:%s", 492dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com name, lua_tostring(L, -1)); 493dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 494dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushstring(L, name); 495dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_call(L, 1, 2); /* call it */ 496dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lua_isfunction(L, -2)) /* did it find a loader? */ 497dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return; /* module loader found */ 498dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else if (lua_isstring(L, -2)) { /* searcher returned error message? */ 499dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); /* remove extra return */ 500dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_addvalue(&msg); /* concatenate error message */ 501dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 502dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else 503dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 2); /* remove both returns */ 504dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 505dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 506dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 507dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 508dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int ll_require (lua_State *L) { 509dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *name = luaL_checkstring(L, 1); 510dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_settop(L, 1); /* _LOADED table will be at index 2 */ 511dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 512dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, 2, name); /* _LOADED[name] */ 513dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lua_toboolean(L, -1)) /* is it there? */ 514dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; /* package is already loaded */ 515dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* else must load package */ 516dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); /* remove 'getfield' result */ 517dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com findloader(L, name); 518dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushstring(L, name); /* pass name as argument to module loader */ 519dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_insert(L, -2); /* name is 1st argument (before search data) */ 520dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_call(L, 2, 1); /* run loader to load module */ 521dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (!lua_isnil(L, -1)) /* non-nil return? */ 522dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ 523dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, 2, name); 524dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lua_isnil(L, -1)) { /* module did not set a value? */ 525dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushboolean(L, 1); /* use true as result */ 526dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -1); /* extra copy to be returned */ 527dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, 2, name); /* _LOADED[name] = true */ 528dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 529dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; 530dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 531dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 532dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */ 533dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 534dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 535dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 536dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 537dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** {====================================================== 538dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** 'module' function 539dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** ======================================================= 540dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 541dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if defined(LUA_COMPAT_MODULE) 542dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 543dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 544dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** changes the environment variable of calling function 545dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 546dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void set_env (lua_State *L) { 547dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_Debug ar; 548dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lua_getstack(L, 1, &ar) == 0 || 549dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ 550dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_iscfunction(L, -1)) 551dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_error(L, LUA_QL("module") " not called from a Lua function"); 552dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -2); /* copy new environment table to top */ 553dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setupvalue(L, -2, 1); 554dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); /* remove function */ 555dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 556dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 557dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 558dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void dooptions (lua_State *L, int n) { 559dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int i; 560dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (i = 2; i <= n; i++) { 561dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ 562dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, i); /* get option (a function) */ 563dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -2); /* module */ 564dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_call(L, 1, 0); 565dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 566dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 567dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 568dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 569dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 570dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void modinit (lua_State *L, const char *modname) { 571dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *dot; 572dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -1); 573dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "_M"); /* module._M = module */ 574dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushstring(L, modname); 575dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "_NAME"); 576dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com dot = strrchr(modname, '.'); /* look for last dot in module name */ 577dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (dot == NULL) dot = modname; 578dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else dot++; 579dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* set _PACKAGE as package name (full module name minus last part) */ 580dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushlstring(L, modname, dot - modname); 581dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "_PACKAGE"); 582dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 583dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 584dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 585dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int ll_module (lua_State *L) { 586dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *modname = luaL_checkstring(L, 1); 587dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int lastarg = lua_gettop(L); /* last parameter */ 588dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_pushmodule(L, modname, 1); /* get/create module table */ 589dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* check whether table already has a _NAME field */ 590dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, -1, "_NAME"); 591dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (!lua_isnil(L, -1)) /* is table an initialized module? */ 592dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); 593dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { /* no; initialize it */ 594dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); 595dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com modinit(L, modname); 596dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 597dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -1); 598dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com set_env(L); 599dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com dooptions(L, lastarg); 600dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; 601dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 602dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 603dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 604dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int ll_seeall (lua_State *L) { 605dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_checktype(L, 1, LUA_TTABLE); 606dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (!lua_getmetatable(L, 1)) { 607dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_createtable(L, 0, 1); /* create new metatable */ 608dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -1); 609dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setmetatable(L, 1); 610dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 611dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushglobaltable(L); 612dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "__index"); /* mt.__index = _G */ 613dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 0; 614dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 615dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 616dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 617dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* }====================================================== */ 618dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 619dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 620dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 621dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* auxiliary mark (for internal use) */ 622dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#define AUXMARK "\1" 623dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 624dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 625dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com/* 626dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com** return registry.LUA_NOENV as a boolean 627dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com*/ 628dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic int noenv (lua_State *L) { 629dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int b; 630dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 631dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com b = lua_toboolean(L, -1); 632dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); /* remove value */ 633dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return b; 634dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 635dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 636dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 637dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void setpath (lua_State *L, const char *fieldname, const char *envname1, 638dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *envname2, const char *def) { 639dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com const char *path = getenv(envname1); 640dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (path == NULL) /* no environment variable? */ 641dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com path = getenv(envname2); /* try alternative name */ 642dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com if (path == NULL || noenv(L)) /* no environment variable? */ 643dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushstring(L, def); /* use default */ 644dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com else { 645dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ 646dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, 647dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com LUA_PATH_SEP AUXMARK LUA_PATH_SEP); 648dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_gsub(L, path, AUXMARK, def); 649dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_remove(L, -2); 650dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 651dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setprogdir(L); 652dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, fieldname); 653dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 654dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 655dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 656dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const luaL_Reg pk_funcs[] = { 657dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com {"loadlib", ll_loadlib}, 658dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com {"searchpath", ll_searchpath}, 659dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if defined(LUA_COMPAT_MODULE) 660dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com {"seeall", ll_seeall}, 661dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 662dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com {NULL, NULL} 663dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}; 664dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 665dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 666dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic const luaL_Reg ll_funcs[] = { 667dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if defined(LUA_COMPAT_MODULE) 668dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com {"module", ll_module}, 669dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 670dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com {"require", ll_require}, 671dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com {NULL, NULL} 672dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com}; 673dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 674dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 675dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comstatic void createsearcherstable (lua_State *L) { 676dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com static const lua_CFunction searchers[] = 677dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; 678dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com int i; 679dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* create 'searchers' table */ 680dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); 681dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* fill it with pre-defined searchers */ 682dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com for (i=0; searchers[i] != NULL; i++) { 683dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ 684dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushcclosure(L, searchers[i], 1); 685dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_rawseti(L, -2, i+1); 686dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com } 687dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 688dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 689dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 690dff7e11c2000d6745261de046d76b1500a05ece9reed@google.comLUAMOD_API int luaopen_package (lua_State *L) { 691dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* create table CLIBS to keep track of loaded C libraries */ 692dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); 693dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_createtable(L, 0, 1); /* metatable for CLIBS */ 694dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushcfunction(L, gctm); 695dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ 696dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setmetatable(L, -2); 697dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* create `package' table */ 698dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_newlib(L, pk_funcs); 699dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com createsearcherstable(L); 700dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#if defined(LUA_COMPAT_LOADERS) 701dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ 702dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ 703dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com#endif 704dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ 705dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* set field 'path' */ 706dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); 707dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* set field 'cpath' */ 708dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); 709dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* store config information */ 710dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" 711dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); 712dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "config"); 713dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* set field `loaded' */ 714dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); 715dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "loaded"); 716dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com /* set field `preload' */ 717dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 718dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_setfield(L, -2, "preload"); 719dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushglobaltable(L); 720dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ 721dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ 722dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com lua_pop(L, 1); /* pop global table */ 723dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com return 1; /* return 'package' table */ 724dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com} 725dff7e11c2000d6745261de046d76b1500a05ece9reed@google.com 726