From 02f0a49bc528ecbc71f1da5386b410f706876a04 Mon Sep 17 00:00:00 2001 From: Mark Gossage Date: Mon, 21 Aug 2006 08:00:13 +0000 Subject: [PATCH] Bugfix #1542466 added code to allow mapping Lua nil's <-> C/C++ NULL's git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@9256 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- CHANGES.current | 7 ++++ Examples/test-suite/lua/voidtest_runme.lua | 37 ++++++++++++++++++++++ Lib/lua/lua.swg | 31 +++++++++++++++--- Lib/lua/luarun.swg | 16 ++++++++-- 4 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 Examples/test-suite/lua/voidtest_runme.lua diff --git a/CHANGES.current b/CHANGES.current index cb90562f0..bf4ac2c97 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -1,6 +1,12 @@ Version 1.3.30 (in progress) ============================ +08/21/2006: mgossage + [Lua] + Bugfix #1542466 added code to allow mapping Lua nil's <-> C/C++ NULL's + updated various typemaps to work correctly with the changes + added voidtest_runme.lua to show the features working + 08/19/2006: wuzzeb (John Lenz) [Guile] Add feature:constasvar to export constants as variables instead of functions that return the constant value. @@ -19,6 +25,7 @@ Version 1.3.30 (in progress) -nocwrap mode. 07/21/2006: mgossage + [Lua] Bugfix #1526022 pdated std::string to support strings with '\0' inside them updated typemaps.i to add support for pointer to pointers diff --git a/Examples/test-suite/lua/voidtest_runme.lua b/Examples/test-suite/lua/voidtest_runme.lua new file mode 100644 index 000000000..e185dbd1f --- /dev/null +++ b/Examples/test-suite/lua/voidtest_runme.lua @@ -0,0 +1,37 @@ +-- demo of lua swig +require("import") -- the import fn +import("voidtest") -- import lib + +-- test calling functions +voidtest.globalfunc() +f = voidtest.Foo() +f:memberfunc() -- member fns must have : not a . + +voidtest.Foo_staticmemberfunc() -- static member fns are still a little messy + +v1 = voidtest.vfunc1(f) +v2 = voidtest.vfunc2(f) + +assert(swig_equals(v1,v2)) -- a raw equals will not work, we look at the raw pointers + +v3 = voidtest.vfunc3(v1) +assert(swig_equals(v3,f)) + +v4 = voidtest.vfunc1(f) +assert(swig_equals(v4,v1)) + +v3:memberfunc() + +-- also testing nil's support +-- nil, are acceptable anywhere a pointer is +n1 = voidtest.vfunc1(nil) +n2 = voidtest.vfunc2(nil) + +assert(n1==nil) +assert(n2==nil) + +n3 = voidtest.vfunc3(n1) +n4 = voidtest.vfunc1(nil) + +assert(n3==nil) +assert(n4==nil) diff --git a/Lib/lua/lua.swg b/Lib/lua/lua.swg index 75e6f4f45..c3e4eb412 100644 --- a/Lib/lua/lua.swg +++ b/Lib/lua/lua.swg @@ -96,7 +96,15 @@ %{ lua_pushfstring(L,"%c",*$1); SWIG_arg++;%} // pointers and references -%typemap(in,checkfn="lua_isuserdata") SWIGTYPE*,SWIGTYPE&,SWIGTYPE[] +// under SWIG rules, it is ok, to have a pass in a lua nil, +// it should be converted to a SWIG NULL. +// This will only be allowed for pointers & arrays, not refs or by value +// the checkfn lua_isuserdata will only work for userdata +// the checkfn SWIG_isptrtype will work for both userdata and nil's +%typemap(in,checkfn="SWIG_isptrtype") SWIGTYPE*,SWIGTYPE[] +%{$1=($1_ltype)SWIG_MustGetPtr(L,$input,$descriptor,0,$argnum,"$symname");%} + +%typemap(in,checkfn="lua_isuserdata") SWIGTYPE& %{$1=($1_ltype)SWIG_MustGetPtr(L,$input,$descriptor,0,$argnum,"$symname");%} %typemap(out) SWIGTYPE*,SWIGTYPE& @@ -138,9 +146,13 @@ A function void fn(void*) should take any kind of pointer as a parameter (just like C/C++ does) but if its an output, then it should be wrappered like any other SWIG object (using default typemap) */ -%typemap(in,checkfn="lua_isuserdata") void* -%{$1=((swig_lua_userdata*)(lua_touserdata(L,$input)))->ptr;%} +//%typemap(in,checkfn="lua_isuserdata") void* +//%typemap(in,checkfn="SWIG_isptrtype") void* +//%{$1=((swig_lua_userdata*)(lua_touserdata(L,$input)))->ptr;%} +%typemap(in,checkfn="SWIG_isptrtype") void* +%{$1=($1_ltype)SWIG_MustGetPtr(L,$input,0,0,$argnum,"$symname");%} +//%{SWIG_ConvertPtr(L,$input, (void **) &ptr, 0, 0)); %} /* ----------------------------------------------------------------------------- * constants typemaps @@ -206,7 +218,16 @@ parmeters match which function $1 = lua_isstring(L,$input); } -%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE, SWIGTYPE *, SWIGTYPE &, SWIGTYPE [] { +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE [] { + void *ptr; + if (SWIG_isptrtype(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $1_descriptor, 0)) { + $1 = 0; + } else { + $1 = 1; + } +} + +%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE, SWIGTYPE & { void *ptr; if (lua_isuserdata(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $1_descriptor, 0)) { $1 = 0; @@ -217,7 +238,7 @@ parmeters match which function %typecheck(SWIG_TYPECHECK_VOIDPTR) void * { void *ptr; - if (lua_isuserdata(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, 0, 0)) { + if (SWIG_isptrtype(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, 0, 0)) { $1 = 0; } else { $1 = 1; diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg index f9f855c9c..931a32421 100644 --- a/Lib/lua/luarun.swg +++ b/Lib/lua/luarun.swg @@ -109,6 +109,9 @@ typedef struct { lua_pushcfunction(L, f), \ lua_rawset(L,-3)) +/* special helper for allowing 'nil' for usertypes */ +#define SWIG_isptrtype(L,I) (lua_isuserdata(L,I) || lua_isnil(L,I)) + /* ----------------------------------------------------------------------------- * global variable support code: modules * ----------------------------------------------------------------------------- */ @@ -507,10 +510,16 @@ SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State* L,int index,void** ptr,swig_type { swig_lua_userdata* usr; swig_cast_info *cast; + if (lua_isnil(L,index)){*ptr=0; return 0;} /* special case: lua nil => NULL pointer */ usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */ if (usr) { - cast=SWIG_TypeCheckStruct(usr->type,type); + if (!type) /* special cast void*, no casting fn */ + { + *ptr=usr->ptr; + return 0; /* ok */ + } + cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */ if (cast) { *ptr=SWIG_TypeCast(cast,usr->ptr); @@ -553,8 +562,9 @@ SWIGRUNTIME int SWIG_Lua_equal(lua_State* L) return 0; /* nil reply */ usr1=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */ usr2=(swig_lua_userdata*)lua_touserdata(L,2); /* get data */ - result=(usr1->ptr==usr2->ptr && usr1->type==usr2->type); - lua_pushboolean(L,result); + /*result=(usr1->ptr==usr2->ptr && usr1->type==usr2->type); only works if type is the same*/ + result=(usr1->ptr==usr2->ptr); + lua_pushboolean(L,result); return 1; }