[Lua] Removed generation of _wrap_delete_XXXXX (wrappered destructor) which was unused and causing warning with g++ -Wall.

Removed other unused warning in typemaps.i and other places.
Added Examples/lua/embed3, and run tests a few test cases.

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@10402 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Mark Gossage 2008-04-30 00:17:53 +00:00
commit ef7c0cbbd2
13 changed files with 317 additions and 19 deletions

View file

@ -1,6 +1,12 @@
Version 1.3.36 (in progress)
=============================
04/30/2008: mgossage
[Lua] Removed generation of _wrap_delete_XXXXX (wrappered destructor)
which was unused and causing warning with g++ -Wall.
Removed other unused warning in typemaps.i and other places.
Added Examples/lua/embed3, and run tests a few test cases.
04/24/2008: olly
[Python] Fix generated code for IBM's C++ compiler on AIX (patch
from Goeran Uddeborg in SF#1928048).

View file

@ -5,6 +5,7 @@ constants
dual
embed
embed2
embed3
exception
funcptr3
functest

View file

@ -0,0 +1,20 @@
TOP = ../..
SWIG = $(TOP)/../preinst-swig
TARGET = embed3
SRCS = example.cpp
INTERFACE = example.i
LUA_INTERP = embed3.cpp
# this is a little different to normal as we have our own special interpreter
# which we want to static link
# we also need the external runtime, so we can get access to certain internals of SWIG
all::
$(SWIG) -c++ -lua $(SWIGOPT) -external-runtime swigluarun.h
$(MAKE) -f $(TOP)/Makefile $(SWIGLIB) SRCS='$(SRCS)' SWIG='$(SWIG)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static_cpp
clean::
$(MAKE) -f $(TOP)/Makefile lua_clean
check: all

View file

@ -0,0 +1,133 @@
/* embed3.cpp A C++ embeded interpreter
This will register a C++ class with Lua, and then call a Lua function
passing C++ objects to this function.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
extern "C" {
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include "swigluarun.h" // the SWIG external runtime
/* the SWIG wrappered library */
extern "C" int luaopen_example(lua_State*L);
// the code itself
#include "example.h"
// this code pushes a C++ pointer as well as the SWIG type onto the Lua stack
bool push_pointer(lua_State*L, void* ptr, const char* type_name, int owned = 0) {
// task 1: get the object 'type' which is registered with SWIG
// you need to call SWIG_TypeQuery() with the class name
// (normally, just look in the wrapper file to get this)
swig_type_info * pTypeInfo = SWIG_TypeQuery(L, type_name);
if (pTypeInfo == 0)
return false; // error
// task 2: push the pointer to the Lua stack
// this requires a pointer & the type
// the last param specifies if Lua is responsible for deleting the object
SWIG_NewPointerObj(L, ptr, pTypeInfo, owned);
return true;
}
/* This is an example of how to call the Lua function
void onEvent(Event e)
its very tedious, but gives you an idea of the issues involed.
*/
int call_onEvent(lua_State *L, Event e) {
int top;
/* ok, here we go:
push a, push b, call 'add' check & return res
*/
top = lua_gettop(L); /* for later */
lua_pushstring(L, "onEvent"); /* function name */
lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
if (!lua_isfunction(L, -1)) {
printf("[C++] error: cannot find function 'OnEvent'\n");
lua_settop(L, top); // reset
return 0;
}
// push the event object
push_pointer(L, &e, "Event *", 0);
if (lua_pcall(L, 1, 0, 0) != 0) /* call function with 1 arguments and no result */
{
printf("[C++] error running function `OnEvent': %s\n", lua_tostring(L, -1));
lua_settop(L, top); // reset
return 0;
}
lua_settop(L, top); /* reset stack */
return 1; // ok
}
int main(int argc, char* argv[]) {
int ok;
int res;
char str[80];
printf("[C++] Welcome to the simple embedded Lua example v3\n");
printf("[C++] We are in C++\n");
printf("[C++] opening a Lua state & loading the libraries\n");
lua_State *L = lua_open();
luaopen_base(L);
luaopen_string(L);
luaopen_math(L);
printf("[C++] now loading the SWIG wrappered library\n");
luaopen_example(L);
printf("[C++] all looks ok\n");
printf("\n");
printf("[C++] lets create an Engine and pass a pointer to Lua\n");
Engine engine;
/* this code will pass a pointer into lua, but C++ still owns the object
this is a little tedious, to do, but lets do it
we need to pass the pointer (obviously), the type name
and a flag which states if Lua should delete the pointer once its finished with it
The type name is a class name string which is registered with SWIG
(normally, just look in the wrapper file to get this)
in this case we don't want Lua to delete the pointer so the ownership flag is 0
*/
push_pointer(L,&engine,"Engine *",0);
lua_setglobal(L, "pEngine"); // set as global variable
printf("[C++] now lets load the file 'runme.lua'\n");
printf("[C++] any lua code in this file will be executed\n");
if (luaL_loadfile(L, "runme.lua") || lua_pcall(L, 0, 0, 0)) {
printf("[C++] ERROR: cannot run lua file: %s", lua_tostring(L, -1));
exit(3);
}
printf("[C++] We are now back in C++, all looks ok\n");
printf("\n");
printf("[C++] Lets call the Lua function onEvent(e)\n");
printf("[C++] We will give it different events, as we wish\n");
printf("[C++] Starting with STARTUP\n");
Event ev;
ev.mType = Event::STARTUP;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("[C++] now we will try MOUSEPRESS,KEYPRESS,MOUSEPRESS\n");
ev.mType = Event::MOUSEPRESS;
call_onEvent(L, ev);
ev.mType = Event::KEYPRESS;
call_onEvent(L, ev);
ev.mType = Event::MOUSEPRESS;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("[C++] Finally we will SHUTDOWN\n");
ev.mType = Event::SHUTDOWN;
call_onEvent(L, ev);
printf("[C++] ok\n");
printf("\n");
printf("[C++] all finished, closing the lua state\n");
lua_close(L);
return 0;
}

