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");
// }