1
0
mirror of https://github.com/lua/lua.git synced 2025-01-14 05:43:00 +08:00

Handling of LUA_PATH/LUA_CPATH moved from package library to stand

alone interpreter (so that 'lua.c' concentrates all handling of
environment variables)
This commit is contained in:
Roberto Ierusalimschy 2016-07-18 14:55:59 -03:00
parent 788109a3de
commit de3fd8ab83
3 changed files with 109 additions and 95 deletions

View File

@ -1,5 +1,5 @@
/*
** $Id: loadlib.c,v 1.126 2015/02/16 13:14:33 roberto Exp roberto $
** $Id: loadlib.c,v 1.127 2015/11/23 11:30:45 roberto Exp roberto $
** Dynamic library loader for Lua
** See Copyright Notice in lua.h
**
@ -25,40 +25,9 @@
/*
** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH_VAR)
#define LUA_PATH_VAR "LUA_PATH"
#endif
#if !defined(LUA_CPATH_VAR)
#define LUA_CPATH_VAR "LUA_CPATH"
#endif
#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
#define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX
#define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
** LUA_IGMARK is a mark to ignore all before it when building the
** luaopen_ function name.
*/
#if !defined (LUA_PATH_SEP)
#define LUA_PATH_SEP ";"
#endif
#if !defined (LUA_PATH_MARK)
#define LUA_PATH_MARK "?"
#endif
#if !defined (LUA_EXEC_DIR)
#define LUA_EXEC_DIR "!"
#endif
#if !defined (LUA_IGMARK)
#define LUA_IGMARK "-"
#endif
@ -94,8 +63,6 @@ static const int CLIBS = 0;
#define LIB_FAIL "open"
#define setprogdir(L) ((void)0)
/*
** system-dependent functions
@ -179,7 +146,6 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#include <windows.h>
#undef setprogdir
/*
** optional flags for LoadLibraryEx
@ -189,21 +155,6 @@ static lua_CFunction lsys_sym (lua_State *L, void *lib, const char *sym) {
#endif
static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize);
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '\0';
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
static void pusherror (lua_State *L) {
int error = GetLastError();
char buffer[128];
@ -666,41 +617,6 @@ 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 || noenv(L)) /* no environment variable? */
lua_pushstring(L, def); /* use default */
else {
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2);
}
setprogdir(L);
lua_setfield(L, -2, fieldname);
}
static const luaL_Reg pk_funcs[] = {
{"loadlib", ll_loadlib},
{"searchpath", ll_searchpath},
@ -764,10 +680,10 @@ LUAMOD_API int luaopen_package (lua_State *L) {
createclibstable(L);
luaL_newlib(L, pk_funcs); /* create 'package' table */
createsearcherstable(L);
/* set field 'path' */
setpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, LUA_PATH_DEFAULT);
/* set field 'cpath' */
setpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, LUA_CPATH_DEFAULT);
lua_pushstring(L, LUA_PATH_DEFAULT);
lua_setfield(L, -2, "path"); /* package.path = default path */
lua_pushstring(L, LUA_CPATH_DEFAULT);
lua_setfield(L, -2, "cpath"); /* package.cpath = default cpath */
/* store config information */
lua_pushliteral(L, LUA_DIRSEP "\n" LUA_PATH_SEP "\n" LUA_PATH_MARK "\n"
LUA_EXEC_DIR "\n" LUA_IGMARK "\n");

96
lua.c
View File