View file

@ -0,0 +1,25 @@
/* File : example.cpp */
#include <stdio.h>
#include "example.h"
void Engine::start()
{
printf("[C++] Engine::start()\n");
}
void Engine::stop()
{
printf("[C++] Engine::stop()\n");
}
void Engine::accelerate(float f)
{
printf("[C++] Engine::accelerate(%f)\n",f);
}
void Engine::decelerate(float f)
{
printf("[C++] Engine::decelerate(%f)\n",f);
}

View file

@ -0,0 +1,24 @@
/* File : example.h */
/* This is some kind of engine of some kind
we will give it some dummy methods for Lua to call*/
class Engine
{
public:
void start();
void stop();
void accelerate(float f);
void decelerate(float f);
};
/* We also want to pass some events to Lua, so lets have a few classes
to do this.
*/
class Event
{
public:
enum {STARTUP,KEYPRESS,MOUSEPRESS,SHUTDOWN} mType;
// etc
};

View file

@ -0,0 +1,8 @@
/* File : example.i */
%module example
%{
#include "example.h"
%}
%include "example.h"

View file

@ -0,0 +1,35 @@
print "[lua] This is runme.lua"
-- test program for embeded lua
-- we do not need to load the library, as it was already in the intrepreter
-- but lets check anyway
assert(type(example)=='table',"Don't appear to have loaded the example module. Do not run this file directly, run the embed3 executable")
print "[lua] looking to see if we have a pointer to the engine"
if type(pEngine)=="userdata" then
print "[lua] looks good"
else
print "[lua] nope, no signs of it"
end
-- the embed program expects a function void onEvent(Event)
-- this is it
function onEvent(e)
print("[Lua] onEvent with event",e.mType)
-- lets do something with the Engine
-- nothing clever, but ...
if e.mType==example.Event_STARTUP then
pEngine:start()
elseif e.mType==example.Event_KEYPRESS then
pEngine:accelerate(0.4)
elseif e.mType==example.Event_MOUSEPRESS then
pEngine:decelerate(0.4)
elseif e.mType==example.Event_SHUTDOWN then
pEngine:stop()
else
error("unknown event type")
end
print("[Lua] ending onEvent")
end

View file

