mirror of
https://github.com/lua/lua
synced 2024-11-25 22:29:39 +03:00
some janitorial work (comments, small refactoring)
This commit is contained in:
parent
925d1b59f9
commit
255d59ed5e
145
loadlib.c
145
loadlib.c
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
** $Id: loadlib.c,v 1.113 2014/03/12 20:57:40 roberto Exp roberto $
|
** $Id: loadlib.c,v 1.114 2014/07/16 13:56:14 roberto Exp roberto $
|
||||||
** Dynamic library loader for Lua
|
** Dynamic library loader for Lua
|
||||||
** See Copyright Notice in lua.h
|
** See Copyright Notice in lua.h
|
||||||
**
|
**
|
||||||
@ -97,20 +97,33 @@
|
|||||||
|
|
||||||
#define LIB_FAIL "open"
|
#define LIB_FAIL "open"
|
||||||
|
|
||||||
|
|
||||||
/* error codes for ll_loadfunc */
|
|
||||||
#define ERRLIB 1
|
|
||||||
#define ERRFUNC 2
|
|
||||||
|
|
||||||
#define setprogdir(L) ((void)0)
|
#define setprogdir(L) ((void)0)
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** system-dependent functions
|
** system-dependent functions
|
||||||
*/
|
*/
|
||||||
static void ll_unloadlib (void *lib);
|
|
||||||
static void *ll_load (lua_State *L, const char *path, int seeglb);
|
/*
|
||||||
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
|
** unload library 'lib'
|
||||||
|
*/
|
||||||
|
static void lsys_unloadlib (void *lib);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** load C library in file 'path'. If 'seeglb', load with all names in
|
||||||
|
** the library global.
|
||||||
|
** Returns the library; in case of error, returns NULL plus an
|
||||||
|
** error string in the stack.
|
||||||
|
*/
|
||||||
|
static void *lsys_load (lua_State *L, const char *path, int seeglb);
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Try to find a function named 'sym' in library 'lib'.
|
||||||
|
** Returns the function; in case of error, returns NULL plus an
|
||||||
|
** error string in the stack.
|
||||||
|
*/
|
||||||
|
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -126,19 +139,19 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
|
|||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
static void ll_unloadlib (void *lib) {
|
static void lsys_unloadlib (void *lib) {
|
||||||
dlclose(lib);
|
dlclose(lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *ll_load (lua_State *L, const char *path, int seeglb) {
|
static void *lsys_load (lua_State *L, const char *path, int seeglb) {
|
||||||
void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
|
void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
|
||||||
if (lib == NULL) lua_pushstring(L, dlerror());
|
if (lib == NULL) lua_pushstring(L, dlerror());
|
||||||
return lib;
|
return lib;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
|
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
|
||||||
lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
|
lua_CFunction f = (lua_CFunction)dlsym(lib, sym);
|
||||||
if (f == NULL) lua_pushstring(L, dlerror());
|
if (f == NULL) lua_pushstring(L, dlerror());
|
||||||
return f;
|
return f;
|
||||||
@ -190,12 +203,12 @@ static void pusherror (lua_State *L) {
|
|||||||
lua_pushfstring(L, "system error %d\n", error);
|
lua_pushfstring(L, "system error %d\n", error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ll_unloadlib (void *lib) {
|
static void lsys_unloadlib (void *lib) {
|
||||||
FreeLibrary((HMODULE)lib);
|
FreeLibrary((HMODULE)lib);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *ll_load (lua_State *L, const char *path, int seeglb) {
|
static void *lsys_load (lua_State *L, const char *path, int seeglb) {
|
||||||
HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
|
HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
|
||||||
(void)(seeglb); /* not used: symbols are 'global' by default */
|
(void)(seeglb); /* not used: symbols are 'global' by default */
|
||||||
if (lib == NULL) pusherror(L);
|
if (lib == NULL) pusherror(L);
|
||||||
@ -203,7 +216,7 @@ static void *ll_load (lua_State *L, const char *path, int seeglb) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
|
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
|
||||||
lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
|
lua_CFunction f = (lua_CFunction)GetProcAddress((HMODULE)lib, sym);
|
||||||
if (f == NULL) pusherror(L);
|
if (f == NULL) pusherror(L);
|
||||||
return f;
|
return f;
|
||||||
@ -226,19 +239,19 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
|
|||||||
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
|
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
|
||||||
|
|
||||||
|
|
||||||
static void ll_unloadlib (void *lib) {
|
static void lsys_unloadlib (void *lib) {
|
||||||
(void)(lib); /* not used */
|
(void)(lib); /* not used */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void *ll_load (lua_State *L, const char *path, int seeglb) {
|
static void *lsys_load (lua_State *L, const char *path, int seeglb) {
|
||||||
(void)(path); (void)(seeglb); /* not used */
|
(void)(path); (void)(seeglb); /* not used */
|
||||||
lua_pushliteral(L, DLMSG);
|
lua_pushliteral(L, DLMSG);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
|
static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
|
||||||
(void)(lib); (void)(sym); /* not used */
|
(void)(lib); (void)(sym); /* not used */
|
||||||
lua_pushliteral(L, DLMSG);
|
lua_pushliteral(L, DLMSG);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -248,7 +261,10 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void *ll_checkclib (lua_State *L, const char *path) {
|
/*
|
||||||
|
** return registry.CLIBS[path]
|
||||||
|
*/
|
||||||
|
static void *checkclib (lua_State *L, const char *path) {
|
||||||
void *plib;
|
void *plib;
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
|
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
|
||||||
lua_getfield(L, -1, path);
|
lua_getfield(L, -1, path);
|
||||||
@ -258,7 +274,11 @@ static void *ll_checkclib (lua_State *L, const char *path) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
|
/*
|
||||||
|
** registry.CLIBS[path] = plib -- for queries
|
||||||
|
** registry.CLIBS[#CLIBS + 1] = plib -- also keep a list of all libraries
|
||||||
|
*/
|
||||||
|
static void addtoclib (lua_State *L, const char *path, void *plib) {
|
||||||
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
|
lua_getfield(L, LUA_REGISTRYINDEX, CLIBS);
|
||||||
lua_pushlightuserdata(L, plib);
|
lua_pushlightuserdata(L, plib);
|
||||||
lua_pushvalue(L, -1);
|
lua_pushvalue(L, -1);
|
||||||
@ -269,33 +289,49 @@ static void ll_addtoclib (lua_State *L, const char *path, void *plib) {
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** __gc tag method for CLIBS table: calls 'll_unloadlib' for all lib
|
** __gc tag method for CLIBS table: calls 'lsys_unloadlib' for all lib
|
||||||
** handles in list CLIBS
|
** handles in list CLIBS
|
||||||
*/
|
*/
|
||||||
static int gctm (lua_State *L) {
|
static int gctm (lua_State *L) {
|
||||||
int n = luaL_len(L, 1);
|
int n = luaL_len(L, 1);
|
||||||
for (; n >= 1; n--) { /* for each handle, in reverse order */
|
for (; n >= 1; n--) { /* for each handle, in reverse order */
|
||||||
lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
|
lua_rawgeti(L, 1, n); /* get handle CLIBS[n] */
|
||||||
ll_unloadlib(lua_touserdata(L, -1));
|
lsys_unloadlib(lua_touserdata(L, -1));
|
||||||
lua_pop(L, 1); /* pop handle */
|
lua_pop(L, 1); /* pop handle */
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
|
|
||||||
void *reg = ll_checkclib(L, path); /* check loaded C libraries */
|
/* error codes for 'lookforfunc' */
|
||||||
|
#define ERRLIB 1
|
||||||
|
#define ERRFUNC 2
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Look for a C function named 'sym' in a dynamically loaded library
|
||||||
|
** 'path'.
|
||||||
|
** First, check whether the library is already loaded; if not, try
|
||||||
|
** to load it.
|
||||||
|
** Then, if 'sym' is '*', return true (as library has been loaded).
|
||||||
|
** Otherwise, look for symbol 'sym' in the library and push a
|
||||||
|
** C function with that symbol.
|
||||||
|
** Return 0 and 'true' or a function in the stack; in case of
|
||||||
|
** errors, return an error code and an error message in the stack.
|
||||||
|
*/
|
||||||
|
static int lookforfunc (lua_State *L, const char *path, const char *sym) {
|
||||||
|
void *reg = checkclib(L, path); /* check loaded C libraries */
|
||||||
if (reg == NULL) { /* must load library? */
|
if (reg == NULL) { /* must load library? */
|
||||||
reg = ll_load(L, path, *sym == '*');
|
reg = lsys_load(L, path, *sym == '*'); /* global symbols if 'sym'=='*' */
|
||||||
if (reg == NULL) return ERRLIB; /* unable to load library */
|
if (reg == NULL) return ERRLIB; /* unable to load library */
|
||||||
ll_addtoclib(L, path, reg);
|
addtoclib(L, path, reg);
|
||||||
}
|
}
|
||||||
if (*sym == '*') { /* loading only library (no function)? */
|
if (*sym == '*') { /* loading only library (no function)? */
|
||||||
lua_pushboolean(L, 1); /* return 'true' */
|
lua_pushboolean(L, 1); /* return 'true' */
|
||||||
return 0; /* no errors */
|
return 0; /* no errors */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
lua_CFunction f = ll_sym(L, reg, sym);
|
lua_CFunction f = lsys_sym(L, reg, sym);
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return ERRFUNC; /* unable to find function */
|
return ERRFUNC; /* unable to find function */
|
||||||
lua_pushcfunction(L, f); /* else create new function */
|
lua_pushcfunction(L, f); /* else create new function */
|
||||||
@ -307,7 +343,7 @@ static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
|
|||||||
static int ll_loadlib (lua_State *L) {
|
static int ll_loadlib (lua_State *L) {
|
||||||
const char *path = luaL_checkstring(L, 1);
|
const char *path = luaL_checkstring(L, 1);
|
||||||
const char *init = luaL_checkstring(L, 2);
|
const char *init = luaL_checkstring(L, 2);
|
||||||
int stat = ll_loadfunc(L, path, init);
|
int stat = lookforfunc(L, path, init);
|
||||||
if (stat == 0) /* no errors? */
|
if (stat == 0) /* no errors? */
|
||||||
return 1; /* return the loaded function */
|
return 1; /* return the loaded function */
|
||||||
else { /* error; error message is on stack top */
|
else { /* error; error message is on stack top */
|
||||||
@ -416,21 +452,29 @@ static int searcher_Lua (lua_State *L) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** Try to find a load function for module 'modname' at file 'filename'.
|
||||||
|
** First, change '.' to '_' in 'modname'; then, if 'modname' has
|
||||||
|
** the form X-Y (that is, it has an "ignore mark"), build a function
|
||||||
|
** name "luaopen_X" and look for it. (For compatibility, if that
|
||||||
|
** fails, it also tries "luaopen_Y".) If there is no ignore mark,
|
||||||
|
** look for a function named "luaopen_modname".
|
||||||
|
*/
|
||||||
static int loadfunc (lua_State *L, const char *filename, const char *modname) {
|
static int loadfunc (lua_State *L, const char *filename, const char *modname) {
|
||||||
const char *funcname;
|
const char *openfunc;
|
||||||
const char *mark;
|
const char *mark;
|
||||||
modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
|
modname = luaL_gsub(L, modname, ".", LUA_OFSEP);
|
||||||
mark = strchr(modname, *LUA_IGMARK);
|
mark = strchr(modname, *LUA_IGMARK);
|
||||||
if (mark) {
|
if (mark) {
|
||||||
int stat;
|
int stat;
|
||||||
funcname = lua_pushlstring(L, modname, mark - modname);
|
openfunc = lua_pushlstring(L, modname, mark - modname);
|
||||||
funcname = lua_pushfstring(L, LUA_POF"%s", funcname);
|
openfunc = lua_pushfstring(L, LUA_POF"%s", openfunc);
|
||||||
stat = ll_loadfunc(L, filename, funcname);
|
stat = lookforfunc(L, filename, openfunc);
|
||||||
if (stat != ERRFUNC) return stat;
|
if (stat != ERRFUNC) return stat;
|
||||||
modname = mark + 1; /* else go ahead and try old-style name */
|
modname = mark + 1; /* else go ahead and try old-style name */
|
||||||
}
|
}
|
||||||
funcname = lua_pushfstring(L, LUA_POF"%s", modname);
|
openfunc = lua_pushfstring(L, LUA_POF"%s", modname);
|
||||||
return ll_loadfunc(L, filename, funcname);
|
return lookforfunc(L, filename, openfunc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -686,24 +730,31 @@ static void createsearcherstable (lua_State *L) {
|
|||||||
lua_pushcclosure(L, searchers[i], 1);
|
lua_pushcclosure(L, searchers[i], 1);
|
||||||
lua_rawseti(L, -2, i+1);
|
lua_rawseti(L, -2, i+1);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
LUAMOD_API int luaopen_package (lua_State *L) {
|
|
||||||
/* create table CLIBS to keep track of loaded C libraries */
|
|
||||||
luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS);
|
|
||||||
lua_createtable(L, 0, 1); /* metatable for CLIBS */
|
|
||||||
lua_pushcfunction(L, gctm);
|
|
||||||
lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
|
|
||||||
lua_setmetatable(L, -2);
|
|
||||||
/* create `package' table */
|
|
||||||
luaL_newlib(L, pk_funcs);
|
|
||||||
createsearcherstable(L);
|
|
||||||
#if defined(LUA_COMPAT_LOADERS)
|
#if defined(LUA_COMPAT_LOADERS)
|
||||||
lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
|
lua_pushvalue(L, -1); /* make a copy of 'searchers' table */
|
||||||
lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */
|
lua_setfield(L, -3, "loaders"); /* put it in field `loaders' */
|
||||||
#endif
|
#endif
|
||||||
lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
|
lua_setfield(L, -2, "searchers"); /* put it in field 'searchers' */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
** create table CLIBS to keep track of loaded C libraries,
|
||||||
|
** setting a finalizer to close all libraries when closing state.
|
||||||
|
*/
|
||||||
|
static void createclibstable (lua_State *L) {
|
||||||
|
luaL_getsubtable(L, LUA_REGISTRYINDEX, CLIBS); /* create CLIBS table */
|
||||||
|
lua_createtable(L, 0, 1); /* create metatable for CLIBS */
|
||||||
|
lua_pushcfunction(L, gctm);
|
||||||
|
lua_setfield(L, -2, "__gc"); /* set finalizer for CLIBS table */
|
||||||
|
lua_setmetatable(L, -2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
LUAMOD_API int luaopen_package (lua_State *L) {
|
||||||
|
createclibstable(L);
|
||||||
|
luaL_newlib(L, pk_funcs); /* create `package' table */
|
||||||
|
createsearcherstable(L);
|
||||||
/* set field 'path' */
|
/* set field 'path' */
|
||||||
setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
|
setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
|
||||||
/* set field 'cpath' */
|
/* set field 'cpath' */
|
||||||
|
Loading…
Reference in New Issue
Block a user