@ -1,5 +1,5 @@
/*
** $Id: lua.c,v 1.225 2015/03/30 15:42:59 roberto Exp roberto $
** $Id: lua.c,v 1.226 2015/08/14 19:11:20 roberto Exp roberto $
** Lua stand-alone interpreter
** See Copyright Notice in lua.h
*/
@ -55,6 +55,8 @@
#elif defined(LUA_USE_WINDOWS) /* }{ */
#include <io.h>
#include <windows.h>
#define lua_stdin_is_tty() _isatty(_fileno(stdin))
#else /* }{ */
@ -529,6 +531,91 @@ static int runargs (lua_State *L, char **argv, int n) {
}
/*
** {==================================================================
** Set Paths
** ===================================================================
*/
/*
** LUA_PATH_VAR and LUA_CPATH_VAR are the names of the environment
** variables that Lua check to set its paths.
*/
#if !defined(LUA_PATH_VAR)
#define LUA_PATH_VAR "LUA_PATH"
#endif
#if !defined(LUA_CPATH_VAR)
#define LUA_CPATH_VAR "LUA_CPATH"
#endif
#define LUA_PATHSUFFIX "_" LUA_VERSION_MAJOR "_" LUA_VERSION_MINOR
#define LUA_PATHVARVERSION LUA_PATH_VAR LUA_PATHSUFFIX
#define LUA_CPATHVARVERSION LUA_CPATH_VAR LUA_PATHSUFFIX
#define AUXMARK "\1" /* auxiliary mark */
#if defined(LUA_USE_WINDOWS)
/*
** Replace in the path (on the top of the stack) any occurrence
** of LUA_EXEC_DIR with the executable's path.
*/
static void setprogdir (lua_State *L) {
char buff[MAX_PATH + 1];
char *lb;
DWORD nsize = sizeof(buff)/sizeof(char);
DWORD n = GetModuleFileNameA(NULL, buff, nsize); /* get exec. name */
if (n == 0 || n == nsize || (lb = strrchr(buff, '\\')) == NULL)
luaL_error(L, "unable to get ModuleFileName");
else {
*lb = '\0'; /* cut name on the last '\\' to get the path */
luaL_gsub(L, lua_tostring(L, -1), LUA_EXEC_DIR, buff);
lua_remove(L, -2); /* remove original string */
}
}
#else
#define setprogdir(L) ((void)0)
#endif
/*
** Change a path according to corresponding environment variables
*/
static void chgpath (lua_State *L, const char *fieldname,
const char *envname1,
const char *envname2,
int noenv) {
const char *path = getenv(envname1);
lua_getglobal(L, LUA_LOADLIBNAME); /* get 'package' table */
lua_getfield(L, -1, fieldname); /* get original path */
if (path == NULL) /* no environment variable? */
path = getenv(envname2); /* try alternative name */
if (path == NULL || noenv) /* no environment variable? */
lua_pushvalue(L, -1); /* use original value */
else {
const char *def = lua_tostring(L, -1); /* default path */
/* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
path = luaL_gsub(L, path, LUA_PATH_SEP LUA_PATH_SEP,
LUA_PATH_SEP AUXMARK LUA_PATH_SEP);
luaL_gsub(L, path, AUXMARK, def);
lua_remove(L, -2); /* remove result from 1st 'gsub' */
}
setprogdir(L);
lua_setfield(L, -3, fieldname); /* set path value */
lua_pop(L, 2); /* pop 'package' table and original path */
}
/* }================================================================== */
static int handle_luainit (lua_State *L) {
const char *name = "=" LUA_INITVARVERSION;
const char *init = getenv(name + 1);
@ -561,11 +648,10 @@ static int pmain (lua_State *L) {
}
if (args & has_v) /* option '-v'? */
print_version();
if (args & has_E) { /* option '-E'? */
lua_pushboolean(L, 1); /* signal for libraries to ignore env. vars. */
lua_setfield(L, LUA_REGISTRYINDEX, "LUA_NOENV");
}
luaL_openlibs(L); /* open standard libraries */
/* change paths according to env variables */
chgpath(L, "path", LUA_PATHVARVERSION, LUA_PATH_VAR, (args & has_E));
chgpath(L, "cpath", LUA_CPATHVARVERSION, LUA_CPATH_VAR, (args & has_E));
createargtable(L, argv, argc, script); /* create table 'arg' */
if (!(args & has_E)) { /* no option '-E'? */
if (handle_luainit(L) != LUA_OK) /* run LUA_INIT */

View File

@ -1,5 +1,5 @@
/*
** $Id: luaconf.h,v 1.254 2015/10/21 18:17:40 roberto Exp roberto $
** $Id: luaconf.h,v 1.255 2016/05/01 20:06:09 roberto Exp roberto $
** Configuration file for Lua
** See Copyright Notice in lua.h
*/
@ -158,6 +158,18 @@
** ===================================================================
*/
/*
** LUA_PATH_SEP is the character that separates templates in a path.
** LUA_PATH_MARK is the string that marks the substitution points in a
** template.
** LUA_EXEC_DIR in a Windows path is replaced by the executable's
** directory.
*/
#define LUA_PATH_SEP ";"
#define LUA_PATH_MARK "?"
#define LUA_EXEC_DIR "!"
/*
@@ LUA_PATH_DEFAULT is the default path that Lua uses to look for
** Lua libraries.