116a5fed65808adf648004b34f98718301d718fa2darylm/* 216a5fed65808adf648004b34f98718301d718fa2darylm** $Id: loadlib.c,v 1.111.1.1 2013/04/12 18:48:47 roberto Exp $ 316a5fed65808adf648004b34f98718301d718fa2darylm** Dynamic library loader for Lua 416a5fed65808adf648004b34f98718301d718fa2darylm** See Copyright Notice in lua.h 516a5fed65808adf648004b34f98718301d718fa2darylm** 616a5fed65808adf648004b34f98718301d718fa2darylm** This module contains an implementation of loadlib for Unix systems 716a5fed65808adf648004b34f98718301d718fa2darylm** that have dlfcn, an implementation for Windows, and a stub for other 816a5fed65808adf648004b34f98718301d718fa2darylm** systems. 916a5fed65808adf648004b34f98718301d718fa2darylm*/ 1016a5fed65808adf648004b34f98718301d718fa2darylm 1116a5fed65808adf648004b34f98718301d718fa2darylm 1216a5fed65808adf648004b34f98718301d718fa2darylm/* 1316a5fed65808adf648004b34f98718301d718fa2darylm** if needed, includes windows header before everything else 1416a5fed65808adf648004b34f98718301d718fa2darylm*/ 1516a5fed65808adf648004b34f98718301d718fa2darylm#if defined(_WIN32) && !defined(UEFI_C_SOURCE) && !defined(_DOS_WATCOM) 1616a5fed65808adf648004b34f98718301d718fa2darylm#include <windows.h> 1716a5fed65808adf648004b34f98718301d718fa2darylm#endif 1816a5fed65808adf648004b34f98718301d718fa2darylm 1916a5fed65808adf648004b34f98718301d718fa2darylm 2016a5fed65808adf648004b34f98718301d718fa2darylm#include <stdlib.h> 2116a5fed65808adf648004b34f98718301d718fa2darylm#include <string.h> 2216a5fed65808adf648004b34f98718301d718fa2darylm 2316a5fed65808adf648004b34f98718301d718fa2darylm 2416a5fed65808adf648004b34f98718301d718fa2darylm#define loadlib_c 2516a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_LIB 2616a5fed65808adf648004b34f98718301d718fa2darylm 2716a5fed65808adf648004b34f98718301d718fa2darylm#include "lua.h" 2816a5fed65808adf648004b34f98718301d718fa2darylm 2916a5fed65808adf648004b34f98718301d718fa2darylm#include "lauxlib.h" 3016a5fed65808adf648004b34f98718301d718fa2darylm#include "lualib.h" 3116a5fed65808adf648004b34f98718301d718fa2darylm 3216a5fed65808adf648004b34f98718301d718fa2darylm 3316a5fed65808adf648004b34f98718301d718fa2darylm/* 3416a5fed65808adf648004b34f98718301d718fa2darylm** LUA_PATH and LUA_CPATH are the names of the environment 3516a5fed65808adf648004b34f98718301d718fa2darylm** variables that Lua check to set its paths. 3616a5fed65808adf648004b34f98718301d718fa2darylm*/ 3716a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_PATH) 3816a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_PATH "LUA_PATH" 3916a5fed65808adf648004b34f98718301d718fa2darylm#endif 4016a5fed65808adf648004b34f98718301d718fa2darylm 4116a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_CPATH) 4216a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_CPATH "LUA_CPATH" 4316a5fed65808adf648004b34f98718301d718fa2darylm#endif 4416a5fed65808adf648004b34f98718301d718fa2darylm 4516a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR 4616a5fed65808adf648004b34f98718301d718fa2darylm 4716a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_PATHVERSION LUA_PATH LUA_PATHSUFFIX 4816a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_CPATHVERSION LUA_CPATH LUA_PATHSUFFIX 4916a5fed65808adf648004b34f98718301d718fa2darylm 5016a5fed65808adf648004b34f98718301d718fa2darylm/* 5116a5fed65808adf648004b34f98718301d718fa2darylm** LUA_PATH_SEP is the character that separates templates in a path. 5216a5fed65808adf648004b34f98718301d718fa2darylm** LUA_PATH_MARK is the string that marks the substitution points in a 5316a5fed65808adf648004b34f98718301d718fa2darylm** template. 5416a5fed65808adf648004b34f98718301d718fa2darylm** LUA_EXEC_DIR in a Windows path is replaced by the executable's 5516a5fed65808adf648004b34f98718301d718fa2darylm** directory. 5616a5fed65808adf648004b34f98718301d718fa2darylm** LUA_IGMARK is a mark to ignore all before it when building the 5716a5fed65808adf648004b34f98718301d718fa2darylm** luaopen_ function name. 5816a5fed65808adf648004b34f98718301d718fa2darylm*/ 5916a5fed65808adf648004b34f98718301d718fa2darylm#if !defined (LUA_PATH_SEP) 6016a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_PATH_SEP ";" 6116a5fed65808adf648004b34f98718301d718fa2darylm#endif 6216a5fed65808adf648004b34f98718301d718fa2darylm#if !defined (LUA_PATH_MARK) 6316a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_PATH_MARK "?" 6416a5fed65808adf648004b34f98718301d718fa2darylm#endif 6516a5fed65808adf648004b34f98718301d718fa2darylm#if !defined (LUA_EXEC_DIR) 6616a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_EXEC_DIR "!" 6716a5fed65808adf648004b34f98718301d718fa2darylm#endif 6816a5fed65808adf648004b34f98718301d718fa2darylm#if !defined (LUA_IGMARK) 6916a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_IGMARK "-" 7016a5fed65808adf648004b34f98718301d718fa2darylm#endif 7116a5fed65808adf648004b34f98718301d718fa2darylm 7216a5fed65808adf648004b34f98718301d718fa2darylm 7316a5fed65808adf648004b34f98718301d718fa2darylm/* 7416a5fed65808adf648004b34f98718301d718fa2darylm** LUA_CSUBSEP is the character that replaces dots in submodule names 7516a5fed65808adf648004b34f98718301d718fa2darylm** when searching for a C loader. 7616a5fed65808adf648004b34f98718301d718fa2darylm** LUA_LSUBSEP is the character that replaces dots in submodule names 7716a5fed65808adf648004b34f98718301d718fa2darylm** when searching for a Lua loader. 7816a5fed65808adf648004b34f98718301d718fa2darylm*/ 7916a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_CSUBSEP) 8016a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_CSUBSEP LUA_DIRSEP 8116a5fed65808adf648004b34f98718301d718fa2darylm#endif 8216a5fed65808adf648004b34f98718301d718fa2darylm 8316a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_LSUBSEP) 8416a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_LSUBSEP LUA_DIRSEP 8516a5fed65808adf648004b34f98718301d718fa2darylm#endif 8616a5fed65808adf648004b34f98718301d718fa2darylm 8716a5fed65808adf648004b34f98718301d718fa2darylm 8816a5fed65808adf648004b34f98718301d718fa2darylm/* prefix for open functions in C libraries */ 8916a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_POF "luaopen_" 9016a5fed65808adf648004b34f98718301d718fa2darylm 9116a5fed65808adf648004b34f98718301d718fa2darylm/* separator for open functions in C libraries */ 9216a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_OFSEP "_" 9316a5fed65808adf648004b34f98718301d718fa2darylm 9416a5fed65808adf648004b34f98718301d718fa2darylm 9516a5fed65808adf648004b34f98718301d718fa2darylm/* table (in the registry) that keeps handles for all loaded C libraries */ 9616a5fed65808adf648004b34f98718301d718fa2darylm#define CLIBS "_CLIBS" 9716a5fed65808adf648004b34f98718301d718fa2darylm 9816a5fed65808adf648004b34f98718301d718fa2darylm#define LIB_FAIL "open" 9916a5fed65808adf648004b34f98718301d718fa2darylm 10016a5fed65808adf648004b34f98718301d718fa2darylm 10116a5fed65808adf648004b34f98718301d718fa2darylm/* error codes for ll_loadfunc */ 10216a5fed65808adf648004b34f98718301d718fa2darylm#define ERRLIB 1 10316a5fed65808adf648004b34f98718301d718fa2darylm#define ERRFUNC 2 10416a5fed65808adf648004b34f98718301d718fa2darylm 10516a5fed65808adf648004b34f98718301d718fa2darylm#define setprogdir(L) ((void)0) 10616a5fed65808adf648004b34f98718301d718fa2darylm 10716a5fed65808adf648004b34f98718301d718fa2darylm 10816a5fed65808adf648004b34f98718301d718fa2darylm/* 10916a5fed65808adf648004b34f98718301d718fa2darylm** system-dependent functions 11016a5fed65808adf648004b34f98718301d718fa2darylm*/ 11116a5fed65808adf648004b34f98718301d718fa2darylmstatic void ll_unloadlib (void *lib); 11216a5fed65808adf648004b34f98718301d718fa2darylmstatic void *ll_load (lua_State *L, const char *path, int seeglb); 11316a5fed65808adf648004b34f98718301d718fa2darylmstatic lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym); 11416a5fed65808adf648004b34f98718301d718fa2darylm 11516a5fed65808adf648004b34f98718301d718fa2darylm 11616a5fed65808adf648004b34f98718301d718fa2darylm 11716a5fed65808adf648004b34f98718301d718fa2darylm#if defined(LUA_USE_DLOPEN) 11816a5fed65808adf648004b34f98718301d718fa2darylm/* 11916a5fed65808adf648004b34f98718301d718fa2darylm** {======================================================================== 12016a5fed65808adf648004b34f98718301d718fa2darylm** This is an implementation of loadlib based on the dlfcn interface. 12116a5fed65808adf648004b34f98718301d718fa2darylm** The dlfcn interface is available in Linux, SunOS, Solaris, IRIX, FreeBSD, 12216a5fed65808adf648004b34f98718301d718fa2darylm** NetBSD, AIX 4.2, HPUX 11, and probably most other Unix flavors, at least 12316a5fed65808adf648004b34f98718301d718fa2darylm** as an emulation layer on top of native functions. 12416a5fed65808adf648004b34f98718301d718fa2darylm** ========================================================================= 12516a5fed65808adf648004b34f98718301d718fa2darylm*/ 12616a5fed65808adf648004b34f98718301d718fa2darylm 12716a5fed65808adf648004b34f98718301d718fa2darylm#include <dlfcn.h> 12816a5fed65808adf648004b34f98718301d718fa2darylm 12916a5fed65808adf648004b34f98718301d718fa2darylmstatic void ll_unloadlib (void *lib) { 13016a5fed65808adf648004b34f98718301d718fa2darylm dlclose(lib); 13116a5fed65808adf648004b34f98718301d718fa2darylm} 13216a5fed65808adf648004b34f98718301d718fa2darylm 13316a5fed65808adf648004b34f98718301d718fa2darylm 13416a5fed65808adf648004b34f98718301d718fa2darylmstatic void *ll_load (lua_State *L, const char *path, int seeglb) { 13516a5fed65808adf648004b34f98718301d718fa2darylm void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL)); 13616a5fed65808adf648004b34f98718301d718fa2darylm if (lib == NULL) lua_pushstring(L, dlerror()); 13716a5fed65808adf648004b34f98718301d718fa2darylm return lib; 13816a5fed65808adf648004b34f98718301d718fa2darylm} 13916a5fed65808adf648004b34f98718301d718fa2darylm 14016a5fed65808adf648004b34f98718301d718fa2darylm 14116a5fed65808adf648004b34f98718301d718fa2darylmstatic lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 14216a5fed65808adf648004b34f98718301d718fa2darylm lua_CFunction f = (lua_CFunction)dlsym(lib, sym); 14316a5fed65808adf648004b34f98718301d718fa2darylm if (f == NULL) lua_pushstring(L, dlerror()); 14416a5fed65808adf648004b34f98718301d718fa2darylm return f; 14516a5fed65808adf648004b34f98718301d718fa2darylm} 14616a5fed65808adf648004b34f98718301d718fa2darylm 14716a5fed65808adf648004b34f98718301d718fa2darylm/* }====================================================== */ 14816a5fed65808adf648004b34f98718301d718fa2darylm 14916a5fed65808adf648004b34f98718301d718fa2darylm 15016a5fed65808adf648004b34f98718301d718fa2darylm 15116a5fed65808adf648004b34f98718301d718fa2darylm#elif defined(LUA_DL_DLL) 15216a5fed65808adf648004b34f98718301d718fa2darylm/* 15316a5fed65808adf648004b34f98718301d718fa2darylm** {====================================================================== 15416a5fed65808adf648004b34f98718301d718fa2darylm** This is an implementation of loadlib for Windows using native functions. 15516a5fed65808adf648004b34f98718301d718fa2darylm** ======================================================================= 15616a5fed65808adf648004b34f98718301d718fa2darylm*/ 15716a5fed65808adf648004b34f98718301d718fa2darylm 15816a5fed65808adf648004b34f98718301d718fa2darylm#undef setprogdir 15916a5fed65808adf648004b34f98718301d718fa2darylm 16016a5fed65808adf648004b34f98718301d718fa2darylm/* 16116a5fed65808adf648004b34f98718301d718fa2darylm** optional flags for LoadLibraryEx 16216a5fed65808adf648004b34f98718301d718fa2darylm*/ 16316a5fed65808adf648004b34f98718301d718fa2darylm#if !defined(LUA_LLE_FLAGS) 16416a5fed65808adf648004b34f98718301d718fa2darylm#define LUA_LLE_FLAGS 0 16516a5fed65808adf648004b34f98718301d718fa2darylm#endif 16616a5fed65808adf648004b34f98718301d718fa2darylm 16716a5fed65808adf648004b34f98718301d718fa2darylm 16816a5fed65808adf648004b34f98718301d718fa2darylmstatic void setprogdir (lua_State *L) { 16916a5fed65808adf648004b34f98718301d718fa2darylm char buff[MAX_PATH + 1]; 17016a5fed65808adf648004b34f98718301d718fa2darylm char *lb; 17116a5fed65808adf648004b34f98718301d718fa2darylm DWORD nsize = sizeof(buff)/sizeof(char); 17216a5fed65808adf648004b34f98718301d718fa2darylm DWORD n = GetModuleFileNameA(NULL, buff, nsize); 17316a5fed65808adf648004b34f98718301d718fa2darylm if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL) 17416a5fed65808adf648004b34f98718301d718fa2darylm luaL_error(L, "unable to get ModuleFileName"); 17516a5fed65808adf648004b34f98718301d718fa2darylm else { 17616a5fed65808adf648004b34f98718301d718fa2darylm *lb = '\0'; 17716a5fed65808adf648004b34f98718301d718fa2darylm luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff); 17816a5fed65808adf648004b34f98718301d718fa2darylm lua_remove(L, -2); /* remove original string */ 17916a5fed65808adf648004b34f98718301d718fa2darylm } 18016a5fed65808adf648004b34f98718301d718fa2darylm} 18116a5fed65808adf648004b34f98718301d718fa2darylm 18216a5fed65808adf648004b34f98718301d718fa2darylm 18316a5fed65808adf648004b34f98718301d718fa2darylmstatic void pusherror (lua_State *L) { 18416a5fed65808adf648004b34f98718301d718fa2darylm int error = GetLastError(); 18516a5fed65808adf648004b34f98718301d718fa2darylm char buffer[128]; 18616a5fed65808adf648004b34f98718301d718fa2darylm if (FormatMessageA(FORMAT_MESSAGE_IGNORE_INSERTS | FORMAT_MESSAGE_FROM_SYSTEM, 18716a5fed65808adf648004b34f98718301d718fa2darylm NULL, error, 0, buffer, sizeof(buffer)/sizeof(char), NULL)) 18816a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, buffer); 18916a5fed65808adf648004b34f98718301d718fa2darylm else 19016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushfstring(L, "system error %d\n", error); 19116a5fed65808adf648004b34f98718301d718fa2darylm} 19216a5fed65808adf648004b34f98718301d718fa2darylm 19316a5fed65808adf648004b34f98718301d718fa2darylmstatic void ll_unloadlib (void *lib) { 19416a5fed65808adf648004b34f98718301d718fa2darylm FreeLibrary((HMODULE)lib); 19516a5fed65808adf648004b34f98718301d718fa2darylm} 19616a5fed65808adf648004b34f98718301d718fa2darylm 19716a5fed65808adf648004b34f98718301d718fa2darylm 19816a5fed65808adf648004b34f98718301d718fa2darylmstatic void *ll_load (lua_State *L, const char *path, int seeglb) { 19916a5fed65808adf648004b34f98718301d718fa2darylm HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS); 20016a5fed65808adf648004b34f98718301d718fa2darylm (void)(seeglb); /* not used: symbols are 'global' by default */ 20116a5fed65808adf648004b34f98718301d718fa2darylm if (lib == NULL) pusherror(L); 20216a5fed65808adf648004b34f98718301d718fa2darylm return lib; 20316a5fed65808adf648004b34f98718301d718fa2darylm} 20416a5fed65808adf648004b34f98718301d718fa2darylm 20516a5fed65808adf648004b34f98718301d718fa2darylm 20616a5fed65808adf648004b34f98718301d718fa2darylmstatic lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 20716a5fed65808adf648004b34f98718301d718fa2darylm lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym); 20816a5fed65808adf648004b34f98718301d718fa2darylm if (f == NULL) pusherror(L); 20916a5fed65808adf648004b34f98718301d718fa2darylm return f; 21016a5fed65808adf648004b34f98718301d718fa2darylm} 21116a5fed65808adf648004b34f98718301d718fa2darylm 21216a5fed65808adf648004b34f98718301d718fa2darylm/* }====================================================== */ 21316a5fed65808adf648004b34f98718301d718fa2darylm 21416a5fed65808adf648004b34f98718301d718fa2darylm 21516a5fed65808adf648004b34f98718301d718fa2darylm#else 21616a5fed65808adf648004b34f98718301d718fa2darylm/* 21716a5fed65808adf648004b34f98718301d718fa2darylm** {====================================================== 21816a5fed65808adf648004b34f98718301d718fa2darylm** Fallback for other systems 21916a5fed65808adf648004b34f98718301d718fa2darylm** ======================================================= 22016a5fed65808adf648004b34f98718301d718fa2darylm*/ 22116a5fed65808adf648004b34f98718301d718fa2darylm 22216a5fed65808adf648004b34f98718301d718fa2darylm#undef LIB_FAIL 22316a5fed65808adf648004b34f98718301d718fa2darylm#define LIB_FAIL "absent" 22416a5fed65808adf648004b34f98718301d718fa2darylm 22516a5fed65808adf648004b34f98718301d718fa2darylm 22616a5fed65808adf648004b34f98718301d718fa2darylm#define DLMSG "dynamic libraries not enabled; check your Lua installation" 22716a5fed65808adf648004b34f98718301d718fa2darylm 22816a5fed65808adf648004b34f98718301d718fa2darylm 22916a5fed65808adf648004b34f98718301d718fa2darylmstatic void ll_unloadlib (void *lib) { 23016a5fed65808adf648004b34f98718301d718fa2darylm (void)(lib); /* not used */ 23116a5fed65808adf648004b34f98718301d718fa2darylm} 23216a5fed65808adf648004b34f98718301d718fa2darylm 23316a5fed65808adf648004b34f98718301d718fa2darylm 23416a5fed65808adf648004b34f98718301d718fa2darylmstatic void *ll_load (lua_State *L, const char *path, int seeglb) { 23516a5fed65808adf648004b34f98718301d718fa2darylm (void)(path); (void)(seeglb); /* not used */ 23616a5fed65808adf648004b34f98718301d718fa2darylm lua_pushliteral(L, DLMSG); 23716a5fed65808adf648004b34f98718301d718fa2darylm return NULL; 23816a5fed65808adf648004b34f98718301d718fa2darylm} 23916a5fed65808adf648004b34f98718301d718fa2darylm 24016a5fed65808adf648004b34f98718301d718fa2darylm 24116a5fed65808adf648004b34f98718301d718fa2darylmstatic lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) { 24216a5fed65808adf648004b34f98718301d718fa2darylm (void)(lib); (void)(sym); /* not used */ 24316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushliteral(L, DLMSG); 24416a5fed65808adf648004b34f98718301d718fa2darylm return NULL; 24516a5fed65808adf648004b34f98718301d718fa2darylm} 24616a5fed65808adf648004b34f98718301d718fa2darylm 24716a5fed65808adf648004b34f98718301d718fa2darylm/* }====================================================== */ 24816a5fed65808adf648004b34f98718301d718fa2darylm#endif 24916a5fed65808adf648004b34f98718301d718fa2darylm 25016a5fed65808adf648004b34f98718301d718fa2darylm 25116a5fed65808adf648004b34f98718301d718fa2darylmstatic void *ll_checkclib (lua_State *L, const char *path) { 25216a5fed65808adf648004b34f98718301d718fa2darylm void *plib; 25316a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); 25416a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, -1, path); 25516a5fed65808adf648004b34f98718301d718fa2darylm plib = lua_touserdata(L, -1); /* plib = CLIBS[path] */ 25616a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 2); /* pop CLIBS table and 'plib' */ 25716a5fed65808adf648004b34f98718301d718fa2darylm return plib; 25816a5fed65808adf648004b34f98718301d718fa2darylm} 25916a5fed65808adf648004b34f98718301d718fa2darylm 26016a5fed65808adf648004b34f98718301d718fa2darylm 26116a5fed65808adf648004b34f98718301d718fa2darylmstatic void ll_addtoclib (lua_State *L, const char *path, void *plib) { 26216a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, LUA_REGISTRYINDEX, CLIBS); 26316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushlightuserdata(L, plib); 26416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -1); 26516a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -3, path); /* CLIBS[path] = plib */ 26616a5fed65808adf648004b34f98718301d718fa2darylm lua_rawseti(L, -2, luaL_len(L, -2) + 1); /* CLIBS[#CLIBS + 1] = plib */ 26716a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* pop CLIBS table */ 26816a5fed65808adf648004b34f98718301d718fa2darylm} 26916a5fed65808adf648004b34f98718301d718fa2darylm 27016a5fed65808adf648004b34f98718301d718fa2darylm 27116a5fed65808adf648004b34f98718301d718fa2darylm/* 27216a5fed65808adf648004b34f98718301d718fa2darylm** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib 27316a5fed65808adf648004b34f98718301d718fa2darylm** handles in list CLIBS 27416a5fed65808adf648004b34f98718301d718fa2darylm*/ 27516a5fed65808adf648004b34f98718301d718fa2darylmstatic int gctm (lua_State *L) { 27616a5fed65808adf648004b34f98718301d718fa2darylm int n = luaL_len(L, 1); 27716a5fed65808adf648004b34f98718301d718fa2darylm for (; n >= 1; n--) { /* for each handle, in reverse order */ 27816a5fed65808adf648004b34f98718301d718fa2darylm lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */ 27916a5fed65808adf648004b34f98718301d718fa2darylm ll_unloadlib(lua_touserdata(L, -1)); 28016a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* pop handle */ 28116a5fed65808adf648004b34f98718301d718fa2darylm } 28216a5fed65808adf648004b34f98718301d718fa2darylm return 0; 28316a5fed65808adf648004b34f98718301d718fa2darylm} 28416a5fed65808adf648004b34f98718301d718fa2darylm 28516a5fed65808adf648004b34f98718301d718fa2darylm 28616a5fed65808adf648004b34f98718301d718fa2darylmstatic int ll_loadfunc (lua_State *L, const char *path, const char *sym) { 28716a5fed65808adf648004b34f98718301d718fa2darylm void *reg = ll_checkclib(L, path); /* check loaded C libraries */ 28816a5fed65808adf648004b34f98718301d718fa2darylm if (reg == NULL) { /* must load library? */ 28916a5fed65808adf648004b34f98718301d718fa2darylm reg = ll_load(L, path, *sym == '*'); 29016a5fed65808adf648004b34f98718301d718fa2darylm if (reg == NULL) return ERRLIB; /* unable to load library */ 29116a5fed65808adf648004b34f98718301d718fa2darylm ll_addtoclib(L, path, reg); 29216a5fed65808adf648004b34f98718301d718fa2darylm } 29316a5fed65808adf648004b34f98718301d718fa2darylm if (*sym == '*') { /* loading only library (no function)? */ 29416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushboolean(L, 1); /* return 'true' */ 29516a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* no errors */ 29616a5fed65808adf648004b34f98718301d718fa2darylm } 29716a5fed65808adf648004b34f98718301d718fa2darylm else { 29816a5fed65808adf648004b34f98718301d718fa2darylm lua_CFunction f = ll_sym(L, reg, sym); 29916a5fed65808adf648004b34f98718301d718fa2darylm if (f == NULL) 30016a5fed65808adf648004b34f98718301d718fa2darylm return ERRFUNC; /* unable to find function */ 30116a5fed65808adf648004b34f98718301d718fa2darylm lua_pushcfunction(L, f); /* else create new function */ 30216a5fed65808adf648004b34f98718301d718fa2darylm return 0; /* no errors */ 30316a5fed65808adf648004b34f98718301d718fa2darylm } 30416a5fed65808adf648004b34f98718301d718fa2darylm} 30516a5fed65808adf648004b34f98718301d718fa2darylm 30616a5fed65808adf648004b34f98718301d718fa2darylm 30716a5fed65808adf648004b34f98718301d718fa2darylmstatic int ll_loadlib (lua_State *L) { 30816a5fed65808adf648004b34f98718301d718fa2darylm const char *path = luaL_checkstring(L, 1); 30916a5fed65808adf648004b34f98718301d718fa2darylm const char *init = luaL_checkstring(L, 2); 31016a5fed65808adf648004b34f98718301d718fa2darylm int stat = ll_loadfunc(L, path, init); 31116a5fed65808adf648004b34f98718301d718fa2darylm if (stat == 0) /* no errors? */ 31216a5fed65808adf648004b34f98718301d718fa2darylm return 1; /* return the loaded function */ 31316a5fed65808adf648004b34f98718301d718fa2darylm else { /* error; error message is on stack top */ 31416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnil(L); 31516a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, -2); 31616a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init"); 31716a5fed65808adf648004b34f98718301d718fa2darylm return 3; /* return nil, error message, and where */ 31816a5fed65808adf648004b34f98718301d718fa2darylm } 31916a5fed65808adf648004b34f98718301d718fa2darylm} 32016a5fed65808adf648004b34f98718301d718fa2darylm 32116a5fed65808adf648004b34f98718301d718fa2darylm 32216a5fed65808adf648004b34f98718301d718fa2darylm 32316a5fed65808adf648004b34f98718301d718fa2darylm/* 32416a5fed65808adf648004b34f98718301d718fa2darylm** {====================================================== 32516a5fed65808adf648004b34f98718301d718fa2darylm** 'require' function 32616a5fed65808adf648004b34f98718301d718fa2darylm** ======================================================= 32716a5fed65808adf648004b34f98718301d718fa2darylm*/ 32816a5fed65808adf648004b34f98718301d718fa2darylm 32916a5fed65808adf648004b34f98718301d718fa2darylm 33016a5fed65808adf648004b34f98718301d718fa2darylmstatic int readable (const char *filename) { 33116a5fed65808adf648004b34f98718301d718fa2darylm FILE *f = fopen(filename, "r"); /* try to open file */ 33216a5fed65808adf648004b34f98718301d718fa2darylm if (f == NULL) return 0; /* open failed */ 33316a5fed65808adf648004b34f98718301d718fa2darylm fclose(f); 33416a5fed65808adf648004b34f98718301d718fa2darylm return 1; 33516a5fed65808adf648004b34f98718301d718fa2darylm} 33616a5fed65808adf648004b34f98718301d718fa2darylm 33716a5fed65808adf648004b34f98718301d718fa2darylm 33816a5fed65808adf648004b34f98718301d718fa2darylmstatic const char *pushnexttemplate (lua_State *L, const char *path) { 33916a5fed65808adf648004b34f98718301d718fa2darylm const char *l; 34016a5fed65808adf648004b34f98718301d718fa2darylm while (*path == *LUA_PATH_SEP) path++; /* skip separators */ 34116a5fed65808adf648004b34f98718301d718fa2darylm if (*path == '\0') return NULL; /* no more templates */ 34216a5fed65808adf648004b34f98718301d718fa2darylm l = strchr(path, *LUA_PATH_SEP); /* find next separator */ 34316a5fed65808adf648004b34f98718301d718fa2darylm if (l == NULL) l = path + strlen(path); 34416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushlstring(L, path, l - path); /* template */ 34516a5fed65808adf648004b34f98718301d718fa2darylm return l; 34616a5fed65808adf648004b34f98718301d718fa2darylm} 34716a5fed65808adf648004b34f98718301d718fa2darylm 34816a5fed65808adf648004b34f98718301d718fa2darylm 34916a5fed65808adf648004b34f98718301d718fa2darylmstatic const char *searchpath (lua_State *L, const char *name, 35016a5fed65808adf648004b34f98718301d718fa2darylm const char *path, 35116a5fed65808adf648004b34f98718301d718fa2darylm const char *sep, 35216a5fed65808adf648004b34f98718301d718fa2darylm const char *dirsep) { 35316a5fed65808adf648004b34f98718301d718fa2darylm luaL_Buffer msg; /* to build error message */ 35416a5fed65808adf648004b34f98718301d718fa2darylm luaL_buffinit(L, &msg); 35516a5fed65808adf648004b34f98718301d718fa2darylm if (*sep != '\0') /* non-empty separator? */ 35616a5fed65808adf648004b34f98718301d718fa2darylm name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */ 35716a5fed65808adf648004b34f98718301d718fa2darylm while ((path = pushnexttemplate(L, path)) != NULL) { 35816a5fed65808adf648004b34f98718301d718fa2darylm const char *filename = luaL_gsub(L, lua_tostring(L, -1), 35916a5fed65808adf648004b34f98718301d718fa2darylm LUA_PATH_MARK, name); 36016a5fed65808adf648004b34f98718301d718fa2darylm lua_remove(L, -2); /* remove path template */ 36116a5fed65808adf648004b34f98718301d718fa2darylm if (readable(filename)) /* does file exist and is readable? */ 36216a5fed65808adf648004b34f98718301d718fa2darylm return filename; /* return that file name */ 36316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushfstring(L, "\n\tno file " LUA_QS, filename); 36416a5fed65808adf648004b34f98718301d718fa2darylm lua_remove(L, -2); /* remove file name */ 36516a5fed65808adf648004b34f98718301d718fa2darylm luaL_addvalue(&msg); /* concatenate error msg. entry */ 36616a5fed65808adf648004b34f98718301d718fa2darylm } 36716a5fed65808adf648004b34f98718301d718fa2darylm luaL_pushresult(&msg); /* create error message */ 36816a5fed65808adf648004b34f98718301d718fa2darylm return NULL; /* not found */ 36916a5fed65808adf648004b34f98718301d718fa2darylm} 37016a5fed65808adf648004b34f98718301d718fa2darylm 37116a5fed65808adf648004b34f98718301d718fa2darylm 37216a5fed65808adf648004b34f98718301d718fa2darylmstatic int ll_searchpath (lua_State *L) { 37316a5fed65808adf648004b34f98718301d718fa2darylm const char *f = searchpath(L, luaL_checkstring(L, 1), 37416a5fed65808adf648004b34f98718301d718fa2darylm luaL_checkstring(L, 2), 37516a5fed65808adf648004b34f98718301d718fa2darylm luaL_optstring(L, 3, "."), 37616a5fed65808adf648004b34f98718301d718fa2darylm luaL_optstring(L, 4, LUA_DIRSEP)); 37716a5fed65808adf648004b34f98718301d718fa2darylm if (f != NULL) return 1; 37816a5fed65808adf648004b34f98718301d718fa2darylm else { /* error message is on top of the stack */ 37916a5fed65808adf648004b34f98718301d718fa2darylm lua_pushnil(L); 38016a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, -2); 38116a5fed65808adf648004b34f98718301d718fa2darylm return 2; /* return nil + error message */ 38216a5fed65808adf648004b34f98718301d718fa2darylm } 38316a5fed65808adf648004b34f98718301d718fa2darylm} 38416a5fed65808adf648004b34f98718301d718fa2darylm 38516a5fed65808adf648004b34f98718301d718fa2darylm 38616a5fed65808adf648004b34f98718301d718fa2darylmstatic const char *findfile (lua_State *L, const char *name, 38716a5fed65808adf648004b34f98718301d718fa2darylm const char *pname, 38816a5fed65808adf648004b34f98718301d718fa2darylm const char *dirsep) { 38916a5fed65808adf648004b34f98718301d718fa2darylm const char *path; 39016a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, lua_upvalueindex(1), pname); 39116a5fed65808adf648004b34f98718301d718fa2darylm path = lua_tostring(L, -1); 39216a5fed65808adf648004b34f98718301d718fa2darylm if (path == NULL) 39316a5fed65808adf648004b34f98718301d718fa2darylm luaL_error(L, LUA_QL("package.%s") " must be a string", pname); 39416a5fed65808adf648004b34f98718301d718fa2darylm return searchpath(L, name, path, ".", dirsep); 39516a5fed65808adf648004b34f98718301d718fa2darylm} 39616a5fed65808adf648004b34f98718301d718fa2darylm 39716a5fed65808adf648004b34f98718301d718fa2darylm 39816a5fed65808adf648004b34f98718301d718fa2darylmstatic int checkload (lua_State *L, int stat, const char *filename) { 39916a5fed65808adf648004b34f98718301d718fa2darylm if (stat) { /* module loaded successfully? */ 40016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, filename); /* will be 2nd argument to module */ 40116a5fed65808adf648004b34f98718301d718fa2darylm return 2; /* return open function and file name */ 40216a5fed65808adf648004b34f98718301d718fa2darylm } 40316a5fed65808adf648004b34f98718301d718fa2darylm else 40416a5fed65808adf648004b34f98718301d718fa2darylm return luaL_error(L, "error loading module " LUA_QS 40516a5fed65808adf648004b34f98718301d718fa2darylm " from file " LUA_QS ":\n\t%s", 40616a5fed65808adf648004b34f98718301d718fa2darylm lua_tostring(L, 1), filename, lua_tostring(L, -1)); 40716a5fed65808adf648004b34f98718301d718fa2darylm} 40816a5fed65808adf648004b34f98718301d718fa2darylm 40916a5fed65808adf648004b34f98718301d718fa2darylm 41016a5fed65808adf648004b34f98718301d718fa2darylmstatic int searcher_Lua (lua_State *L) { 41116a5fed65808adf648004b34f98718301d718fa2darylm const char *filename; 41216a5fed65808adf648004b34f98718301d718fa2darylm const char *name = luaL_checkstring(L, 1); 41316a5fed65808adf648004b34f98718301d718fa2darylm filename = findfile(L, name, "path", LUA_LSUBSEP); 41416a5fed65808adf648004b34f98718301d718fa2darylm if (filename == NULL) return 1; /* module not found in this path */ 41516a5fed65808adf648004b34f98718301d718fa2darylm return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename); 41616a5fed65808adf648004b34f98718301d718fa2darylm} 41716a5fed65808adf648004b34f98718301d718fa2darylm 41816a5fed65808adf648004b34f98718301d718fa2darylm 41916a5fed65808adf648004b34f98718301d718fa2darylmstatic int loadfunc (lua_State *L, const char *filename, const char *modname) { 42016a5fed65808adf648004b34f98718301d718fa2darylm const char *funcname; 42116a5fed65808adf648004b34f98718301d718fa2darylm const char *mark; 42216a5fed65808adf648004b34f98718301d718fa2darylm modname = luaL_gsub(L, modname, ".", LUA_OFSEP); 42316a5fed65808adf648004b34f98718301d718fa2darylm mark = strchr(modname, *LUA_IGMARK); 42416a5fed65808adf648004b34f98718301d718fa2darylm if (mark) { 42516a5fed65808adf648004b34f98718301d718fa2darylm int stat; 42616a5fed65808adf648004b34f98718301d718fa2darylm funcname = lua_pushlstring(L, modname, mark - modname); 42716a5fed65808adf648004b34f98718301d718fa2darylm funcname = lua_pushfstring(L, LUA_POF"%s", funcname); 42816a5fed65808adf648004b34f98718301d718fa2darylm stat = ll_loadfunc(L, filename, funcname); 42916a5fed65808adf648004b34f98718301d718fa2darylm if (stat != ERRFUNC) return stat; 43016a5fed65808adf648004b34f98718301d718fa2darylm modname = mark + 1; /* else go ahead and try old-style name */ 43116a5fed65808adf648004b34f98718301d718fa2darylm } 43216a5fed65808adf648004b34f98718301d718fa2darylm funcname = lua_pushfstring(L, LUA_POF"%s", modname); 43316a5fed65808adf648004b34f98718301d718fa2darylm return ll_loadfunc(L, filename, funcname); 43416a5fed65808adf648004b34f98718301d718fa2darylm} 43516a5fed65808adf648004b34f98718301d718fa2darylm 43616a5fed65808adf648004b34f98718301d718fa2darylm 43716a5fed65808adf648004b34f98718301d718fa2darylmstatic int searcher_C (lua_State *L) { 43816a5fed65808adf648004b34f98718301d718fa2darylm const char *name = luaL_checkstring(L, 1); 43916a5fed65808adf648004b34f98718301d718fa2darylm const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP); 44016a5fed65808adf648004b34f98718301d718fa2darylm if (filename == NULL) return 1; /* module not found in this path */ 44116a5fed65808adf648004b34f98718301d718fa2darylm return checkload(L, (loadfunc(L, filename, name) == 0), filename); 44216a5fed65808adf648004b34f98718301d718fa2darylm} 44316a5fed65808adf648004b34f98718301d718fa2darylm 44416a5fed65808adf648004b34f98718301d718fa2darylm 44516a5fed65808adf648004b34f98718301d718fa2darylmstatic int searcher_Croot (lua_State *L) { 44616a5fed65808adf648004b34f98718301d718fa2darylm const char *filename; 44716a5fed65808adf648004b34f98718301d718fa2darylm const char *name = luaL_checkstring(L, 1); 44816a5fed65808adf648004b34f98718301d718fa2darylm const char *p = strchr(name, '.'); 44916a5fed65808adf648004b34f98718301d718fa2darylm int stat; 45016a5fed65808adf648004b34f98718301d718fa2darylm if (p == NULL) return 0; /* is root */ 45116a5fed65808adf648004b34f98718301d718fa2darylm lua_pushlstring(L, name, p - name); 45216a5fed65808adf648004b34f98718301d718fa2darylm filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP); 45316a5fed65808adf648004b34f98718301d718fa2darylm if (filename == NULL) return 1; /* root not found */ 45416a5fed65808adf648004b34f98718301d718fa2darylm if ((stat = loadfunc(L, filename, name)) != 0) { 45516a5fed65808adf648004b34f98718301d718fa2darylm if (stat != ERRFUNC) 45616a5fed65808adf648004b34f98718301d718fa2darylm return checkload(L, 0, filename); /* real error */ 45716a5fed65808adf648004b34f98718301d718fa2darylm else { /* open function not found */ 45816a5fed65808adf648004b34f98718301d718fa2darylm lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS, 45916a5fed65808adf648004b34f98718301d718fa2darylm name, filename); 46016a5fed65808adf648004b34f98718301d718fa2darylm return 1; 46116a5fed65808adf648004b34f98718301d718fa2darylm } 46216a5fed65808adf648004b34f98718301d718fa2darylm } 46316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, filename); /* will be 2nd argument to module */ 46416a5fed65808adf648004b34f98718301d718fa2darylm return 2; 46516a5fed65808adf648004b34f98718301d718fa2darylm} 46616a5fed65808adf648004b34f98718301d718fa2darylm 46716a5fed65808adf648004b34f98718301d718fa2darylm 46816a5fed65808adf648004b34f98718301d718fa2darylmstatic int searcher_preload (lua_State *L) { 46916a5fed65808adf648004b34f98718301d718fa2darylm const char *name = luaL_checkstring(L, 1); 47016a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, LUA_REGISTRYINDEX, "_PRELOAD"); 47116a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, -1, name); 47216a5fed65808adf648004b34f98718301d718fa2darylm if (lua_isnil(L, -1)) /* not found? */ 47316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushfstring(L, "\n\tno field package.preload['%s']", name); 47416a5fed65808adf648004b34f98718301d718fa2darylm return 1; 47516a5fed65808adf648004b34f98718301d718fa2darylm} 47616a5fed65808adf648004b34f98718301d718fa2darylm 47716a5fed65808adf648004b34f98718301d718fa2darylm 47816a5fed65808adf648004b34f98718301d718fa2darylmstatic void findloader (lua_State *L, const char *name) { 47916a5fed65808adf648004b34f98718301d718fa2darylm int i; 48016a5fed65808adf648004b34f98718301d718fa2darylm luaL_Buffer msg; /* to build error message */ 48116a5fed65808adf648004b34f98718301d718fa2darylm luaL_buffinit(L, &msg); 48216a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */ 48316a5fed65808adf648004b34f98718301d718fa2darylm if (!lua_istable(L, 3)) 48416a5fed65808adf648004b34f98718301d718fa2darylm luaL_error(L, LUA_QL("package.searchers") " must be a table"); 48516a5fed65808adf648004b34f98718301d718fa2darylm /* iterate over available searchers to find a loader */ 48616a5fed65808adf648004b34f98718301d718fa2darylm for (i = 1; ; i++) { 48716a5fed65808adf648004b34f98718301d718fa2darylm lua_rawgeti(L, 3, i); /* get a searcher */ 48816a5fed65808adf648004b34f98718301d718fa2darylm if (lua_isnil(L, -1)) { /* no more searchers? */ 48916a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* remove nil */ 49016a5fed65808adf648004b34f98718301d718fa2darylm luaL_pushresult(&msg); /* create error message */ 49116a5fed65808adf648004b34f98718301d718fa2darylm luaL_error(L, "module " LUA_QS " not found:%s", 49216a5fed65808adf648004b34f98718301d718fa2darylm name, lua_tostring(L, -1)); 49316a5fed65808adf648004b34f98718301d718fa2darylm } 49416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, name); 49516a5fed65808adf648004b34f98718301d718fa2darylm lua_call(L, 1, 2); /* call it */ 49616a5fed65808adf648004b34f98718301d718fa2darylm if (lua_isfunction(L, -2)) /* did it find a loader? */ 49716a5fed65808adf648004b34f98718301d718fa2darylm return; /* module loader found */ 49816a5fed65808adf648004b34f98718301d718fa2darylm else if (lua_isstring(L, -2)) { /* searcher returned error message? */ 49916a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* remove extra return */ 50016a5fed65808adf648004b34f98718301d718fa2darylm luaL_addvalue(&msg); /* concatenate error message */ 50116a5fed65808adf648004b34f98718301d718fa2darylm } 50216a5fed65808adf648004b34f98718301d718fa2darylm else 50316a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 2); /* remove both returns */ 50416a5fed65808adf648004b34f98718301d718fa2darylm } 50516a5fed65808adf648004b34f98718301d718fa2darylm} 50616a5fed65808adf648004b34f98718301d718fa2darylm 50716a5fed65808adf648004b34f98718301d718fa2darylm 50816a5fed65808adf648004b34f98718301d718fa2darylmstatic int ll_require (lua_State *L) { 50916a5fed65808adf648004b34f98718301d718fa2darylm const char *name = luaL_checkstring(L, 1); 51016a5fed65808adf648004b34f98718301d718fa2darylm lua_settop(L, 1); /* _LOADED table will be at index 2 */ 51116a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); 51216a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, 2, name); /* _LOADED[name] */ 51316a5fed65808adf648004b34f98718301d718fa2darylm if (lua_toboolean(L, -1)) /* is it there? */ 51416a5fed65808adf648004b34f98718301d718fa2darylm return 1; /* package is already loaded */ 51516a5fed65808adf648004b34f98718301d718fa2darylm /* else must load package */ 51616a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* remove 'getfield' result */ 51716a5fed65808adf648004b34f98718301d718fa2darylm findloader(L, name); 51816a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, name); /* pass name as argument to module loader */ 51916a5fed65808adf648004b34f98718301d718fa2darylm lua_insert(L, -2); /* name is 1st argument (before search data) */ 52016a5fed65808adf648004b34f98718301d718fa2darylm lua_call(L, 2, 1); /* run loader to load module */ 52116a5fed65808adf648004b34f98718301d718fa2darylm if (!lua_isnil(L, -1)) /* non-nil return? */ 52216a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, 2, name); /* _LOADED[name] = returned value */ 52316a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, 2, name); 52416a5fed65808adf648004b34f98718301d718fa2darylm if (lua_isnil(L, -1)) { /* module did not set a value? */ 52516a5fed65808adf648004b34f98718301d718fa2darylm lua_pushboolean(L, 1); /* use true as result */ 52616a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -1); /* extra copy to be returned */ 52716a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, 2, name); /* _LOADED[name] = true */ 52816a5fed65808adf648004b34f98718301d718fa2darylm } 52916a5fed65808adf648004b34f98718301d718fa2darylm return 1; 53016a5fed65808adf648004b34f98718301d718fa2darylm} 53116a5fed65808adf648004b34f98718301d718fa2darylm 53216a5fed65808adf648004b34f98718301d718fa2darylm/* }====================================================== */ 53316a5fed65808adf648004b34f98718301d718fa2darylm 53416a5fed65808adf648004b34f98718301d718fa2darylm 53516a5fed65808adf648004b34f98718301d718fa2darylm 53616a5fed65808adf648004b34f98718301d718fa2darylm/* 53716a5fed65808adf648004b34f98718301d718fa2darylm** {====================================================== 53816a5fed65808adf648004b34f98718301d718fa2darylm** 'module' function 53916a5fed65808adf648004b34f98718301d718fa2darylm** ======================================================= 54016a5fed65808adf648004b34f98718301d718fa2darylm*/ 54116a5fed65808adf648004b34f98718301d718fa2darylm#if defined(LUA_COMPAT_MODULE) 54216a5fed65808adf648004b34f98718301d718fa2darylm 54316a5fed65808adf648004b34f98718301d718fa2darylm/* 54416a5fed65808adf648004b34f98718301d718fa2darylm** changes the environment variable of calling function 54516a5fed65808adf648004b34f98718301d718fa2darylm*/ 54616a5fed65808adf648004b34f98718301d718fa2darylmstatic void set_env (lua_State *L) { 54716a5fed65808adf648004b34f98718301d718fa2darylm lua_Debug ar; 54816a5fed65808adf648004b34f98718301d718fa2darylm if (lua_getstack(L, 1, &ar) == 0 || 54916a5fed65808adf648004b34f98718301d718fa2darylm lua_getinfo(L, "f", &ar) == 0 || /* get calling function */ 55016a5fed65808adf648004b34f98718301d718fa2darylm lua_iscfunction(L, -1)) 55116a5fed65808adf648004b34f98718301d718fa2darylm luaL_error(L, LUA_QL("module") " not called from a Lua function"); 55216a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -2); /* copy new environment table to top */ 55316a5fed65808adf648004b34f98718301d718fa2darylm lua_setupvalue(L, -2, 1); 55416a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* remove function */ 55516a5fed65808adf648004b34f98718301d718fa2darylm} 55616a5fed65808adf648004b34f98718301d718fa2darylm 55716a5fed65808adf648004b34f98718301d718fa2darylm 55816a5fed65808adf648004b34f98718301d718fa2darylmstatic void dooptions (lua_State *L, int n) { 55916a5fed65808adf648004b34f98718301d718fa2darylm int i; 56016a5fed65808adf648004b34f98718301d718fa2darylm for (i = 2; i <= n; i++) { 56116a5fed65808adf648004b34f98718301d718fa2darylm if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */ 56216a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, i); /* get option (a function) */ 56316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -2); /* module */ 56416a5fed65808adf648004b34f98718301d718fa2darylm lua_call(L, 1, 0); 56516a5fed65808adf648004b34f98718301d718fa2darylm } 56616a5fed65808adf648004b34f98718301d718fa2darylm } 56716a5fed65808adf648004b34f98718301d718fa2darylm} 56816a5fed65808adf648004b34f98718301d718fa2darylm 56916a5fed65808adf648004b34f98718301d718fa2darylm 57016a5fed65808adf648004b34f98718301d718fa2darylmstatic void modinit (lua_State *L, const char *modname) { 57116a5fed65808adf648004b34f98718301d718fa2darylm const char *dot; 57216a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -1); 57316a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "_M"); /* module._M = module */ 57416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, modname); 57516a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "_NAME"); 57616a5fed65808adf648004b34f98718301d718fa2darylm dot = strrchr(modname, '.'); /* look for last dot in module name */ 57716a5fed65808adf648004b34f98718301d718fa2darylm if (dot == NULL) dot = modname; 57816a5fed65808adf648004b34f98718301d718fa2darylm else dot++; 57916a5fed65808adf648004b34f98718301d718fa2darylm /* set _PACKAGE as package name (full module name minus last part) */ 58016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushlstring(L, modname, dot - modname); 58116a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "_PACKAGE"); 58216a5fed65808adf648004b34f98718301d718fa2darylm} 58316a5fed65808adf648004b34f98718301d718fa2darylm 58416a5fed65808adf648004b34f98718301d718fa2darylm 58516a5fed65808adf648004b34f98718301d718fa2darylmstatic int ll_module (lua_State *L) { 58616a5fed65808adf648004b34f98718301d718fa2darylm const char *modname = luaL_checkstring(L, 1); 58716a5fed65808adf648004b34f98718301d718fa2darylm int lastarg = lua_gettop(L); /* last parameter */ 58816a5fed65808adf648004b34f98718301d718fa2darylm luaL_pushmodule(L, modname, 1); /* get/create module table */ 58916a5fed65808adf648004b34f98718301d718fa2darylm /* check whether table already has a _NAME field */ 59016a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, -1, "_NAME"); 59116a5fed65808adf648004b34f98718301d718fa2darylm if (!lua_isnil(L, -1)) /* is table an initialized module? */ 59216a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); 59316a5fed65808adf648004b34f98718301d718fa2darylm else { /* no; initialize it */ 59416a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); 59516a5fed65808adf648004b34f98718301d718fa2darylm modinit(L, modname); 59616a5fed65808adf648004b34f98718301d718fa2darylm } 59716a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -1); 59816a5fed65808adf648004b34f98718301d718fa2darylm set_env(L); 59916a5fed65808adf648004b34f98718301d718fa2darylm dooptions(L, lastarg); 60016a5fed65808adf648004b34f98718301d718fa2darylm return 1; 60116a5fed65808adf648004b34f98718301d718fa2darylm} 60216a5fed65808adf648004b34f98718301d718fa2darylm 60316a5fed65808adf648004b34f98718301d718fa2darylm 60416a5fed65808adf648004b34f98718301d718fa2darylmstatic int ll_seeall (lua_State *L) { 60516a5fed65808adf648004b34f98718301d718fa2darylm luaL_checktype(L, 1, LUA_TTABLE); 60616a5fed65808adf648004b34f98718301d718fa2darylm if (!lua_getmetatable(L, 1)) { 60716a5fed65808adf648004b34f98718301d718fa2darylm lua_createtable(L, 0, 1); /* create new metatable */ 60816a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -1); 60916a5fed65808adf648004b34f98718301d718fa2darylm lua_setmetatable(L, 1); 61016a5fed65808adf648004b34f98718301d718fa2darylm } 61116a5fed65808adf648004b34f98718301d718fa2darylm lua_pushglobaltable(L); 61216a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "__index"); /* mt.__index = _G */ 61316a5fed65808adf648004b34f98718301d718fa2darylm return 0; 61416a5fed65808adf648004b34f98718301d718fa2darylm} 61516a5fed65808adf648004b34f98718301d718fa2darylm 61616a5fed65808adf648004b34f98718301d718fa2darylm#endif 61716a5fed65808adf648004b34f98718301d718fa2darylm/* }====================================================== */ 61816a5fed65808adf648004b34f98718301d718fa2darylm 61916a5fed65808adf648004b34f98718301d718fa2darylm 62016a5fed65808adf648004b34f98718301d718fa2darylm 62116a5fed65808adf648004b34f98718301d718fa2darylm/* auxiliary mark (for internal use) */ 62216a5fed65808adf648004b34f98718301d718fa2darylm#define AUXMARK "\1" 62316a5fed65808adf648004b34f98718301d718fa2darylm 62416a5fed65808adf648004b34f98718301d718fa2darylm 62516a5fed65808adf648004b34f98718301d718fa2darylm/* 62616a5fed65808adf648004b34f98718301d718fa2darylm** return registry.LUA_NOENV as a boolean 62716a5fed65808adf648004b34f98718301d718fa2darylm*/ 62816a5fed65808adf648004b34f98718301d718fa2darylmstatic int noenv (lua_State *L) { 62916a5fed65808adf648004b34f98718301d718fa2darylm int b; 63016a5fed65808adf648004b34f98718301d718fa2darylm lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV"); 63116a5fed65808adf648004b34f98718301d718fa2darylm b = lua_toboolean(L, -1); 63216a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* remove value */ 63316a5fed65808adf648004b34f98718301d718fa2darylm return b; 63416a5fed65808adf648004b34f98718301d718fa2darylm} 63516a5fed65808adf648004b34f98718301d718fa2darylm 63616a5fed65808adf648004b34f98718301d718fa2darylm 63716a5fed65808adf648004b34f98718301d718fa2darylmstatic void setpath (lua_State *L, const char *fieldname, const char *envname1, 63816a5fed65808adf648004b34f98718301d718fa2darylm const char *envname2, const char *def) { 63916a5fed65808adf648004b34f98718301d718fa2darylm const char *path = getenv(envname1); 64016a5fed65808adf648004b34f98718301d718fa2darylm if (path == NULL) /* no environment variable? */ 64116a5fed65808adf648004b34f98718301d718fa2darylm path = getenv(envname2); /* try alternative name */ 64216a5fed65808adf648004b34f98718301d718fa2darylm if (path == NULL || noenv(L)) /* no environment variable? */ 64316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushstring(L, def); /* use default */ 64416a5fed65808adf648004b34f98718301d718fa2darylm else { 64516a5fed65808adf648004b34f98718301d718fa2darylm /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */ 64616a5fed65808adf648004b34f98718301d718fa2darylm path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP, 64716a5fed65808adf648004b34f98718301d718fa2darylm LUA_PATH_SEP AUXMARK LUA_PATH_SEP); 64816a5fed65808adf648004b34f98718301d718fa2darylm luaL_gsub(L, path, AUXMARK, def); 64916a5fed65808adf648004b34f98718301d718fa2darylm lua_remove(L, -2); 65016a5fed65808adf648004b34f98718301d718fa2darylm } 65116a5fed65808adf648004b34f98718301d718fa2darylm setprogdir(L); 65216a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, fieldname); 65316a5fed65808adf648004b34f98718301d718fa2darylm} 65416a5fed65808adf648004b34f98718301d718fa2darylm 65516a5fed65808adf648004b34f98718301d718fa2darylm 65616a5fed65808adf648004b34f98718301d718fa2darylmstatic const luaL_Reg pk_funcs[] = { 65716a5fed65808adf648004b34f98718301d718fa2darylm {"loadlib", ll_loadlib}, 65816a5fed65808adf648004b34f98718301d718fa2darylm {"searchpath", ll_searchpath}, 65916a5fed65808adf648004b34f98718301d718fa2darylm#if defined(LUA_COMPAT_MODULE) 66016a5fed65808adf648004b34f98718301d718fa2darylm {"seeall", ll_seeall}, 66116a5fed65808adf648004b34f98718301d718fa2darylm#endif 66216a5fed65808adf648004b34f98718301d718fa2darylm {NULL, NULL} 66316a5fed65808adf648004b34f98718301d718fa2darylm}; 66416a5fed65808adf648004b34f98718301d718fa2darylm 66516a5fed65808adf648004b34f98718301d718fa2darylm 66616a5fed65808adf648004b34f98718301d718fa2darylmstatic const luaL_Reg ll_funcs[] = { 66716a5fed65808adf648004b34f98718301d718fa2darylm#if defined(LUA_COMPAT_MODULE) 66816a5fed65808adf648004b34f98718301d718fa2darylm {"module", ll_module}, 66916a5fed65808adf648004b34f98718301d718fa2darylm#endif 67016a5fed65808adf648004b34f98718301d718fa2darylm {"require", ll_require}, 67116a5fed65808adf648004b34f98718301d718fa2darylm {NULL, NULL} 67216a5fed65808adf648004b34f98718301d718fa2darylm}; 67316a5fed65808adf648004b34f98718301d718fa2darylm 67416a5fed65808adf648004b34f98718301d718fa2darylm 67516a5fed65808adf648004b34f98718301d718fa2darylmstatic void createsearcherstable (lua_State *L) { 67616a5fed65808adf648004b34f98718301d718fa2darylm static const lua_CFunction searchers[] = 67716a5fed65808adf648004b34f98718301d718fa2darylm {searcher_preload, searcher_Lua, searcher_C, searcher_Croot, NULL}; 67816a5fed65808adf648004b34f98718301d718fa2darylm int i; 67916a5fed65808adf648004b34f98718301d718fa2darylm /* create 'searchers' table */ 68016a5fed65808adf648004b34f98718301d718fa2darylm lua_createtable(L, sizeof(searchers)/sizeof(searchers[0]) - 1, 0); 68116a5fed65808adf648004b34f98718301d718fa2darylm /* fill it with pre-defined searchers */ 68216a5fed65808adf648004b34f98718301d718fa2darylm for (i=0; searchers[i] != NULL; i++) { 68316a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -2); /* set 'package' as upvalue for all searchers */ 68416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushcclosure(L, searchers[i], 1); 68516a5fed65808adf648004b34f98718301d718fa2darylm lua_rawseti(L, -2, i+1); 68616a5fed65808adf648004b34f98718301d718fa2darylm } 68716a5fed65808adf648004b34f98718301d718fa2darylm} 68816a5fed65808adf648004b34f98718301d718fa2darylm 68916a5fed65808adf648004b34f98718301d718fa2darylm 69016a5fed65808adf648004b34f98718301d718fa2darylmLUAMOD_API int luaopen_package (lua_State *L) { 69116a5fed65808adf648004b34f98718301d718fa2darylm /* create table CLIBS to keep track of loaded C libraries */ 69216a5fed65808adf648004b34f98718301d718fa2darylm luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); 69316a5fed65808adf648004b34f98718301d718fa2darylm lua_createtable(L, 0, 1); /* metatable for CLIBS */ 69416a5fed65808adf648004b34f98718301d718fa2darylm lua_pushcfunction(L, gctm); 69516a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */ 69616a5fed65808adf648004b34f98718301d718fa2darylm lua_setmetatable(L, -2); 69716a5fed65808adf648004b34f98718301d718fa2darylm /* create `package' table */ 69816a5fed65808adf648004b34f98718301d718fa2darylm luaL_newlib(L, pk_funcs); 69916a5fed65808adf648004b34f98718301d718fa2darylm createsearcherstable(L); 70016a5fed65808adf648004b34f98718301d718fa2darylm#if defined(LUA_COMPAT_LOADERS) 70116a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -1); /* make a copy of 'searchers' table */ 70216a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */ 70316a5fed65808adf648004b34f98718301d718fa2darylm#endif 70416a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */ 70516a5fed65808adf648004b34f98718301d718fa2darylm /* set field 'path' */ 70616a5fed65808adf648004b34f98718301d718fa2darylm setpath(L, "path", LUA_PATHVERSION, LUA_PATH, LUA_PATH_DEFAULT); 70716a5fed65808adf648004b34f98718301d718fa2darylm /* set field 'cpath' */ 70816a5fed65808adf648004b34f98718301d718fa2darylm setpath(L, "cpath", LUA_CPATHVERSION, LUA_CPATH, LUA_CPATH_DEFAULT); 70916a5fed65808adf648004b34f98718301d718fa2darylm /* store config information */ 71016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n" 71116a5fed65808adf648004b34f98718301d718fa2darylm LUA_EXEC_DIR "\n" LUA_IGMARK "\n"); 71216a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "config"); 71316a5fed65808adf648004b34f98718301d718fa2darylm /* set field `loaded' */ 71416a5fed65808adf648004b34f98718301d718fa2darylm luaL_getsubtable(L, LUA_REGISTRYINDEX, "_LOADED"); 71516a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "loaded"); 71616a5fed65808adf648004b34f98718301d718fa2darylm /* set field `preload' */ 71716a5fed65808adf648004b34f98718301d718fa2darylm luaL_getsubtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); 71816a5fed65808adf648004b34f98718301d718fa2darylm lua_setfield(L, -2, "preload"); 71916a5fed65808adf648004b34f98718301d718fa2darylm lua_pushglobaltable(L); 72016a5fed65808adf648004b34f98718301d718fa2darylm lua_pushvalue(L, -2); /* set 'package' as upvalue for next lib */ 72116a5fed65808adf648004b34f98718301d718fa2darylm luaL_setfuncs(L, ll_funcs, 1); /* open lib into global table */ 72216a5fed65808adf648004b34f98718301d718fa2darylm lua_pop(L, 1); /* pop global table */ 72316a5fed65808adf648004b34f98718301d718fa2darylm return 1; /* return 'package' table */ 72416a5fed65808adf648004b34f98718301d718fa2darylm} 72516a5fed65808adf648004b34f98718301d718fa2darylm 726