diff --git a/lauxlib.c b/lauxlib.c index 38e40404..2f0168f1 100644 --- a/lauxlib.c +++ b/lauxlib.c @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.c,v 1.215 2010/06/09 17:53:59 roberto Exp roberto $ +** $Id: lauxlib.c,v 1.216 2010/06/30 17:40:27 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -729,20 +729,33 @@ LUALIB_API void luaL_openlib (lua_State *L, const char *libname, luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ } + luaL_setfuncs(L, l, nup); +} + +/* }====================================================== */ + +/* +** set functions from list 'l' into table at top - 'nup'; each +** function gets the 'nup' elements at the top as upvalues. +** Returns with only the table at the stack. +*/ +LUALIB_API void luaL_setfuncs (lua_State *L, const luaL_Reg *l, int nup) { luaL_checkstack(L, nup, "too many upvalues"); for (; l && l->name; l++) { /* fill the table with given functions */ int i; for (i = 0; i < nup; i++) /* copy upvalues to the top */ lua_pushvalue(L, -nup); - lua_pushcclosure(L, l->func, nup); + lua_pushcclosure(L, l->func, nup); /* closure with those upvalues */ lua_setfield(L, -(nup + 2), l->name); } lua_pop(L, nup); /* remove upvalues */ } -/* }====================================================== */ - +/* +** ensure that stack[idx][fname] has a table and push that table +** into the stack +*/ LUALIB_API void luaL_findtable (lua_State *L, int idx, const char *fname) { lua_getfield(L, idx, fname); if (lua_istable(L, -1)) return; /* table already there */ @@ -756,6 +769,30 @@ LUALIB_API void luaL_findtable (lua_State *L, int idx, const char *fname) { } +/* +** stripped-down 'require'. Calls 'openf' to open a module, +** registers the result in 'package.loaded' table and, if 'glb' +** is true, also registers the result in the global table. +** Leaves resulting module on the top. +*/ +LUALIB_API void luaL_requiref (lua_State *L, const char *modname, + lua_CFunction openf, int glb) { + lua_pushcfunction(L, openf); + lua_pushstring(L, modname); /* argument to open function */ + lua_call(L, 1, 1); /* open module */ + luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED"); + lua_pushvalue(L, -2); /* make copy of module (call result) */ + lua_setfield(L, -2, modname); /* _LOADED[modname] = module */ + lua_pop(L, 1); /* remove _LOADED table */ + if (glb) { + lua_pushglobaltable(L); + lua_pushvalue(L, -2); /* copy of 'mod' */ + lua_setfield(L, -2, modname); /* _G[modname] = module */ + lua_pop(L, 1); /* remove _G table */ + } +} + + LUALIB_API const char *luaL_gsub (lua_State *L, const char *s, const char *p, const char *r) { const char *wild; diff --git a/lauxlib.h b/lauxlib.h index d5728b58..4d762886 100644 --- a/lauxlib.h +++ b/lauxlib.h @@ -1,5 +1,5 @@ /* -** $Id: lauxlib.h,v 1.106 2010/05/31 16:34:19 roberto Exp roberto $ +** $Id: lauxlib.h,v 1.107 2010/06/30 17:40:27 roberto Exp roberto $ ** Auxiliary functions for building Lua libraries ** See Copyright Notice in lua.h */ @@ -29,10 +29,6 @@ typedef struct luaL_Reg { LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) -LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, - int sizehint); -LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, - const luaL_Reg *l, int nup); LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); LUALIB_API int (luaL_callmeta) (lua_State *L, int obj, const char *e); LUALIB_API const char *(luaL_tolstring) (lua_State *L, int idx, size_t *len); @@ -78,11 +74,15 @@ LUALIB_API int (luaL_len) (lua_State *L, int idx); LUALIB_API const char *(luaL_gsub) (lua_State *L, const char *s, const char *p, const char *r); +LUALIB_API void (luaL_setfuncs) (lua_State *L, const luaL_Reg *l, int nup); + LUALIB_API void (luaL_findtable) (lua_State *L, int idx, const char *fname); LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, const char *msg, int level); +LUALIB_API void (luaL_requiref) (lua_State *L, const char *modname, + lua_CFunction openf, int glb); /* ** =============================================================== @@ -90,6 +90,12 @@ LUALIB_API void (luaL_traceback) (lua_State *L, lua_State *L1, ** =============================================================== */ + +#define luaL_newlibtable(L,l) \ + lua_createtable(L, 0, sizeof(l)/sizeof((l)[0]) - 1) + +#define luaL_newlib(L,l) (luaL_newlibtable(L,l), luaL_setfuncs(L,l,0)) + #define luaL_argcheck(L, cond,numarg,extramsg) \ ((void)((cond) || luaL_argerror(L, (numarg), (extramsg)))) #define luaL_checkstring(L,n) (luaL_checklstring(L, (n), NULL)) @@ -149,6 +155,12 @@ LUALIB_API char *(luaL_buffinitsize) (lua_State *L, luaL_Buffer *B, size_t sz); /* }====================================================== */ +LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, + int sizehint); +LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, + const luaL_Reg *l, int nup); + + /* compatibility with ref system */ /* pre-defined references */ diff --git a/lbaselib.c b/lbaselib.c index a84e682d..9680bb38 100644 --- a/lbaselib.c +++ b/lbaselib.c @@ -1,5 +1,5 @@ /* -** $Id: lbaselib.c,v 1.244 2010/06/10 21:29:47 roberto Exp roberto $ +** $Id: lbaselib.c,v 1.245 2010/06/13 19:41:34 roberto Exp roberto $ ** Basic library ** See Copyright Notice in lua.h */ @@ -496,7 +496,7 @@ LUAMOD_API int luaopen_base (lua_State *L) { lua_pushglobaltable(L); lua_setfield(L, -2, "_G"); /* open lib into global table */ - luaL_register(L, "_G", base_funcs); + luaL_setfuncs(L, base_funcs, 0); lua_pushliteral(L, LUA_VERSION); lua_setfield(L, -2, "_VERSION"); /* set global _VERSION */ /* `newproxy' needs a weaktable as upvalue */ diff --git a/lbitlib.c b/lbitlib.c index 3b5f5b83..cae1b1f5 100644 --- a/lbitlib.c +++ b/lbitlib.c @@ -1,5 +1,5 @@ /* -** $Id: lbitlib.c,v 1.3 2010/01/12 19:40:02 roberto Exp roberto $ +** $Id: lbitlib.c,v 1.4 2010/02/11 15:55:29 roberto Exp roberto $ ** Standard library for bitwise operations ** See Copyright Notice in lua.h */ @@ -141,6 +141,6 @@ static const luaL_Reg bitlib[] = { LUAMOD_API int luaopen_bit (lua_State *L) { - luaL_register(L, LUA_BITLIBNAME, bitlib); + luaL_newlib(L, bitlib); return 1; } diff --git a/lcorolib.c b/lcorolib.c index fdcbc6de..1eef89c9 100644 --- a/lcorolib.c +++ b/lcorolib.c @@ -1,5 +1,5 @@ /* -** $Id: lcorolib.c,v $ +** $Id: lcorolib.c,v 1.1 2010/06/10 21:30:26 roberto Exp roberto $ ** Coroutine Library ** See Copyright Notice in lua.h */ @@ -148,7 +148,7 @@ static const luaL_Reg co_funcs[] = { LUAMOD_API int luaopen_coroutine (lua_State *L) { - luaL_register(L, LUA_COLIBNAME, co_funcs); + luaL_newlib(L, co_funcs); return 1; } diff --git a/ldblib.c b/ldblib.c index d6d58233..6afc1fc1 100644 --- a/ldblib.c +++ b/ldblib.c @@ -1,5 +1,5 @@ /* -** $Id: ldblib.c,v 1.121 2010/03/26 20:58:11 roberto Exp roberto $ +** $Id: ldblib.c,v 1.122 2010/06/21 16:30:12 roberto Exp roberto $ ** Interface from Lua to its debug API ** See Copyright Notice in lua.h */ @@ -395,7 +395,7 @@ static const luaL_Reg dblib[] = { LUAMOD_API int luaopen_debug (lua_State *L) { - luaL_register(L, LUA_DBLIBNAME, dblib); + luaL_newlib(L, dblib); return 1; } diff --git a/linit.c b/linit.c index 6c803270..2779e9b1 100644 --- a/linit.c +++ b/linit.c @@ -1,5 +1,5 @@ /* -** $Id: linit.c,v 1.26 2010/06/10 21:29:47 roberto Exp roberto $ +** $Id: linit.c,v 1.27 2010/06/30 17:40:27 roberto Exp roberto $ ** Initialization of libraries for lua.c and other clients ** See Copyright Notice in lua.h */ @@ -36,6 +36,9 @@ static const luaL_Reg loadedlibs[] = { {LUA_STRLIBNAME, luaopen_string}, {LUA_BITLIBNAME, luaopen_bit}, {LUA_MATHLIBNAME, luaopen_math}, +#if defined(LUA_COMPAT_DEBUGLIB) + {LUA_DBLIBNAME, luaopen_debug}, +#endif {NULL, NULL} }; @@ -51,25 +54,17 @@ static const luaL_Reg preloadedlibs[] = { LUALIB_API void luaL_openlibs (lua_State *L) { const luaL_Reg *lib; - /* call open functions from 'loadedlibs' */ + /* call open functions from 'loadedlibs' and set results to global table */ for (lib = loadedlibs; lib->func; lib++) { - lua_pushcfunction(L, lib->func); - lua_pushstring(L, lib->name); - lua_call(L, 1, 0); + luaL_requiref(L, lib->name, lib->func, 1); + lua_pop(L, 1); /* remove lib */ } /* add open functions from 'preloadedlibs' into 'package.preload' table */ - lua_pushglobaltable(L); luaL_findtable(L, LUA_REGISTRYINDEX, "_PRELOAD"); for (lib = preloadedlibs; lib->func; lib++) { lua_pushcfunction(L, lib->func); lua_setfield(L, -2, lib->name); } - lua_pop(L, 1); /* remove package.preload table */ -#if defined(LUA_COMPAT_DEBUGLIB) - lua_getglobal(L, "require"); - lua_pushliteral(L, LUA_DBLIBNAME); - lua_call(L, 1, 0); /* call 'require"debug"' */ - lua_pop(L, 1); /* remove global table */ -#endif + lua_pop(L, 1); /* remove _PRELOAD table */ } diff --git a/liolib.c b/liolib.c index 6a290098..a26aff5a 100644 --- a/liolib.c +++ b/liolib.c @@ -1,5 +1,5 @@ /* -** $Id: liolib.c,v 2.87 2010/03/17 21:37:37 roberto Exp roberto $ +** $Id: liolib.c,v 2.88 2010/03/26 20:58:11 roberto Exp roberto $ ** Standard I/O (and system) library ** See Copyright Notice in lua.h */ @@ -615,8 +615,9 @@ LUAMOD_API int luaopen_io (lua_State *L) { createmeta(L); /* create (private) environment (with fields IO_INPUT, IO_OUTPUT, __close) */ newenv(L, io_fclose); /* upvalue for all io functions at index 1 */ - lua_pushvalue(L, -1); /* copy to be consumed by 'openlib' */ - luaL_openlib(L, LUA_IOLIBNAME, iolib, 1); /* new module at index 2 */ + luaL_newlibtable(L, iolib); /* new module at index 2 */ + lua_pushvalue(L, 1); /* copy of env to be consumed by 'setfuncs' */ + luaL_setfuncs(L, iolib, 1); /* create (and set) default files */ newenv(L, io_noclose); /* environment for default files at index 3 */ createstdfile(L, stdin, IO_INPUT, "stdin"); diff --git a/lmathlib.c b/lmathlib.c index 391a31e7..83eaf22e 100644 --- a/lmathlib.c +++ b/lmathlib.c @@ -1,5 +1,5 @@ /* -** $Id: lmathlib.c,v 1.73 2009/03/17 17:55:39 roberto Exp roberto $ +** $Id: lmathlib.c,v 1.74 2009/11/24 12:05:44 roberto Exp roberto $ ** Standard mathematical library ** See Copyright Notice in lua.h */ @@ -263,7 +263,7 @@ static const luaL_Reg mathlib[] = { ** Open math library */ LUAMOD_API int luaopen_math (lua_State *L) { - luaL_register(L, LUA_MATHLIBNAME, mathlib); + luaL_newlib(L, mathlib); lua_pushnumber(L, PI); lua_setfield(L, -2, "pi"); lua_pushnumber(L, HUGE_VAL); diff --git a/loadlib.c b/loadlib.c index bb517801..712fcfef 100644 --- a/loadlib.c +++ b/loadlib.c @@ -1,5 +1,5 @@ /* -** $Id: loadlib.c,v 1.85 2010/06/18 17:23:02 roberto Exp roberto $ +** $Id: loadlib.c,v 1.86 2010/06/30 17:40:27 roberto Exp roberto $ ** Dynamic library loader for Lua ** See Copyright Notice in lua.h ** @@ -616,7 +616,7 @@ LUAMOD_API int luaopen_package (lua_State *L) { lua_pushcfunction(L, gctm); lua_setfield(L, -2, "__gc"); /* create `package' table */ - luaL_register(L, LUA_LOADLIBNAME, pk_funcs); + luaL_newlib(L, pk_funcs); /* create `loaders' table */ lua_createtable(L, sizeof(loaders)/sizeof(loaders[0]) - 1, 0); /* fill it with pre-defined loaders */ diff --git a/loslib.c b/loslib.c index c51ce5eb..2c378e9b 100644 --- a/loslib.c +++ b/loslib.c @@ -1,5 +1,5 @@ /* -** $Id: loslib.c,v 1.28 2009/12/17 12:26:09 roberto Exp roberto $ +** $Id: loslib.c,v 1.29 2009/12/17 13:08:51 roberto Exp roberto $ ** Standard Operating System library ** See Copyright Notice in lua.h */ @@ -304,7 +304,7 @@ static const luaL_Reg syslib[] = { LUAMOD_API int luaopen_os (lua_State *L) { - luaL_register(L, LUA_OSLIBNAME, syslib); + luaL_newlib(L, syslib); return 1; } diff --git a/lstrlib.c b/lstrlib.c index 565d913e..79b3ab37 100644 --- a/lstrlib.c +++ b/lstrlib.c @@ -1,5 +1,5 @@ /* -** $Id: lstrlib.c,v 1.152 2010/05/04 17:20:33 roberto Exp roberto $ +** $Id: lstrlib.c,v 1.153 2010/05/24 19:34:57 roberto Exp roberto $ ** Standard library for string operations and pattern-matching ** See Copyright Notice in lua.h */ @@ -913,7 +913,7 @@ static void createmetatable (lua_State *L) { ** Open string library */ LUAMOD_API int luaopen_string (lua_State *L) { - luaL_register(L, LUA_STRLIBNAME, strlib); + luaL_newlib(L, strlib); createmetatable(L); return 1; } diff --git a/ltablib.c b/ltablib.c index 533f9ac9..93cc3442 100644 --- a/ltablib.c +++ b/ltablib.c @@ -1,5 +1,5 @@ /* -** $Id: ltablib.c,v 1.54 2010/01/13 19:59:10 roberto Exp roberto $ +** $Id: ltablib.c,v 1.55 2010/03/13 03:57:46 roberto Exp roberto $ ** Library for Table Manipulation ** See Copyright Notice in lua.h */ @@ -324,7 +324,7 @@ static const luaL_Reg tab_funcs[] = { LUAMOD_API int luaopen_table (lua_State *L) { - luaL_register(L, LUA_TABLIBNAME, tab_funcs); + luaL_newlib(L, tab_funcs); #if defined(LUA_COMPAT_UNPACK) /* _G.unpack = table.unpack */ lua_getfield(L, -1, "unpack"); diff --git a/ltests.c b/ltests.c index 7bafe829..ec70a954 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.109 2010/06/10 21:29:47 roberto Exp roberto $ +** $Id: ltests.c,v 2.110 2010/06/25 12:18:10 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -841,19 +841,23 @@ static lua_State *getstate (lua_State *L) { static int loadlib (lua_State *L) { static const luaL_Reg libs[] = { - {"baselibopen", luaopen_base}, - {"corolibopen", luaopen_coroutine}, - {"dblibopen", luaopen_debug}, - {"iolibopen", luaopen_io}, - {"mathlibopen", luaopen_math}, - {"strlibopen", luaopen_string}, - {"tablibopen", luaopen_table}, - {"packageopen", luaopen_package}, + {"_G", luaopen_base}, + {"coroutine", luaopen_coroutine}, + {"debug", luaopen_debug}, + {"io", luaopen_io}, + {"math", luaopen_math}, + {"string", luaopen_string}, + {"table", luaopen_table}, {NULL, NULL} }; lua_State *L1 = getstate(L); - lua_pushglobaltable(L1); - luaL_register(L1, NULL, libs); + int i; + luaL_requiref(L1, "package", luaopen_package, 1); + luaL_findtable(L1, LUA_REGISTRYINDEX, "_PRELOAD"); + for (i = 0; libs[i].name; i++) { + lua_pushcfunction(L1, libs[i].func); + lua_setfield(L1, -2, libs[i].name); + } return 0; } @@ -874,8 +878,8 @@ static int doremote (lua_State *L) { status = lua_pcall(L1, 0, LUA_MULTRET, 0); if (status != LUA_OK) { lua_pushnil(L); - lua_pushinteger(L, status); lua_pushstring(L, lua_tostring(L1, -1)); + lua_pushinteger(L, status); return 3; } else {