From dd3a63c205a97339d8c8aec3cd49941bc10ba45c Mon Sep 17 00:00:00 2001 From: Roberto Ierusalimschy <roberto@inf.puc-rio.br> Date: Mon, 26 Mar 2001 11:31:49 -0300 Subject: new way to handle `profiles' --- lbaselib.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 9 deletions(-) (limited to 'lbaselib.c') diff --git a/lbaselib.c b/lbaselib.c index 20efb03e..d26bc7b0 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.29 2001/03/06 20:09:38 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.30 2001/03/07 12:43:52 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -11,6 +11,7 @@ #include <stdlib.h> #include <string.h> +#define LUA_PRIVATE #include "lua.h" #include "lauxlib.h" @@ -42,7 +43,7 @@ static int luaB__ALERT (lua_State *L) { */ static int luaB__ERRORMESSAGE (lua_State *L) { luaL_checktype(L, 1, LUA_TSTRING); - lua_getglobal(L, LUA_ALERT); + lua_getglobal(L, l_s(LUA_ALERT)); if (lua_isfunction(L, -1)) { /* avoid error loop if _ALERT is not defined */ lua_Debug ar; lua_pushliteral(L, l_s("error: ")); @@ -303,6 +304,68 @@ static int luaB_dofile (lua_State *L) { } +#define LUA_PATH l_s("LUA_PATH") + +#define LUA_PATH_SEP l_s(";") + +#ifndef LUA_PATH_DEFAULT +#define LUA_PATH_DEFAULT l_s("./") +#endif + +static int luaB_require (lua_State *L) { + const l_char *path; + luaL_check_string(L, 1); + lua_settop(L, 1); + lua_getglobal(L, LUA_PATH); /* get path */ + if (lua_isstring(L, 2)) /* is LUA_PATH defined? */ + path = lua_tostring(L, 2); + else { /* LUA_PATH not defined */ + lua_pop(L, 1); /* pop old global value */ + path = getenv(LUA_PATH); /* try environment variable */ + if (path == NULL) path = LUA_PATH_DEFAULT; /* else use default */ + lua_pushstring(L, path); + lua_pushvalue(L, -1); /* duplicate to leave a copy on stack */ + lua_setglobal(L, LUA_PATH); + } + lua_getregistry(L); + lua_pushliteral(L, LUA_PATH); + lua_gettable(L, 3); /* get book-keeping table */ + if (lua_isnil(L, 4)) { /* no book-keeping table? */ + lua_pop(L, 1); /* pop the `nil' */ + lua_newtable(L); /* create book-keeping table */ + lua_pushliteral(L, LUA_PATH); + lua_pushvalue(L, -2); /* duplicate table to leave a copy on stack */ + lua_settable(L, 3); /* store book-keeping table in registry */ + } + lua_pushvalue(L, 1); + lua_gettable(L, 4); /* check package's name in book-keeping table */ + if (!lua_isnil(L, -1)) /* is it there? */ + return 0; /* package is already loaded */ + else { /* must load it */ + for (;;) { /* traverse path */ + int res; + int l = strcspn(path, LUA_PATH_SEP); /* find separator */ + lua_pushlstring(L, path, l); /* directory name */ + lua_pushvalue(L, 1); /* package name */ + lua_concat(L, 2); /* concat directory with package name */ + res = lua_dofile(L, lua_tostring(L, -1)); /* try to load it */ + lua_settop(L, 4); /* pop string and eventual results from dofile */ + if (res == 0) break; /* ok; file done */ + else if (res != LUA_ERRFILE) + lua_error(L, NULL); /* error running package; propagate it */ + if (*(path+l) == l_c('\0')) /* no more directories? */ + luaL_verror(L, l_s("could not load package `%.20s' from path `%.200s'"), + lua_tostring(L, 1), lua_tostring(L, 2)); + path += l+1; /* try next directory */ + } + } + lua_pushvalue(L, 1); + lua_pushnumber(L, 1); + lua_settable(L, 4); /* mark it as loaded */ + return 0; +} + + static int luaB_pack (lua_State *L) { int n = lua_gettop(L); lua_newtable(L); @@ -337,10 +400,10 @@ static int luaB_call (lua_State *L) { int status; int n; if (!lua_isnull(L, 4)) { /* set new error method */ - lua_getglobal(L, LUA_ERRORMESSAGE); + lua_getglobal(L, l_s(LUA_ERRORMESSAGE)); err = lua_gettop(L); /* get index */ lua_pushvalue(L, 4); - lua_setglobal(L, LUA_ERRORMESSAGE); + lua_setglobal(L, l_s(LUA_ERRORMESSAGE)); } oldtop = lua_gettop(L); /* top before function-call preparation */ /* push function */ @@ -349,7 +412,7 @@ static int luaB_call (lua_State *L) { status = lua_call(L, n, LUA_MULTRET); if (err != 0) { /* restore old error method */ lua_pushvalue(L, err); - lua_setglobal(L, LUA_ERRORMESSAGE); + lua_setglobal(L, l_s(LUA_ERRORMESSAGE)); } if (status != 0) { /* error in call? */ if (strchr(options, l_c('x'))) @@ -382,7 +445,8 @@ static int luaB_tostring (lua_State *L) { case LUA_TUSERDATA: { const l_char *t = lua_xtype(L, 1); if (strcmp(t, l_s("userdata")) == 0) - sprintf(buff, l_s("userdata(%d): %p"), lua_tag(L, 1), lua_touserdata(L, 1)); + sprintf(buff, l_s("userdata(%d): %p"), lua_tag(L, 1), + lua_touserdata(L, 1)); else sprintf(buff, l_s("%.40s: %p"), t, lua_touserdata(L, 1)); break; @@ -663,8 +727,8 @@ static void deprecated_funcs (lua_State *L) { /* }====================================================== */ static const luaL_reg base_funcs[] = { - {LUA_ALERT, luaB__ALERT}, - {LUA_ERRORMESSAGE, luaB__ERRORMESSAGE}, + {l_s(LUA_ALERT), luaB__ALERT}, + {l_s(LUA_ERRORMESSAGE), luaB__ERRORMESSAGE}, {l_s("call"), luaB_call}, {l_s("collectgarbage"), luaB_collectgarbage}, {l_s("copytagmethods"), luaB_copytagmethods}, @@ -685,6 +749,7 @@ static const luaL_reg base_funcs[] = { {l_s("rawset"), luaB_rawset}, {l_s("rawgettable"), luaB_rawget}, /* for compatibility 3.2 */ {l_s("rawsettable"), luaB_rawset}, /* for compatibility 3.2 */ + {l_s("require"), luaB_require}, {l_s("setglobal"), luaB_setglobal}, {l_s("settag"), luaB_settag}, {l_s("settagmethod"), luaB_settagmethod}, @@ -706,7 +771,7 @@ static const luaL_reg base_funcs[] = { LUALIB_API int lua_baselibopen (lua_State *L) { luaL_openl(L, base_funcs); - lua_pushliteral(L, LUA_VERSION); + lua_pushliteral(L, l_s(LUA_VERSION)); lua_setglobal(L, l_s("_VERSION")); deprecated_funcs(L); return 0; -- cgit v1.2.3-55-g6feb