@ -27,9 +27,6 @@ void add_Shape(Shape* s,ShapeOwner* own){own->add(s);}
// or a better solution is a typemap
%apply SWIGTYPE *DISOWN {Shape* ptr};
//%ignore ShapeOwner::add;
// now we can grab the header file
%include "example.h"

View file

@ -0,0 +1,12 @@
require("import") -- the import fn
import("disown") -- import code
-- catch "undefined" global variables
setmetatable(getfenv(),{__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
for x=0,100 do
a=disown.A()
b=disown.B()
b:acquire(a)
end
collectgarbage() -- this will double delete unless the memory is managed properly

View file

@ -0,0 +1,14 @@
require("import") -- the import fn
import("import_nomodule") -- import code
-- catch "undefined" global variables
setmetatable(getfenv(),{__index=function (t,i) error("undefined global variable `"..i.."'",2) end})
f = import_nomodule.create_Foo()
import_nomodule.test1(f,42)
import_nomodule.delete_Foo(f)
b = import_nomodule.Bar()
import_nomodule.test1(b,37)
collectgarbage()

View file

@ -192,7 +192,7 @@ There probably is some compiler that its not true for, so the code is left here
#define SWIG_FREE_ARRAY(PTR) free(PTR);
#endif
/* counting the size of arrays:*/
int SWIG_itable_size(lua_State* L, int index)
SWIGINTERN int SWIG_itable_size(lua_State* L, int index)
{
int n=0;
while(1){
@ -205,7 +205,7 @@ int SWIG_itable_size(lua_State* L, int index)
return n;
}
int SWIG_table_size(lua_State* L, int index)
SWIGINTERN int SWIG_table_size(lua_State* L, int index)
{
int n=0;
lua_pushnil(L); /* first key*/
@ -218,7 +218,7 @@ int SWIG_table_size(lua_State* L, int index)
/* super macro to declare array typemap helper fns */
#define SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE)\
int SWIG_read_##NAME##_num_array(lua_State* L,int index,TYPE *array,int size){\
SWIGINTERN int SWIG_read_##NAME##_num_array(lua_State* L,int index,TYPE *array,int size){\
int i;\
for (i = 0; i < size; i++) {\
lua_rawgeti(L,index,i+1);\
@ -232,7 +232,7 @@ int SWIG_table_size(lua_State* L, int index)
}\
return 1;\
}\
static TYPE* SWIG_get_##NAME##_num_array_fixed(lua_State* L, int index, int size){\
SWIGINTERN TYPE* SWIG_get_##NAME##_num_array_fixed(lua_State* L, int index, int size){\
TYPE *array;\
if (!lua_istable(L,index) || SWIG_itable_size(L,index) != size) {\
lua_pushfstring(L,"expected a table of size %d",size);\
@ -246,7 +246,7 @@ int SWIG_table_size(lua_State* L, int index)
}\
return array;\
}\
static TYPE* SWIG_get_##NAME##_num_array_var(lua_State* L, int index, int* size)\
SWIGINTERN TYPE* SWIG_get_##NAME##_num_array_var(lua_State* L, int index, int* size)\
{\
TYPE *array;\
if (!lua_istable(L,index)) {\
@ -266,7 +266,7 @@ int SWIG_table_size(lua_State* L, int index)
}\
return array;\
}\
void SWIG_write_##NAME##_num_array(lua_State* L,TYPE *array,int size){\
SWIGINTERN void SWIG_write_##NAME##_num_array(lua_State* L,TYPE *array,int size){\
int i;\
lua_newtable(L);\
for (i = 0; i < size; i++){\
@ -414,7 +414,7 @@ so if the C/C++ frees then Lua is not aware
*/
%{
int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_info *type){
SWIGINTERN int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_info *type){
int i;
for (i = 0; i < size; i++) {
lua_rawgeti(L,index,i+1);
@ -426,7 +426,7 @@ int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_i
}
return 1;
}
static void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_type_info *type){
SWIGINTERN void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_type_info *type){
void **array;
if (!lua_istable(L,index) || SWIG_itable_size(L,index) != size) {
lua_pushfstring(L,"expected a table of size %d",size);
@ -440,7 +440,7 @@ static void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_ty
}
return array;
}
static void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_type_info *type){
SWIGINTERN void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_type_info *type){
void **array;
if (!lua_istable(L,index)) {
lua_pushstring(L,"expected a table");
@ -459,7 +459,7 @@ static void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_typ
}
return array;
}
void SWIG_write_ptr_array(lua_State* L,void **array,int size,swig_type_info *type,int own){
SWIGINTERN void SWIG_write_ptr_array(lua_State* L,void **array,int size,swig_type_info *type,int own){
int i;
lua_newtable(L);
for (i = 0; i < size; i++){

View file

@ -51,6 +51,7 @@ char cvsroot_lua_cxx[] = "$Id$";
*/
#define REPORT(T,D) // no info:
//#define REPORT(T,D) {Printf(stdout,T"\n");} // only title
//#define REPORT(T,D) {Printf(stdout,T" %p\n",n);} // title & pointer
//#define REPORT(T,D) {Printf(stdout,T"\n");display_mapping(D);} // the works
//#define REPORT(T,D) {Printf(stdout,T"\n");if(D)Swig_print_node(D);} // the works
@ -333,7 +334,7 @@ public:
* --------------------------------------------------------------------- */
virtual int functionWrapper(Node *n) {
// REPORT("functionWrapper",n);
REPORT("functionWrapper",n);
String *name = Getattr(n, "name");
String *iname = Getattr(n, "sym:name");
@ -620,8 +621,17 @@ public:
Replaceall(f->code, "$result", "result");
/* Dump the function out */
Wrapper_print(f, f_wrappers);
/* in Lua we will not emit the destructor as a wrappered function,
Lua will automatically call the destructor when the object is free'd
However: you cannot just skip this function as it will not emit
any custom destructor (using %extend), as you need to call emit_action()
Therefore we go though the whole function,
but do not write the code into the wrapper
*/
if(current!=DESTRUCTOR) {
Wrapper_print(f, f_wrappers);
}
/* NEW LANGUAGE NOTE:***********************************************
register the function in SWIG
different language mappings seem to use different ideas
@ -689,7 +699,18 @@ public:
Replaceall(dispatch, "$args", "self,args");
Printv(f->code, dispatch, "\n", NIL);
Printf(f->code, "lua_pushstring(L,\"No matching function for overloaded '%s'\");\n", symname);
Node *sibl = n;
while (Getattr(sibl, "sym:previousSibling"))
sibl = Getattr(sibl, "sym:previousSibling"); // go all the way up
String *protoTypes = NewString("");
do {
Printf(protoTypes, "\n\" %s(%s)\\n\"", SwigType_str(Getattr(sibl, "name"), 0), ParmList_protostr(Getattr(sibl, "wrap:parms")));
} while ((sibl = Getattr(sibl, "sym:nextSibling")));
Printf(f->code, "lua_pushstring(L,\"Wrong arguments for overloaded function '%s'\\n\"\n"
"\" Possible C/C++ prototypes are:\\n\"%s);\n",symname,protoTypes);
Delete(protoTypes);
Printf(f->code, "lua_error(L);return 0;\n");
Printv(f->code, "}\n", NIL);
Wrapper_print(f, f_wrappers);
@ -840,7 +861,7 @@ public:
* ------------------------------------------------------------ */
virtual int classHandler(Node *n) {
REPORT("classHandler", n);
//REPORT("classHandler", n);
String *mangled_classname = 0;
String *real_classname = 0;
@ -892,6 +913,8 @@ public:
// Register the class structure with the type checker
// Printf(f_init,"SWIG_TypeClientData(SWIGTYPE%s, (void *) &_wrap_class_%s);\n", SwigType_manglestr(t), mangled_classname);
// emit a function to be called to delete the object
if (have_destructor) {
Printv(f_wrappers, "static void swig_delete_", class_name, "(void *obj) {\n", NIL);
if (destructor_action) {
@ -1061,7 +1084,7 @@ public:
* ------------------------------------------------------------ */
virtual int destructorHandler(Node *n) {
//REPORT("destructorHandler", n);
REPORT("destructorHandler", n);
current = DESTRUCTOR;
Language::destructorHandler(n);
current = NO_CPP;