diff --git a/lauxlib.c b/lauxlib.c index e99f6f60..a19cb079 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.148 2005/08/18 20:36:26 roberto Exp roberto $ +** $Id: lauxlib.c,v 1.149 2005/08/25 15:39:16 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -66,7 +66,7 @@ LUALIB_API int luaL_typerror (lua_State *L, int narg, const char *tname) { static void tag_error (lua_State *L, int narg, int tag) { - luaL_typerror(L, narg, lua_typename(L, tag)); + luaL_typerror(L, narg, lua_typename(L, tag)); } @@ -235,15 +235,9 @@ LUALIB_API void luaI_openlib (lua_State *L, const char *libname, lua_getfield(L, -1, libname); /* get _LOADED[libname] */ if (!lua_istable(L, -1)) { /* not found? */ lua_pop(L, 1); /* remove previous result */ - luaL_getfield(L, LUA_GLOBALSINDEX, libname); /* try global variable */ - if (!lua_istable(L, -1)) { - if (!lua_isnil(L, -1)) - luaL_error(L, "name conflict for module " LUA_QS, libname); - lua_pop(L, 1); - lua_newtable(L); /* create it */ - lua_pushvalue(L, -1); /* register it with given name */ - luaL_setfield(L, LUA_GLOBALSINDEX, libname); - } + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, libname) != NULL) + luaL_error(L, "name conflict for module " LUA_QS, libname); lua_pushvalue(L, -1); lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ } @@ -337,30 +331,13 @@ LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, } - -LUALIB_API const char *luaL_getfield (lua_State *L, int idx, - const char *fname) { +LUALIB_API const char *luaL_findtable (lua_State *L, int idx, + const char *fname) { const char *e; lua_pushvalue(L, idx); - while ((e = strchr(fname, '.')) != NULL) { - lua_pushlstring(L, fname, e - fname); - lua_rawget(L, -2); - lua_remove(L, -2); /* remove previous table */ - fname = e + 1; - if (!lua_istable(L, -1)) return fname; - } - lua_pushstring(L, fname); - lua_rawget(L, -2); /* get last field */ - lua_remove(L, -2); /* remove previous table */ - return NULL; -} - - -LUALIB_API const char *luaL_setfield (lua_State *L, int idx, - const char *fname) { - const char *e; - lua_pushvalue(L, idx); - while ((e = strchr(fname, '.')) != NULL) { + do { + e = strchr(fname, '.'); + if (e == NULL) e = fname + strlen(fname); lua_pushlstring(L, fname, e - fname); lua_rawget(L, -2); if (lua_isnil(L, -1)) { /* no such field? */ @@ -370,16 +347,13 @@ LUALIB_API const char *luaL_setfield (lua_State *L, int idx, lua_pushvalue(L, -2); lua_settable(L, -4); /* set new table into field */ } + else if (!lua_istable(L, -1)) { /* field has a non-table value? */ + lua_pop(L, 2); /* remove table and value */ + return fname; /* return problematic part of the name */ + } lua_remove(L, -2); /* remove previous table */ fname = e + 1; - if (!lua_istable(L, -1)) { - lua_pop(L, 2); /* remove table and value */ - return fname; - } - } - lua_pushvalue(L, -2); /* move value to the top */ - lua_setfield(L, -2, fname); /* set last field */ - lua_pop(L, 2); /* remove value and table */ + } while (*e == '.'); return NULL; } @@ -635,7 +609,7 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) { free(ptr); return NULL; } - else + else return realloc(ptr, nsize); } diff --git a/lauxlib.h b/lauxlib.h index b31b818e..7c1acaeb 100644 --- a/lauxlib.h +++ b/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.81 2005/08/15 14:12:32 roberto Exp roberto $ +** $Id: lauxlib.h,v 1.82 2005/08/18 20:36:26 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -84,10 +84,9 @@ LUALIB_API lua_State *(luaL_newstate) (void); LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r); -LUALIB_API const char *(luaL_getfield) (lua_State *L, int idx, - const char *fname); -LUALIB_API const char *(luaL_setfield) (lua_State *L, int idx, - const char *fname); + +LUALIB_API const char *(luaL_findtable) (lua_State *L, int idx, + const char *fname); diff --git a/loadlib.c b/loadlib.c index 1b310330..017564d0 100644 --- a/loadlib.c +++ b/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.39 2005/08/17 19:05:04 roberto Exp roberto $ +** $Id: loadlib.c,v 1.40 2005/08/25 15:39:16 roberto Exp roberto $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -511,15 +511,9 @@ static int ll_module (lua_State *L) { lua_getfield(L, 2, modname); /* get _LOADED[modname] */ if (!lua_istable(L, -1)) { /* not found? */ lua_pop(L, 1); /* remove previous result */ - luaL_getfield(L, LUA_GLOBALSINDEX, modname); /* try global variable */ - if (!lua_istable(L, -1)) { - if (!lua_isnil(L, -1)) - return luaL_error(L, "name conflict for module " LUA_QS, modname); - lua_pop(L, 1); - lua_newtable(L); /* create it */ - lua_pushvalue(L, -1); /* register it with given name */ - luaL_setfield(L, LUA_GLOBALSINDEX, modname); - } + /* try global variable (and create one if it does not exist) */ + if (luaL_findtable(L, LUA_GLOBALSINDEX, modname) != NULL) + return luaL_error(L, "name conflict for module " LUA_QS, modname); lua_pushvalue(L, -1); lua_setfield(L, 2, modname); /* _LOADED[modname] = new table */ } @@ -573,6 +567,12 @@ static void setpath (lua_State *L, const char *fieldname, const char *envname, } +static const luaL_reg pk_funcs[] = { + {"loadlib", ll_loadlib}, + {NULL, NULL} +}; + + static const luaL_reg ll_funcs[] = { {"module", ll_module}, {"require", ll_require}, @@ -591,9 +591,11 @@ LUALIB_API int luaopen_package (lua_State *L) { lua_pushcfunction(L, gctm); lua_setfield(L, -2, "__gc"); /* create `package' table */ - lua_newtable(L); - lua_pushvalue(L, -1); - lua_setglobal(L, LUA_LOADLIBNAME); + luaL_register(L, LUA_LOADLIBNAME, pk_funcs); +#if defined(LUA_COMPAT_LOADLIB) + lua_getfield(L, -1, "loadlib"); + lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); +#endif lua_pushvalue(L, -1); lua_setfield(L, LUA_REGISTRYINDEX, "_PACKAGE"); lua_pushvalue(L, -1); @@ -618,15 +620,9 @@ LUALIB_API int luaopen_package (lua_State *L) { /* set field `preload' */ lua_newtable(L); lua_setfield(L, -2, "preload"); - /* create `loadlib' function */ - lua_pushcfunction(L, ll_loadlib); -#if defined(LUA_COMPAT_LOADLIB) - lua_pushvalue(L, -1); - lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); -#endif - lua_setfield(L, -2, "loadlib"); lua_pushvalue(L, LUA_GLOBALSINDEX); luaL_register(L, NULL, ll_funcs); /* open lib into global table */ - return 1; + lua_pop(L, 1); + return 1; /* return 'package' table */ } diff --git a/ltests.c b/ltests.c index ba2f01a1..f27e21bd 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.27 2005/07/12 14:32:08 roberto Exp roberto $ +** $Id: ltests.c,v 2.28 2005/08/15 14:12:32 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -1078,23 +1078,6 @@ static int auxgsub (lua_State *L) { } -static int auxgetf (lua_State *L) { - const char *s = luaL_checkstring(L, 1); - lua_settop(L, 2); - lua_pushstring(L, luaL_getfield(L, 2, s)); - lua_assert(lua_gettop(L) == 4); - return 2; -} - - -static int auxsetf (lua_State *L) { - const char *s = luaL_checkstring(L, 1); - lua_settop(L, 3); - lua_pushstring(L, luaL_setfield(L, 2, s)); - lua_assert(lua_gettop(L) == 3); - return 1; -} - /* }====================================================== */ @@ -1107,7 +1090,6 @@ static const struct luaL_reg tests_funcs[] = { {"doremote", doremote}, {"gccolor", get_gccolor}, {"gcstate", gcstate}, - {"getfield", auxgetf}, {"getref", getref}, {"gsub", auxgsub}, {"hash", hash_query}, @@ -1127,7 +1109,6 @@ static const struct luaL_reg tests_funcs[] = { {"ref", tref}, {"resume", coresume}, {"s2d", s2d}, - {"setfield", auxsetf}, {"setyhook", setyhook}, {"stacklevel", stacklevel}, {"testC", testC}, diff --git a/lua.c b/lua.c index 28975968..8028d15f 100644 --- a/lua.c +++ b/lua.c @@ -1,5 +1,5 @@ /* -** $Id: lua.c,v 1.147 2005/08/25 15:39:16 roberto Exp roberto $ +** $Id: lua.c,v 1.148 2005/08/25 19:55:38 roberto Exp roberto $ ** Lua stand-alone interpreter ** See Copyright Notice in lua.h */ @@ -71,14 +71,19 @@ static int report (lua_State *L, int status) { static int traceback (lua_State *L) { - luaL_getfield(L, LUA_GLOBALSINDEX, "debug.traceback"); - if (!lua_isfunction(L, -1)) + lua_getfield(L, LUA_GLOBALSINDEX, "debug"); + if (!lua_istable(L, -1)) { lua_pop(L, 1); - else { - lua_pushvalue(L, 1); /* pass error message */ - lua_pushinteger(L, 2); /* skip this function and traceback */ - lua_call(L, 2, 1); /* call debug.traceback */ + return 1; } + lua_getfield(L, -1, "traceback"); + if (!lua_isfunction(L, -1)) { + lua_pop(L, 2); + return 1; + } + lua_pushvalue(L, 1); /* pass error message */ + lua_pushinteger(L, 2); /* skip this function and traceback */ + lua_call(L, 2, 1); /* call debug.traceback */ return 1; }