From: <mgo...@us...> - 2007-05-02 02:20:32
|
Revision: 9748 http://swig.svn.sourceforge.net/swig/?rev=9748&view=rev Author: mgossage Date: 2007-05-01 19:20:29 -0700 (Tue, 01 May 2007) Log Message: ----------- Fixed issues with C++ classes and hierachies across multiple source files. Fixed imports test case & added run test. Added Examples/imports. Added typename for raw lua_State* Added documentation on native functions. Modified Paths: -------------- trunk/CHANGES.current trunk/Doc/Manual/Lua.html trunk/Examples/lua/check.list trunk/Lib/lua/luarun.swg trunk/Lib/lua/luaruntime.swg trunk/Lib/lua/luatypemaps.swg trunk/Source/Modules/lua.cxx Added Paths: ----------- trunk/Examples/lua/import/ trunk/Examples/lua/import/Makefile trunk/Examples/lua/import/README trunk/Examples/lua/import/bar.h trunk/Examples/lua/import/bar.i trunk/Examples/lua/import/base.h trunk/Examples/lua/import/base.i trunk/Examples/lua/import/foo.h trunk/Examples/lua/import/foo.i trunk/Examples/lua/import/runme.lua trunk/Examples/lua/import/spam.h trunk/Examples/lua/import/spam.i trunk/Examples/test-suite/lua/imports_runme.lua Modified: trunk/CHANGES.current =================================================================== --- trunk/CHANGES.current 2007-05-02 01:28:21 UTC (rev 9747) +++ trunk/CHANGES.current 2007-05-02 02:20:29 UTC (rev 9748) @@ -1,6 +1,13 @@ Version 1.3.32 (in progress) ============================ +05/02/2007: mgossage + [Lua] Fixed issues with C++ classes and hierachies across multiple + source files. Fixed imports test case & added run test. + Added Examples/imports. + Added typename for raw lua_State* + Added documentation on native functions. + 05/07/2007: gga [Ruby] Docstrings are now supported. Modified: trunk/Doc/Manual/Lua.html =================================================================== --- trunk/Doc/Manual/Lua.html 2007-05-02 01:28:21 UTC (rev 9747) +++ trunk/Doc/Manual/Lua.html 2007-05-02 02:20:29 UTC (rev 9748) @@ -33,12 +33,13 @@ <li><a href="#Lua_nn19">Class extension with %extend</a> <li><a href="#Lua_nn20">C++ templates</a> <li><a href="#Lua_nn21">C++ Smart Pointers</a> +<li><a href="#Lua_nn22">Writing your own custom wrappers</a> </ul> -<li><a href="#Lua_nn22">Details on the Lua binding</a> +<li><a href="#Lua_nn23">Details on the Lua binding</a> <ul> -<li><a href="#Lua_nn23">Binding global data into the module.</a> -<li><a href="#Lua_nn24">Userdata and Metatables</a> -<li><a href="#Lua_nn25">Memory management</a> +<li><a href="#Lua_nn24">Binding global data into the module.</a> +<li><a href="#Lua_nn25">Userdata and Metatables</a> +<li><a href="#Lua_nn26">Memory management</a> </ul> </ul> </div> @@ -952,9 +953,26 @@ > f = p:__deref__() -- Returns underlying Foo * </pre></div> -<H2><a name="Lua_nn22"></a>22.4 Details on the Lua binding</H2> +<H3><a name="Lua_nn22"></a>22.3.15 Writing your own custom wrappers</H3> +<p> +Sometimes, it may be neccesary to add your own special functions, which bypass the normal SWIG wrappering method, and just use the native lua-c API calls. These 'native' functions allow direct adding of your own code into the module. This is performed with the <tt>%native</tt> directive as follows: +</p> +<div class="code"><pre>%native(my_func) int native_function(lua_State*L); // registers it with SWIG +... +%{ +int native_function(lua_State*L) // my native code +{ + ... +} +%} +</pre></div> +<p> +The <tt>%native</tt> directive in the above example, tells SWIG that there is a function <tt>int native_function(lua_State*L);</tt> which is to be added into the module under the name '<tt>my_func</tt>'. SWIG will not add any wrappering for this function, beyond adding it into the function table. How you write your code is entirely up to you. +</p> +<H2><a name="Lua_nn23"></a>22.4 Details on the Lua binding</H2> + <p> In the previous section, a high-level view of Lua wrapping was presented. Obviously a lot of stuff happens behind the scenes to make this happen. This section will explain some of the low-level details on how this is achieved. </p> @@ -963,7 +981,7 @@ </i> </p> -<H3><a name="Lua_nn23"></a>22.4.1 Binding global data into the module.</H3> +<H3><a name="Lua_nn24"></a>22.4.1 Binding global data into the module.</H3> <p> @@ -1023,7 +1041,7 @@ <p> That way when you call '<tt>a=example.Foo</tt>', the interpreter looks at the table 'example' sees that there is no field 'Foo' and calls __index. This will in turn check in '.get' table and find the existence of 'Foo' and then return the value of the C function call 'Foo_get()'. Similarly for the code '<tt>example.Foo=10</tt>', the interpreter will check the table, then call the __newindex which will then check the '.set' table and call the C function 'Foo_set(10)'. </p> -<H3><a name="Lua_nn24"></a>22.4.2 Userdata and Metatables</H3> +<H3><a name="Lua_nn25"></a>22.4.2 Userdata and Metatables</H3> <p> @@ -1103,7 +1121,7 @@ <p> Note: Operator overloads are basically done in the same way, by adding functions such as '__add' & '__call' to the classes metatable. The current implementation is a bit rough as it will add any member function beginning with '__' into the metatable too, assuming its an operator overload. </p> -<H3><a name="Lua_nn25"></a>22.4.3 Memory management</H3> +<H3><a name="Lua_nn26"></a>22.4.3 Memory management</H3> <p> Modified: trunk/Examples/lua/check.list =================================================================== --- trunk/Examples/lua/check.list 2007-05-02 01:28:21 UTC (rev 9747) +++ trunk/Examples/lua/check.list 2007-05-02 02:20:29 UTC (rev 9748) @@ -4,6 +4,7 @@ funcptr3 functest functor +import pointer simple variables Added: trunk/Examples/lua/import/Makefile =================================================================== --- trunk/Examples/lua/import/Makefile (rev 0) +++ trunk/Examples/lua/import/Makefile 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SWIGOPT = +LIBS = + +all:: + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='base' INTERFACE='base.i' lua_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='foo' INTERFACE='foo.i' lua_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='bar' INTERFACE='bar.i' lua_cpp + $(MAKE) -f $(TOP)/Makefile SWIG='$(SWIG)' SWIGOPT='$(SWIGOPT)' \ + LIBS='$(LIBS)' TARGET='spam' INTERFACE='spam.i' lua_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all Added: trunk/Examples/lua/import/README =================================================================== --- trunk/Examples/lua/import/README (rev 0) +++ trunk/Examples/lua/import/README 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,36 @@ +This example tests the %import directive and working with multiple modules. + +Use 'lua runme.lua' to run a test. + +Overview: +--------- + +The example defines 4 different extension modules--each wrapping +a separate C++ class. + + base.i - Base class + foo.i - Foo class derived from Base + bar.i - Bar class derived from Base + spam.i - Spam class derived from Bar + +Each module uses %import to refer to another module. For +example, the 'foo.i' module uses '%import base.i' to get +definitions for its base class. + +If everything is okay, all of the modules will load properly and +type checking will work correctly. Caveat: Some compilers, for example +gcc-3.2.x, generate broken vtables with the inline methods in this test. +This is not a SWIG problem and can usually be solved with non-inlined +destructors compiled into separate shared objects/DLLs. + +Unix: +----- +- Run make +- Run the test as described above + +Windows: +-------- +Sorry, no files here. +If you know how, you could copy the python or ruby example dsw & dsp and try editing that + + Added: trunk/Examples/lua/import/bar.h =================================================================== --- trunk/Examples/lua/import/bar.h (rev 0) +++ trunk/Examples/lua/import/bar.h 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,21 @@ +#include "base.h" + +class Bar : public Base { + public: + Bar() { } + ~Bar() { } + virtual const char * A() const { + return "Bar::A"; + } + const char * B() const { + return "Bar::B"; + } + virtual Base *toBase() { + return static_cast<Base *>(this); + } + static Bar *fromBase(Base *b) { + return dynamic_cast<Bar *>(b); + } +}; + + Added: trunk/Examples/lua/import/bar.i =================================================================== --- trunk/Examples/lua/import/bar.i (rev 0) +++ trunk/Examples/lua/import/bar.i 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,9 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + + Added: trunk/Examples/lua/import/base.h =================================================================== --- trunk/Examples/lua/import/base.h (rev 0) +++ trunk/Examples/lua/import/base.h 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,16 @@ +class Base { + public: + Base() { }; + virtual ~Base() { }; + virtual const char * A() const { + return "Base::A"; + } + const char * B() const { + return "Base::B"; + } + virtual Base *toBase() { + return static_cast<Base *>(this); + } +}; + + Added: trunk/Examples/lua/import/base.i =================================================================== --- trunk/Examples/lua/import/base.i (rev 0) +++ trunk/Examples/lua/import/base.i 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,6 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h Added: trunk/Examples/lua/import/foo.h =================================================================== --- trunk/Examples/lua/import/foo.h (rev 0) +++ trunk/Examples/lua/import/foo.h 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,21 @@ +#include "base.h" + +class Foo : public Base { + public: + Foo() { } + ~Foo() { } + virtual const char * A() const { + return "Foo::A"; + } + const char * B() const { + return "Foo::B"; + } + virtual Base *toBase() { + return static_cast<Base *>(this); + } + static Foo *fromBase(Base *b) { + return dynamic_cast<Foo *>(b); + } +}; + + Added: trunk/Examples/lua/import/foo.i =================================================================== --- trunk/Examples/lua/import/foo.i (rev 0) +++ trunk/Examples/lua/import/foo.i 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,8 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + Added: trunk/Examples/lua/import/runme.lua =================================================================== --- trunk/Examples/lua/import/runme.lua (rev 0) +++ trunk/Examples/lua/import/runme.lua 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,103 @@ +# Test various properties of classes defined in separate modules + +print("Testing the %import directive") + +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + function loadit(a,b) + lib=loadlib(a..':dll',b) or loadlib(a..':so',b) + assert(lib)() + end + loadit('base','Base_Init') + loadit('foo','Foo_Init') + loadit('bar','Bar_Init') + loadit('spam','Spam_Init') +else + -- lua 5.1 does + require 'base' + require 'foo' + require 'bar' + require 'spam' +end + +-- Create some objects + +print("Creating some objects") + +a = base.Base() +b = foo.Foo() +c = bar.Bar() +d = spam.Spam() + +-- Try calling some methods +print("Testing some methods") +print("Should see 'Base::A' ---> ",a:A()) +print("Should see 'Base::B' ---> ",a:B()) + +print("Should see 'Foo::A' ---> ",b:A()) +print("Should see 'Foo::B' ---> ",b:B()) + +print("Should see 'Bar::A' ---> ",c:A()) +print("Should see 'Bar::B' ---> ",c:B()) + +print("Should see 'Spam::A' ---> ",d:A()) +print("Should see 'Spam::B' ---> ",d:B()) + +-- Try some casts + +print("\nTesting some casts") + +x = a:toBase() +print("Should see 'Base::A' ---> ",x:A()) +print("Should see 'Base::B' ---> ",x:B()) + +x = b:toBase() +print("Should see 'Foo::A' ---> ",x:A()) +print("Should see 'Base::B' ---> ",x:B()) + +x = c:toBase() +print("Should see 'Bar::A' ---> ",x:A()) +print("Should see 'Base::B' ---> ",x:B()) + +x = d:toBase() +print("Should see 'Spam::A' ---> ",x:A()) +print("Should see 'Base::B' ---> ",x:B()) + +x = d:toBar() +print("Should see 'Bar::B' ---> ",x:B()) + + +print "\nTesting some dynamic casts\n" +x = d:toBase() + +print " Spam -> Base -> Foo : " +y = foo.Foo_fromBase(x) +if y then + print "bad swig" +else + print "good swig" +end + +print " Spam -> Base -> Bar : " +y = bar.Bar_fromBase(x) +if y then + print "good swig" +else + print "bad swig" +end + +print " Spam -> Base -> Spam : " +y = spam.Spam_fromBase(x) +if y then + print "good swig" +else + print "bad swig" +end + +print " Foo -> Spam : " +y = spam.Spam_fromBase(b) +if y then + print "bad swig" +else + print "good swig" +end Added: trunk/Examples/lua/import/spam.h =================================================================== --- trunk/Examples/lua/import/spam.h (rev 0) +++ trunk/Examples/lua/import/spam.h 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,24 @@ +#include "bar.h" + +class Spam : public Bar { + public: + Spam() { } + ~Spam() { } + virtual const char * A() const { + return "Spam::A"; + } + const char * B() const { + return "Spam::B"; + } + virtual Base *toBase() { + return static_cast<Base *>(this); + } + virtual Bar *toBar() { + return static_cast<Bar *>(this); + } + static Spam *fromBase(Base *b) { + return dynamic_cast<Spam *>(b); + } +}; + + Added: trunk/Examples/lua/import/spam.i =================================================================== --- trunk/Examples/lua/import/spam.i (rev 0) +++ trunk/Examples/lua/import/spam.i 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,9 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + + Added: trunk/Examples/test-suite/lua/imports_runme.lua =================================================================== --- trunk/Examples/test-suite/lua/imports_runme.lua (rev 0) +++ trunk/Examples/test-suite/lua/imports_runme.lua 2007-05-02 02:20:29 UTC (rev 9748) @@ -0,0 +1,28 @@ +require("import") -- the import fn +-- need to load two modules +import("imports_a") -- import code +import("imports_b") -- import code + +b=imports_b.B() +b:hello() -- call member function in A which is in a different SWIG generated library. +b:bye() + +assert (b:member_virtual_test(imports_a.A_memberenum1) == imports_a.A_memberenum2) +assert (b:global_virtual_test(imports_a.globalenum1) == imports_a.globalenum2) + +imports_b.global_test(imports_a.A_memberenum1) + +--[[ B b = new B(); + b.hello(); //call member function in A which is in a different SWIG generated library. + + B b = new B(); + b.hello(); //call member function in A which is in a different SWIG generated library. + b.bye(); + + if (b.member_virtual_test(A.MemberEnum.memberenum1) != A.MemberEnum.memberenum2) + throw new Exception("Test 1 failed"); + if (b.global_virtual_test(GlobalEnum.globalenum1) != GlobalEnum.globalenum2) + throw new Exception("Test 2 failed"); + + imports_b.global_test(A.MemberEnum.memberenum1); +]] Modified: trunk/Lib/lua/luarun.swg =================================================================== --- trunk/Lib/lua/luarun.swg 2007-05-02 01:28:21 UTC (rev 9747) +++ trunk/Lib/lua/luarun.swg 2007-05-02 02:20:29 UTC (rev 9748) @@ -16,7 +16,7 @@ #include "lua.h" #include "lauxlib.h" #include <stdlib.h> /* for malloc */ -#include <assert.h> /* for a few sanity tests */ +#include <assert.h> /* for a few sanity tests */ /* ----------------------------------------------------------------------------- * global swig types @@ -58,21 +58,22 @@ } swig_lua_attribute; typedef struct swig_lua_class { - const char *name; + const char *name; swig_type_info **type; - lua_CFunction constructor; - void (*destructor)(void *); - swig_lua_method *methods; + lua_CFunction constructor; + void (*destructor)(void *); + swig_lua_method *methods; swig_lua_attribute *attributes; struct swig_lua_class **bases; + char **base_names; } swig_lua_class; /* this is the struct for wrappering all pointers in SwigLua */ typedef struct { swig_type_info *type; - int own; /* 1 if owned & must be destroyed */ - void *ptr; + int own; /* 1 if owned & must be destroyed */ + void *ptr; } swig_lua_userdata; /* this is the struct for wrappering arbitary packed binary data @@ -82,17 +83,17 @@ */ typedef struct { swig_type_info *type; - int own; /* 1 if owned & must be destroyed */ - char data[1]; /* arbitary amount of data */ + int own; /* 1 if owned & must be destroyed */ + char data[1]; /* arbitary amount of data */ } swig_lua_rawdata; /* Common SWIG API */ -#define SWIG_NewPointerObj(L, ptr, type, owner) SWIG_Lua_NewPointerObj(L, (void *)ptr, type, owner) -#define SWIG_ConvertPtr(L,idx, ptr, type, flags) SWIG_Lua_ConvertPtr(L,idx,ptr,type,flags) +#define SWIG_NewPointerObj(L, ptr, type, owner) SWIG_Lua_NewPointerObj(L, (void *)ptr, type, owner) +#define SWIG_ConvertPtr(L,idx, ptr, type, flags) SWIG_Lua_ConvertPtr(L,idx,ptr,type,flags) #define SWIG_MustGetPtr(L,idx, type,flags, argnum,fnname) SWIG_Lua_MustGetPtr(L,idx, type,flags, argnum,fnname) /* for C++ member pointers, ie, member methods */ -#define SWIG_ConvertMember(L, idx, ptr, sz, ty) SWIG_Lua_ConvertPacked(L, idx, ptr, sz, ty) -#define SWIG_NewMemberObj(L, ptr, sz, type) SWIG_Lua_NewPackedObj(L, ptr, sz, type) +#define SWIG_ConvertMember(L, idx, ptr, sz, ty) SWIG_Lua_ConvertPacked(L, idx, ptr, sz, ty) +#define SWIG_NewMemberObj(L, ptr, sz, type) SWIG_Lua_NewPackedObj(L, ptr, sz, type) /* Runtime API */ #define SWIG_GetModule(clientdata) SWIG_Lua_GetModule((lua_State*)(clientdata)) @@ -107,17 +108,17 @@ #define SWIG_fail {goto fail;} #define SWIG_fail_arg(I) {lua_pushfstring(L,"argument %d incorrect/missing",I);goto fail;} #define SWIG_fail_ptr(func_name,argnum,type) \ - {lua_pushfstring(L,"Error in %s, expected a %s at argument number %d\n",\ - func_name,(type && type->str)?type->str:"void*",argnum);\ - goto fail;} + {lua_pushfstring(L,"Error in %s, expected a %s at argument number %d\n",\ + func_name,(type && type->str)?type->str:"void*",argnum);\ + goto fail;} #define SWIG_Lua_get_table(L,n) \ - (lua_pushstring(L, n), lua_rawget(L,-2)) + (lua_pushstring(L, n), lua_rawget(L,-2)) #define SWIG_Lua_add_function(L,n,f) \ - (lua_pushstring(L, n), \ - lua_pushcfunction(L, f), \ - lua_rawset(L,-3)) + (lua_pushstring(L, n), \ + 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)) @@ -128,6 +129,26 @@ //#define SWIG_mem_fn_as_voidptr(a) (*((char**)&(a))) #endif +/* storing/access of swig_module_info */ +SWIGRUNTIME swig_module_info * +SWIG_Lua_GetModule(lua_State* L) { + swig_module_info *ret = 0; + lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME); + lua_rawget(L,LUA_REGISTRYINDEX); + if (lua_islightuserdata(L,-1)) + ret=(swig_module_info*)lua_touserdata(L,-1); + lua_pop(L,1); /* tidy */ + return ret; +} + +SWIGRUNTIME void +SWIG_Lua_SetModule(lua_State* L, swig_module_info *module) { + /* add this all into the Lua registry: */ + lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME); + lua_pushlightuserdata(L,(void*)module); + lua_rawset(L,LUA_REGISTRYINDEX); +} + /* ----------------------------------------------------------------------------- * global variable support code: modules * ----------------------------------------------------------------------------- */ @@ -137,11 +158,11 @@ This can removed with a compile flag SWIGLUA_IGNORE_SET_IMMUTABLE */ SWIGINTERN int SWIG_Lua_set_immutable(lua_State* L) { -/* there should be 1 param passed in: the new value */ +/* there should be 1 param passed in: the new value */ #ifndef SWIGLUA_IGNORE_SET_IMMUTABLE - lua_pop(L,1); /* remove it */ - lua_pushstring(L,"This variable is immutable"); - lua_error(L); + lua_pop(L,1); /* remove it */ + lua_pushstring(L,"This variable is immutable"); + lua_error(L); #endif return 0; /* should not return anything */ } @@ -149,121 +170,121 @@ /* the module.get method used for getting linked data */ SWIGINTERN int SWIG_Lua_module_get(lua_State* L) { -/* there should be 2 params passed in - (1) table (not the meta table) - (2) string name of the attribute - printf("SWIG_Lua_module_get %p(%s) '%s'\n", - lua_topointer(L,1),lua_typename(L,lua_type(L,1)), - lua_tostring(L,2)); +/* there should be 2 params passed in + (1) table (not the meta table) + (2) string name of the attribute + printf("SWIG_Lua_module_get %p(%s) '%s'\n", + lua_topointer(L,1),lua_typename(L,lua_type(L,1)), + lua_tostring(L,2)); */ - /* get the metatable */ - assert(lua_istable(L,1)); /* just in case */ - lua_getmetatable(L,1); /* get the metatable */ - assert(lua_istable(L,-1)); /* just in case */ - SWIG_Lua_get_table(L,".get"); /* get the .get table */ - lua_remove(L,3); /* remove metatable */ - if (lua_istable(L,-1)) - { - /* look for the key in the .get table */ - lua_pushvalue(L,2); /* key */ - lua_rawget(L,-2); - lua_remove(L,3); /* remove .get */ - if (lua_iscfunction(L,-1)) - { /* found it so call the fn & return its value */ - lua_call(L,0,1); - return 1; - } - lua_pop(L,1); /* remove the top */ - } - lua_pop(L,1); /* remove the .get */ - lua_pushnil(L); /* return a nil */ + /* get the metatable */ + assert(lua_istable(L,1)); /* just in case */ + lua_getmetatable(L,1); /* get the metatable */ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_get_table(L,".get"); /* get the .get table */ + lua_remove(L,3); /* remove metatable */ + if (lua_istable(L,-1)) + { + /* look for the key in the .get table */ + lua_pushvalue(L,2); /* key */ + lua_rawget(L,-2); + lua_remove(L,3); /* remove .get */ + if (lua_iscfunction(L,-1)) + { /* found it so call the fn & return its value */ + lua_call(L,0,1); + return 1; + } + lua_pop(L,1); /* remove the top */ + } + lua_pop(L,1); /* remove the .get */ + lua_pushnil(L); /* return a nil */ return 1; } /* the module.set method used for setting linked data */ SWIGINTERN int SWIG_Lua_module_set(lua_State* L) { -/* there should be 3 params passed in - (1) table (not the meta table) - (2) string name of the attribute - (3) any for the new value +/* there should be 3 params passed in + (1) table (not the meta table) + (2) string name of the attribute + (3) any for the new value */ - /* get the metatable */ - assert(lua_istable(L,1)); /* just in case */ - lua_getmetatable(L,1); /* get the metatable */ - assert(lua_istable(L,-1)); /* just in case */ - SWIG_Lua_get_table(L,".set"); /* get the .set table */ - lua_remove(L,4); /* remove metatable */ - if (lua_istable(L,-1)) - { - /* look for the key in the .set table */ - lua_pushvalue(L,2); /* key */ - lua_rawget(L,-2); - lua_remove(L,4); /* remove .set */ - if (lua_iscfunction(L,-1)) - { /* found it so call the fn & return its value */ - lua_pushvalue(L,3); /* value */ - lua_call(L,1,0); - return 0; - } - } - lua_settop(L,3); /* reset back to start */ - /* we now have the table, key & new value, so just set directly */ - lua_rawset(L,1); /* add direct */ - return 0; + /* get the metatable */ + assert(lua_istable(L,1)); /* just in case */ + lua_getmetatable(L,1); /* get the metatable */ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_get_table(L,".set"); /* get the .set table */ + lua_remove(L,4); /* remove metatable */ + if (lua_istable(L,-1)) + { + /* look for the key in the .set table */ + lua_pushvalue(L,2); /* key */ + lua_rawget(L,-2); + lua_remove(L,4); /* remove .set */ + if (lua_iscfunction(L,-1)) + { /* found it so call the fn & return its value */ + lua_pushvalue(L,3); /* value */ + lua_call(L,1,0); + return 0; + } + } + lua_settop(L,3); /* reset back to start */ + /* we now have the table, key & new value, so just set directly */ + lua_rawset(L,1); /* add direct */ + return 0; } /* registering a module in lua */ SWIGINTERN void SWIG_Lua_module_begin(lua_State* L,const char* name) { - assert(lua_istable(L,-1)); /* just in case */ - lua_pushstring(L,name); - lua_newtable(L); /* the table */ - /* add meta table */ - lua_newtable(L); /* the meta table */ - SWIG_Lua_add_function(L,"__index",SWIG_Lua_module_get); - SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_module_set); - lua_pushstring(L,".get"); - lua_newtable(L); /* the .get table */ - lua_rawset(L,-3); /* add .get into metatable */ - lua_pushstring(L,".set"); - lua_newtable(L); /* the .set table */ - lua_rawset(L,-3); /* add .set into metatable */ - lua_setmetatable(L,-2); /* sets meta table in module */ - lua_rawset(L,-3); /* add module into parent */ - SWIG_Lua_get_table(L,name); /* get the table back out */ + assert(lua_istable(L,-1)); /* just in case */ + lua_pushstring(L,name); + lua_newtable(L); /* the table */ + /* add meta table */ + lua_newtable(L); /* the meta table */ + SWIG_Lua_add_function(L,"__index",SWIG_Lua_module_get); + SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_module_set); + lua_pushstring(L,".get"); + lua_newtable(L); /* the .get table */ + lua_rawset(L,-3); /* add .get into metatable */ + lua_pushstring(L,".set"); + lua_newtable(L); /* the .set table */ + lua_rawset(L,-3); /* add .set into metatable */ + lua_setmetatable(L,-2); /* sets meta table in module */ + lua_rawset(L,-3); /* add module into parent */ + SWIG_Lua_get_table(L,name); /* get the table back out */ } /* ending the register */ SWIGINTERN void SWIG_Lua_module_end(lua_State* L) { - lua_pop(L,1); /* tidy stack (remove module) */ + lua_pop(L,1); /* tidy stack (remove module) */ } /* adding a linked variable to the module */ SWIGINTERN void SWIG_Lua_module_add_variable(lua_State* L,const char* name,lua_CFunction getFn,lua_CFunction setFn) { - assert(lua_istable(L,-1)); /* just in case */ - lua_getmetatable(L,-1); /* get the metatable */ - assert(lua_istable(L,-1)); /* just in case */ - SWIG_Lua_get_table(L,".get"); /* find the .get table */ - assert(lua_istable(L,-1)); /* should be a table: */ - SWIG_Lua_add_function(L,name,getFn); - lua_pop(L,1); /* tidy stack (remove table) */ - if (setFn) /* if there is a set fn */ - { - SWIG_Lua_get_table(L,".set"); /* find the .set table */ - assert(lua_istable(L,-1)); /* should be a table: */ - SWIG_Lua_add_function(L,name,setFn); - lua_pop(L,1); /* tidy stack (remove table) */ - } - lua_pop(L,1); /* tidy stack (remove meta) */ + assert(lua_istable(L,-1)); /* just in case */ + lua_getmetatable(L,-1); /* get the metatable */ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_get_table(L,".get"); /* find the .get table */ + assert(lua_istable(L,-1)); /* should be a table: */ + SWIG_Lua_add_function(L,name,getFn); + lua_pop(L,1); /* tidy stack (remove table) */ + if (setFn) /* if there is a set fn */ + { + SWIG_Lua_get_table(L,".set"); /* find the .set table */ + assert(lua_istable(L,-1)); /* should be a table: */ + SWIG_Lua_add_function(L,name,setFn); + lua_pop(L,1); /* tidy stack (remove table) */ + } + lua_pop(L,1); /* tidy stack (remove meta) */ } /* adding a function module */ SWIGINTERN void SWIG_Lua_module_add_function(lua_State* L,const char* name,lua_CFunction fn) { - SWIG_Lua_add_function(L,name,fn); + SWIG_Lua_add_function(L,name,fn); } /* ----------------------------------------------------------------------------- @@ -273,236 +294,251 @@ /* the class.get method, performs the lookup of class attributes */ SWIGINTERN int SWIG_Lua_class_get(lua_State* L) { -/* there should be 2 params passed in - (1) userdata (not the meta table) - (2) string name of the attribute +/* there should be 2 params passed in + (1) userdata (not the meta table) + (2) string name of the attribute */ - assert(lua_isuserdata(L,-2)); /* just in case */ - lua_getmetatable(L,-2); /* get the meta table */ - assert(lua_istable(L,-1)); /* just in case */ - SWIG_Lua_get_table(L,".get"); /* find the .get table */ - assert(lua_istable(L,-1)); /* just in case */ - /* look for the key in the .get table */ - lua_pushvalue(L,2); /* key */ - lua_rawget(L,-2); - lua_remove(L,-2); /* stack tidy, remove .get table */ - if (lua_iscfunction(L,-1)) - { /* found it so call the fn & return its value */ - lua_pushvalue(L,1); /* the userdata */ - lua_call(L,1,1); /* 1 value in (userdata),1 out (result) */ - lua_remove(L,-2); /* stack tidy, remove metatable */ - return 1; - } - lua_pop(L,1); /* remove whatever was there */ - /* ok, so try the .fn table */ - SWIG_Lua_get_table(L,".fn"); /* find the .get table */ - assert(lua_istable(L,-1)); /* just in case */ - lua_pushvalue(L,2); /* key */ - lua_rawget(L,-2); /* look for the fn */ - lua_remove(L,-2); /* stack tidy, remove .fn table */ - if (lua_iscfunction(L,-1)) - { /* found it so return the fn & let lua call it */ - lua_remove(L,-2); /* stack tidy, remove metatable */ - return 1; - } - lua_pop(L,1); /* remove whatever was there */ - /* NEW: looks for the __getitem() fn - this is a user provided get fn */ - SWIG_Lua_get_table(L,"__getitem"); /* find the __getitem fn */ - if (lua_iscfunction(L,-1)) /* if its there */ - { /* found it so call the fn & return its value */ - lua_pushvalue(L,1); /* the userdata */ - lua_pushvalue(L,2); /* the parameter */ - lua_call(L,2,1); /* 2 value in (userdata),1 out (result) */ - lua_remove(L,-2); /* stack tidy, remove metatable */ - return 1; - } - return 0; /* sorry not known */ + assert(lua_isuserdata(L,-2)); /* just in case */ + lua_getmetatable(L,-2); /* get the meta table */ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_get_table(L,".get"); /* find the .get table */ + assert(lua_istable(L,-1)); /* just in case */ + /* look for the key in the .get table */ + lua_pushvalue(L,2); /* key */ + lua_rawget(L,-2); + lua_remove(L,-2); /* stack tidy, remove .get table */ + if (lua_iscfunction(L,-1)) + { /* found it so call the fn & return its value */ + lua_pushvalue(L,1); /* the userdata */ + lua_call(L,1,1); /* 1 value in (userdata),1 out (result) */ + lua_remove(L,-2); /* stack tidy, remove metatable */ + return 1; + } + lua_pop(L,1); /* remove whatever was there */ + /* ok, so try the .fn table */ + SWIG_Lua_get_table(L,".fn"); /* find the .get table */ + assert(lua_istable(L,-1)); /* just in case */ + lua_pushvalue(L,2); /* key */ + lua_rawget(L,-2); /* look for the fn */ + lua_remove(L,-2); /* stack tidy, remove .fn table */ + if (lua_iscfunction(L,-1)) + { /* found it so return the fn & let lua call it */ + lua_remove(L,-2); /* stack tidy, remove metatable */ + return 1; + } + lua_pop(L,1); /* remove whatever was there */ + /* NEW: looks for the __getitem() fn + this is a user provided get fn */ + SWIG_Lua_get_table(L,"__getitem"); /* find the __getitem fn */ + if (lua_iscfunction(L,-1)) /* if its there */ + { /* found it so call the fn & return its value */ + lua_pushvalue(L,1); /* the userdata */ + lua_pushvalue(L,2); /* the parameter */ + lua_call(L,2,1); /* 2 value in (userdata),1 out (result) */ + lua_remove(L,-2); /* stack tidy, remove metatable */ + return 1; + } + return 0; /* sorry not known */ } /* the class.set method, performs the lookup of class attributes */ SWIGINTERN int SWIG_Lua_class_set(lua_State* L) { -/* there should be 3 params passed in - (1) table (not the meta table) - (2) string name of the attribute - (3) any for the new value +/* there should be 3 params passed in + (1) table (not the meta table) + (2) string name of the attribute + (3) any for the new value printf("SWIG_Lua_class_set %p(%s) '%s' %p(%s)\n", - lua_topointer(L,1),lua_typename(L,lua_type(L,1)), - lua_tostring(L,2), - lua_topointer(L,3),lua_typename(L,lua_type(L,3)));*/ + lua_topointer(L,1),lua_typename(L,lua_type(L,1)), + lua_tostring(L,2), + lua_topointer(L,3),lua_typename(L,lua_type(L,3)));*/ - assert(lua_isuserdata(L,1)); /* just in case */ - lua_getmetatable(L,1); /* get the meta table */ - assert(lua_istable(L,-1)); /* just in case */ + assert(lua_isuserdata(L,1)); /* just in case */ + lua_getmetatable(L,1); /* get the meta table */ + assert(lua_istable(L,-1)); /* just in case */ - SWIG_Lua_get_table(L,".set"); /* find the .set table */ - if (lua_istable(L,-1)) - { - /* look for the key in the .set table */ - lua_pushvalue(L,2); /* key */ - lua_rawget(L,-2); - if (lua_iscfunction(L,-1)) - { /* found it so call the fn & return its value */ - lua_pushvalue(L,1); /* userdata */ - lua_pushvalue(L,3); /* value */ - lua_call(L,2,0); - return 0; - } - lua_pop(L,1); /* remove the value */ - } - lua_pop(L,1); /* remove the value .set table */ - /* NEW: looks for the __setitem() fn - this is a user provided set fn */ - SWIG_Lua_get_table(L,"__setitem"); /* find the fn */ - if (lua_iscfunction(L,-1)) /* if its there */ - { /* found it so call the fn & return its value */ - lua_pushvalue(L,1); /* the userdata */ - lua_pushvalue(L,2); /* the parameter */ - lua_pushvalue(L,3); /* the value */ - lua_call(L,3,0); /* 3 values in ,0 out */ - lua_remove(L,-2); /* stack tidy, remove metatable */ - return 1; - } - return 0; + SWIG_Lua_get_table(L,".set"); /* find the .set table */ + if (lua_istable(L,-1)) + { + /* look for the key in the .set table */ + lua_pushvalue(L,2); /* key */ + lua_rawget(L,-2); + if (lua_iscfunction(L,-1)) + { /* found it so call the fn & return its value */ + lua_pushvalue(L,1); /* userdata */ + lua_pushvalue(L,3); /* value */ + lua_call(L,2,0); + return 0; + } + lua_pop(L,1); /* remove the value */ + } + lua_pop(L,1); /* remove the value .set table */ + /* NEW: looks for the __setitem() fn + this is a user provided set fn */ + SWIG_Lua_get_table(L,"__setitem"); /* find the fn */ + if (lua_iscfunction(L,-1)) /* if its there */ + { /* found it so call the fn & return its value */ + lua_pushvalue(L,1); /* the userdata */ + lua_pushvalue(L,2); /* the parameter */ + lua_pushvalue(L,3); /* the value */ + lua_call(L,3,0); /* 3 values in ,0 out */ + lua_remove(L,-2); /* stack tidy, remove metatable */ + return 1; + } + return 0; } /* the class.destruct method called by the interpreter */ SWIGINTERN int SWIG_Lua_class_destruct(lua_State* L) { -/* there should be 1 params passed in - (1) userdata (not the meta table) */ - swig_lua_userdata* usr; - swig_lua_class* clss; - assert(lua_isuserdata(L,-1)); /* just in case */ - usr=(swig_lua_userdata*)lua_touserdata(L,-1); /* get it */ - /* if must be destroyed & has a destructor */ - if (usr->own) /* if must be destroyed */ - { - clss=(swig_lua_class*)usr->type->clientdata; /* get the class */ - if (clss && clss->destructor) /* there is a destroy fn */ - { - clss->destructor(usr->ptr); /* bye bye */ - } - } - return 0; +/* there should be 1 params passed in + (1) userdata (not the meta table) */ + swig_lua_userdata* usr; + swig_lua_class* clss; + assert(lua_isuserdata(L,-1)); /* just in case */ + usr=(swig_lua_userdata*)lua_touserdata(L,-1); /* get it */ + /* if must be destroyed & has a destructor */ + if (usr->own) /* if must be destroyed */ + { + clss=(swig_lua_class*)usr->type->clientdata; /* get the class */ + if (clss && clss->destructor) /* there is a destroy fn */ + { + clss->destructor(usr->ptr); /* bye bye */ + } + } + return 0; } /* gets the swig class registry (or creates it) */ SWIGINTERN void SWIG_Lua_get_class_registry(lua_State* L) { - /* add this all into the swig registry: */ - lua_pushstring(L,"SWIG"); - lua_rawget(L,LUA_REGISTRYINDEX); /* get the registry */ - if (!lua_istable(L,-1)) /* not there */ - { /* must be first time, so add it */ - lua_pop(L,1); /* remove the result */ - lua_pushstring(L,"SWIG"); - lua_newtable(L); - lua_rawset(L,LUA_REGISTRYINDEX); - /* then get it */ - lua_pushstring(L,"SWIG"); - lua_rawget(L,LUA_REGISTRYINDEX); - } + /* add this all into the swig registry: */ + lua_pushstring(L,"SWIG"); + lua_rawget(L,LUA_REGISTRYINDEX); /* get the registry */ + if (!lua_istable(L,-1)) /* not there */ + { /* must be first time, so add it */ + lua_pop(L,1); /* remove the result */ + lua_pushstring(L,"SWIG"); + lua_newtable(L); + lua_rawset(L,LUA_REGISTRYINDEX); + /* then get it */ + lua_pushstring(L,"SWIG"); + lua_rawget(L,LUA_REGISTRYINDEX); + } } /* helper fn to get the classes metatable from the register */ SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State* L,const char* cname) { - SWIG_Lua_get_class_registry(L); /* get the registry */ - lua_pushstring(L,cname); /* get the name */ - lua_rawget(L,-2); /* get it */ - lua_remove(L,-2); /* tidy up (remove registry) */ + SWIG_Lua_get_class_registry(L); /* get the registry */ + lua_pushstring(L,cname); /* get the name */ + lua_rawget(L,-2); /* get it */ + lua_remove(L,-2); /* tidy up (remove registry) */ } /* helper add a variable to a registered class */ SWIGINTERN void SWIG_Lua_add_class_variable(lua_State* L,const char* name,lua_CFunction getFn,lua_CFunction setFn) { - assert(lua_istable(L,-1)); /* just in case */ - SWIG_Lua_get_table(L,".get"); /* find the .get table */ - assert(lua_istable(L,-1)); /* just in case */ - SWIG_Lua_add_function(L,name,getFn); - lua_pop(L,1); /* tidy stack (remove table) */ - if (setFn) - { - SWIG_Lua_get_table(L,".set"); /* find the .set table */ - assert(lua_istable(L,-1)); /* just in case */ - SWIG_Lua_add_function(L,name,setFn); - lua_pop(L,1); /* tidy stack (remove table) */ - } + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_get_table(L,".get"); /* find the .get table */ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_add_function(L,name,getFn); + lua_pop(L,1); /* tidy stack (remove table) */ + if (setFn) + { + SWIG_Lua_get_table(L,".set"); /* find the .set table */ + assert(lua_istable(L,-1)); /* just in case */ + SWIG_Lua_add_function(L,name,setFn); + lua_pop(L,1); /* tidy stack (remove table) */ + } } /* helper to recursively add class details (attributes & operations) */ SWIGINTERN void SWIG_Lua_add_class_details(lua_State* L,swig_lua_class* clss) { - int i; - /* call all the base classes first: we can then override these later: */ - for(i=0;clss->bases[i];i++) - { - SWIG_Lua_add_class_details(L,clss->bases[i]); - } - /* add fns */ - for(i=0;clss->attributes[i].name;i++){ - SWIG_Lua_add_class_variable(L,clss->attributes[i].name,clss->attributes[i].getmethod,clss->attributes[i].setmethod); - } - /* add methods to the metatable */ - SWIG_Lua_get_table(L,".fn"); /* find the .fn table */ - assert(lua_istable(L,-1)); /* just in case */ - for(i=0;clss->methods[i].name;i++){ - SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].method); - } - lua_pop(L,1); /* tidy stack (remove table) */ - /* add operator overloads - these look ANY method which start with "__" and assume they - are operator overloads & add them to the metatable - (this might mess up is someone defines a method __gc (the destructor)*/ - for(i=0;clss->methods[i].name;i++){ - if (clss->methods[i].name[0]=='_' && clss->methods[i].name[1]=='_'){ - SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].method); - } - } + int i; + /* call all the base classes first: we can then override these later: */ + for(i=0;clss->bases[i];i++) + { + SWIG_Lua_add_class_details(L,clss->bases[i]); + } + /* add fns */ + for(i=0;clss->attributes[i].name;i++){ + SWIG_Lua_add_class_variable(L,clss->attributes[i].name,clss->attributes[i].getmethod,clss->attributes[i].setmethod); + } + /* add methods to the metatable */ + SWIG_Lua_get_table(L,".fn"); /* find the .fn table */ + assert(lua_istable(L,-1)); /* just in case */ + for(i=0;clss->methods[i].name;i++){ + SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].method); + } + lua_pop(L,1); /* tidy stack (remove table) */ + /* add operator overloads + these look ANY method which start with "__" and assume they + are operator overloads & add them to the metatable + (this might mess up is someone defines a method __gc (the destructor)*/ + for(i=0;clss->methods[i].name;i++){ + if (clss->methods[i].name[0]=='_' && clss->methods[i].name[1]=='_'){ + SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].method); + } + } } /* performs the entire class registration process */ SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss) { -/* add its constructor to module with the name of the class - so you can do MyClass(...) as well as new_MyClass(...) - BUT only if a constructor is defined - (this overcomes the problem of pure virtual classes without constructors)*/ - if (clss->constructor) - SWIG_Lua_add_function(L,clss->name,clss->constructor); + int i; + /* add its constructor to module with the name of the class + so you can do MyClass(...) as well as new_MyClass(...) + BUT only if a constructor is defined + (this overcomes the problem of pure virtual classes without constructors)*/ + if (clss->constructor) + SWIG_Lua_add_function(L,clss->name,clss->constructor); - SWIG_Lua_get_class_registry(L); /* get the registry */ - lua_pushstring(L,clss->name); /* get the name */ - lua_newtable(L); /* create the metatable */ - /* add string of class name called ".type" */ - lua_pushstring(L,".type"); - lua_pushstring(L,clss->name); - lua_rawset(L,-3); - /* add a table called ".get" */ - lua_pushstring(L,".get"); - lua_newtable(L); - lua_rawset(L,-3); - /* add a table called ".set" */ - lua_pushstring(L,".set"); - lua_newtable(L); - lua_rawset(L,-3); - /* add a table called ".fn" */ - lua_pushstring(L,".fn"); - lua_newtable(L); - 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 it */ - lua_rawset(L,-3); /* metatable into registry */ - lua_pop(L,1); /* tidy stack (remove registry) */ + SWIG_Lua_get_class_registry(L); /* get the registry */ + lua_pushstring(L,clss->name); /* get the name */ + lua_newtable(L); /* create the metatable */ + /* add string of class name called ".type" */ + lua_pushstring(L,".type"); + lua_pushstring(L,clss->name); + lua_rawset(L,-3); + /* add a table called ".get" */ + lua_pushstring(L,".get"); + lua_newtable(L); + lua_rawset(L,-3); + /* add a table called ".set" */ + lua_pushstring(L,".set"); + lua_newtable(L); + lua_rawset(L,-3); + /* add a table called ".fn" */ + lua_pushstring(L,".fn"); + lua_newtable(L); + 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 it */ + lua_rawset(L,-3); /* metatable into registry */ + lua_pop(L,1); /* tidy stack (remove registry) */ - SWIG_Lua_get_class_metatable(L,clss->name); - SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */ - lua_pop(L,1); /* tidy stack (remove class metatable) */ + /* set up the class base classes + we need to check the names of the classes to see if the base class exists + if so, we need to set up the pointer to it */ + swig_module_info* module=SWIG_GetModule(L); + for(i=0;clss->base_names[i];i++) + { + if (clss->bases[i]==0) /* not found yet */ + { + /* lookup and cache the base class */ + swig_type_info *info = SWIG_TypeQueryModule(module,module,clss->base_names[i]); + if (info) clss->bases[i] = (swig_lua_class *) info->clientdata; + } + } + + SWIG_Lua_get_class_metatable(L,clss->name); + SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */ + lua_pop(L,1); /* tidy stack (remove class metatable) */ } /* ----------------------------------------------------------------------------- @@ -512,107 +548,106 @@ /* helper to add metatable to new lua object */ SWIGINTERN void _SWIG_Lua_AddMetatable(lua_State* L,swig_type_info *type) { - if (type->clientdata) /* there is clientdata: so add the metatable */ - { - SWIG_Lua_get_class_metatable(L,((swig_lua_class*)(type->clientdata))->name); - if (lua_istable(L,-1)) - { - lua_setmetatable(L,-2); - } - else - { - lua_pop(L,1); - } - } + if (type->clientdata) /* there is clientdata: so add the metatable */ + { + SWIG_Lua_get_class_metatable(L,((swig_lua_class*)(type->clientdata))->name); + if (lua_istable(L,-1)) + { + lua_setmetatable(L,-2); + } + else + { + lua_pop(L,1); + } + } } /* pushes a new object into the lua stack */ SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type, int own) { - swig_lua_userdata* usr; - if (!ptr){ - lua_pushnil(L); - return; - } - usr=(swig_lua_userdata*)lua_newuserdata(L,sizeof(swig_lua_userdata)); /* get data */ - usr->ptr=ptr; /* set the ptr */ - usr->type=type; - usr->own=own; - _SWIG_Lua_AddMetatable(L,type); /* add metatable */ + swig_lua_userdata* usr; + if (!ptr){ + lua_pushnil(L); + return; + } + usr=(swig_lua_userdata*)lua_newuserdata(L,sizeof(swig_lua_userdata)); /* get data */ + usr->ptr=ptr; /* set the ptr */ + usr->type=type; + usr->own=own; + _SWIG_Lua_AddMetatable(L,type); /* add metatable */ } /* takes a object from the lua stack & converts it into an object of the correct type (if possible) */ SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State* L,int index,void** ptr,swig_type_info *type,int flags) { - swig_lua_userdata* usr; - swig_cast_info *cast; - if (lua_isnil(L,index)){*ptr=0; return SWIG_OK;} /* special case: lua nil => NULL pointer */ - usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */ - if (usr) - { - if (!type) /* special cast void*, no casting fn */ - { - *ptr=usr->ptr; - return SWIG_OK; /* ok */ - } - cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */ - if (cast) - { - *ptr=SWIG_TypeCast(cast,usr->ptr); - return SWIG_OK; /* ok */ - } - } - return SWIG_ERROR; /* error */ + swig_lua_userdata* usr; + swig_cast_info *cast; + if (lua_isnil(L,index)){*ptr=0; return SWIG_OK;} /* special case: lua nil => NULL pointer */ + usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */ + if (usr) + { + if (!type) /* special cast void*, no casting fn */ + { + *ptr=usr->ptr; + return SWIG_OK; /* ok */ + } + cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */ + if (cast) + { + *ptr=SWIG_TypeCast(cast,usr->ptr); + return SWIG_OK; /* ok */ + } + } + return SWIG_ERROR; /* error */ } SWIGRUNTIME void* SWIG_Lua_MustGetPtr(lua_State* L,int index,swig_type_info *type,int flags, - int argnum,const char* func_name){ - void* result; - if (!SWIG_IsOK(SWIG_ConvertPtr(L,index,&result,type,flags))){ - lua_pushfstring(L,"Error in %s, expected a %s at argument number %d\n", - func_name,(type && type->str)?type->str:"void*",argnum); - lua_error(L); - } - return result; + int argnum,const char* func_name){ + void* result; + if (!SWIG_IsOK(SWIG_ConvertPtr(L,index,&result,type,flags))){ + lua_pushfstring(L,"Error in %s, expected a %s at argument number %d\n", + func_name,(type && type->str)?type->str:"void*",argnum); + lua_error(L); + } + return result; } /* pushes a packed userdata. user for member fn pointers only */ SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State* L,void* ptr,size_t size,swig_type_info *type) { - swig_lua_rawdata* raw; - assert(ptr); /* not acceptable to pass in a NULL value */ - raw=(swig_lua_rawdata*)lua_newuserdata(L,sizeof(swig_lua_rawdata)-1+size); /* alloc data */ - raw->type=type; - raw->own=0; - memcpy(raw->data,ptr,size); /* copy the data */ - _SWIG_Lua_AddMetatable(L,type); /* add metatable */ + swig_lua_rawdata* raw; + assert(ptr); /* not acceptable to pass in a NULL value */ + raw=(swig_lua_rawdata*)lua_newuserdata(L,sizeof(swig_lua_rawdata)-1+size); /* alloc data */ + raw->type=type; + raw->own=0; + memcpy(raw->data,ptr,size); /* copy the data */ + _SWIG_Lua_AddMetatable(L,type); /* add metatable */ } /* converts a packed userdata. user for member fn pointers only */ SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State* L,int index,void* ptr,size_t size,swig_type_info *type) { - swig_lua_rawdata* raw; - swig_cast_info *cast; - raw=(swig_lua_rawdata*)lua_touserdata(L,index); /* get data */ - if (!raw) return SWIG_ERROR; /* error */ - if (type==0 || type==raw->type) /* void* or identical type */ - { - memcpy(ptr,raw->data,size); /* copy it */ - return SWIG_OK; /* ok */ - } - return SWIG_ERROR; /* error */ + swig_lua_rawdata* raw; + raw=(swig_lua_rawdata*)lua_touserdata(L,index); /* get data */ + if (!raw) return SWIG_ERROR; /* error */ + if (type==0 || type==raw->type) /* void* or identical type */ + { + memcpy(ptr,raw->data,size); /* copy it */ + return SWIG_OK; /* ok */ + } + return SWIG_ERROR; /* error */ } /* lua callable function to get the userdata's type */ SWIGRUNTIME int SWIG_Lua_type(lua_State* L) { - swig_lua_userdata* usr; - if (!lua_isuserdata(L,1)) /* just in case */ - return 0; /* nil reply */ - usr=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */ - lua_pushstring(L,usr->type->name); - return 1; + swig_lua_userdata* usr; + if (!lua_isuserdata(L,1)) /* just in case */ + return 0; /* nil reply */ + usr=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */ + lua_pushstring(L,usr->type->name); + return 1; } /* lua callable function to compare userdata's value @@ -620,16 +655,16 @@ but to lua, they are different objects */ SWIGRUNTIME int SWIG_Lua_equal(lua_State* L) { - int result; - swig_lua_userdata *usr1,*usr2; - if (!lua_isuserdata(L,1) || !lua_isuserdata(L,2)) /* just in case */ - 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); only works if type is the same*/ - result=(usr1->ptr==usr2->ptr); - lua_pushboolean(L,result); - return 1; + int result; + swig_lua_userdata *usr1,*usr2; + if (!lua_isuserdata(L,1) || !lua_isuserdata(L,2)) /* just in case */ + 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); only works if type is the same*/ + result=(usr1->ptr==usr2->ptr); + lua_pushboolean(L,result); + return 1; } @@ -678,26 +713,6 @@ } } -/* storing/access of swig_module_info */ -SWIGRUNTIME swig_module_info * -SWIG_Lua_GetModule(lua_State* L) { - swig_module_info *ret = 0; - lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME); - lua_rawget(L,LUA_REGISTRYINDEX); - if (lua_islightuserdata(L,-1)) - ret=(swig_module_info*)lua_touserdata(L,-1); - lua_pop(L,1); /* tidy */ - return ret; -} - -SWIGRUNTIME void -SWIG_Lua_SetModule(lua_State* L, swig_module_info *module) { - /* add this all into the Lua registry: */ - lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME); - lua_pushlightuserdata(L,(void*)module); - lua_rawset(L,LUA_REGISTRYINDEX); -} - #ifdef __cplusplus } #endif Modified: trunk/Lib/lua/luaruntime.swg =================================================================== --- trunk/Lib/lua/luaruntime.swg 2007-05-02 01:28:21 UTC (rev 9747) +++ trunk/Lib/lua/luaruntime.swg 2007-05-02 02:20:29 UTC (rev 9748) @@ -21,56 +21,56 @@ void SWIG_init_user(lua_State* L ); /* this is the initialization function - added at the very end of the code - the function is always called SWIG_init, but an eariler #define will rename it + added at the very end of the code + the function is always called SWIG_init, but an eariler #define will rename it */ SWIGEXPORT int SWIG_init(lua_State* L) { - int i; + int i; - /* start with global table */ - lua_pushvalue(L,LUA_GLOBALSINDEX); + /* start with global table */ + lua_pushvalue(L,LUA_GLOBALSINDEX); - SWIG_InitializeModule((void*)L); - SWIG_PropagateClientData(); + SWIG_InitializeModule((void*)L); + SWIG_PropagateClientData(); - /* invoke user-specific initialization */ - SWIG_init_user(L); + /* invoke user-specific initialization */ + SWIG_init_user(L); - /* add a global fn */ - SWIG_Lua_add_function(L,"swig_type",SWIG_Lua_type); - SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_equal); + /* add a global fn */ + SWIG_Lua_add_function(L,"swig_type",SWIG_Lua_type); + SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_equal); - /* begin the module (its a table with the same name as the module) */ - SWIG_Lua_module_begin(L,SWIG_name); - /* add commands/functions */ - for (i = 0; swig_commands[i].name; i++){ - SWIG_Lua_module_add_function(L,swig_commands[i].name,swig_commands[i].func); - } - /*luaL_openlib(L,NULL,swig_commands,0);*/ - /* all in one */ - /*luaL_openlib(L,SWIG_name,swig_commands,0);*/ - /* add variables */ - for (i = 0; swig_variables[i].name; i++){ - SWIG_Lua_module_add_variable(L,swig_variables[i].name,swig_variables[i].get,swig_variables[i].set); - } + /* begin the module (its a table with the same name as the module) */ + SWIG_Lua_module_begin(L,SWIG_name); + /* add commands/functions */ + for (i = 0; swig_commands[i].name; i++){ + SWIG_Lua_module_add_function(L,swig_commands[i].name,swig_commands[i].func); + } + /*luaL_openlib(L,NULL,swig_commands,0);*/ + /* all in one */ + /*luaL_openlib(L,SWIG_name,swig_commands,0);*/ + /* add variables */ + for (i = 0; swig_variables[i].name; i++){ + SWIG_Lua_module_add_variable(L,swig_variables[i].name,swig_variables[i].get,swig_variables[i].set); + } - /* additional registration structs & classes in lua: */ - for (i = 0; swig_types[i]; i++){ - if (swig_types[i]->clientdata){ - SWIG_Lua_class_register(L,(swig_lua_class*)(swig_types[i]->clientdata)); - } - } + /* additional registration structs & classes in lua: */ + for (i = 0; swig_types[i]; i++){ + if (swig_types[i]->clientdata){ + SWIG_Lua_class_register(L,(swig_lua_class*)(swig_types[i]->clientdata)); + } + } - /* constants */ - SWIG_Lua_InstallConstants(L,swig_constants); + /* constants */ + SWIG_Lua_InstallConstants(L,swig_constants); - /* end module */ - /*SWIG_Lua_module_end(L);*/ - lua_pop(L,1); /* tidy stack (remove module table)*/ - lua_pop(L,1); /* tidy stack (remove global table)*/ + /* end module */ + /*SWIG_Lua_module_end(L);*/ + lua_pop(L,1); /* tidy stack (remove module table)*/ + lua_pop(L,1); /* tidy stack (remove global table)*/ - return 1; + return 1; } /* Lua 5.1 has a different name for importing libraries @@ -81,7 +81,7 @@ SWIGEXPORT int SWIG_import(lua_State* L) { - return SWIG_init(L); + return SWIG_init(L); } #ifdef __cplusplus Modified: trunk/Lib/lua/luatypemaps.swg =================================================================== --- trunk/Lib/lua/luatypemaps.swg 2007-05-02 01:28:21 UTC (rev 9747) +++ trunk/Lib/lua/luatypemaps.swg 2007-05-02 02:20:29 UTC (rev 9748) @@ -197,6 +197,13 @@ %typemap(out) long long, unsigned long long, signed long long %{ lua_pushnumber(L, (lua_Number) $1); SWIG_arg++;%} +/* It is possible to also pass a lua_State* into a function, so +void fn(int a, float b, lua_State* s) is wrappable as +> fn(1,4.3) -- note: the state is implicitly passed in +*/ +%typemap(in, numinputs=0) lua_State* +%{$1 = L;%} + /* ----------------------------------------------------------------------------- * typecheck rules * ----------------------------------------------------------------------------- */ Modified: trunk/Source/Modules/lua.cxx =================================================================== --- trunk/Source/Modules/lua.cxx 2007-05-02 01:28:21 UTC (rev 9747) +++ trunk/Source/Modules/lua.cxx 2007-05-02 02:20:29 UTC (rev 9748) @@ -583,6 +583,7 @@ /* Close the function */ Printv(f->code, "return SWIG_arg;\n", NIL); // add the failure cleanup code: + Printv(f->code, "\nif(0) SWIG_fail;\n", NIL); Printv(f->code, "\nfail:\n", NIL); Printv(f->code, "$cleanup", "lua_error(L);\n", NIL); Printv(f->code, "return SWIG_arg;\n", NIL); @@ -891,8 +892,16 @@ Delete(s_attr_tab); // Handle inheritance - + // note: with the idea of class hireachied spread over mutliple modules + // cf test-suite: imports.i + // it is not possible to just add the pointers to the base classes to the code + // (as sometimes these classes are not present) + // therefore we instead hold the name of the base class and a null pointer + // at runtime: we can query the swig type manager & see if the class exists + // if so, we can get the pointer to the base class & replace the null pointer + // if the type does not exist, then we cannot... String *base_class = NewString(""); + String *base_class_names = NewString(""); List *baselist = Getattr(n, "bases"); if (baselist && Len(baselist)) { @@ -905,44 +914,24 @@ b = Next(b); continue; } -/* if( itcl ) { - have_base_classes = 1; - Printv( base_classes, bname, " ", NIL ); - Printv( base_class_init , " ", bname, "Ptr::constructor $ptr\n", NIL ); - }*/ - String *bmangle = Swig_name_mangle(bname); - // Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL); - Printf(base_class, "&_wrap_class_%s", bmangle); - // Put code to register base classes in init function + // old code: (used the pointer to the base class) + //String *bmangle = Swig_name_mangle(bname); + //Printf(base_class, "&_wrap_class_%s", bmangle); + //Putc(',', base_class); + //Delete(bmangle); + // new code: stores a null pointer & the name + Printf(base_class, "0,"); + Printf(base_class_names, "\"%s *\",", SwigType_namestr(bname)); -// Printf(f_init,"/* Register base : %s */\n", bmangle); -// Printf(f_init,"swig_%s_bases[%d] = (swig_class *) SWIG_TypeQuery(\"%s *\")->clientdata;\n", mangled_classname, index, SwigType_namestr(bname)); b = Next(b); index++; - Putc(',', base_class); - Delete(bmangle); } } -/* List *baselist = Getattr(n,"bases"); - if (baselist && Len(baselist)) { - Node *base = First(baselist); - while (base) { - String *bname = Getattr(base, "name"); - if ((!bname) || GetFlag(base,"feature:ignore") || (!Getattr(base,"module"))) { - base = Next(baselist); - continue; - } - String *bmangle = Swig_name_mangle(bname); - Printv(f_wrappers,"extern swig_class _wrap_class_", bmangle, ";\n", NIL); - Printf(base_class,"&_wrap_class_%... [truncated message content] |