diff options
Diffstat (limited to 'Examples/lua')
80 files changed, 3281 insertions, 0 deletions
diff --git a/Examples/lua/arrays/Makefile b/Examples/lua/arrays/Makefile new file mode 100644 index 0000000..bb9cf0b --- /dev/null +++ b/Examples/lua/arrays/Makefile @@ -0,0 +1,18 @@ +TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+SRCS = example.c
+TARGET = example
+INTERFACE = example.i
+
+all::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua
+
+static::
+ $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \
+ TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile lua_clean
+
+check: all
diff --git a/Examples/lua/arrays/example.c b/Examples/lua/arrays/example.c new file mode 100644 index 0000000..56c7b19 --- /dev/null +++ b/Examples/lua/arrays/example.c @@ -0,0 +1,25 @@ +/* File : example.c */
+
+#include <stdlib.h>
+
+/* we are using the qsort function, which needs a helper function to sort */
+int compare_int(const void * a, const void * b)
+{
+ return ( *(int*)a - *(int*)b );
+}
+
+void sort_int(int* arr, int len)
+{
+ qsort(arr, len, sizeof(int), compare_int);
+}
+
+// ditto doubles
+int compare_double(const void * a, const void * b)
+{
+ return (int)( *(double*)a - *(double*)b );
+}
+
+void sort_double(double* arr, int len)
+{
+ qsort(arr, len, sizeof(double), compare_double);
+}
diff --git a/Examples/lua/arrays/example.i b/Examples/lua/arrays/example.i new file mode 100644 index 0000000..197a5a2 --- /dev/null +++ b/Examples/lua/arrays/example.i @@ -0,0 +1,42 @@ +/* File : example.i */
+%module example
+
+/* in this file there are two sorting functions
+and three different ways to wrap them.
+
+See the lua code for how they are called
+*/
+
+%include <carrays.i> // array helpers
+
+// this declares a batch of function for manipulating C integer arrays
+%array_functions(int,int)
+
+// this adds some lua code directly into the module
+// warning: you need the example. prefix if you want it added into the module
+// addmittedly this code is a bit tedious, but its a one off effort
+%luacode {
+function example.sort_int2(t)
+ local len=table.maxn(t) -- the len
+ local arr=example.new_int(len)
+ for i=1,len do
+ example.int_setitem(arr,i-1,t[i]) -- note: C index is one less then lua indea
+ end
+ example.sort_int(arr,len) -- call the fn
+ -- copy back
+ for i=1,len do
+ t[i]=example.int_getitem(arr,i-1) -- note: C index is one less then lua indea
+ end
+ example.delete_int(arr) -- must delete it
+end
+}
+
+// this way uses the SWIG-Lua typemaps to do the conversion for us
+// the %apply command states to apply this wherever the argument signature matches
+%include <typemaps.i>
+%apply (double *INOUT,int) {(double* arr,int len)};
+
+%inline %{
+extern void sort_int(int* arr, int len);
+extern void sort_double(double* arr, int len);
+%}
\ No newline at end of file diff --git a/Examples/lua/arrays/runme.lua b/Examples/lua/arrays/runme.lua new file mode 100644 index 0000000..b0f5cfc --- /dev/null +++ b/Examples/lua/arrays/runme.lua @@ -0,0 +1,74 @@ +---- importing ----
+if string.sub(_VERSION,1,7)=='Lua 5.0' then
+ -- lua5.0 doesnt have a nice way to do this
+ lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
+ assert(lib)()
+else
+ -- lua 5.1 does
+ require('example')
+end
+
+-- a helper to print a Lua table
+function print_table(t)
+ print(table.concat(t,","))
+end
+
+-- a helper to print a C array
+function print_array(arr,len)
+ for i=0,len-1 do
+ io.write(example.int_getitem(arr,i),",")
+ end
+ io.write("\n")
+end
+
+math.randomseed(0) -- init random
+
+
+--[[ version 1: passing a C array to the code
+lets test call sort_int()
+this requires a C array, so is the hardest to use]]
+ARRAY_SIZE=10
+arr=example.new_int(ARRAY_SIZE)
+for i=0,ARRAY_SIZE-1 do
+ example.int_setitem(arr,i,math.random(1000))
+end
+print "unsorted"
+print_array(arr,ARRAY_SIZE)
+example.sort_int(arr,ARRAY_SIZE)
+print "sorted"
+print_array(arr,ARRAY_SIZE)
+example.delete_int(arr) -- must delete it
+print ""
+
+--[[ version 2: using %luacode to write a helper
+a simpler way is to use a %luacode
+which is a lua function added into the module
+this can do the conversion for us
+so we can just add a lua table directly
+(what we do is move the lua code into the module instead)
+]]
+t={}
+for i=1,ARRAY_SIZE do
+ t[i]=math.random(1000)
+end
+print "unsorted"
+print_table(t)
+example.sort_int2(t) -- calls lua helper which then calls C
+print "sorted"
+print_table(t)
+print ""
+
+--[[ version 3: use a typemap
+this is the best way
+it uses the SWIG-Lua typemaps to do the work
+one item of note: the typemap creates a copy, rather than edit-in-place]]
+t={}
+for i=1,ARRAY_SIZE do
+ t[i]=math.random(1000)/10
+end
+print "unsorted"
+print_table(t)
+t=example.sort_double(t) -- replace t with the result
+print "sorted"
+print_table(t)
+
diff --git a/Examples/lua/check.list b/Examples/lua/check.list new file mode 100644 index 0000000..6862e44 --- /dev/null +++ b/Examples/lua/check.list @@ -0,0 +1,17 @@ +# see top-level Makefile.in +arrays +class +constants +dual +embed +embed2 +embed3 +exception +funcptr3 +functest +functor +import +owner +pointer +simple +variables diff --git a/Examples/lua/class/Makefile b/Examples/lua/class/Makefile new file mode 100644 index 0000000..44888f6 --- /dev/null +++ b/Examples/lua/class/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = example.cxx +TARGET = example +INTERFACE = example.i +LIBS = -lm + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all diff --git a/Examples/lua/class/example.cxx b/Examples/lua/class/example.cxx new file mode 100644 index 0000000..1e8e203 --- /dev/null +++ b/Examples/lua/class/example.cxx @@ -0,0 +1,28 @@ +/* File : example.c */ + +#include "example.h" +#define M_PI 3.14159265358979323846 + +/* Move the shape to a new location */ +void Shape::move(double dx, double dy) { + x += dx; + y += dy; +} + +int Shape::nshapes = 0; + +double Circle::area(void) { + return M_PI*radius*radius; +} + +double Circle::perimeter(void) { + return 2*M_PI*radius; +} + +double Square::area(void) { + return width*width; +} + +double Square::perimeter(void) { + return 4*width; +} diff --git a/Examples/lua/class/example.h b/Examples/lua/class/example.h new file mode 100644 index 0000000..46d9013 --- /dev/null +++ b/Examples/lua/class/example.h @@ -0,0 +1,39 @@ +/* File : example.h */ + +class Shape { +public: + Shape() { + nshapes++; + } + virtual ~Shape() { + nshapes--; + }; + double x, y; + void move(double dx, double dy); + virtual double area(void) = 0; + virtual double perimeter(void) = 0; + static int nshapes; +}; + +class Circle : public Shape { +private: + double radius; +public: + Circle(double r) : radius(r) { }; + virtual double area(void); + virtual double perimeter(void); +}; + +class Square : public Shape { +private: + double width; +public: + Square(double w) : width(w) { }; + virtual double area(void); + virtual double perimeter(void); +}; + + + + + diff --git a/Examples/lua/class/example.i b/Examples/lua/class/example.i new file mode 100644 index 0000000..75700b3 --- /dev/null +++ b/Examples/lua/class/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%{ +#include "example.h" +%} + +/* Let's just grab the original header file here */ +%include "example.h" + diff --git a/Examples/lua/class/runme.lua b/Examples/lua/class/runme.lua new file mode 100644 index 0000000..2c3ad8c --- /dev/null +++ b/Examples/lua/class/runme.lua @@ -0,0 +1,62 @@ +-- file: runme.lua + +-- This file illustrates class C++ interface generated +-- by SWIG. + +---- importing ---- +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example') + assert(lib)() +else + -- lua 5.1 does + require('example') +end + +----- Object creation ----- + +print("Creating some objects:") +c = example.Circle(10) +print(" Created circle", c) +s = example.Square(10) +print(" Created square", s) + +----- Access a static member ----- + +print("\nA total of",example.Shape_nshapes,"shapes were created") + +----- Member data access ----- + +-- Set the location of the object + +c.x = 20 +c.y = 30 + +s.x = -10 +s.y = 5 + +print("\nHere is their current position:") +print(string.format(" Circle = (%f, %f)",c.x,c.y)) +print(string.format(" Square = (%f, %f)",s.x,s.y)) + +----- Call some methods ----- + +print("\nHere are some properties of the shapes:") +for _,o in pairs({c,s}) do + print(" ", o) + print(" area = ", o:area()) + print(" perimeter = ", o:perimeter()) +end + +print("\nGuess I'll clean up now") + +-- Note: this invokes the virtual destructor +c=nil +s=nil +s = 3 + +-- call gc to make sure they are collected +collectgarbage() + +print(example.Shape_nshapes,"shapes remain") +print "Goodbye" diff --git a/Examples/lua/constants/Makefile b/Examples/lua/constants/Makefile new file mode 100644 index 0000000..4204545 --- /dev/null +++ b/Examples/lua/constants/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all diff --git a/Examples/lua/constants/example.i b/Examples/lua/constants/example.i new file mode 100644 index 0000000..4f7b1a4 --- /dev/null +++ b/Examples/lua/constants/example.i @@ -0,0 +1,27 @@ +/* File : example.i */ +%module example + +/* A few preprocessor macros */ + +#define ICONST 42 +#define FCONST 2.1828 +#define CCONST 'x' +#define CCONST2 '\n' +#define SCONST "Hello World" +#define SCONST2 "\"Hello World\"" + +/* This should work just fine */ +#define EXPR ICONST + 3*(FCONST) + +/* This shouldn't do anything */ +#define EXTERN extern + +/* Neither should this (BAR isn't defined) */ +#define FOO (ICONST + BAR) + +/* The following directives also produce constants */ + +%constant int iconst = 37; +%constant double fconst = 3.14; + + diff --git a/Examples/lua/constants/runme.lua b/Examples/lua/constants/runme.lua new file mode 100644 index 0000000..751e7d6 --- /dev/null +++ b/Examples/lua/constants/runme.lua @@ -0,0 +1,35 @@ +-- file: example.lua + +---- importing ---- +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example') + assert(lib)() +else + -- lua 5.1 does + require('example') +end + +print("ICONST = "..example.ICONST.." (should be 42)") +print("FCONST = "..example.FCONST.." (should be 2.1828)") +print("CCONST = "..example.CCONST.." (should be 'x')") +print("CCONST2 = "..example.CCONST2.." (this should be on a new line)") +print("SCONST = "..example.SCONST.." (should be 'Hello World')") +print("SCONST2 = "..example.SCONST2.." (should be '\"Hello World\"')") +print("EXPR = "..example.EXPR.." (should be 48.5484)") +print("iconst = "..example.iconst.." (should be 37)") +print("fconst = "..example.fconst.." (should be 3.14)") + +-- helper to check that a fn failed +function checkfail(fn) + if pcall(fn)==true then + print("that shouldn't happen, it worked") + else + print("function failed as expected") + end +end + +-- these should fail +-- example.EXTERN is a nil value, so concatentatin will make it fail +checkfail(function() print("EXTERN = "..example.EXTERN) end) +checkfail(function() print("FOO = "..example.FOO) end) diff --git a/Examples/lua/dual/Makefile b/Examples/lua/dual/Makefile new file mode 100644 index 0000000..b4e28f3 --- /dev/null +++ b/Examples/lua/dual/Makefile @@ -0,0 +1,21 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +TARGET = dual +CXXSRCS = example2_wrap.cxx +INTERFACE = dual.i +LUA_INTERP = dual.cpp + +# This is a little different to normal as we need to static link two modules and a custom interpreter +# We need the external runtime, then swig examples2, and build the module as normal +all:: + $(SWIG) -lua -external-runtime + $(SWIG) -c++ -lua $(SWIGOPT) example2.i + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static_cpp + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + rm -f swigluarun.h + +check: all + diff --git a/Examples/lua/dual/dual.cpp b/Examples/lua/dual/dual.cpp new file mode 100644 index 0000000..d2a9eca --- /dev/null +++ b/Examples/lua/dual/dual.cpp @@ -0,0 +1,109 @@ +/* +dual.cpp a test for multiple modules and multiple intrepreters staticly linked together. + +Earlier version of lua bindings for SWIG would fail if staticly linked. + +What is happening is as follows: +example.i declares a type Foo +examples2.i declares Bar + +The first lua state will load example.i +and check to see if types Foo and Bar are registered with it +(Foo should be & Bar should not) + +The second lua state will load example2.i +and check to see if types Foo and Bar are registered with it +(Bar should be & Foo should not) + +Note: Though both the modules exist and are loaded, they are not linked together, +as they are connected to seperate lua interpreters. + +When the third lua state loads both example.i and example2.i, +the two modules are now linked together, and all can now find +both Foo and Bar. +*/ + +#include "swigluarun.h" // the swig runtimes + +#include <stdio.h> +#include <stdlib.h> + +// the 2 libraries which are wrappered via SWIG +extern "C" int luaopen_example(lua_State*L); +extern "C" int luaopen_example2(lua_State*L); + +#define DEBUG(X) {printf(X);fflush(stdout);} +#define DEBUG2(X,Y) {printf(X,Y);fflush(stdout);} +#define DEBUG3(X,Y,Z) {printf(X,Y,Z);fflush(stdout);} + +void testModule(lua_State *L) +{ + swig_type_info *pTypeInfo=0,*pTypeInfo2=0; + swig_module_info *pModule=0; + pModule=SWIG_GetModule(L); + DEBUG2(" SWIG_GetModule() returns %p\n",pModule) + if(pModule==0) return; + pTypeInfo = SWIG_TypeQuery(L,"Foo *"); + DEBUG2(" Type (Foo*) is %s\n",pTypeInfo==0?"unknown":"known"); + DEBUG3(" Module %p typeinfo(Foo*) %p\n",pModule,pTypeInfo); + pTypeInfo2 = SWIG_TypeQuery(L,"Bar *"); + DEBUG2(" Type (Bar*) is %s\n",pTypeInfo2==0?"unknown":"known"); + DEBUG3(" Module %p typeinfo(Bar*) %p\n",pModule,pTypeInfo2); +} + +int main(int argc,char* argv[]) +{ + lua_State *L1=0,*L2=0,*L3=0; + + printf("This is a test of having two SWIG'ed modules and three lua states\n" + "statically linked together.\n" + "Its mainly to check that all the types are correctly managed\n\n"); + + DEBUG("creating lua states(L1,L2,L3)"); + L1=lua_open(); + L2=lua_open(); + L3=lua_open(); + DEBUG("ok\n\n"); + + DEBUG("luaopen_example(L1).."); + luaopen_example(L1); + DEBUG("ok\n"); + + DEBUG("Testing Module L1\n"); + DEBUG("This module should know about Foo* but not Bar*\n"); + testModule(L1); + DEBUG("End Testing Module L1\n\n"); + + DEBUG("luaopen_example2(L2).."); + luaopen_example2(L2); + DEBUG("ok\n"); + + DEBUG("Testing Module L2\n"); + DEBUG("This module should know about Bar* but not Foo*\n"); + testModule(L2); + DEBUG("End Testing Module L2\n\n"); + + DEBUG("luaopen_example(L3).."); + luaopen_example(L3); + DEBUG("ok\n"); + DEBUG("luaopen_example2(L3).."); + luaopen_example2(L3); + DEBUG("ok\n"); + + DEBUG("Testing Module L3\n"); + DEBUG("This module should know about Foo* and Bar*\n"); + testModule(L3); + DEBUG("End Testing Module L3\n\n"); + + DEBUG("Testing Module L1 again\n"); + DEBUG("It now should know about Foo* and Bar*\n"); + testModule(L1); + DEBUG("End Testing Module L1 again\n\n"); + + DEBUG("close all.."); + lua_close(L1); + lua_close(L2); + lua_close(L3); + DEBUG("ok, exiting\n"); + return 0; +} diff --git a/Examples/lua/dual/example.i b/Examples/lua/dual/example.i new file mode 100644 index 0000000..5e573dd --- /dev/null +++ b/Examples/lua/dual/example.i @@ -0,0 +1,10 @@ +/* File : example.i */ +%module example + +%inline %{ + +struct Foo{ + int i; +}; + +%} diff --git a/Examples/lua/dual/example2.i b/Examples/lua/dual/example2.i new file mode 100644 index 0000000..9449664 --- /dev/null +++ b/Examples/lua/dual/example2.i @@ -0,0 +1,10 @@ +/* File : example2.i */ +%module example2 + +%inline %{ + +struct Bar{ + int i; +}; + +%} diff --git a/Examples/lua/embed/Makefile b/Examples/lua/embed/Makefile new file mode 100644 index 0000000..51d0e61 --- /dev/null +++ b/Examples/lua/embed/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +TARGET = embed +SRCS = example.c +INTERFACE = example.i +LUA_INTERP = embed.c + +# this is a little different to normal as we have our own special interpreter +# which we want to static link +all:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all + diff --git a/Examples/lua/embed/embed.c b/Examples/lua/embed/embed.c new file mode 100644 index 0000000..55ea099 --- /dev/null +++ b/Examples/lua/embed/embed.c @@ -0,0 +1,85 @@ +/* embed.c a simple test for an embeded interpreter
+
+The idea is that we wrapper a few simple function (example.c)
+and write our own app to call it.
+
+What it will do is load the wrappered lib, load runme.lua and then call some functions.
+To make life easier, all the printf's have either [C] or [Lua] at the start
+so you can see where they are coming from.
+
+We will be using the luaL_dostring()/lua_dostring() function to call into lua
+
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+/* the SWIG wrappered library */
+extern int luaopen_example(lua_State*L);
+
+/* a really simple way of calling lua from C
+ just give it a lua state & a string to execute
+Unfortunately lua keeps changing its API's.
+In lua 5.0.X its lua_dostring()
+In lua 5.1.X its luaL_dostring()
+so we have a few extra compiles
+*/
+int dostring(lua_State *L, char* str) {
+ int ok;
+#if (defined(LUA_VERSION_NUM) && (LUA_VERSION_NUM>=501))
+
+ ok=luaL_dostring(L,str); /* looks like this is lua 5.1.X or later, good */
+#else
+
+ ok=lua_dostring(L,str); /* might be lua 5.0.x, using lua_dostring */
+#endif
+
+ if (ok!=0)
+ printf("[C] ERROR in dostring: %s\n",lua_tostring(L,-1));
+ return ok;
+}
+
+
+int main(int argc,char* argv[]) {
+ lua_State *L;
+ int ok;
+ printf("[C] Welcome to the simple embedded lua example\n");
+ printf("[C] We are in C\n");
+ printf("[C] opening a lua state & loading the libraries\n");
+ 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 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 function 'do_tests()'\n");
+ ok=dostring(L,"do_tests()");
+ printf("[C] We are back in C, the dostring() function returned %d\n",ok);
+ printf("\n");
+ printf("[C] Lets call lua again, but create an error\n");
+ ok=dostring(L,"no_such_function()");
+ printf("[C] We are back in C, the dostring() function returned %d\n",ok);
+ printf("[C] it should also have returned 1 and printed an error message\n");
+ printf("\n");
+ printf("[C] Lets call lua again, calling the greeting function\n");
+ ok=dostring(L,"call_greeting()");
+ printf("[C] This was C=>Lua=>C (getting a bit complex)\n");
+ printf("\n");
+ printf("[C] all finished, closing the lua state\n");
+ lua_close(L);
+ return 0;
+}
diff --git a/Examples/lua/embed/example.c b/Examples/lua/embed/example.c new file mode 100644 index 0000000..c6c6d7b --- /dev/null +++ b/Examples/lua/embed/example.c @@ -0,0 +1,22 @@ +/* File : example.c */
+
+#include <stdio.h>
+
+/* A global variable */
+double Foo = 3.0;
+
+/* Compute the greatest common divisor of positive integers */
+int gcd(int x, int y) {
+ int g;
+ g = y;
+ while (x > 0) {
+ g = x;
+ x = y % x;
+ y = g;
+ }
+ return g;
+}
+
+void greeting() {
+ printf("Hello from the C function 'greeting'\n");
+}
diff --git a/Examples/lua/embed/example.i b/Examples/lua/embed/example.i new file mode 100644 index 0000000..7784b8e --- /dev/null +++ b/Examples/lua/embed/example.i @@ -0,0 +1,8 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +extern void greeting(); +%}
\ No newline at end of file diff --git a/Examples/lua/embed/runme.lua b/Examples/lua/embed/runme.lua new file mode 100644 index 0000000..e02fd1d --- /dev/null +++ b/Examples/lua/embed/runme.lua @@ -0,0 +1,40 @@ +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") + +-- a test function to run the tests +function do_tests() + print("[lua] We are now in Lua, inside the do_tests() function") + print("[lua] We will be calling example.gcd() and changing example.Foo") + -- Call our gcd() function + x = 42 + y = 105 + g = example.gcd(x,y) + print("[lua] The gcd of",x,"and",y,"is",g) + + -- Manipulate the Foo global variable + + -- Output its current value + print("[lua] Foo = ", example.Foo) + + -- Change its value + example.Foo = 3.1415926 + + -- See if the change took effect + print("[lua] Foo = ", example.Foo) + print("[lua] ending the do_tests() function") +end + +function call_greeting() + print("[lua] We are now in Lua, inside the call_greeting() function") + example.greeting() + print("[lua] ending the call_greeting() function") +end + + + + + + diff --git a/Examples/lua/embed2/Makefile b/Examples/lua/embed2/Makefile new file mode 100644 index 0000000..5f267d9 --- /dev/null +++ b/Examples/lua/embed2/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +TARGET = embed2 +SRCS = example.c +INTERFACE = example.i +LUA_INTERP = embed2.c + +# this is a little different to normal as we have our own special interpreter +# which we want to static link +all:: + $(MAKE) -f $(TOP)/Makefile $(SWIGLIB) SRCS='$(SRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='example.i' LUA_INTERP='$(LUA_INTERP)' lua_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all + diff --git a/Examples/lua/embed2/embed2.c b/Examples/lua/embed2/embed2.c new file mode 100644 index 0000000..dac527e --- /dev/null +++ b/Examples/lua/embed2/embed2.c @@ -0,0 +1,233 @@ +/* embed2.c some more test for an embeded interpreter
+
+This will go a bit further as it will pass values to and from the lua code.
+It uses less of the SWIG code, and more of the raw lua API's
+
+What it will do is load the wrappered lib, load runme.lua and then call some functions.
+To make life easier, all the printf's have either [C] or [Lua] at the start
+so you can see where they are coming from.
+
+We will be using the luaL_dostring()/lua_dostring() function to call into lua
+
+*/
+
+/* Deal with Microsoft's attempt at deprecating C standard runtime functions */
+#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE)
+# define _CRT_SECURE_NO_DEPRECATE
+#endif
+
+/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */
+#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE)
+# define _SCL_SECURE_NO_DEPRECATE
+#endif
+
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+#include <stdarg.h>
+#include <string.h>
+
+
+/* the SWIG wrappered library */
+extern int luaopen_example(lua_State*L);
+
+/* This is an example of how to call the Lua function
+ int add(int,int)
+ its very tedious, but gives you an idea of the issues involded.
+ (look below for a better idea)
+*/
+int call_add(lua_State *L,int a,int b,int* res) {
+ int top;
+ /* ok, here we go:
+ push a, push b, call 'add' check & return res
+ */
+ top=lua_gettop(L); /* for later */
+ lua_pushstring(L, "add"); /* function name */
+ lua_gettable(L, LUA_GLOBALSINDEX); /* function to be called */
+ if (!lua_isfunction(L,-1)) {
+ printf("[C] error: cannot find function 'add'\n");
+ lua_settop(L,top); // reset
+ return 0;
+ }
+ lua_pushnumber(L,a);
+ lua_pushnumber(L,b);
+ if (lua_pcall(L, 2, 1, 0) != 0) /* call function with 2 arguments and 1 result */
+ {
+ printf("[C] error running function `add': %s\n",lua_tostring(L, -1));
+ lua_settop(L,top); // reset
+ return 0;
+ }
+ // check results
+ if (!lua_isnumber(L,-1)) {
+ printf("[C] error: returned value is not a number\n");
+ lua_settop(L,top); // reset
+ return 0;
+ }
+ *res=(int)lua_tonumber(L,-1);
+ lua_settop(L,top); /* reset stack */
+ return 1; // ok
+}
+
+/* This is a variargs call function for calling from C into Lua.
+Original Code from Programming in Lua (PIL) by Roberto Ierusalimschy
+ISBN 85-903798-1-7
+http://www.lua.org/pil/25.3.html
+This has been modified slightly to make it compile, and its still a bit rough.
+But it gives the idea of how to make it work.
+*/
+int call_va (lua_State *L,const char *func, const char *sig, ...) {
+ va_list vl;
+ int narg, nres; /* number of arguments and results */
+ int top;
+ top=lua_gettop(L); /* for later */
+
+ va_start(vl, sig);
+ lua_getglobal(L, func); /* get function */
+
+ /* push arguments */
+ narg = 0;
+ while (*sig) { /* push arguments */
+ switch (*sig++) {
+
+ case 'd': /* double argument */
+ lua_pushnumber(L, va_arg(vl, double));
+ break;
+
+ case 'i': /* int argument */
+ lua_pushnumber(L, va_arg(vl, int));
+ break;
+
+ case 's': /* string argument */
+ lua_pushstring(L, va_arg(vl, char *));
+ break;
+
+ case '>':
+ goto endwhile;
+
+ default:
+ printf("invalid option (%c)\n", *(sig - 1));
+ goto fail;
+ }
+ narg++;
+ /* do we need this?*/
+ /* luaL_checkstack(L, 1, "too many arguments"); */
+ }
+endwhile:
+
+ /* do the call */
+ nres = (int)strlen(sig); /* number of expected results */
+ if (lua_pcall(L, narg, nres, 0) != 0) /* do the call */
+ {
+ printf("error running function `%s': %s\n",func, lua_tostring(L, -1));
+ goto fail;
+ }
+
+ /* retrieve results */
+ nres = -nres; /* stack index of first result */
+ while (*sig) { /* get results */
+ switch (*sig++) {
+
+ case 'd': /* double result */
+ if (!lua_isnumber(L, nres)) {
+ printf("wrong result type\n");
+ goto fail;
+ }
+ *va_arg(vl, double *) = lua_tonumber(L, nres);
+ break;
+
+ case 'i': /* int result */
+ if (!lua_isnumber(L, nres)) {
+ printf("wrong result type\n");
+ goto fail;
+ }
+ *va_arg(vl, int *) = (int)lua_tonumber(L, nres);
+ break;
+
+ case 's': /* string result */
+ if (!lua_isstring(L, nres)) {
+ printf("wrong result type\n");
+ goto fail;
+ }
+ strcpy(va_arg(vl, char *),lua_tostring(L, nres));/* WARNING possible buffer overflow */
+ break;
+
+ default: {
+ printf("invalid option (%c)", *(sig - 1));
+ goto fail;
+ }
+ }
+ nres++;
+ }
+ va_end(vl);
+
+ lua_settop(L,top); /* reset stack */
+ return 1; /* ok */
+fail:
+ lua_settop(L,top); /* reset stack */
+ return 0; /* error */
+}
+
+int main(int argc,char* argv[]) {
+ lua_State *L;
+ int ok;
+ int res;
+ char str[80];
+ printf("[C] Welcome to the simple embedded Lua example v2\n");
+ printf("[C] We are in C\n");
+ printf("[C] opening a Lua state & loading the libraries\n");
+ 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 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 'add(1,1)'\n");
+ printf("[C] using the C function 'call_add'\n");
+ ok=call_add(L,1,1,&res);
+ printf("[C] the function returned %d with value %d\n",ok,res);
+ printf("\n");
+ printf("[C] lets do this rather easier\n");
+ printf("[C] we will call the same Lua function using a generic C function 'call_va'\n");
+ ok=call_va(L,"add","ii>i",1,1,&res);
+ printf("[C] the function returned %d with value %d\n",ok,res);
+ printf("\n");
+ printf("[C] we will now use the same generic C function to call 'append(\"cat\",\"dog\")'\n");
+ ok=call_va(L,"append","ss>s","cat","dog",str);
+ printf("[C] the function returned %d with value %s\n",ok,str);
+ printf("\n");
+ printf("[C] we can also make some bad calls to ensure the code doesn't fail\n");
+ printf("[C] calling adds(1,2)\n");
+ ok=call_va(L,"adds","ii>i",1,2,&res);
+ printf("[C] the function returned %d with value %d\n",ok,res);
+ printf("[C] calling add(1,'fred')\n");
+ ok=call_va(L,"add","is>i",1,"fred",&res);
+ printf("[C] the function returned %d with value %d\n",ok,res);
+ printf("\n");
+ printf("[C] Note: no protection if you mess up the va-args, this is C\n");
+ printf("\n");
+ printf("[C] Finally we will call the wrappered gcd function gdc(6,9):\n");
+ printf("[C] This will pass the values to Lua, then call the wrappered function\n");
+ printf(" Which will get the values from Lua, call the C code \n");
+ printf(" and return the value to Lua and eventually back to C\n");
+ printf("[C] Certainly not the best way to do it :-)\n");
+ ok=call_va(L,"gcd","ii>i",6,9,&res);
+ printf("[C] the function returned %d with value %d\n",ok,res);
+ printf("\n");
+ printf("[C] all finished, closing the lua state\n");
+ lua_close(L);
+ return 0;
+}
diff --git a/Examples/lua/embed2/example.c b/Examples/lua/embed2/example.c new file mode 100644 index 0000000..c6c6d7b --- /dev/null +++ b/Examples/lua/embed2/example.c @@ -0,0 +1,22 @@ +/* File : example.c */
+
+#include <stdio.h>
+
+/* A global variable */
+double Foo = 3.0;
+
+/* Compute the greatest common divisor of positive integers */
+int gcd(int x, int y) {
+ int g;
+ g = y;
+ while (x > 0) {
+ g = x;
+ x = y % x;
+ y = g;
+ }
+ return g;
+}
+
+void greeting() {
+ printf("Hello from the C function 'greeting'\n");
+}
diff --git a/Examples/lua/embed2/example.i b/Examples/lua/embed2/example.i new file mode 100644 index 0000000..7784b8e --- /dev/null +++ b/Examples/lua/embed2/example.i @@ -0,0 +1,8 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +extern void greeting(); +%}
\ No newline at end of file diff --git a/Examples/lua/embed2/runme.lua b/Examples/lua/embed2/runme.lua new file mode 100644 index 0000000..73af9c5 --- /dev/null +++ b/Examples/lua/embed2/runme.lua @@ -0,0 +1,27 @@ +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") +
+-- note: we will copy the functions from example table into global
+-- this will help us later
+for k,v in pairs(example) do _G[k]=v end
+ +-- our add function
+-- we will be calling this from C +function add(a,b)
+ print("[lua] this is function add(",a,b,")")
+ c=a+b
+ print("[lua] returning",c)
+ return c
+end + +function append(a,b)
+ print("[lua] this is function append(",a,b,")")
+ c=a..b
+ print("[lua] returning",c)
+ return c
+end + + diff --git a/Examples/lua/embed3/Makefile b/Examples/lua/embed3/Makefile new file mode 100644 index 0000000..def3528 --- /dev/null +++ b/Examples/lua/embed3/Makefile @@ -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 + diff --git a/Examples/lua/embed3/embed3.cpp b/Examples/lua/embed3/embed3.cpp new file mode 100644 index 0000000..e5e0e0a --- /dev/null +++ b/Examples/lua/embed3/embed3.cpp @@ -0,0 +1,146 @@ +/* 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. + +*/ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +/* Deal with Microsoft's attempt at deprecating methods in the standard C++ library */ +#if !defined(SWIG_NO_SCL_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_SCL_SECURE_NO_DEPRECATE) +# define _SCL_SECURE_NO_DEPRECATE +#endif + + +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <stdarg.h> + +extern "C" { +#include <lua.h> +#include <lauxlib.h> +#include <lualib.h> +} +
+/* The SWIG external runtime is generated by using.
+swig -lua -externalruntime swigluarun.h
+It contains useful function used by SWIG in its wrappering
+SWIG_TypeQuery() SWIG_NewPointerObj()
+*/ +#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[]) { + 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; +} diff --git a/Examples/lua/embed3/example.cpp b/Examples/lua/embed3/example.cpp new file mode 100644 index 0000000..a8264f3 --- /dev/null +++ b/Examples/lua/embed3/example.cpp @@ -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); +} + diff --git a/Examples/lua/embed3/example.h b/Examples/lua/embed3/example.h new file mode 100644 index 0000000..41c13e9 --- /dev/null +++ b/Examples/lua/embed3/example.h @@ -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 +}; diff --git a/Examples/lua/embed3/example.i b/Examples/lua/embed3/example.i new file mode 100644 index 0000000..032805c --- /dev/null +++ b/Examples/lua/embed3/example.i @@ -0,0 +1,8 @@ +/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+%include "example.h"
diff --git a/Examples/lua/embed3/runme.lua b/Examples/lua/embed3/runme.lua new file mode 100644 index 0000000..3a44bd2 --- /dev/null +++ b/Examples/lua/embed3/runme.lua @@ -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
\ No newline at end of file diff --git a/Examples/lua/exception/Makefile b/Examples/lua/exception/Makefile new file mode 100644 index 0000000..8657f19 --- /dev/null +++ b/Examples/lua/exception/Makefile @@ -0,0 +1,19 @@ +TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS =
+TARGET = example
+INTERFACE = example.i
+LIBS = -lm
+
+all::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
+
+static::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile lua_clean
+
+check: all
diff --git a/Examples/lua/exception/example.h b/Examples/lua/exception/example.h new file mode 100644 index 0000000..5148a59 --- /dev/null +++ b/Examples/lua/exception/example.h @@ -0,0 +1,53 @@ +/* File : example.h */
+
+#include <string>
+#ifndef SWIG
+struct A {
+};
+#endif
+
+class Exc {
+public:
+ Exc(int c, const char *m) {
+ code = c;
+ strncpy(msg,m,256);
+ }
+ int code;
+ char msg[256];
+};
+
+#if defined(_MSC_VER)
+ #pragma warning(disable: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
+#endif
+
+class Test {
+public:
+ int simple() throw(int&) {
+ throw(37);
+ return 1;
+ }
+ int message() throw(const char *) {
+ throw("I died.");
+ return 1;
+ }
+ int hosed() throw(Exc) {
+ throw(Exc(42,"Hosed"));
+ return 1;
+ }
+ int unknown() throw(A*) {
+ static A a;
+ throw &a;
+ return 1;
+ }
+ int multi(int x) throw(int, const char *, Exc) {
+ if (x == 1) throw(37);
+ if (x == 2) throw("Bleah!");
+ if (x == 3) throw(Exc(42,"No-go-diggy-die"));
+ return 1;
+ }
+};
+
+#if defined(_MSC_VER)
+ #pragma warning(default: 4290) // C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
+#endif
+
diff --git a/Examples/lua/exception/example.i b/Examples/lua/exception/example.i new file mode 100644 index 0000000..09cd9e8 --- /dev/null +++ b/Examples/lua/exception/example.i @@ -0,0 +1,17 @@ +/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+%include "std_string.i"
+
+// we want to return Exc objects to the interpreter
+// therefore we add this typemap
+// note: only works if Exc is copyable
+%apply SWIGTYPE EXCEPTION_BY_VAL {Exc};
+
+/* Let's just grab the original header file here */
+%include "example.h"
+
diff --git a/Examples/lua/exception/runme.lua b/Examples/lua/exception/runme.lua new file mode 100644 index 0000000..39b2d6d --- /dev/null +++ b/Examples/lua/exception/runme.lua @@ -0,0 +1,96 @@ +-- file: example.lua
+
+---- importing ----
+if string.sub(_VERSION,1,7)=='Lua 5.0' then
+ -- lua5.0 doesnt have a nice way to do this
+ lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
+ assert(lib)()
+else
+ -- lua 5.1 does
+ require('example')
+end
+
+-- throw a lot of exceptions:
+-- you must catch exceptions using pcall and then checking the result
+
+t = example.Test()
+
+print "calling t:unknown()"
+ok,res=pcall(function() t:unknown() end)
+if ok then
+ print " that worked! Funny"
+else
+ print(" call failed with error:",res)
+end
+
+print "calling t:simple()"
+ok,res=pcall(function() t:simple() end)
+if ok then
+ print " that worked! Funny"
+else
+ print(" call failed with error:",res)
+end
+
+print "calling t:message()"
+ok,res=pcall(function() t:message() end)
+if ok then
+ print " that worked! Funny"
+else
+ print(" call failed with error:",res)
+end
+
+print "calling t:hosed()"
+ok,res=pcall(function() t:hosed() end)
+if ok then
+ print " that worked! Funny"
+else
+ print(" call failed with error:",res.code,res.msg)
+end
+
+-- this is a rather strange way to perform the multiple catch of exceptions
+print "calling t:mutli()"
+for i=1,3 do
+ ok,res=pcall(function() t:multi(i) end)
+ if ok then
+ print " that worked! Funny"
+ else
+ if swig_type(res)=="Exc *" then
+ print(" call failed with Exc exception:",res.code,res.msg)
+ else
+ print(" call failed with error:",res)
+ end
+ end
+end
+
+-- this is a bit crazy, but it shows obtaining of the stacktrace
+function a()
+ b()
+end
+function b()
+ t:message()
+end
+print [[
+Now lets call function a()
+ which calls b()
+ which calls into C++
+ which will throw an exception!]]
+ok,res=pcall(a)
+if ok then
+ print " that worked! Funny"
+else
+ print(" call failed with error:",res)
+end
+print "Now lets do the same using xpcall(a,debug.traceback)"
+ok,res=xpcall(a,debug.traceback)
+if ok then
+ print " that worked! Funny"
+else
+ print(" call failed with error:",res)
+end
+print "As you can see, the xpcall gives a nice stacktrace to work with"
+
+
+ok,res=pcall(a)
+print(ok,res)
+ok,res=xpcall(a,debug.traceback)
+print(ok,res)
diff --git a/Examples/lua/funcptr3/Makefile b/Examples/lua/funcptr3/Makefile new file mode 100644 index 0000000..ac0fff4 --- /dev/null +++ b/Examples/lua/funcptr3/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +LIBS = + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all diff --git a/Examples/lua/funcptr3/example.c b/Examples/lua/funcptr3/example.c new file mode 100644 index 0000000..5c4a3da --- /dev/null +++ b/Examples/lua/funcptr3/example.c @@ -0,0 +1,19 @@ +/* File : example.c */ + +int do_op(int a, int b, int (*op)(int,int)) { + return (*op)(a,b); +} + +int add(int a, int b) { + return a+b; +} + +int sub(int a, int b) { + return a-b; +} + +int mul(int a, int b) { + return a*b; +} + +int (*funcvar)(int,int) = add; diff --git a/Examples/lua/funcptr3/example.h b/Examples/lua/funcptr3/example.h new file mode 100644 index 0000000..9936e24 --- /dev/null +++ b/Examples/lua/funcptr3/example.h @@ -0,0 +1,9 @@ +/* file: example.h */ + +extern int do_op(int,int, int (*op)(int,int)); +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + +extern int (*funcvar)(int,int); + diff --git a/Examples/lua/funcptr3/example.i b/Examples/lua/funcptr3/example.i new file mode 100644 index 0000000..319b227 --- /dev/null +++ b/Examples/lua/funcptr3/example.i @@ -0,0 +1,69 @@ +/* File : example.i */ +/* +This demonstrates how to pass a lua function, into some C code and then call it. + +There are two examples, the first is as a parameter, the second as a global variable. + +*/ +%module example +%{ +#include "example.h" +%} +/* the extra wrappers for lua functions, see SWIG/Lib/lua/lua_fnptr.i for more details */ +%include "lua_fnptr.i" + +/* these are a bunch of C functions which we want to be able to call from lua */ +extern int add(int,int); +extern int sub(int,int); +extern int mul(int,int); + +/* this function takes a lua function as a parameter and calls it. +As this is takes a lua fn it needs lua code +*/ +%inline %{ + +int callback(int a, int b, SWIGLUA_FN fn) +{ + SWIGLUA_FN_GET(fn); + lua_pushnumber(fn.L,a); + lua_pushnumber(fn.L,b); + lua_call(fn.L,2,1); /* 2 in, 1 out */ + return (int)luaL_checknumber(fn.L,-1); +} +%} + +/****************** +Second code uses a stored reference. +*******************/ + +%inline %{ +/* note: this is not so good to just have it as a raw ref + people could set anything to this + a better solution would to be to have a fn which wants a SWIGLUA_FN, then + checks the type & converts to a SWIGLUA_REF. +*/ +SWIGLUA_REF the_func={0,0}; + +void call_the_func(int a) +{ + int i; + if (the_func.L==0){ + printf("the_func is zero\n"); + return; + } + swiglua_ref_get(&the_func); + if (!lua_isfunction(the_func.L,-1)) + { + printf("the_func is not a function\n"); + return; + } + lua_pop(the_func.L,1); /* tidy stack */ + for(i=0;i<a;i++) + { + swiglua_ref_get(&the_func); + lua_pushnumber(the_func.L,i); + lua_call(the_func.L,1,0); /* 1 in, 0 out */ + } +} + +%} diff --git a/Examples/lua/funcptr3/runme.lua b/Examples/lua/funcptr3/runme.lua new file mode 100644 index 0000000..b78c504 --- /dev/null +++ b/Examples/lua/funcptr3/runme.lua @@ -0,0 +1,54 @@ +---- importing ---- +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example') + assert(lib)() +else + -- lua 5.1 does + require('example') +end + +a = 37 +b = 42 + +-- Now call our C function + +print("Trying some C functions") +print(" a =", a) +print(" b =", b) +print(" add(a,b) =", example.add(a,b)) +print(" sub(a,b) =", example.sub(a,b)) +print(" mul(a,b) =", example.mul(a,b)) + +print("Calling them using the my_func()") +print(" add(a,b) =", example.callback(a,b,example.add)) +print(" sub(a,b) =", example.callback(a,b,example.sub)) +print(" mul(a,b) =", example.callback(a,b,example.mul)) + +print("Now let us write our own function") +function foo(a,b) return 101 end +print(" foo(a,b) =", example.callback(a,b,foo)) + +print("Now let us try something that will fail") +local ok,c=pcall(example.callback,a,b,print) +if ok==false then + print("this failed as expected, error:",c) +else + print("oops, that worked! result:",c) +end + + +-- part2 stored function +print("trying a stored fn") +print("the_func=",example.the_func) +print("setting to print") +example.the_func=print +print("the_func=",example.the_func) +print("call_the_func(5)") +example.call_the_func(5) + +function bar(i) print("bar",i) end +print("setting to bar") +example.the_func=bar +print("call_the_func(5)") +example.call_the_func(5) diff --git a/Examples/lua/functest/Makefile b/Examples/lua/functest/Makefile new file mode 100644 index 0000000..ac0fff4 --- /dev/null +++ b/Examples/lua/functest/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +LIBS = + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all diff --git a/Examples/lua/functest/example.c b/Examples/lua/functest/example.c new file mode 100644 index 0000000..8eb647f --- /dev/null +++ b/Examples/lua/functest/example.c @@ -0,0 +1,25 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +int add1(int x, int y) +{ + return x+y; +} + +void add2(int x, int *y, int *z) +{ + *z = x+*y; +} + +int add3(int x, int y, int *z) +{ + *z = x-y; + return x+y; +} + +void add4(int x, int *y) +{ + *y += x; +} diff --git a/Examples/lua/functest/example.i b/Examples/lua/functest/example.i new file mode 100644 index 0000000..631e060 --- /dev/null +++ b/Examples/lua/functest/example.i @@ -0,0 +1,13 @@ +/* File : example.i */ +%module example + +%include "typemaps.i" // you must have this for the typemaps for ptrs +// basic function testing +// +%inline %{ +extern int add1(int x, int y); // return x+y -- basic function test +extern void add2(int x, int *INPUT, int *OUTPUT); // *z = x+*y -- argin and argout test +extern int add3(int x, int y, int *OUTPUT); // return x+y, *z=x-y -- returning 2 values +extern void add4(int x, int *INOUT); // *y += x -- INOUT dual purpose variable +%} + diff --git a/Examples/lua/functest/runme.lua b/Examples/lua/functest/runme.lua new file mode 100644 index 0000000..65b3cc2 --- /dev/null +++ b/Examples/lua/functest/runme.lua @@ -0,0 +1,20 @@ +---- importing ---- +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example') + assert(lib)() +else + -- lua 5.1 does + require('example') +end + + +x,y = 42,105 +print("add1 - simple arg passing and single return value -- ") +print(example.add1(x,y)) +print("add2 - pointer arg passing and single return value through pointer arg -- ") +print(example.add2(x,y)) +print("add3 - simple arg passing and double return value through return and ptr arg -- ") +print(example.add3(x,y)) +print("add4 - dual use arg and return value -- ") +print(example.add4(x,y)) diff --git a/Examples/lua/functor/Makefile b/Examples/lua/functor/Makefile new file mode 100644 index 0000000..432bfbe --- /dev/null +++ b/Examples/lua/functor/Makefile @@ -0,0 +1,20 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +CXXSRCS = +TARGET = example +INTERFACE = example.i +LIBS = -lm +SWIGOPT = + +all:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp + +static:: + $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \ + TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all diff --git a/Examples/lua/functor/example.i b/Examples/lua/functor/example.i new file mode 100644 index 0000000..cc7a679 --- /dev/null +++ b/Examples/lua/functor/example.i @@ -0,0 +1,29 @@ +/* File : example.i */ +%module example + + +%inline %{ +// From B. Strousjoup, "The C++ Programming Language, Third Edition", p. 514 +template<class T> class Sum { + T res; +public: + Sum(T i = 0) : res(i) { } + void operator() (T x) { res += x; } + T result() const { return res; } +}; + +%} + +// Rename the application operator to __call. +// Note: this is normally automatic, but if you had to do it yourself +// you would use this directive: +// +// %rename(__call) *::operator(); // the fn call operator + +// Instantiate a few versions +%template(intSum) Sum<int>; +%template(doubleSum) Sum<double>; + + + + diff --git a/Examples/lua/functor/runme.lua b/Examples/lua/functor/runme.lua new file mode 100644 index 0000000..adf124a --- /dev/null +++ b/Examples/lua/functor/runme.lua @@ -0,0 +1,24 @@ +-- Operator overloading example +---- importing ---- +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example') + assert(lib)() +else + -- lua 5.1 does + require('example') +end + +a = example.intSum(0) +b = example.doubleSum(100.0) + +-- Use the objects. They should be callable just like a normal +-- lua function. + +for i=0,100 do + a(i) -- Note: function call + b(math.sqrt(i)) -- Note: function call +end +print("int sum 0..100 is",a:result(),"(expected 5050)") +print("double sum 0..100 is",b:result(),"(expected ~771.46)") + diff --git a/Examples/lua/import.lua b/Examples/lua/import.lua new file mode 100644 index 0000000..b2a40b0 --- /dev/null +++ b/Examples/lua/import.lua @@ -0,0 +1,42 @@ +-- import +-- the lua 5.0 loading mechanism is rather poor & relies upon the loadlib() fn +-- the lua 5.1 loading mechanism is simplicity itself +-- for now we need a bridge which will use the correct verion + +function import_5_0(module) + -- imports the file into the program + -- for a module 'example' + -- this must load 'example.dll' or 'example.so' + -- and look for the fn 'Example_Init()' (note the capitalisation) + if rawget(_G,module)~=nil then return end -- module appears to be loaded + + -- capitialising the first letter + local c=string.upper(string.sub(module,1,1)) + local fnname=c..string.sub(module,2).."_Init" + + local suffix,lib + -- note: as there seems to be no way in lua to determine the platform + -- we will try loading all possible names + -- providing one works, we can load + for _,suffix in pairs{".dll",".so"} do + lib=loadlib(module..suffix,fnname) + if lib then -- found + break + end + end + assert(lib,"error loading module:"..module) + + lib() -- execute the function: initalising the lib + local m=rawget(_G,module) -- gets the module object + assert(m~=nil,"no module table found") +end + +function import_5_1(module) + require(module) +end + +if string.sub(_VERSION,1,7)=='Lua 5.0' then + import=import_5_0 +else + import=import_5_1 +end
\ No newline at end of file diff --git a/Examples/lua/import/Makefile b/Examples/lua/import/Makefile new file mode 100644 index 0000000..8f692d1 --- /dev/null +++ b/Examples/lua/import/Makefile @@ -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 diff --git a/Examples/lua/import/README b/Examples/lua/import/README new file mode 100644 index 0000000..1a52e3c --- /dev/null +++ b/Examples/lua/import/README @@ -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
+ +
diff --git a/Examples/lua/import/bar.h b/Examples/lua/import/bar.h new file mode 100644 index 0000000..1c99f28 --- /dev/null +++ b/Examples/lua/import/bar.h @@ -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); + } +}; + + diff --git a/Examples/lua/import/bar.i b/Examples/lua/import/bar.i new file mode 100644 index 0000000..5816cbe --- /dev/null +++ b/Examples/lua/import/bar.i @@ -0,0 +1,9 @@ +%module bar +%{ +#include "bar.h" +%} + +%import base.i +%include "bar.h" + + diff --git a/Examples/lua/import/base.h b/Examples/lua/import/base.h new file mode 100644 index 0000000..fec0f32 --- /dev/null +++ b/Examples/lua/import/base.h @@ -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); + } +}; + + diff --git a/Examples/lua/import/base.i b/Examples/lua/import/base.i new file mode 100644 index 0000000..f6e19ef --- /dev/null +++ b/Examples/lua/import/base.i @@ -0,0 +1,6 @@ +%module base +%{ +#include "base.h" +%} + +%include base.h diff --git a/Examples/lua/import/foo.h b/Examples/lua/import/foo.h new file mode 100644 index 0000000..1abe2c0 --- /dev/null +++ b/Examples/lua/import/foo.h @@ -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); + } +}; + + diff --git a/Examples/lua/import/foo.i b/Examples/lua/import/foo.i new file mode 100644 index 0000000..27feb2e --- /dev/null +++ b/Examples/lua/import/foo.i @@ -0,0 +1,8 @@ +%module foo +%{ +#include "foo.h" +%} + +%import base.i +%include "foo.h" + diff --git a/Examples/lua/import/runme.lua b/Examples/lua/import/runme.lua new file mode 100644 index 0000000..9cd7ae0 --- /dev/null +++ b/Examples/lua/import/runme.lua @@ -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) + lib=loadlib(a..'.dll','luaopen_'..a) or loadlib(a..'.so','luaopen_'..a) + assert(lib)() + end + loadit('base') + loadit('foo') + loadit('bar') + loadit('spam') +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 diff --git a/Examples/lua/import/spam.h b/Examples/lua/import/spam.h new file mode 100644 index 0000000..57db845 --- /dev/null +++ b/Examples/lua/import/spam.h @@ -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); + } +}; + + diff --git a/Examples/lua/import/spam.i b/Examples/lua/import/spam.i new file mode 100644 index 0000000..d3d9121 --- /dev/null +++ b/Examples/lua/import/spam.i @@ -0,0 +1,9 @@ +%module spam +%{ +#include "spam.h" +%} + +%import bar.i +%include "spam.h" + + diff --git a/Examples/lua/lua.c b/Examples/lua/lua.c new file mode 100644 index 0000000..b0c0729 --- /dev/null +++ b/Examples/lua/lua.c @@ -0,0 +1,439 @@ +/* +** $Id: lua.c 7470 2005-09-20 19:35:23Z wsfulton $ +** Lua stand-alone interpreter +** See Copyright Notice in lua.h +*/ + + +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#define lua_c + +#include "lua.h" + +#include "lauxlib.h" +#include "lualib.h" + + +/* +** generic extra include file +*/ +#ifdef LUA_USERCONFIG +#include LUA_USERCONFIG +#endif + + +/* +** definition of `isatty' +*/ +#ifdef _POSIX_C_SOURCE +#include <unistd.h> +#define stdin_is_tty() isatty(0) +#else +#define stdin_is_tty() 1 /* assume stdin is a tty */ +#endif + + + +#ifndef PROMPT +#define PROMPT "> " +#endif + + +#ifndef PROMPT2 +#define PROMPT2 ">> " +#endif + +#ifndef PROGNAME +#define PROGNAME "lua" +#endif + +#ifndef lua_userinit +#define lua_userinit(L) openstdlibs(L) +#endif + + +#ifndef LUA_EXTRALIBS +#define LUA_EXTRALIBS /* empty */ +#endif + + +static lua_State *L = NULL; + +static const char *progname = PROGNAME; + +extern int Example_Init(lua_State* L); + +static const luaL_reg lualibs[] = { + {"base", luaopen_base}, + {"table", luaopen_table}, + {"io", luaopen_io}, + {"string", luaopen_string}, + {"math", luaopen_math}, + {"debug", luaopen_debug}, + {"loadlib", luaopen_loadlib}, + /* add your libraries here */ + {"example", Example_Init}, + LUA_EXTRALIBS + {NULL, NULL} +}; + + + +static void lstop (lua_State *l, lua_Debug *ar) { + (void)ar; /* unused arg. */ + lua_sethook(l, NULL, 0, 0); + luaL_error(l, "interrupted!"); +} + + +static void laction (int i) { + signal(i, SIG_DFL); /* if another SIGINT happens before lstop, + terminate process (default action) */ + lua_sethook(L, lstop, LUA_MASKCALL | LUA_MASKRET | LUA_MASKCOUNT, 1); +} + + +static void print_usage (void) { + fprintf(stderr, + "usage: %s [options] [script [args]].\n" + "Available options are:\n" + " - execute stdin as a file\n" + " -e stat execute string `stat'\n" + " -i enter interactive mode after executing `script'\n" + " -l name load and run library `name'\n" + " -v show version information\n" + " -- stop handling options\n" , + progname); +} + + +static void l_message (const char *pname, const char *msg) { + if (pname) fprintf(stderr, "%s: ", pname); + fprintf(stderr, "%s\n", msg); +} + + +static int report (int status) { + const char *msg; + if (status) { + msg = lua_tostring(L, -1); + if (msg == NULL) msg = "(error with no message)"; + l_message(progname, msg); + lua_pop(L, 1); + } + return status; +} + + +static int lcall (int narg, int clear) { + int status; + int base = lua_gettop(L) - narg; /* function index */ + lua_pushliteral(L, "_TRACEBACK"); + lua_rawget(L, LUA_GLOBALSINDEX); /* get traceback function */ + lua_insert(L, base); /* put it under chunk and args */ + signal(SIGINT, laction); + status = lua_pcall(L, narg, (clear ? 0 : LUA_MULTRET), base); + signal(SIGINT, SIG_DFL); + lua_remove(L, base); /* remove traceback function */ + return status; +} + + +static void print_version (void) { + l_message(NULL, LUA_VERSION " " LUA_COPYRIGHT); +} + + +static void getargs (char *argv[], int n) { + int i; + lua_newtable(L); + for (i=0; argv[i]; i++) { + lua_pushnumber(L, i - n); + lua_pushstring(L, argv[i]); + lua_rawset(L, -3); + } + /* arg.n = maximum index in table `arg' */ + lua_pushliteral(L, "n"); + lua_pushnumber(L, i-n-1); + lua_rawset(L, -3); +} + + +static int docall (int status) { + if (status == 0) status = lcall(0, 1); + return report(status); +} + + +static int file_input (const char *name) { + return docall(luaL_loadfile(L, name)); +} + + +static int dostring (const char *s, const char *name) { + return docall(luaL_loadbuffer(L, s, strlen(s), name)); +} + + +static int load_file (const char *name) { + lua_pushliteral(L, "require"); + lua_rawget(L, LUA_GLOBALSINDEX); + if (!lua_isfunction(L, -1)) { /* no `require' defined? */ + lua_pop(L, 1); + return file_input(name); + } + else { + lua_pushstring(L, name); + return report(lcall(1, 1)); + } +} + + +/* +** this macro can be used by some `history' system to save lines +** read in manual input +*/ +#ifndef lua_saveline +#define lua_saveline(L,line) /* empty */ +#endif + + +/* +** this macro defines a function to show the prompt and reads the +** next line for manual input +*/ +#ifndef lua_readline +#define lua_readline(L,prompt) readline(L,prompt) + +/* maximum length of an input line */ +#ifndef MAXINPUT +#define MAXINPUT 512 +#endif + + +static int readline (lua_State *l, const char *prompt) { + static char buffer[MAXINPUT]; + if (prompt) { + fputs(prompt, stdout); + fflush(stdout); + } + if (fgets(buffer, sizeof(buffer), stdin) == NULL) + return 0; /* read fails */ + else { + lua_pushstring(l, buffer); + return 1; + } +} + +#endif + + +static const char *get_prompt (int firstline) { + const char *p = NULL; + lua_pushstring(L, firstline ? "_PROMPT" : "_PROMPT2"); + lua_rawget(L, LUA_GLOBALSINDEX); + p = lua_tostring(L, -1); + if (p == NULL) p = (firstline ? PROMPT : PROMPT2); + lua_pop(L, 1); /* remove global */ + return p; +} + + +static int incomplete (int status) { + if (status == LUA_ERRSYNTAX && + strstr(lua_tostring(L, -1), "near `<eof>'") != NULL) { + lua_pop(L, 1); + return 1; + } + else + return 0; +} + + +static int load_string (void) { + int status; + lua_settop(L, 0); + if (lua_readline(L, get_prompt(1)) == 0) /* no input? */ + return -1; + if (lua_tostring(L, -1)[0] == '=') { /* line starts with `=' ? */ + lua_pushfstring(L, "return %s", lua_tostring(L, -1)+1);/* `=' -> `return' */ + lua_remove(L, -2); /* remove original line */ + } + for (;;) { /* repeat until gets a complete line */ + status = luaL_loadbuffer(L, lua_tostring(L, 1), lua_strlen(L, 1), "=stdin"); + if (!incomplete(status)) break; /* cannot try to add lines? */ + if (lua_readline(L, get_prompt(0)) == 0) /* no more input? */ + return -1; + lua_concat(L, lua_gettop(L)); /* join lines */ + } + lua_saveline(L, lua_tostring(L, 1)); + lua_remove(L, 1); /* remove line */ + return status; +} + + +static void manual_input (void) { + int status; + const char *oldprogname = progname; + progname = NULL; + while ((status = load_string()) != -1) { + if (status == 0) status = lcall(0, 0); + report(status); + if (status == 0 && lua_gettop(L) > 0) { /* any result to print? */ + lua_getglobal(L, "print"); + lua_insert(L, 1); + if (lua_pcall(L, lua_gettop(L)-1, 0, 0) != 0) + l_message(progname, lua_pushfstring(L, "error calling `print' (%s)", + lua_tostring(L, -1))); + } + } + lua_settop(L, 0); /* clear stack */ + fputs("\n", stdout); + progname = oldprogname; +} + + +static int handle_argv (char *argv[], int *interactive) { + if (argv[1] == NULL) { /* no more arguments? */ + if (stdin_is_tty()) { + print_version(); + manual_input(); + } + else + file_input(NULL); /* executes stdin as a file */ + } + else { /* other arguments; loop over them */ + int i; + for (i = 1; argv[i] != NULL; i++) { + if (argv[i][0] != '-') break; /* not an option? */ + switch (argv[i][1]) { /* option */ + case '-': { /* `--' */ + if (argv[i][2] != '\0') { + print_usage(); + return 1; + } + i++; /* skip this argument */ + goto endloop; /* stop handling arguments */ + } + case '\0': { + file_input(NULL); /* executes stdin as a file */ + break; + } + case 'i': { + *interactive = 1; + break; + } + case 'v': { + print_version(); + break; + } + case 'e': { + const char *chunk = argv[i] + 2; + if (*chunk == '\0') chunk = argv[++i]; + if (chunk == NULL) { + print_usage(); + return 1; + } + if (dostring(chunk, "=<command line>") != 0) + return 1; + break; + } + case 'l': { + const char *filename = argv[i] + 2; + if (*filename == '\0') filename = argv[++i]; + if (filename == NULL) { + print_usage(); + return 1; + } + if (load_file(filename)) + return 1; /* stop if file fails */ + break; + } + case 'c': { + l_message(progname, "option `-c' is deprecated"); + break; + } + case 's': { + l_message(progname, "option `-s' is deprecated"); + break; + } + default: { + print_usage(); + return 1; + } + } + } endloop: + if (argv[i] != NULL) { + const char *filename = argv[i]; + getargs(argv, i); /* collect arguments */ + lua_setglobal(L, "arg"); + return file_input(filename); /* stop scanning arguments */ + } + } + return 0; +} + + +static void openstdlibs (lua_State *l) { + const luaL_reg *lib = lualibs; + for (; lib->func; lib++) { + lib->func(l); /* open library */ + lua_settop(l, 0); /* discard any results */ + } +} + + +static int handle_luainit (void) { + const char *init = getenv("LUA_INIT"); + if (init == NULL) return 0; /* status OK */ + else if (init[0] == '@') + return file_input(init+1); + else + return dostring(init, "=LUA_INIT"); +} + + +struct Smain { + int argc; + char **argv; + int status; +}; + + +static int pmain (lua_State *l) { + struct Smain *s = (struct Smain *)lua_touserdata(l, 1); + int status; + int interactive = 0; + if (s->argv[0] && s->argv[0][0]) progname = s->argv[0]; + L = l; + lua_userinit(l); /* open libraries */ + status = handle_luainit(); + if (status == 0) { + status = handle_argv(s->argv, &interactive); + if (status == 0 && interactive) manual_input(); + } + s->status = status; + return 0; +} + + +int main (int argc, char *argv[]) { + int status; + struct Smain s; + lua_State *l = lua_open(); /* create state */ + if (l == NULL) { + l_message(argv[0], "cannot create state: not enough memory"); + return EXIT_FAILURE; + } + s.argc = argc; + s.argv = argv; + status = lua_cpcall(l, &pmain, &s); + report(status); + lua_close(l); + return (status || s.status) ? EXIT_FAILURE : EXIT_SUCCESS; +} + diff --git a/Examples/lua/owner/Makefile b/Examples/lua/owner/Makefile new file mode 100644 index 0000000..1fe68ec --- /dev/null +++ b/Examples/lua/owner/Makefile @@ -0,0 +1,19 @@ +TOP = ../..
+SWIG = $(TOP)/../preinst-swig
+CXXSRCS = example.cxx
+TARGET = example
+INTERFACE = example.i
+LIBS = -lm
+
+all::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua_cpp
+
+static::
+ $(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
+ TARGET='mylua' INTERFACE='$(INTERFACE)' lua_cpp_static
+
+clean::
+ $(MAKE) -f $(TOP)/Makefile lua_clean
+
+check: all
diff --git a/Examples/lua/owner/example.cxx b/Examples/lua/owner/example.cxx new file mode 100644 index 0000000..d6caeef --- /dev/null +++ b/Examples/lua/owner/example.cxx @@ -0,0 +1,69 @@ +/* File : example.c */
+
+#include "example.h"
+#include <stdio.h>
+
+#define M_PI 3.14159265358979323846
+
+/* Move the shape to a new location */
+void Shape::move(double dx, double dy) {
+ x += dx;
+ y += dy;
+}
+
+int Shape::nshapes = 0;
+
+double Circle::area(void) {
+ return M_PI*radius*radius;
+}
+
+double Circle::perimeter(void) {
+ return 2*M_PI*radius;
+}
+
+double Square::area(void) {
+ return width*width;
+}
+
+double Square::perimeter(void) {
+ return 4*width;
+}
+
+Circle* createCircle(double w)
+{
+ return new Circle(w);
+}
+
+Square* createSquare(double w)
+{
+ return new Square(w);
+}
+
+ShapeOwner::ShapeOwner() {printf(" ShapeOwner(%p)\n",this);}
+ShapeOwner::~ShapeOwner()
+{
+ printf(" ~ShapeOwner(%p)\n",this);
+ for(unsigned i=0;i<shapes.size();i++)
+ delete shapes[i];
+}
+
+void ShapeOwner::add(Shape* ptr) // this method takes ownership of the object
+{
+ shapes.push_back(ptr);
+}
+
+Shape* ShapeOwner::get(int idx) // this pointer is still owned by the class (assessor)
+{
+ if (idx < 0 || idx >= static_cast<int>(shapes.size()))
+ return NULL;
+ return shapes[idx];
+}
+
+Shape* ShapeOwner::remove(int idx) // this method returns memory which must be deleted
+{
+ if (idx < 0 || idx >= static_cast<int>(shapes.size()))
+ return NULL;
+ Shape* ptr=shapes[idx];
+ shapes.erase(shapes.begin()+idx);
+ return ptr;
+}
diff --git a/Examples/lua/owner/example.h b/Examples/lua/owner/example.h new file mode 100644 index 0000000..b005680 --- /dev/null +++ b/Examples/lua/owner/example.h @@ -0,0 +1,54 @@ +/* File : example.h */
+#include <vector>
+
+class Shape {
+public:
+ Shape() {
+ nshapes++;
+ }
+ virtual ~Shape() {
+ nshapes--;
+ };
+ double x, y;
+ void move(double dx, double dy);
+ virtual double area(void) = 0;
+ virtual double perimeter(void) = 0;
+ static int nshapes;
+};
+
+class Circle : public Shape {
+private:
+ double radius;
+public:
+ Circle(double r) : radius(r) { };
+ virtual double area(void);
+ virtual double perimeter(void);
+};
+
+class Square : public Shape {
+private:
+ double width;
+public:
+ Square(double w) : width(w) { };
+ virtual double area(void);
+ virtual double perimeter(void);
+};
+
+
+Circle* createCircle(double w); // this method creates a new object
+Square* createSquare(double w); // this method creates a new object
+
+class ShapeOwner {
+private:
+ std::vector<Shape*> shapes;
+ ShapeOwner(const ShapeOwner&); // no copying
+ ShapeOwner& operator=(const ShapeOwner&); // no copying
+public:
+ ShapeOwner();
+ ~ShapeOwner();
+ void add(Shape* ptr); // this method takes ownership of the object
+ Shape* get(int idx); // this pointer is still owned by the class (assessor)
+ Shape* remove(int idx); // this method returns memory which must be deleted
+};
+
+
diff --git a/Examples/lua/owner/example.i b/Examples/lua/owner/example.i new file mode 100644 index 0000000..4e7c331 --- /dev/null +++ b/Examples/lua/owner/example.i @@ -0,0 +1,32 @@ +/* File : example.i */
+%module example
+
+%{
+#include "example.h"
+%}
+
+// before we grab the header file, we must warn SWIG about some of these functions.
+
+// these functions create data, so must be managed
+%newobject createCircle;
+%newobject createSquare;
+
+// this method returns as pointer which must be managed
+%newobject ShapeOwner::remove;
+
+// you cannot use %delobject on ShapeOwner::add()
+// as this disowns the ShapeOwner, not the Shape (oops)
+//%delobject ShapeOwner::add(Shape*); DO NOT USE
+
+// either you can use a new function (such as this)
+/*%delobject add_Shape;
+%inline %{
+void add_Shape(Shape* s,ShapeOwner* own){own->add(s);}
+%}*/
+
+// or a better solution is a typemap
+%apply SWIGTYPE *DISOWN {Shape* ptr};
+
+// now we can grab the header file
+%include "example.h"
+
diff --git a/Examples/lua/owner/runme.lua b/Examples/lua/owner/runme.lua new file mode 100644 index 0000000..d2d8a9c --- /dev/null +++ b/Examples/lua/owner/runme.lua @@ -0,0 +1,104 @@ +-- Operator overloading example
+---- importing ----
+if string.sub(_VERSION,1,7)=='Lua 5.0' then
+ -- lua5.0 doesnt have a nice way to do this
+ lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example')
+ assert(lib)()
+else
+ -- lua 5.1 does
+ require('example')
+end
+
+print "ok, lets test Lua's ownership of C++ objects"
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
+
+print "\nLets make a couple"
+a=example.Square(10)
+b=example.Circle(1)
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 2)")
+
+print "\nNote lets use the createX functions"
+c=example.createCircle(5)
+d=example.createSquare(3)
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
+
+print "\nWe will run the garbage collector & see if they are till here"
+collectgarbage()
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 4)")
+
+print "\nLets get rid of them all, collect garbage & see if they are till here"
+a,b,c,d=nil,nil,nil,nil
+collectgarbage()
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
+
+print "\nLets start putting stuff into the ShapeOwner"
+print "The ShapeOwner now owns the shapes, but Lua still has pointers to them"
+o=example.ShapeOwner()
+a=example.Square(10)
+b=example.Circle(1)
+o:add(a)
+o:add(b)
+o:add(example.createSquare(5))
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
+
+print "\nWe will nil our references,run the garbage collector & see if they are till here"
+print "they should be, as the ShapeOwner owns them"
+a,b=nil,nil
+collectgarbage()
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
+
+print "\nWe will access them and check that they are still valid"
+a=o:get(0)
+b=o:get(1)
+print(" Area's are",a:area(),b:area(),o:get(2):area())
+collectgarbage()
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
+
+print "\nWe will remove one from the C++ owner & pass its ownership to Lua,"
+print " then check that they are still unchanged"
+a,b=nil,nil
+a=o:remove(0) -- a now owns it
+collectgarbage()
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 3)")
+
+print "\nDelete the ShapeOwner (this should destroy two shapes),"
+print " but we have one left in Lua"
+o=nil
+collectgarbage()
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 1)")
+
+print "\nFinal tidy up "
+a=nil
+collectgarbage()
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
+
+
+print "Final test, we will create some Shapes & pass them around like mad"
+print "If there is any memory leak, you will see it in the memory usage"
+io.flush()
+sh={}
+-- make some objects
+for i=0,10 do
+ a=example.Circle(i)
+ b=example.Square(i)
+ sh[a]=true
+ sh[b]=true
+end
+o=example.ShapeOwner()
+for i=0,10000 do
+ for k,_ in pairs(sh) do
+ o:add(k)
+ end
+ sh={} -- clear it
+ while true do
+ a=o:remove(0)
+ if a==nil then break end
+ sh[a]=true
+ end
+ if i%100==0 then collectgarbage() end
+end
+print "done"
+o,sh=nil,nil
+collectgarbage()
+print("Currently there are",example.Shape_nshapes,"shapes (there should be 0)")
+print "thats all folks!"
\ No newline at end of file diff --git a/Examples/lua/pointer/Makefile b/Examples/lua/pointer/Makefile new file mode 100644 index 0000000..ac0fff4 --- /dev/null +++ b/Examples/lua/pointer/Makefile @@ -0,0 +1,19 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i +LIBS = + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all diff --git a/Examples/lua/pointer/example.c b/Examples/lua/pointer/example.c new file mode 100644 index 0000000..b877d9a --- /dev/null +++ b/Examples/lua/pointer/example.c @@ -0,0 +1,16 @@ +/* File : example.c */ + +void add(int *x, int *y, int *result) { + *result = *x + *y; +} + +void sub(int *x, int *y, int *result) { + *result = *x - *y; +} + +int divide(int n, int d, int *r) { + int q; + q = n/d; + *r = n - q*d; + return q; +} diff --git a/Examples/lua/pointer/example.i b/Examples/lua/pointer/example.i new file mode 100644 index 0000000..d49365b --- /dev/null +++ b/Examples/lua/pointer/example.i @@ -0,0 +1,35 @@ +/* File : example.i */ +%module example + +%{ + #include <stdlib.h> +%} + +/* This example illustrates a couple of different techniques + for manipulating C pointers */ + +/* First we'll use the pointer library */ +%inline %{ +extern void add(int *x, int *y, int *result); +%} +%include cpointer.i +%pointer_functions(int, intp); + +/* Next we'll use some typemaps */ + +%include typemaps.i +extern void sub(int *INPUT, int *INPUT, int *OUTPUT); +%{ +extern void sub(int *, int *, int *); +%} + +/* Next we'll use typemaps and the %apply directive */ + +%apply int *OUTPUT { int *r }; +%inline %{ +extern int divide(int n, int d, int *r); +%} + + + + diff --git a/Examples/lua/pointer/runme.lua b/Examples/lua/pointer/runme.lua new file mode 100644 index 0000000..8deee67 --- /dev/null +++ b/Examples/lua/pointer/runme.lua @@ -0,0 +1,48 @@ +---- importing ---- +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example') + assert(lib)() +else + -- lua 5.1 does + require('example') +end + +-- First create some objects using the pointer library. +print("Testing the pointer library") +a = example.new_intp() +b = example.new_intp() +c = example.new_intp() +example.intp_assign(a,37) +example.intp_assign(b,42) + +print(" a = "..tostring(a)) +print(" b = "..tostring(b)) +print(" c = "..tostring(c)) + +-- Call the add() function with some pointers +example.add(a,b,c) + +-- Now get the result +r = example.intp_value(c) +print(" 37 + 42 = "..r) + +-- Clean up the pointers +-- since this is C-style pointers you must clean it up +example.delete_intp(a) +example.delete_intp(b) +example.delete_intp(c) + +-- Now try the typemap library +-- This should be much easier. Now how it is no longer +-- necessary to manufacture pointers. + +print("Trying the typemap library") +r = example.sub(37,42) +print(" 37 - 42 = "..r) + +-- Now try the version with multiple return values + +print("Testing multiple return values") +q,r = example.divide(42,37) +print(" 42/37 = "..q.." remainder "..r) diff --git a/Examples/lua/simple/Makefile b/Examples/lua/simple/Makefile new file mode 100644 index 0000000..f181818 --- /dev/null +++ b/Examples/lua/simple/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all diff --git a/Examples/lua/simple/example.c b/Examples/lua/simple/example.c new file mode 100644 index 0000000..1c2af78 --- /dev/null +++ b/Examples/lua/simple/example.c @@ -0,0 +1,18 @@ +/* File : example.c */ + +/* A global variable */ +double Foo = 3.0; + +/* Compute the greatest common divisor of positive integers */ +int gcd(int x, int y) { + int g; + g = y; + while (x > 0) { + g = x; + x = y % x; + y = g; + } + return g; +} + + diff --git a/Examples/lua/simple/example.i b/Examples/lua/simple/example.i new file mode 100644 index 0000000..86ae9f3 --- /dev/null +++ b/Examples/lua/simple/example.i @@ -0,0 +1,7 @@ +/* File : example.i */ +%module example + +%inline %{ +extern int gcd(int x, int y); +extern double Foo; +%}
\ No newline at end of file diff --git a/Examples/lua/simple/runme.lua b/Examples/lua/simple/runme.lua new file mode 100644 index 0000000..1e5a139 --- /dev/null +++ b/Examples/lua/simple/runme.lua @@ -0,0 +1,35 @@ +---- importing ---- +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example') + assert(lib)() +else + -- lua 5.1 does + require('example') +end + +-- Call our gcd() function +x = 42 +y = 105 +g = example.gcd(x,y) +print("The gcd of",x,"and",y,"is",g) + +-- Manipulate the Foo global variable + +-- Output its current value +print("Foo = ", example.Foo) + +-- Change its value +example.Foo = 3.1415926 + +-- See if the change took effect +print("Foo = ", example.Foo) + + + + + + + + + diff --git a/Examples/lua/variables/Makefile b/Examples/lua/variables/Makefile new file mode 100644 index 0000000..f181818 --- /dev/null +++ b/Examples/lua/variables/Makefile @@ -0,0 +1,18 @@ +TOP = ../.. +SWIG = $(TOP)/../preinst-swig +SRCS = example.c +TARGET = example +INTERFACE = example.i + +all:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' lua + +static:: + $(MAKE) -f $(TOP)/Makefile SRCS='$(SRCS)' SWIG='$(SWIG)' \ + TARGET='mylua' INTERFACE='$(INTERFACE)' lua_static + +clean:: + $(MAKE) -f $(TOP)/Makefile lua_clean + +check: all diff --git a/Examples/lua/variables/example.c b/Examples/lua/variables/example.c new file mode 100644 index 0000000..aa4ffe9 --- /dev/null +++ b/Examples/lua/variables/example.c @@ -0,0 +1,91 @@ +/* File : example.c */ + +/* I'm a file containing some C global variables */ + +/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ +#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +# define _CRT_SECURE_NO_DEPRECATE +#endif + +#include <stdio.h> +#include <stdlib.h> +#include "example.h" + +int ivar = 0; +short svar = 0; +long lvar = 0; +unsigned int uivar = 0; +unsigned short usvar = 0; +unsigned long ulvar = 0; +signed char scvar = 0; +unsigned char ucvar = 0; +char cvar = 0; +float fvar = 0; +double dvar = 0; +char *strvar = 0; +const char cstrvar[] = "Goodbye"; +int *iptrvar = 0; +char name[256] = "Dave"; +char path[256] = "/home/beazley"; + + +/* Global variables involving a structure */ +Point *ptptr = 0; +Point pt = { 10, 20 }; + +/* A variable that we will make read-only in the interface */ +int status = 1; + +/* A debugging function to print out their values */ + +void print_vars() { + printf("ivar = %d\n", ivar); + printf("svar = %d\n", svar); + printf("lvar = %ld\n", lvar); + printf("uivar = %u\n", uivar); + printf("usvar = %u\n", usvar); + printf("ulvar = %lu\n", ulvar); + printf("scvar = %d\n", scvar); + printf("ucvar = %u\n", ucvar); + printf("fvar = %g\n", fvar); + printf("dvar = %g\n", dvar); + printf("cvar = %c\n", cvar); + printf("strvar = %s\n", strvar ? strvar : "(null)"); + printf("cstrvar = %s\n", cstrvar ? cstrvar : "(null)"); + printf("iptrvar = %p\n", iptrvar); + printf("name = %s\n", name); + printf("ptptr = %p (%d, %d)\n", ptptr, ptptr ? ptptr->x : 0, ptptr ? ptptr->y : 0); + printf("pt = (%d, %d)\n", pt.x, pt.y); + printf("status = %d\n", status); +} + +/* A function to create an integer (to test iptrvar) */ + +int *new_int(int value) { + int *ip = (int *) malloc(sizeof(int)); + *ip = value; + return ip; +} + +/* A function to create a point */ + +Point *new_Point(int x, int y) { + Point *p = (Point *) malloc(sizeof(Point)); + p->x = x; + p->y = y; + return p; +} + +char * Point_print(Point *p) { + static char buffer[256]; + if (p) { + sprintf(buffer,"(%d,%d)", p->x,p->y); + } else { + sprintf(buffer,"null"); + } + return buffer; +} + +void pt_print() { + printf("(%d, %d)\n", pt.x, pt.y); +} diff --git a/Examples/lua/variables/example.h b/Examples/lua/variables/example.h new file mode 100644 index 0000000..0f7e895 --- /dev/null +++ b/Examples/lua/variables/example.h @@ -0,0 +1,6 @@ +/* File: example.h */ + +typedef struct { + int x,y; +} Point; + diff --git a/Examples/lua/variables/example.i b/Examples/lua/variables/example.i new file mode 100644 index 0000000..591b871 --- /dev/null +++ b/Examples/lua/variables/example.i @@ -0,0 +1,49 @@ +/* File : example.i */ +%module example +%{ +#include "example.h" +%} + +/* Some global variable declarations */ +%inline %{ +extern int ivar; +extern short svar; +extern long lvar; +extern unsigned int uivar; +extern unsigned short usvar; +extern unsigned long ulvar; +extern signed char scvar; +extern unsigned char ucvar; +extern char cvar; +extern float fvar; +extern double dvar; +extern char *strvar; +extern const char cstrvar[]; +extern int *iptrvar; +extern char name[256]; + +extern Point *ptptr; +extern Point pt; +%} + + +/* Some read-only variables */ + +%immutable; + +%inline %{ +extern int status; +extern char path[256]; +%} + +%mutable; + +/* Some helper functions to make it easier to test */ +%inline %{ +extern void print_vars(); +extern int *new_int(int value); +extern Point *new_Point(int x, int y); +extern char *Point_print(Point *p); +extern void pt_print(); +%} + diff --git a/Examples/lua/variables/runme.lua b/Examples/lua/variables/runme.lua new file mode 100644 index 0000000..05b2d3f --- /dev/null +++ b/Examples/lua/variables/runme.lua @@ -0,0 +1,81 @@ +---- importing ---- +if string.sub(_VERSION,1,7)=='Lua 5.0' then + -- lua5.0 doesnt have a nice way to do this + lib=loadlib('example.dll','luaopen_example') or loadlib('example.so','luaopen_example') + assert(lib)() +else + -- lua 5.1 does + require('example') +end + +-- Try to set the values of some global variables + +example.ivar = 42 +example.svar = -31000 +example.lvar = 65537 +example.uivar = 123456 +example.usvar = 61000 +example.ulvar = 654321 +example.scvar = -13 +example.ucvar = 251 +example.cvar = "S" +example.fvar = 3.14159 +example.dvar = 2.1828 +example.strvar = "Hello World" +example.iptrvar= example.new_int(37) +example.ptptr = example.new_Point(37,42) +example.name = "Bill" + +-- Now print out the values of the variables + +print("Variables (values printed from Lua)") + +print("ivar =", example.ivar) +print("svar =", example.svar) +print("lvar =", example.lvar) +print("uivar =", example.uivar) +print("usvar =", example.usvar) +print("ulvar =", example.ulvar) +print("scvar =", example.scvar) +print("ucvar =", example.ucvar) +print("fvar =", example.fvar) +print("dvar =", example.dvar) +print("cvar =", example.cvar) +print("strvar =", example.strvar) +print("cstrvar =", example.cstrvar) +print("iptrvar =", example.iptrvar) +print("name =", example.name) +print("ptptr =", example.ptptr, example.Point_print(example.ptptr)) +print("pt =", example.pt, example.Point_print(example.pt)) + +print("\nVariables (values printed from C)") + +example.print_vars() + +print "\nNow I'm going to try and modify some read only variables"; + +print " Tring to set 'path' to 'Whoa!'"; +if pcall(function() example.path = "Whoa!" end)==true then + print " Thats funny, it didn't give an error!" +else + print " It gave an error, as it should" +end +print(" Just checking the value: path =", example.path) + +print " Trying to set 'status' to '0'"; +if pcall(function() example.status = 0 end)==true then + print " Thats funny, it didn't give an error!" +else + print " It gave an error, as it should" +end +print(" Just checking the value: status =", example.status) + + +print "\nI'm going to try and update a structure variable.\n" + +example.pt = example.ptptr + +print "The new value is" +example.pt_print() +print("You should see the value", example.Point_print(example.ptptr)) + |