summaryrefslogtreecommitdiff
path: root/src/loadlib_rel.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/loadlib_rel.c')
-rw-r--r--src/loadlib_rel.c131
1 files changed, 91 insertions, 40 deletions
diff --git a/src/loadlib_rel.c b/src/loadlib_rel.c
index 9ebd8cc..13fce89 100644
--- a/src/loadlib_rel.c
+++ b/src/loadlib_rel.c
@@ -1,5 +1,5 @@
/*
-** $Id: loadlib.c,v 1.100 2011/07/05 12:49:35 roberto Exp $
+** $Id: loadlib.c,v 1.108 2011/12/12 16:34:03 roberto Exp $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@@ -9,6 +9,14 @@
*/
+/*
+** if needed, includes windows header before everything else
+*/
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
+
#include <stdlib.h>
#include <string.h>
@@ -62,6 +70,20 @@
#endif
+/*
+** LUA_CSUBSEP is the character that replaces dots in submodule names
+** when searching for a C loader.
+** LUA_LSUBSEP is the character that replaces dots in submodule names
+** when searching for a Lua loader.
+*/
+#if !defined(LUA_CSUBSEP)
+#define LUA_CSUBSEP LUA_DIRSEP
+#endif
+
+#if !defined(LUA_LSUBSEP)
+#define LUA_LSUBSEP LUA_DIRSEP
+#endif
+
/* prefix for open functions in C libraries */
#define LUA_POF "luaopen_"
@@ -91,6 +113,7 @@ static void setprogdir (lua_State *L);
/*
** {=========================================================================
** This determines the location of the executable for relative module loading
+** Modified by the LuaDist project for UNIX platforms
** ==========================================================================
*/
#if defined(_WIN32) || defined(__CYGWIN__)
@@ -161,7 +184,6 @@ static void setprogdir (lua_State *L) {
}
}
-
#if defined(LUA_USE_DLOPEN)
/*
** {========================================================================
@@ -180,7 +202,7 @@ static void ll_unloadlib (void *lib) {
static void *ll_load (lua_State *L, const char *path, int seeglb) {
- void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : 0));
+ void *lib = dlopen(path, RTLD_NOW | (seeglb ? RTLD_GLOBAL : RTLD_LOCAL));
if (lib == NULL) lua_pushstring(L, dlerror());
return lib;
}
@@ -203,8 +225,6 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
** =======================================================================
*/
-#include <windows.h>
-
/*
** optional flags for LoadLibraryEx
*/
@@ -229,7 +249,7 @@ static void ll_unloadlib (void *lib) {
static void *ll_load (lua_State *L, const char *path, int seeglb) {
HMODULE lib = LoadLibraryExA(path, NULL, LUA_LLE_FLAGS);
- (void)(seeglb); /* symbols are 'global' by default */
+ (void)(seeglb); /* not used: symbols are 'global' by default */
if (lib == NULL) pusherror(L);
return lib;
}
@@ -259,19 +279,19 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
static void ll_unloadlib (void *lib) {
- (void)(lib); /* to avoid warnings */
+ (void)(lib); /* not used */
}
static void *ll_load (lua_State *L, const char *path, int seeglb) {
- (void)(path); (void)(seeglb); /* to avoid warnings */
+ (void)(path); (void)(seeglb); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- (void)(lib); (void)(sym); /* to avoid warnings */
+ (void)(lib); (void)(sym); /* not used */
lua_pushliteral(L, DLMSG);
return NULL;
}
@@ -374,10 +394,12 @@ static const char *pushnexttemplate (lua_State *L, const char *path) {
static const char *searchpath (lua_State *L, const char *name,
const char *path,
- const char *sep) {
+ const char *sep,
+ const char *dirsep) {
+ luaL_Buffer msg; /* to build error message */
+ luaL_buffinit(L, &msg);
if (*sep != '\0') /* non-empty separator? */
- name = luaL_gsub(L, name, sep, LUA_DIRSEP); /* replace it by proper one */
- lua_pushliteral(L, ""); /* error accumulator */
+ name = luaL_gsub(L, name, sep, dirsep); /* replace it by 'dirsep' */
while ((path = pushnexttemplate(L, path)) != NULL) {
const char *filename = luaL_gsub(L, lua_tostring(L, -1),
LUA_PATH_MARK, name);
@@ -386,8 +408,9 @@ static const char *searchpath (lua_State *L, const char *name,
return filename; /* return that file name */
lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
lua_remove(L, -2); /* remove file name */
- lua_concat(L, 2); /* add entry to possible error message */
+ luaL_addvalue(&msg); /* concatenate error msg. entry */
}
+ luaL_pushresult(&msg); /* create error message */
return NULL; /* not found */
}
@@ -395,7 +418,8 @@ static const char *searchpath (lua_State *L, const char *name,
static int ll_searchpath (lua_State *L) {
const char *f = searchpath(L, luaL_checkstring(L, 1),
luaL_checkstring(L, 2),
- luaL_optstring(L, 3, "."));
+ luaL_optstring(L, 3, "."),
+ luaL_optstring(L, 4, LUA_DIRSEP));
if (f != NULL) return 1;
else { /* error message is on top of the stack */
lua_pushnil(L);
@@ -406,13 +430,14 @@ static int ll_searchpath (lua_State *L) {
static const char *findfile (lua_State *L, const char *name,
- const char *pname) {
+ const char *pname,
+ const char *dirsep) {
const char *path;
lua_getfield(L, lua_upvalueindex(1), pname);
path = lua_tostring(L, -1);
if (path == NULL)
luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
- return searchpath(L, name, path, ".");
+ return searchpath(L, name, path, ".", dirsep);
}
@@ -431,7 +456,7 @@ static int checkload (lua_State *L, int stat, const char *filename) {
static int searcher_Lua (lua_State *L) {
const char *filename;
const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path");
+ filename = findfile(L, name, "path", LUA_LSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (luaL_loadfile(L, filename) == LUA_OK), filename);
}
@@ -457,7 +482,7 @@ static int loadfunc (lua_State *L, const char *filename, const char *modname) {
static int searcher_C (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath");
+ const char *filename = findfile(L, name, "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* module not found in this path */
return checkload(L, (loadfunc(L, filename, name) == 0), filename);
}
@@ -470,7 +495,7 @@ static int searcher_Croot (lua_State *L) {
int stat;
if (p == NULL) return 0; /* is root */
lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath");
+ filename = findfile(L, lua_tostring(L, -1), "cpath", LUA_CSUBSEP);
if (filename == NULL) return 1; /* root not found */
if ((stat = loadfunc(L, filename, name)) != 0) {
if (stat != ERRFUNC)
@@ -496,35 +521,46 @@ static int searcher_preload (lua_State *L) {
}
-static int ll_require (lua_State *L) {
- const char *name = luaL_checkstring(L, 1);
+static void findloader (lua_State *L, const char *name) {
int i;
- lua_settop(L, 1); /* _LOADED table will be at index 2 */
- lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
- lua_getfield(L, 2, name);
- if (lua_toboolean(L, -1)) /* is it there? */
- return 1; /* package is already loaded */
- /* else must load it; iterate over available seachers to find a loader */
- lua_getfield(L, lua_upvalueindex(1), "searchers");
- if (!lua_istable(L, -1))
+ luaL_Buffer msg; /* to build error message */
+ luaL_buffinit(L, &msg);
+ lua_getfield(L, lua_upvalueindex(1), "searchers"); /* will be at index 3 */
+ if (!lua_istable(L, 3))
luaL_error(L, LUA_QL("package.searchers") " must be a table");
- lua_pushliteral(L, ""); /* error message accumulator */
- for (i=1; ; i++) {
- lua_rawgeti(L, -2, i); /* get a seacher */
- if (lua_isnil(L, -1)) /* no more searchers? */
+ /* iterate over available seachers to find a loader */
+ for (i = 1; ; i++) {
+ lua_rawgeti(L, 3, i); /* get a seacher */
+ if (lua_isnil(L, -1)) { /* no more searchers? */
+ lua_pop(L, 1); /* remove nil */
+ luaL_pushresult(&msg); /* create error message */
luaL_error(L, "module " LUA_QS " not found:%s",
- name, lua_tostring(L, -2));
+ name, lua_tostring(L, -1));
+ }
lua_pushstring(L, name);
lua_call(L, 1, 2); /* call it */
if (lua_isfunction(L, -2)) /* did it find a loader? */
- break; /* module loader found */
+ return; /* module loader found */
else if (lua_isstring(L, -2)) { /* searcher returned error message? */
lua_pop(L, 1); /* remove extra return */
- lua_concat(L, 2); /* accumulate error message */
+ luaL_addvalue(&msg); /* concatenate error message */
}
else
lua_pop(L, 2); /* remove both returns */
}
+}
+
+
+static int ll_require (lua_State *L) {
+ const char *name = luaL_checkstring(L, 1);
+ lua_settop(L, 1); /* _LOADED table will be at index 2 */
+ lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
+ lua_getfield(L, 2, name); /* _LOADED[name] */
+ if (lua_toboolean(L, -1)) /* is it there? */
+ return 1; /* package is already loaded */
+ /* else must load package */
+ lua_pop(L, 1); /* remove 'getfield' result */
+ findloader(L, name);
lua_pushstring(L, name); /* pass name as argument to module loader */
lua_insert(L, -2); /* name is 1st argument (before search data) */
lua_call(L, 2, 1); /* run loader to load module */
@@ -568,9 +604,11 @@ static void set_env (lua_State *L) {
static void dooptions (lua_State *L, int n) {
int i;
for (i = 2; i <= n; i++) {
- lua_pushvalue(L, i); /* get option (a function) */
- lua_pushvalue(L, -2); /* module */
- lua_call(L, 1, 0);
+ if (lua_isfunction(L, i)) { /* avoid 'calling' extra info. */
+ lua_pushvalue(L, i); /* get option (a function) */
+ lua_pushvalue(L, -2); /* module */
+ lua_call(L, 1, 0);
+ }
}
}
@@ -629,12 +667,25 @@ static int ll_seeall (lua_State *L) {
/* auxiliary mark (for internal use) */
#define AUXMARK "\1"
+
+/*
+** return registry.LUA_NOENV as a boolean
+*/
+static int noenv (lua_State *L) {
+ int b;
+ lua_getfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
+ b = lua_toboolean(L, -1);
+ lua_pop(L, 1); /* remove value */
+ return b;
+}
+
+
static void setpath (lua_State *L, const char *fieldname, const char *envname1,
const char *envname2, const char *def) {
const char *path = getenv(envname1);
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
- if (path == NULL) /* no environment variable? */
+ if (path == NULL || noenv(L)) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */