diff --git a/CHANGES.current b/CHANGES.current index 24319515e..01944f978 100644 --- a/CHANGES.current +++ b/CHANGES.current @@ -5,6 +5,12 @@ See the RELEASENOTES file for a summary of changes in each release. Version 2.0.5 (in progress) =========================== +2012-04-13: wsfulton + [Lua] Apply #3219676 from Shane Liesegang which adds: + - support for %factory + - a __tostring method + - a __disown method + 2012-04-13: wsfulton [Xml] Apply #3513569 which adds a catchlist to the xml output. diff --git a/Examples/test-suite/disown.i b/Examples/test-suite/disown.i index 8b3aeb0ec..884fdaa74 100644 --- a/Examples/test-suite/disown.i +++ b/Examples/test-suite/disown.i @@ -42,6 +42,12 @@ _a = disown; return 5; } + + int remove(A *remove) + { + delete remove; + return 5; + } }; } diff --git a/Examples/test-suite/lua/disown_runme.lua b/Examples/test-suite/lua/disown_runme.lua index 72115bbc7..79c3df3c4 100644 --- a/Examples/test-suite/lua/disown_runme.lua +++ b/Examples/test-suite/lua/disown_runme.lua @@ -12,3 +12,9 @@ for x=0,100 do b:acquire(a) end collectgarbage() -- this will double delete unless the memory is managed properly + +a=disown.A() +a:__disown() +b:remove(a) +a=nil +collectgarbage() -- this will double delete unless the manual disown call worked diff --git a/Lib/lua/luarun.swg b/Lib/lua/luarun.swg index 6fe0bccce..31808e82b 100644 --- a/Lib/lua/luarun.swg +++ b/Lib/lua/luarun.swg @@ -469,6 +469,39 @@ SWIGINTERN int SWIG_Lua_class_destruct(lua_State* L) return 0; } +/* the class.__tostring method called by the interpreter and print */ +SWIGINTERN int SWIG_Lua_class_tostring(lua_State* L) +{ +/* there should be 1 param passed in + (1) userdata (not the metatable) */ + assert(lua_isuserdata(L,1)); /* just in case */ + unsigned long userData = (unsigned long)lua_touserdata(L,1); /* get the userdata address for later */ + lua_getmetatable(L,1); /* get the meta table */ + assert(lua_istable(L,-1)); /* just in case */ + + lua_getfield(L, -1, ".type"); + const char* className = lua_tostring(L, -1); + + char output[256]; + sprintf(output, "<%s userdata: %lX>", className, userData); + + lua_pushstring(L, (const char*)output); + return 1; +} + +/* to manually disown some userdata */ +SWIGINTERN int SWIG_Lua_class_disown(lua_State* L) +{ +/* there should be 1 params passed in + (1) userdata (not the meta table) */ + swig_lua_userdata* usr; + assert(lua_isuserdata(L,-1)); /* just in case */ + usr=(swig_lua_userdata*)lua_touserdata(L,-1); /* get it */ + + usr->own = 0; /* clear our ownership */ + return 0; +} + /* gets the swig class registry (or creates it) */ SWIGINTERN void SWIG_Lua_get_class_registry(lua_State* L) { @@ -594,11 +627,15 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss) /* add a table called ".fn" */ lua_pushstring(L,".fn"); lua_newtable(L); + /* add manual disown method */ + SWIG_Lua_add_function(L,"__disown",SWIG_Lua_class_disown); lua_rawset(L,-3); /* add accessor fns for using the .get,.set&.fn */ SWIG_Lua_add_function(L,"__index",SWIG_Lua_class_get); SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_class_set); SWIG_Lua_add_function(L,"__gc",SWIG_Lua_class_destruct); + /* add tostring method for better output */ + SWIG_Lua_add_function(L,"__tostring",SWIG_Lua_class_tostring); /* add it */ lua_rawset(L,-3); /* metatable into registry */ lua_pop(L,1); /* tidy stack (remove registry) */