diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-31 13:34:19 -0300 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2010-05-31 13:34:19 -0300 |
commit | 2c1a5d678daadec5de189c58a5fef7e12d463b71 (patch) | |
tree | 00d363586a9efe67b532c19c96ffdefca31396ba | |
parent | bd619b931173fc35f38dfbb07746bcdc5ef11808 (diff) | |
download | lua-2c1a5d678daadec5de189c58a5fef7e12d463b71.tar.gz lua-2c1a5d678daadec5de189c58a5fef7e12d463b71.tar.bz2 lua-2c1a5d678daadec5de189c58a5fef7e12d463b71.zip |
factoring out common code in 'module' and 'luaL_openlib'
-rw-r--r-- | lauxlib.c | 42 | ||||
-rw-r--r-- | lauxlib.h | 4 | ||||
-rw-r--r-- | loadlib.c | 18 |
3 files changed, 35 insertions, 29 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.c,v 1.212 2010/05/18 17:21:24 roberto Exp roberto $ | 2 | ** $Id: lauxlib.c,v 1.213 2010/05/18 17:32:19 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -639,6 +639,9 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) { | |||
639 | } | 639 | } |
640 | 640 | ||
641 | 641 | ||
642 | /* | ||
643 | ** Count number of elements in a luaL_Reg list. | ||
644 | */ | ||
642 | static int libsize (const luaL_Reg *l) { | 645 | static int libsize (const luaL_Reg *l) { |
643 | int size = 0; | 646 | int size = 0; |
644 | for (; l && l->name; l++) size++; | 647 | for (; l && l->name; l++) size++; |
@@ -646,23 +649,34 @@ static int libsize (const luaL_Reg *l) { | |||
646 | } | 649 | } |
647 | 650 | ||
648 | 651 | ||
652 | /* | ||
653 | ** Find or create a module table with a given name. The function | ||
654 | ** first looks at the _LOADED table and, if that fails, try a | ||
655 | ** global variable with that name. In any case, leaves on the stack | ||
656 | ** the module table. | ||
657 | */ | ||
658 | LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname, | ||
659 | int sizehint) { | ||
660 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); /* get _LOADED table */ | ||
661 | lua_getfield(L, -1, modname); /* get _LOADED[modname] */ | ||
662 | if (!lua_istable(L, -1)) { /* not found? */ | ||
663 | lua_pop(L, 1); /* remove previous result */ | ||
664 | /* try global variable (and create one if it does not exist) */ | ||
665 | lua_pushglobaltable(L); | ||
666 | if (luaL_findtable(L, 0, modname, sizehint) != NULL) | ||
667 | luaL_error(L, "name conflict for module " LUA_QS, modname); | ||
668 | lua_pushvalue(L, -1); | ||
669 | lua_setfield(L, -3, modname); /* _LOADED[modname] = new table */ | ||
670 | } | ||
671 | lua_remove(L, -2); /* remove _LOADED table */ | ||
672 | } | ||
673 | |||
674 | |||
649 | LUALIB_API void luaL_openlib (lua_State *L, const char *libname, | 675 | LUALIB_API void luaL_openlib (lua_State *L, const char *libname, |
650 | const luaL_Reg *l, int nup) { | 676 | const luaL_Reg *l, int nup) { |
651 | luaL_checkversion(L); | 677 | luaL_checkversion(L); |
652 | if (libname) { | 678 | if (libname) { |
653 | /* check whether lib already exists */ | 679 | luaL_pushmodule(L, libname, libsize(l)); /* get/create library table */ |
654 | luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1); | ||
655 | lua_getfield(L, -1, libname); /* get _LOADED[libname] */ | ||
656 | if (!lua_istable(L, -1)) { /* not found? */ | ||
657 | lua_pop(L, 1); /* remove previous result */ | ||
658 | /* try global variable (and create one if it does not exist) */ | ||
659 | lua_pushglobaltable(L); | ||
660 | if (luaL_findtable(L, 0, libname, libsize(l)) != NULL) | ||
661 | luaL_error(L, "name conflict for module " LUA_QS, libname); | ||
662 | lua_pushvalue(L, -1); | ||
663 | lua_setfield(L, -3, libname); /* _LOADED[libname] = new table */ | ||
664 | } | ||
665 | lua_remove(L, -2); /* remove _LOADED table */ | ||
666 | lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ | 680 | lua_insert(L, -(nup + 1)); /* move library table to below upvalues */ |
667 | } | 681 | } |
668 | luaL_checkstack(L, nup, "too many upvalues"); | 682 | luaL_checkstack(L, nup, "too many upvalues"); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lauxlib.h,v 1.104 2010/04/19 18:52:15 roberto Exp roberto $ | 2 | ** $Id: lauxlib.h,v 1.105 2010/05/04 17:21:08 roberto Exp roberto $ |
3 | ** Auxiliary functions for building Lua libraries | 3 | ** Auxiliary functions for building Lua libraries |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -29,6 +29,8 @@ typedef struct luaL_Reg { | |||
29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); | 29 | LUALIB_API void (luaL_checkversion_) (lua_State *L, lua_Number ver); |
30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) | 30 | #define luaL_checkversion(L) luaL_checkversion_(L, LUA_VERSION_NUM) |
31 | 31 | ||
32 | LUALIB_API void (luaL_pushmodule) (lua_State *L, const char *modname, | ||
33 | int sizehint); | ||
32 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, | 34 | LUALIB_API void (luaL_openlib) (lua_State *L, const char *libname, |
33 | const luaL_Reg *l, int nup); | 35 | const luaL_Reg *l, int nup); |
34 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); | 36 | LUALIB_API int (luaL_getmetafield) (lua_State *L, int obj, const char *e); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: loadlib.c,v 1.81 2010/03/17 21:37:37 roberto Exp roberto $ | 2 | ** $Id: loadlib.c,v 1.82 2010/03/19 15:02:34 roberto Exp roberto $ |
3 | ** Dynamic library loader for Lua | 3 | ** Dynamic library loader for Lua |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | ** | 5 | ** |
@@ -620,18 +620,8 @@ static void modinit (lua_State *L, const char *modname) { | |||
620 | 620 | ||
621 | static int ll_module (lua_State *L) { | 621 | static int ll_module (lua_State *L) { |
622 | const char *modname = luaL_checkstring(L, 1); | 622 | const char *modname = luaL_checkstring(L, 1); |
623 | int loaded = lua_gettop(L) + 1; /* index of _LOADED table */ | 623 | int lastarg = lua_gettop(L); /* last parameter */ |
624 | lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED"); | 624 | luaL_pushmodule(L, modname, 1); /* get/create module table */ |
625 | lua_getfield(L, loaded, modname); /* get _LOADED[modname] */ | ||
626 | if (!lua_istable(L, -1)) { /* not found? */ | ||
627 | lua_pop(L, 1); /* remove previous result */ | ||
628 | /* try global variable (and create one if it does not exist) */ | ||
629 | lua_pushglobaltable(L); | ||
630 | if (luaL_findtable(L, 0, modname, 1) != NULL) | ||
631 | return luaL_error(L, "name conflict for module " LUA_QS, modname); | ||
632 | lua_pushvalue(L, -1); | ||
633 | lua_setfield(L, loaded, modname); /* _LOADED[modname] = new table */ | ||
634 | } | ||
635 | /* check whether table already has a _NAME field */ | 625 | /* check whether table already has a _NAME field */ |
636 | lua_getfield(L, -1, "_NAME"); | 626 | lua_getfield(L, -1, "_NAME"); |
637 | if (!lua_isnil(L, -1)) /* is table an initialized module? */ | 627 | if (!lua_isnil(L, -1)) /* is table an initialized module? */ |
@@ -642,7 +632,7 @@ static int ll_module (lua_State *L) { | |||
642 | } | 632 | } |
643 | lua_pushvalue(L, -1); | 633 | lua_pushvalue(L, -1); |
644 | set_env(L); | 634 | set_env(L); |
645 | dooptions(L, loaded - 1); | 635 | dooptions(L, lastarg); |
646 | return 1; | 636 | return 1; |
647 | } | 637 | } |
648 | 638 | ||