Hi Miles,

incredible, that this bug stands for two years now. I spent to hours to create a patch which is attached to this email.

I forwarded the patch upstream and hope they will integrate it.

Greetings, Torsten

commit 8f8bd9496bd405cadf8dd499aefe2651f9a5f73f
Author: Torsten Landschoff <tors...@landschoff.net>
Date:   Thu Aug 18 23:40:20 2011 +0200

    Debian Bug #468414: require "module" should return the module table.
    
    This also adds an option to disable installing the module table as a global
    variable which looks like a candidate for some surprises. Also, this ensures
    that package.loaded["module"] contains the module table.

diff --git a/Examples/test-suite/common.mk b/Examples/test-suite/common.mk
index e86c0fb..28d569f 100644
--- a/Examples/test-suite/common.mk
+++ b/Examples/test-suite/common.mk
@@ -499,6 +499,7 @@ C_TEST_CASES += \
 	li_cpointer \
 	li_math \
 	long_long \
+	lua_no_module_global \
 	memberin_extend_c \
 	name \
 	nested \
diff --git a/Examples/test-suite/lua/Makefile.in b/Examples/test-suite/lua/Makefile.in
index 0ddc86a..0ffdaaf 100644
--- a/Examples/test-suite/lua/Makefile.in
+++ b/Examples/test-suite/lua/Makefile.in
@@ -25,7 +25,7 @@ include $(srcdir)/../common.mk
 LIBS       = -L.
 
 # Custom tests - tests with additional commandline options
-# none!
+lua_no_module_global.ctest: SWIGOPT += -nomoduleglobal
 
 # Rules for the different types of tests
 %.cpptest: 
diff --git a/Examples/test-suite/lua/lua_no_module_global_runme.lua b/Examples/test-suite/lua/lua_no_module_global_runme.lua
new file mode 100644
index 0000000..9eb436c
--- /dev/null
+++ b/Examples/test-suite/lua/lua_no_module_global_runme.lua
@@ -0,0 +1,24 @@
+-- require is only available in Lua 5.1
+
+if string.sub(_VERSION,1,7)=='Lua 5.1' then
+
+        -- Initially the package should not be loaded
+        assert(package.loaded["lua_no_module_global"] == nil)
+
+        -- Load the module
+        the_module = require "lua_no_module_global"
+
+        -- require should return the module table
+        assert(the_module.hi_mom ~= nil)
+        assert(the_module.hi_mom() == "hi mom!")
+
+        -- But it should not end up in the global table _G, subject to
+        -- the -nomoduleglobal swig option.
+        assert(_G["lua_no_module_global"] == nil)
+
+        -- According to the Lua 5.1 reference manual, require should also
+        -- store the module table into package.loaded["name"]
+        assert(package.loaded["lua_no_module_global"] == the_module)
+        assert(package.loaded["lua_no_module_global"].hi_mom() == "hi mom!")
+
+end
diff --git a/Examples/test-suite/lua_no_module_global.i b/Examples/test-suite/lua_no_module_global.i
new file mode 100644
index 0000000..21d2113
--- /dev/null
+++ b/Examples/test-suite/lua_no_module_global.i
@@ -0,0 +1,5 @@
+%module lua_no_module_global
+%{
+    char *hi_mom() { return "hi mom!"; }
+%}
+char *hi_mom();
diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg
index 89b7626..1810e98 100644
--- a/Lib/lua/luarun.swg
+++ b/Lib/lua/luarun.swg
@@ -237,7 +237,7 @@ SWIGINTERN int SWIG_Lua_module_set(lua_State* L)
   return 0;
 }
 
-/* registering a module in lua */
+/* registering a module in lua. Pushes the module table on the stack. */
 SWIGINTERN void  SWIG_Lua_module_begin(lua_State* L,const char* name)
 {
   assert(lua_istable(L,-1));  /* just in case */
@@ -254,8 +254,16 @@ SWIGINTERN void  SWIG_Lua_module_begin(lua_State* L,const char* name)
   lua_newtable(L);    /* the .set table */
   lua_rawset(L,-3);  /* add .set into metatable */
   lua_setmetatable(L,-2);  /* sets meta table in module */
+#ifdef SWIG_LUA_MODULE_GLOBAL
+  /* If requested, install the module directly into the global namespace. */
   lua_rawset(L,-3);        /* add module into parent */
   SWIG_Lua_get_table(L,name);   /* get the table back out */
+#else
+  /* Do not install the module table as global name. The stack top has
+     the module table with the name below. We pop the top and replace
+     the name with it. */
+  lua_replace(L,-2);
+#endif
 }
 
 /* ending the register */
diff --git a/Lib/lua/luaruntime.swg b/Lib/lua/luaruntime.swg
index 5823d4f..e286445 100644
--- a/Lib/lua/luaruntime.swg
+++ b/Lib/lua/luaruntime.swg
@@ -59,8 +59,9 @@ SWIGEXPORT int SWIG_init(lua_State* L)
   /* invoke user-specific initialization */
   SWIG_init_user(L);
   /* end module */
-  lua_pop(L,1);  /* tidy stack (remove module table)*/
-  lua_pop(L,1);  /* tidy stack (remove global table)*/
+  /* Note: We do not clean up the stack here (Lua will do this for us). At this
+     point, we have the globals table and out module table on the stack. Returning
+     one value makes the module table the result of the require command. */
   return 1;
 }
 
diff --git a/Source/Modules/lua.cxx b/Source/Modules/lua.cxx
index c38ffda..c6fd114 100644
--- a/Source/Modules/lua.cxx
+++ b/Source/Modules/lua.cxx
@@ -83,10 +83,11 @@ void display_mapping(DOH *d) {
 NEW LANGUAGE NOTE:END ************************************************/
 static const char *usage = (char *) "\
 Lua Options (available with -lua)\n\
-     [no additional options]\n\
+     -nomoduleglobal - Do not register the module name as global variable but \n\
+                       return the module table from require.\n\
 \n";
 
-
+static int nomoduleglobal = 0;
 
 /* NEW LANGUAGE NOTE:***********************************************
  To add a new language, you need to derive your class from
@@ -172,6 +173,9 @@ public:
       if (argv[i]) {
         if (strcmp(argv[i], "-help") == 0) {	// usage flags
           fputs(usage, stdout);
+        } else if (strcmp(argv[i], "-nomoduleglobal") == 0) {
+          nomoduleglobal = 1;
+          Swig_mark_arg(i);
         }
       }
     }
@@ -263,6 +267,12 @@ public:
     Printf(f_runtime, "\n");
     Printf(f_runtime, "#define SWIGLUA\n");
 
+    if (nomoduleglobal) {
+      Printf(f_runtime, "#define SWIG_LUA_NO_MODULE_GLOBAL\n");
+    } else {
+      Printf(f_runtime, "#define SWIG_LUA_MODULE_GLOBAL\n");
+    }
+
     //    if (NoInclude) {
     //      Printf(f_runtime, "#define SWIG_NOINCLUDE\n");
     //    }

Reply via email to