2
0
Эх сурвалжийг харах

factoring out common code in 'module' and 'luaL_openlib'

Roberto Ierusalimschy 15 жил өмнө
parent
commit
2c1a5d678d
3 өөрчлөгдсөн 35 нэмэгдсэн , 29 устгасан
  1. 28 14
      lauxlib.c
  2. 3 1
      lauxlib.h
  3. 4 14
      loadlib.c

+ 28 - 14
lauxlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.c,v 1.212 2010/05/18 17:21:24 roberto Exp roberto $
+** $Id: lauxlib.c,v 1.213 2010/05/18 17:32:19 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -639,6 +639,9 @@ LUALIB_API const char *luaL_tolstring (lua_State *L, int idx, size_t *len) {
 }
 
 
+/*
+** Count number of elements in a luaL_Reg list.
+*/
 static int libsize (const luaL_Reg *l) {
   int size = 0;
   for (; l && l->name; l++) size++;
@@ -646,23 +649,34 @@ static int libsize (const luaL_Reg *l) {
 }
 
 
+/*
+** Find or create a module table with a given name. The function
+** first looks at the _LOADED table and, if that fails, try a
+** global variable with that name. In any case, leaves on the stack
+** the module table.
+*/
+LUALIB_API void luaL_pushmodule (lua_State *L, const char *modname,
+                                 int sizehint) {
+  luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);  /* get _LOADED table */
+  lua_getfield(L, -1, modname);  /* get _LOADED[modname] */
+  if (!lua_istable(L, -1)) {  /* not found? */
+    lua_pop(L, 1);  /* remove previous result */
+    /* try global variable (and create one if it does not exist) */
+    lua_pushglobaltable(L);
+    if (luaL_findtable(L, 0, modname, sizehint) != NULL)
+      luaL_error(L, "name conflict for module " LUA_QS, modname);
+    lua_pushvalue(L, -1);
+    lua_setfield(L, -3, modname);  /* _LOADED[modname] = new table */
+  }
+  lua_remove(L, -2);  /* remove _LOADED table */
+}
+
+
 LUALIB_API void luaL_openlib (lua_State *L, const char *libname,
                                const luaL_Reg *l, int nup) {
   luaL_checkversion(L);
   if (libname) {
-    /* check whether lib already exists */
-    luaL_findtable(L, LUA_REGISTRYINDEX, "_LOADED", 1);
-    lua_getfield(L, -1, libname);  /* get _LOADED[libname] */
-    if (!lua_istable(L, -1)) {  /* not found? */
-      lua_pop(L, 1);  /* remove previous result */
-      /* try global variable (and create one if it does not exist) */
-      lua_pushglobaltable(L);
-      if (luaL_findtable(L, 0, libname, libsize(l)) != NULL)
-        luaL_error(L, "name conflict for module " LUA_QS, libname);
-      lua_pushvalue(L, -1);
-      lua_setfield(L, -3, libname);  /* _LOADED[libname] = new table */
-    }
-    lua_remove(L, -2);  /* remove _LOADED table */
+    luaL_pushmodule(L, libname, libsize(l));  /* get/create library table */
     lua_insert(L, -(nup + 1));  /* move library table to below upvalues */
   }
   luaL_checkstack(L, nup, "too many upvalues");

+ 3 - 1
lauxlib.h

@@ -1,5 +1,5 @@
 /*
-** $Id: lauxlib.h,v 1.104 2010/04/19 18:52:15 roberto Exp roberto $
+** $Id: lauxlib.h,v 1.105 2010/05/04 17:21:08 roberto Exp roberto $
 ** Auxiliary functions for building Lua libraries
 ** See Copyright Notice in lua.h
 */
@@ -29,6 +29,8 @@ 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);

+ 4 - 14
loadlib.c

@@ -1,5 +1,5 @@
 /*
-** $Id: loadlib.c,v 1.81 2010/03/17 21:37:37 roberto Exp roberto $
+** $Id: loadlib.c,v 1.82 2010/03/19 15:02:34 roberto Exp roberto $
 ** Dynamic library loader for Lua
 ** See Copyright Notice in lua.h
 **
@@ -620,18 +620,8 @@ static void modinit (lua_State *L, const char *modname) {
 
 static int ll_module (lua_State *L) {
   const char *modname = luaL_checkstring(L, 1);
-  int loaded = lua_gettop(L) + 1;  /* index of _LOADED table */
-  lua_getfield(L, LUA_REGISTRYINDEX, "_LOADED");
-  lua_getfield(L, loaded, modname);  /* get _LOADED[modname] */
-  if (!lua_istable(L, -1)) {  /* not found? */
-    lua_pop(L, 1);  /* remove previous result */
-    /* try global variable (and create one if it does not exist) */
-    lua_pushglobaltable(L);
-    if (luaL_findtable(L, 0, modname, 1) != NULL)
-      return luaL_error(L, "name conflict for module " LUA_QS, modname);
-    lua_pushvalue(L, -1);
-    lua_setfield(L, loaded, modname);  /* _LOADED[modname] = new table */
-  }
+  int lastarg = lua_gettop(L);  /* last parameter */
+  luaL_pushmodule(L, modname, 1);  /* get/create module table */
   /* check whether table already has a _NAME field */
   lua_getfield(L, -1, "_NAME");
   if (!lua_isnil(L, -1))  /* is table an initialized module? */
@@ -642,7 +632,7 @@ static int ll_module (lua_State *L) {
   }
   lua_pushvalue(L, -1);
   set_env(L);
-  dooptions(L, loaded - 1);
+  dooptions(L, lastarg);
   return 1;
 }