This commit is contained in:
FluorescentCIAAfricanAmerican
2020-04-22 12:56:21 -04:00
commit 3bf9df6b27
15370 changed files with 5489726 additions and 0 deletions
@@ -0,0 +1,96 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* _std_common.i
*
* std::helpers for LUA
* ----------------------------------------------------------------------------- */
%include <std_except.i> // the general exepctions
/*
The basic idea here, is instead of trying to feed SWIG all the
horribly templated STL code, to give it a neatened version.
These %defines cover some of the more common methods
so the class declarations become just a set of %defines
*/
/* #define for basic container features
note: I allow front(), back() & pop_back() to throw execptions
upon empty containers, rather than coredump
(as we have'nt defined the methods, we can use %extend to add with
new features)
*/
%define %STD_CONTAINER_METHODS(CLASS,T)
public:
CLASS();
CLASS(const CLASS&);
unsigned int size() const;
unsigned int max_size() const;
bool empty() const;
void clear();
%extend { // the extra stuff which must be checked
T front()const throw (std::out_of_range){ // only read front & back
if (self->empty())
throw std::out_of_range("in "#CLASS"::front()");
return self->front();
}
T back()const throw (std::out_of_range){ // not write to them
if (self->empty())
throw std::out_of_range("in "#CLASS"::back()");
return self->back();
}
}
%enddef
/* push/pop for front/back
also note: front & back are read only methods, not used for writing
*/
%define %STD_FRONT_ACCESS_METHODS(CLASS,T)
public:
void push_front(const T& val);
%extend { // must check this
void pop_front() throw (std::out_of_range){
if (self->empty())
throw std::out_of_range("in "#CLASS"::pop_front()");
self->pop_back();
}
}
%enddef
%define %STD_BACK_ACCESS_METHODS(CLASS,T)
public:
void push_back(const T& val);
%extend { // must check this
void pop_back() throw (std::out_of_range){
if (self->empty())
throw std::out_of_range("in "#CLASS"::pop_back()");
self->pop_back();
}
}
%enddef
/*
Random access methods
*/
%define %STD_RANDOM_ACCESS_METHODS(CLASS,T)
%extend // this is a extra bit of SWIG code
{
// [] is replaced by __getitem__ & __setitem__
// simply throws a string, which causes a lua error
T __getitem__(unsigned int idx) throw (std::out_of_range){
if (idx>=self->size())
throw std::out_of_range("in "#CLASS"::__getitem__()");
return (*self)[idx];
}
void __setitem__(unsigned int idx,const T& val) throw (std::out_of_range){
if (idx>=self->size())
throw std::out_of_range("in "#CLASS"::__setitem__()");
(*self)[idx]=val;
}
};
%enddef
@@ -0,0 +1,8 @@
/* Small change to the standard carrays.i
renaming the field to __getitem__ & __setitem__
for operator[] access
*/
%rename(__getitem) *::getitem; // the v=X[i] (get operator)
%rename(__setitem) *::setitem; // the X[i]=v (set operator)
%include <../carrays.i>
+207
View File
@@ -0,0 +1,207 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* lua.swg
*
* SWIG Configuration File for Lua.
* This file is parsed by SWIG before reading any other interface file.
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* includes
* ----------------------------------------------------------------------------- */
%include <luatypemaps.swg> /* The typemaps */
%include <luaruntime.swg> /* The runtime stuff */
/* -----------------------------------------------------------------------------
* constants typemaps
* ----------------------------------------------------------------------------- */
// this basically adds to a table of constants
%typemap(consttab) int, unsigned int, short, unsigned short, long, unsigned long, unsigned char, signed char, bool, enum SWIGTYPE
{ SWIG_LUA_INT, (char *)"$symname", (long) $value, 0, 0, 0}
%typemap(consttab) float, double
{ SWIG_LUA_FLOAT, (char *)"$symname", 0, (double) $value, 0, 0}
%typemap(consttab) long long, unsigned long long, signed long long
{ SWIG_LUA_FLOAT, (char *)"$symname", 0, (double) $value, 0, 0}
%typemap(consttab) const long long&, const unsigned long long&, const signed long long&
{ SWIG_LUA_FLOAT, (char *)"$symname", 0, (double) *$value, 0, 0}
%typemap(consttab) char *, const char *, char [], const char []
{ SWIG_LUA_STRING, (char *)"$symname", 0, 0, (void *)$value, 0}
// note: char is treated as a seperate special type
// signed char & unsigned char are numbers
%typemap(consttab) char
{ SWIG_LUA_CHAR, (char *)"$symname", (long)$value, 0, 0, 0}
%typemap(consttab) long long, unsigned long long
{ SWIG_LUA_STRING, (char *) "$symname", 0, 0, (void *)"$value", 0}
%typemap(consttab) SWIGTYPE *, SWIGTYPE &, SWIGTYPE []
{ SWIG_LUA_POINTER, (char *)"$symname", 0, 0, (void *)$value, &$1_descriptor}
// member function pointers
%typemap(consttab) SWIGTYPE (CLASS::*)
{ SWIG_LUA_BINARY, (char *)"$symname", sizeof($type), 0, (void *)&$value, &$1_descriptor}
/* -----------------------------------------------------------------------------
* Overloaded operator support
* ----------------------------------------------------------------------------- */
// lua calls the + operator '__add'
// python likes to call it '__add__'
// Assuming most SWIGers will probably use the __add__ if they extend their classes
// we have two sets of renames
// one to rename the operator+() to __add()
// (this lets SWIG rename the operator overloads)
// another is to rename __add__() to __add()
// (this means that people who wrote SWIG code to do that add will also work)
#ifdef __cplusplus
// this is extra renaming for lua
// not all operators are supported, so only those that are, are listed
%rename(__add) *::operator+;
%rename(__sub) *::operator-;
%rename(__mul) *::operator*;
%rename(__div) *::operator/;
%rename(__unm) *::operator-();
%rename(__unm) *::operator-() const;
%rename(__eq) *::operator==;
%ignore *::operator!=; // note: Lua does not have a notequal operator
// it just uses 'not (a==b)'
%rename(__lt) *::operator<;
%ignore *::operator>; // ditto less than vs greater than
%rename(__le) *::operator<=;
%ignore *::operator>=; // ditto less than vs greater than
%ignore *::operator!; // does not support not
%rename(__call) *::operator(); // the fn call operator
// lua does not support overloading of:
// logical/bitwise operators
// assign operator
// +=,-=,*=, etc
// therefore ignoring them for now
// it also doesn't support non class operators
// eg friends or XX operator+(XX,XX)
// also ignoring
// note: some of these might be better to rename, but not doing that for now
%ignore *::operator&&; %ignore operator&&;
%ignore *::operator||; %ignore operator||;
%ignore *::operator+=;
%ignore *::operator-=;
%ignore *::operator*=;
%ignore *::operator/=;
%ignore *::operator%=;
%ignore *::operator++; %ignore *::operator--;
%ignore *::operator=; // note: this might be better to rename to assign() or similar
%ignore operator+;
%ignore operator-;
%ignore operator*;
%ignore operator/;
%ignore operator%;
%ignore operator[];
%ignore operator>; %ignore operator>=;
%ignore operator<; %ignore operator<=;
%ignore operator==; %ignore operator!=;
// renaming the python operators to be compatible with lua
// this means that if a developer has written a fn __add__()
// it will be used for the lua +
%rename(__add) *::__add__;
%rename(__sub) *::__sub__;
%rename(__mul) *::__mul__;
%rename(__div) *::__div__;
%rename(__unm) *::__neg__; // lua calls unary minus,'unm' not 'neg'
%rename(__tostring) *::__str__; // both map to __tostring
%rename(__tostring) *::__repr__; // both map to __tostring
%rename(__pow) *::__pow__; // lua power '^' operator
%rename(__concat) *::__concat__; // lua concat '..' operator
%rename(__eq) *::__eq__;
%rename(__lt) *::__lt__;
%rename(__le) *::__le__;
%rename(__call) *::__call__; // the fn call operator()
// the [] operator has two parts, the get & the set
%rename(__getitem) *::__getitem__; // the v=X[i] (get operator)
%rename(__setitem) *::__setitem__; // the X[i]=v (set operator)
#endif
/* ------------------------------------------------------------
* Exceptions
* ------------------------------------------------------------ */
/* Confession: I dont really like C++ exceptions
The python/lua ones are great, but C++ ones I dont like
(mainly because I cannot get the stack trace out of it)
Therefore I have not bothered to try doing much in this
Therefore currently its just enough to get a few test cases running ok
note: if you wish to throw anything related to std::exception
use %include <std_except.i> instead
*/
%typemap(throws) int,unsigned int,signed int,
long,unsigned long,signed long,
short,unsigned short,signed short,
bool,float,double,
long long,unsigned long long,
char, unsigned char, signed char,
enum SWIGTYPE
%{lua_pushfstring(L,"numeric exception:%f",(double)$1);SWIG_fail; %}
// strings are just sent as errors
%typemap(throws) char*, const char*
%{lua_pushstring(L,$1);SWIG_fail;%}
/*
Throwing object is a serious problem:
Assuming some code throws a 'FooBar'
There are a few options:
- return a pointer to it: but its unclear how long this will last for.
- return a copy of it: but not all objects are copyable
(see exception_partial_info in the test suite for a case where you cannot)
- convert to a string & throw that
its not so useful, but it works (this is more lua like).
The third option (though not nice) is used
For a more useful solution: see std_except for more details
*/
%typemap(throws) SWIGTYPE
{
(void)$1;
lua_pushfstring(L,"object exception:%s",SWIG_TypePrettyName($1_descriptor));
SWIG_fail;
}
// old code: fails under exception_partial_info
// if you have a function which throws a FooBar & you want SWIG to throw the actual object
// then use
// %apply SWIGTYPE BY_VAL {FooBar};
%typemap(throws) SWIGTYPE BY_VAL
{
SWIG_NewPointerObj(L,(void *)new $1_ltype(($1_ltype &) $1),$&1_descriptor,1);
SWIG_fail;
}
/* -----------------------------------------------------------------------------
* extras
* ----------------------------------------------------------------------------- */
/* ------------------------------ end lua.swg ------------------------------ */
+128
View File
@@ -0,0 +1,128 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* lua_fnptr.i
*
* SWIG Library file containing the main typemap code to support Lua modules.
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* Basic function pointer support
* ----------------------------------------------------------------------------- */
/*
The structure: SWIGLUA_FN provides a simple (local only) wrappering for a function.
For example if you wanted to have a C/C++ function take a lua function as a parameter.
You could declare it as:
int my_func(int a, int b, SWIGLUA_FN fn);
note: it should be passed by value, not byref or as a pointer.
The SWIGLUA_FN holds a pointer to the lua_State, and the stack index where the function is held.
The macro SWIGLUA_FN_GET() will put a copy of the lua function at the top of the stack.
After that its fairly simple to write the rest of the code (assuming know how to use lua),
just push the parameters, call the function and return the result.
int my_func(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 luaL_checknumber(fn.L,-1);
}
SWIG will automatically performs the wrappering of the arguments in and out.
However: if you wish to store the function between calls, look to the SWIGLUA_REF below.
*/
// this is for the C code only, we don't want SWIG to wrapper it for us.
%{
typedef struct{
lua_State* L; /* the state */
int idx; /* the index on the stack */
}SWIGLUA_FN;
#define SWIGLUA_FN_GET(fn) {lua_pushvalue(fn.L,fn.idx);}
%}
// the actual typemap
%typemap(in,checkfn="lua_isfunction") SWIGLUA_FN
%{ $1.L=L; $1.idx=$input; %}
/* -----------------------------------------------------------------------------
* Storing lua object support
* ----------------------------------------------------------------------------- */
/*
The structure: SWIGLUA_REF provides a mechanism to store object (usually functions)
between calls to the interpreter.
For example if you wanted to have a C/C++ function take a lua function as a parameter.
Then call it later, You could declare it as:
SWIGLUA_REF myref;
void set_func(SWIGLUA_REF ref);
SWIGLUA_REF get_func();
void call_func(int val);
note: it should be passed by value, not byref or as a pointer.
The SWIGLUA_REF holds a pointer to the lua_State, and an integer reference to the object.
Because it holds a permenet ref to an object, the SWIGLUA_REF must be handled with a bit more care.
It should be initalised to {0,0}. The function swiglua_ref_set() should be used to set it.
swiglua_ref_clear() should be used to clear it when not in use, and swiglua_ref_get() to get the
data back.
Note: the typemap does not check that the object is in fact a function,
if you need that you must add it yourself.
int my_func(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 luaL_checknumber(fn.L,-1);
}
SWIG will automatically performs the wrappering of the arguments in and out.
However: if you wish to store the function between calls, look to the SWIGLUA_REF below.
*/
%{
typedef struct{
lua_State* L; /* the state */
int ref; /* a ref in the lua global index */
}SWIGLUA_REF;
void swiglua_ref_clear(SWIGLUA_REF* pref){
if (pref->L!=0 && pref->ref!=LUA_NOREF && pref->ref!=LUA_REFNIL){
luaL_unref(pref->L,LUA_REGISTRYINDEX,pref->ref);
}
pref->L=0; pref->ref=0;
}
void swiglua_ref_set(SWIGLUA_REF* pref,lua_State* L,int idx){
// swiglua_ref_clear(pref); /* just in case */
pref->L=L;
lua_pushvalue(L,idx); /* copy obj to top */
pref->ref=luaL_ref(L,LUA_REGISTRYINDEX); /* remove obj from top & put into registry */
}
void swiglua_ref_get(SWIGLUA_REF* pref){
if (pref->L!=0)
lua_rawgeti(pref->L,LUA_REGISTRYINDEX,pref->ref);
}
%}
%typemap(in) SWIGLUA_REF
%{ swiglua_ref_set(&$1,L,$input); %}
%typemap(out) SWIGLUA_REF
%{ if ($1.L!=0) {swiglua_ref_get(&$1);} else {lua_pushnil(L);}
SWIG_arg++; %}
+754
View File
@@ -0,0 +1,754 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* luarun.swg
*
* This file contains the runtime support for Lua modules
* and includes code for managing global variables and pointer
* type checking.
* ----------------------------------------------------------------------------- */
#ifdef __cplusplus
extern "C" {
#endif
#include "lua.h"
#include "lauxlib.h"
#include <stdlib.h> /* for malloc */
#include <assert.h> /* for a few sanity tests */
/* -----------------------------------------------------------------------------
* global swig types
* ----------------------------------------------------------------------------- */
/* Constant table */
#define SWIG_LUA_INT 1
#define SWIG_LUA_FLOAT 2
#define SWIG_LUA_STRING 3
#define SWIG_LUA_POINTER 4
#define SWIG_LUA_BINARY 5
#define SWIG_LUA_CHAR 6
/* Structure for variable linking table */
typedef struct {
const char *name;
lua_CFunction get;
lua_CFunction set;
} swig_lua_var_info;
/* Constant information structure */
typedef struct {
int type;
char *name;
long lvalue;
double dvalue;
void *pvalue;
swig_type_info **ptype;
} swig_lua_const_info;
typedef struct {
const char *name;
lua_CFunction method;
} swig_lua_method;
typedef struct {
const char *name;
lua_CFunction getmethod;
lua_CFunction setmethod;
} swig_lua_attribute;
typedef struct swig_lua_class {
const char *name;
swig_type_info **type;
lua_CFunction constructor;
void (*destructor)(void *);
swig_lua_method *methods;
swig_lua_attribute *attributes;
struct swig_lua_class **bases;
const char **base_names;
} swig_lua_class;
/* this is the struct for wrappering all pointers in SwigLua
*/
typedef struct {
swig_type_info *type;
int own; /* 1 if owned & must be destroyed */
void *ptr;
} swig_lua_userdata;
/* this is the struct for wrapping arbitary packed binary data
(currently it is only used for member function pointers)
the data ordering is similar to swig_lua_userdata, but it is currently not possible
to tell the two structures apart within Swig, other than by looking at the type
*/
typedef struct {
swig_type_info *type;
int own; /* 1 if owned & must be destroyed */
char data[1]; /* arbitary amount of data */
} swig_lua_rawdata;
/* Common SWIG API */
#define SWIG_NewPointerObj(L, ptr, type, owner) SWIG_Lua_NewPointerObj(L, (void *)ptr, type, owner)
#define SWIG_ConvertPtr(L,idx, ptr, type, flags) SWIG_Lua_ConvertPtr(L,idx,ptr,type,flags)
#define SWIG_MustGetPtr(L,idx, type,flags, argnum,fnname) SWIG_Lua_MustGetPtr(L,idx, type,flags, argnum,fnname)
/* for C++ member pointers, ie, member methods */
#define SWIG_ConvertMember(L, idx, ptr, sz, ty) SWIG_Lua_ConvertPacked(L, idx, ptr, sz, ty)
#define SWIG_NewMemberObj(L, ptr, sz, type) SWIG_Lua_NewPackedObj(L, ptr, sz, type)
/* Runtime API */
#define SWIG_GetModule(clientdata) SWIG_Lua_GetModule((lua_State*)(clientdata))
#define SWIG_SetModule(clientdata, pointer) SWIG_Lua_SetModule((lua_State*) (clientdata), pointer)
#define SWIG_MODULE_CLIENTDATA_TYPE lua_State*
/* Contract support */
#define SWIG_contract_assert(expr, msg) \
if (!(expr)) { lua_pushstring(L, (char *) msg); goto fail; } else
/* helper #defines */
#define SWIG_fail {goto fail;}
#define SWIG_fail_arg(func_name,argnum,type) \
{lua_pushfstring(L,"Error in %s (arg %d), expected '%s' got '%s'",\
func_name,argnum,type,SWIG_Lua_typename(L,argnum));\
goto fail;}
#define SWIG_fail_ptr(func_name,argnum,type) \
SWIG_fail_arg(func_name,argnum,(type && type->str)?type->str:"void*")
#define SWIG_check_num_args(func_name,a,b) \
if (lua_gettop(L)<a || lua_gettop(L)>b) \
{lua_pushfstring(L,"Error in %s expected %d..%d args, got %d",func_name,a,b,lua_gettop(L));\
goto fail;}
#define SWIG_Lua_get_table(L,n) \
(lua_pushstring(L, n), lua_rawget(L,-2))
#define SWIG_Lua_add_function(L,n,f) \
(lua_pushstring(L, n), \
lua_pushcfunction(L, f), \
lua_rawset(L,-3))
/* special helper for allowing 'nil' for usertypes */
#define SWIG_isptrtype(L,I) (lua_isuserdata(L,I) || lua_isnil(L,I))
#ifdef __cplusplus
/* Special helper for member function pointers
it gets the address, casts it, then dereferences it */
//#define SWIG_mem_fn_as_voidptr(a) (*((char**)&(a)))
#endif
/* storing/access of swig_module_info */
SWIGRUNTIME swig_module_info *
SWIG_Lua_GetModule(lua_State* L) {
swig_module_info *ret = 0;
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
lua_rawget(L,LUA_REGISTRYINDEX);
if (lua_islightuserdata(L,-1))
ret=(swig_module_info*)lua_touserdata(L,-1);
lua_pop(L,1); /* tidy */
return ret;
}
SWIGRUNTIME void
SWIG_Lua_SetModule(lua_State* L, swig_module_info *module) {
/* add this all into the Lua registry: */
lua_pushstring(L,"swig_runtime_data_type_pointer" SWIG_RUNTIME_VERSION SWIG_TYPE_TABLE_NAME);
lua_pushlightuserdata(L,(void*)module);
lua_rawset(L,LUA_REGISTRYINDEX);
}
/* -----------------------------------------------------------------------------
* global variable support code: modules
* ----------------------------------------------------------------------------- */
/* this function is called when trying to set an immutable.
default value is to print an error.
This can removed with a compile flag SWIGLUA_IGNORE_SET_IMMUTABLE */
SWIGINTERN int SWIG_Lua_set_immutable(lua_State* L)
{
/* there should be 1 param passed in: the new value */
#ifndef SWIGLUA_IGNORE_SET_IMMUTABLE
lua_pop(L,1); /* remove it */
lua_pushstring(L,"This variable is immutable");
lua_error(L);
#endif
return 0; /* should not return anything */
}
/* the module.get method used for getting linked data */
SWIGINTERN int SWIG_Lua_module_get(lua_State* L)
{
/* there should be 2 params passed in
(1) table (not the meta table)
(2) string name of the attribute
printf("SWIG_Lua_module_get %p(%s) '%s'\n",
lua_topointer(L,1),lua_typename(L,lua_type(L,1)),
lua_tostring(L,2));
*/
/* get the metatable */
assert(lua_istable(L,1)); /* just in case */
lua_getmetatable(L,1); /* get the metatable */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_get_table(L,".get"); /* get the .get table */
lua_remove(L,3); /* remove metatable */
if (lua_istable(L,-1))
{
/* look for the key in the .get table */
lua_pushvalue(L,2); /* key */
lua_rawget(L,-2);
lua_remove(L,3); /* remove .get */
if (lua_iscfunction(L,-1))
{ /* found it so call the fn & return its value */
lua_call(L,0,1);
return 1;
}
lua_pop(L,1); /* remove the top */
}
lua_pop(L,1); /* remove the .get */
lua_pushnil(L); /* return a nil */
return 1;
}
/* the module.set method used for setting linked data */
SWIGINTERN int SWIG_Lua_module_set(lua_State* L)
{
/* there should be 3 params passed in
(1) table (not the meta table)
(2) string name of the attribute
(3) any for the new value
*/
/* get the metatable */
assert(lua_istable(L,1)); /* just in case */
lua_getmetatable(L,1); /* get the metatable */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_get_table(L,".set"); /* get the .set table */
lua_remove(L,4); /* remove metatable */
if (lua_istable(L,-1))
{
/* look for the key in the .set table */
lua_pushvalue(L,2); /* key */
lua_rawget(L,-2);
lua_remove(L,4); /* remove .set */
if (lua_iscfunction(L,-1))
{ /* found it so call the fn & return its value */
lua_pushvalue(L,3); /* value */
lua_call(L,1,0);
return 0;
}
}
lua_settop(L,3); /* reset back to start */
/* we now have the table, key & new value, so just set directly */
lua_rawset(L,1); /* add direct */
return 0;
}
/* registering a module in lua */
SWIGINTERN void SWIG_Lua_module_begin(lua_State* L,const char* name)
{
assert(lua_istable(L,-1)); /* just in case */
lua_pushstring(L,name);
lua_newtable(L); /* the table */
/* add meta table */
lua_newtable(L); /* the meta table */
SWIG_Lua_add_function(L,"__index",SWIG_Lua_module_get);
SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_module_set);
lua_pushstring(L,".get");
lua_newtable(L); /* the .get table */
lua_rawset(L,-3); /* add .get into metatable */
lua_pushstring(L,".set");
lua_newtable(L); /* the .set table */
lua_rawset(L,-3); /* add .set into metatable */
lua_setmetatable(L,-2); /* sets meta table in module */
lua_rawset(L,-3); /* add module into parent */
SWIG_Lua_get_table(L,name); /* get the table back out */
}
/* ending the register */
SWIGINTERN void SWIG_Lua_module_end(lua_State* L)
{
lua_pop(L,1); /* tidy stack (remove module) */
}
/* adding a linked variable to the module */
SWIGINTERN void SWIG_Lua_module_add_variable(lua_State* L,const char* name,lua_CFunction getFn,lua_CFunction setFn)
{
assert(lua_istable(L,-1)); /* just in case */
lua_getmetatable(L,-1); /* get the metatable */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_get_table(L,".get"); /* find the .get table */
assert(lua_istable(L,-1)); /* should be a table: */
SWIG_Lua_add_function(L,name,getFn);
lua_pop(L,1); /* tidy stack (remove table) */
if (setFn) /* if there is a set fn */
{
SWIG_Lua_get_table(L,".set"); /* find the .set table */
assert(lua_istable(L,-1)); /* should be a table: */
SWIG_Lua_add_function(L,name,setFn);
lua_pop(L,1); /* tidy stack (remove table) */
}
lua_pop(L,1); /* tidy stack (remove meta) */
}
/* adding a function module */
SWIGINTERN void SWIG_Lua_module_add_function(lua_State* L,const char* name,lua_CFunction fn)
{
SWIG_Lua_add_function(L,name,fn);
}
/* -----------------------------------------------------------------------------
* global variable support code: classes
* ----------------------------------------------------------------------------- */
/* the class.get method, performs the lookup of class attributes */
SWIGINTERN int SWIG_Lua_class_get(lua_State* L)
{
/* there should be 2 params passed in
(1) userdata (not the meta table)
(2) string name of the attribute
*/
assert(lua_isuserdata(L,-2)); /* just in case */
lua_getmetatable(L,-2); /* get the meta table */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_get_table(L,".get"); /* find the .get table */
assert(lua_istable(L,-1)); /* just in case */
/* look for the key in the .get table */
lua_pushvalue(L,2); /* key */
lua_rawget(L,-2);
lua_remove(L,-2); /* stack tidy, remove .get table */
if (lua_iscfunction(L,-1))
{ /* found it so call the fn & return its value */
lua_pushvalue(L,1); /* the userdata */
lua_call(L,1,1); /* 1 value in (userdata),1 out (result) */
lua_remove(L,-2); /* stack tidy, remove metatable */
return 1;
}
lua_pop(L,1); /* remove whatever was there */
/* ok, so try the .fn table */
SWIG_Lua_get_table(L,".fn"); /* find the .get table */
assert(lua_istable(L,-1)); /* just in case */
lua_pushvalue(L,2); /* key */
lua_rawget(L,-2); /* look for the fn */
lua_remove(L,-2); /* stack tidy, remove .fn table */
if (lua_isfunction(L,-1)) /* note: if its a C function or lua function */
{ /* found it so return the fn & let lua call it */
lua_remove(L,-2); /* stack tidy, remove metatable */
return 1;
}
lua_pop(L,1); /* remove whatever was there */
/* NEW: looks for the __getitem() fn
this is a user provided get fn */
SWIG_Lua_get_table(L,"__getitem"); /* find the __getitem fn */
if (lua_iscfunction(L,-1)) /* if its there */
{ /* found it so call the fn & return its value */
lua_pushvalue(L,1); /* the userdata */
lua_pushvalue(L,2); /* the parameter */
lua_call(L,2,1); /* 2 value in (userdata),1 out (result) */
lua_remove(L,-2); /* stack tidy, remove metatable */
return 1;
}
return 0; /* sorry not known */
}
/* the class.set method, performs the lookup of class attributes */
SWIGINTERN int SWIG_Lua_class_set(lua_State* L)
{
/* there should be 3 params passed in
(1) table (not the meta table)
(2) string name of the attribute
(3) any for the new value
printf("SWIG_Lua_class_set %p(%s) '%s' %p(%s)\n",
lua_topointer(L,1),lua_typename(L,lua_type(L,1)),
lua_tostring(L,2),
lua_topointer(L,3),lua_typename(L,lua_type(L,3)));*/
assert(lua_isuserdata(L,1)); /* just in case */
lua_getmetatable(L,1); /* get the meta table */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_get_table(L,".set"); /* find the .set table */
if (lua_istable(L,-1))
{
/* look for the key in the .set table */
lua_pushvalue(L,2); /* key */
lua_rawget(L,-2);
if (lua_iscfunction(L,-1))
{ /* found it so call the fn & return its value */
lua_pushvalue(L,1); /* userdata */
lua_pushvalue(L,3); /* value */
lua_call(L,2,0);
return 0;
}
lua_pop(L,1); /* remove the value */
}
lua_pop(L,1); /* remove the value .set table */
/* NEW: looks for the __setitem() fn
this is a user provided set fn */
SWIG_Lua_get_table(L,"__setitem"); /* find the fn */
if (lua_iscfunction(L,-1)) /* if its there */
{ /* found it so call the fn & return its value */
lua_pushvalue(L,1); /* the userdata */
lua_pushvalue(L,2); /* the parameter */
lua_pushvalue(L,3); /* the value */
lua_call(L,3,0); /* 3 values in ,0 out */
lua_remove(L,-2); /* stack tidy, remove metatable */
return 1;
}
return 0;
}
/* the class.destruct method called by the interpreter */
SWIGINTERN int SWIG_Lua_class_destruct(lua_State* L)
{
/* there should be 1 params passed in
(1) userdata (not the meta table) */
swig_lua_userdata* usr;
swig_lua_class* clss;
assert(lua_isuserdata(L,-1)); /* just in case */
usr=(swig_lua_userdata*)lua_touserdata(L,-1); /* get it */
/* if must be destroyed & has a destructor */
if (usr->own) /* if must be destroyed */
{
clss=(swig_lua_class*)usr->type->clientdata; /* get the class */
if (clss && clss->destructor) /* there is a destroy fn */
{
clss->destructor(usr->ptr); /* bye bye */
}
}
return 0;
}
/* gets the swig class registry (or creates it) */
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State* L)
{
/* add this all into the swig registry: */
lua_pushstring(L,"SWIG");
lua_rawget(L,LUA_REGISTRYINDEX); /* get the registry */
if (!lua_istable(L,-1)) /* not there */
{ /* must be first time, so add it */
lua_pop(L,1); /* remove the result */
lua_pushstring(L,"SWIG");
lua_newtable(L);
lua_rawset(L,LUA_REGISTRYINDEX);
/* then get it */
lua_pushstring(L,"SWIG");
lua_rawget(L,LUA_REGISTRYINDEX);
}
}
/* helper fn to get the classes metatable from the register */
SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State* L,const char* cname)
{
SWIG_Lua_get_class_registry(L); /* get the registry */
lua_pushstring(L,cname); /* get the name */
lua_rawget(L,-2); /* get it */
lua_remove(L,-2); /* tidy up (remove registry) */
}
/* helper add a variable to a registered class */
SWIGINTERN void SWIG_Lua_add_class_variable(lua_State* L,const char* name,lua_CFunction getFn,lua_CFunction setFn)
{
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_get_table(L,".get"); /* find the .get table */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_add_function(L,name,getFn);
lua_pop(L,1); /* tidy stack (remove table) */
if (setFn)
{
SWIG_Lua_get_table(L,".set"); /* find the .set table */
assert(lua_istable(L,-1)); /* just in case */
SWIG_Lua_add_function(L,name,setFn);
lua_pop(L,1); /* tidy stack (remove table) */
}
}
/* helper to recursively add class details (attributes & operations) */
SWIGINTERN void SWIG_Lua_add_class_details(lua_State* L,swig_lua_class* clss)
{
int i;
/* call all the base classes first: we can then override these later: */
for(i=0;clss->bases[i];i++)
{
SWIG_Lua_add_class_details(L,clss->bases[i]);
}
/* add fns */
for(i=0;clss->attributes[i].name;i++){
SWIG_Lua_add_class_variable(L,clss->attributes[i].name,clss->attributes[i].getmethod,clss->attributes[i].setmethod);
}
/* add methods to the metatable */
SWIG_Lua_get_table(L,".fn"); /* find the .fn table */
assert(lua_istable(L,-1)); /* just in case */
for(i=0;clss->methods[i].name;i++){
SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].method);
}
lua_pop(L,1); /* tidy stack (remove table) */
/* add operator overloads
these look ANY method which start with "__" and assume they
are operator overloads & add them to the metatable
(this might mess up is someone defines a method __gc (the destructor)*/
for(i=0;clss->methods[i].name;i++){
if (clss->methods[i].name[0]=='_' && clss->methods[i].name[1]=='_'){
SWIG_Lua_add_function(L,clss->methods[i].name,clss->methods[i].method);
}
}
}
/* set up the base classes pointers.
Each class structure has a list of pointers to the base class structures.
This function fills them.
It cannot be done at compile time, as this will not work with hireachies
spread over more than one swig file.
Therefore it must be done at runtime, querying the SWIG type system.
*/
SWIGINTERN void SWIG_Lua_init_base_class(lua_State* L,swig_lua_class* clss)
{
int i=0;
swig_module_info* module=SWIG_GetModule(L);
for(i=0;clss->base_names[i];i++)
{
if (clss->bases[i]==0) /* not found yet */
{
/* lookup and cache the base class */
swig_type_info *info = SWIG_TypeQueryModule(module,module,clss->base_names[i]);
if (info) clss->bases[i] = (swig_lua_class *) info->clientdata;
}
}
}
/* performs the entire class registration process */
SWIGINTERN void SWIG_Lua_class_register(lua_State* L,swig_lua_class* clss)
{
/* add its constructor to module with the name of the class
so you can do MyClass(...) as well as new_MyClass(...)
BUT only if a constructor is defined
(this overcomes the problem of pure virtual classes without constructors)*/
if (clss->constructor)
SWIG_Lua_add_function(L,clss->name,clss->constructor);
SWIG_Lua_get_class_registry(L); /* get the registry */
lua_pushstring(L,clss->name); /* get the name */
lua_newtable(L); /* create the metatable */
/* add string of class name called ".type" */
lua_pushstring(L,".type");
lua_pushstring(L,clss->name);
lua_rawset(L,-3);
/* add a table called ".get" */
lua_pushstring(L,".get");
lua_newtable(L);
lua_rawset(L,-3);
/* add a table called ".set" */
lua_pushstring(L,".set");
lua_newtable(L);
lua_rawset(L,-3);
/* add a table called ".fn" */
lua_pushstring(L,".fn");
lua_newtable(L);
lua_rawset(L,-3);
/* add accessor fns for using the .get,.set&.fn */
SWIG_Lua_add_function(L,"__index",SWIG_Lua_class_get);
SWIG_Lua_add_function(L,"__newindex",SWIG_Lua_class_set);
SWIG_Lua_add_function(L,"__gc",SWIG_Lua_class_destruct);
/* add it */
lua_rawset(L,-3); /* metatable into registry */
lua_pop(L,1); /* tidy stack (remove registry) */
SWIG_Lua_get_class_metatable(L,clss->name);
SWIG_Lua_add_class_details(L,clss); /* recursive adding of details (atts & ops) */
lua_pop(L,1); /* tidy stack (remove class metatable) */
}
/* -----------------------------------------------------------------------------
* Class/structure conversion fns
* ----------------------------------------------------------------------------- */
/* helper to add metatable to new lua object */
SWIGINTERN void _SWIG_Lua_AddMetatable(lua_State* L,swig_type_info *type)
{
if (type->clientdata) /* there is clientdata: so add the metatable */
{
SWIG_Lua_get_class_metatable(L,((swig_lua_class*)(type->clientdata))->name);
if (lua_istable(L,-1))
{
lua_setmetatable(L,-2);
}
else
{
lua_pop(L,1);
}
}
}
/* pushes a new object into the lua stack */
SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State* L,void* ptr,swig_type_info *type, int own)
{
swig_lua_userdata* usr;
if (!ptr){
lua_pushnil(L);
return;
}
usr=(swig_lua_userdata*)lua_newuserdata(L,sizeof(swig_lua_userdata)); /* get data */
usr->ptr=ptr; /* set the ptr */
usr->type=type;
usr->own=own;
_SWIG_Lua_AddMetatable(L,type); /* add metatable */
}
/* takes a object from the lua stack & converts it into an object of the correct type
(if possible) */
SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State* L,int index,void** ptr,swig_type_info *type,int flags)
{
swig_lua_userdata* usr;
swig_cast_info *cast;
if (lua_isnil(L,index)){*ptr=0; return SWIG_OK;} /* special case: lua nil => NULL pointer */
usr=(swig_lua_userdata*)lua_touserdata(L,index); /* get data */
if (usr)
{
if (!type) /* special cast void*, no casting fn */
{
*ptr=usr->ptr;
return SWIG_OK; /* ok */
}
cast=SWIG_TypeCheckStruct(usr->type,type); /* performs normal type checking */
if (cast)
{
int newmemory = 0;
*ptr=SWIG_TypeCast(cast,usr->ptr,&newmemory);
assert(!newmemory); /* newmemory handling not yet implemented */
return SWIG_OK; /* ok */
}
}
return SWIG_ERROR; /* error */
}
SWIGRUNTIME void* SWIG_Lua_MustGetPtr(lua_State* L,int index,swig_type_info *type,int flags,
int argnum,const char* func_name){
void* result;
if (!SWIG_IsOK(SWIG_ConvertPtr(L,index,&result,type,flags))){
lua_pushfstring(L,"Error in %s, expected a %s at argument number %d\n",
func_name,(type && type->str)?type->str:"void*",argnum);
lua_error(L);
}
return result;
}
/* pushes a packed userdata. user for member fn pointers only */
SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State* L,void* ptr,size_t size,swig_type_info *type)
{
swig_lua_rawdata* raw;
assert(ptr); /* not acceptable to pass in a NULL value */
raw=(swig_lua_rawdata*)lua_newuserdata(L,sizeof(swig_lua_rawdata)-1+size); /* alloc data */
raw->type=type;
raw->own=0;
memcpy(raw->data,ptr,size); /* copy the data */
_SWIG_Lua_AddMetatable(L,type); /* add metatable */
}
/* converts a packed userdata. user for member fn pointers only */
SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State* L,int index,void* ptr,size_t size,swig_type_info *type)
{
swig_lua_rawdata* raw;
raw=(swig_lua_rawdata*)lua_touserdata(L,index); /* get data */
if (!raw) return SWIG_ERROR; /* error */
if (type==0 || type==raw->type) /* void* or identical type */
{
memcpy(ptr,raw->data,size); /* copy it */
return SWIG_OK; /* ok */
}
return SWIG_ERROR; /* error */
}
/* a function to get the typestring of a piece of data */
SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp)
{
swig_lua_userdata* usr;
if (lua_isuserdata(L,tp))
{
usr=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */
if (usr && usr->type && usr->type->str)
return usr->type->str;
return "userdata (unknown type)";
}
return lua_typename(L,lua_type(L,tp));
}
/* lua callable function to get the userdata's type */
SWIGRUNTIME int SWIG_Lua_type(lua_State* L)
{
/* swig_lua_userdata* usr;
if (!lua_isuserdata(L,1)) /* just in case */
/* return 0; /* nil reply */
/*usr=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */
/*lua_pushstring(L,usr->type->name);
return 1;*/
lua_pushstring(L,SWIG_Lua_typename(L,1));
return 1;
}
/* lua callable function to compare userdata's value
the issue is that two userdata may point to the same thing
but to lua, they are different objects */
SWIGRUNTIME int SWIG_Lua_equal(lua_State* L)
{
int result;
swig_lua_userdata *usr1,*usr2;
if (!lua_isuserdata(L,1) || !lua_isuserdata(L,2)) /* just in case */
return 0; /* nil reply */
usr1=(swig_lua_userdata*)lua_touserdata(L,1); /* get data */
usr2=(swig_lua_userdata*)lua_touserdata(L,2); /* get data */
/*result=(usr1->ptr==usr2->ptr && usr1->type==usr2->type); only works if type is the same*/
result=(usr1->ptr==usr2->ptr);
lua_pushboolean(L,result);
return 1;
}
/* -----------------------------------------------------------------------------
* global variable support code: class/struct typemap functions
* ----------------------------------------------------------------------------- */
/* Install Constants */
SWIGINTERN void
SWIG_Lua_InstallConstants(lua_State* L, swig_lua_const_info constants[]) {
int i;
for (i = 0; constants[i].type; i++) {
switch(constants[i].type) {
case SWIG_LUA_INT:
lua_pushstring(L,constants[i].name);
lua_pushnumber(L,(lua_Number)constants[i].lvalue);
lua_rawset(L,-3);
break;
case SWIG_LUA_FLOAT:
lua_pushstring(L,constants[i].name);
lua_pushnumber(L,(lua_Number)constants[i].dvalue);
lua_rawset(L,-3);
break;
case SWIG_LUA_CHAR:
lua_pushstring(L,constants[i].name);
lua_pushfstring(L,"%c",(char)constants[i].lvalue);
lua_rawset(L,-3);
break;
case SWIG_LUA_STRING:
lua_pushstring(L,constants[i].name);
lua_pushstring(L,(char *) constants[i].pvalue);
lua_rawset(L,-3);
break;
case SWIG_LUA_POINTER:
lua_pushstring(L,constants[i].name);
SWIG_NewPointerObj(L,constants[i].pvalue, *(constants[i]).ptype,0);
lua_rawset(L,-3);
break;
case SWIG_LUA_BINARY:
lua_pushstring(L,constants[i].name);
SWIG_NewMemberObj(L,constants[i].pvalue,constants[i].lvalue,*(constants[i]).ptype);
lua_rawset(L,-3);
break;
default:
break;
}
}
}
#ifdef __cplusplus
}
#endif
/* ------------------------------ end luarun.swg ------------------------------ */
@@ -0,0 +1,77 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* luaruntime.swg
*
* all the runtime code for .
* ----------------------------------------------------------------------------- */
%runtime "swigrun.swg"; /* Common C API type-checking code */
%runtime "luarun.swg"; /* Lua runtime stuff */
%insert(initbeforefunc) "swiginit.swg"
%insert(initbeforefunc) %{
/* Forward declaration of where the user's %init{} gets inserted */
void SWIG_init_user(lua_State* L );
#ifdef __cplusplus
extern "C" {
#endif
/* this is the initialization function
added at the very end of the code
the function is always called SWIG_init, but an eariler #define will rename it
*/
SWIGEXPORT int SWIG_init(lua_State* L)
{
int i;
/* start with global table */
lua_pushvalue(L,LUA_GLOBALSINDEX);
/* SWIG's internal initalisation */
SWIG_InitializeModule((void*)L);
SWIG_PropagateClientData();
/* add a global fn */
SWIG_Lua_add_function(L,"swig_type",SWIG_Lua_type);
SWIG_Lua_add_function(L,"swig_equals",SWIG_Lua_equal);
/* begin the module (its a table with the same name as the module) */
SWIG_Lua_module_begin(L,SWIG_name);
/* add commands/functions */
for (i = 0; swig_commands[i].name; i++){
SWIG_Lua_module_add_function(L,swig_commands[i].name,swig_commands[i].func);
}
/* add variables */
for (i = 0; swig_variables[i].name; i++){
SWIG_Lua_module_add_variable(L,swig_variables[i].name,swig_variables[i].get,swig_variables[i].set);
}
/* set up base class pointers (the hierachy) */
for (i = 0; swig_types[i]; i++){
if (swig_types[i]->clientdata){
SWIG_Lua_init_base_class(L,(swig_lua_class*)(swig_types[i]->clientdata));
}
}
/* additional registration structs & classes in lua */
for (i = 0; swig_types[i]; i++){
if (swig_types[i]->clientdata){
SWIG_Lua_class_register(L,(swig_lua_class*)(swig_types[i]->clientdata));
}
}
/* constants */
SWIG_Lua_InstallConstants(L,swig_constants);
/* invoke user-specific initialization */
SWIG_init_user(L);
/* end module */
lua_pop(L,1); /* tidy stack (remove module table)*/
lua_pop(L,1); /* tidy stack (remove global table)*/
return 1;
}
#ifdef __cplusplus
}
#endif
%}
/* Note: the initialization function is closed after all code is generated */
@@ -0,0 +1,353 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* luatypemaps.swg
*
* basic typemaps for Lua.
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* standard typemaps
* ----------------------------------------------------------------------------- */
/* NEW LANGUAGE NOTE:
the 'checkfn' param is something that I added for typemap(in)
it is an optional fn call to check the type of the lua object
the fn call must be of the form
int checkfn(lua_State *L, int index);
and return 1/0 depending upon if this is the correct type
For the typemap(out), an additional SWIG_arg parmeter must be incremented
to reflect the number of values returned (normally SWIG_arg++; will do)
*/
// numbers
%typemap(in,checkfn="lua_isnumber") int,short,long,
unsigned int,unsigned short,unsigned long,
signed char,unsigned char,
float,double
%{$1 = ($type)lua_tonumber(L, $input);%}
%typemap(out) int,short,long,
unsigned int,unsigned short,unsigned long,
signed char,unsigned char,
float,double
%{ lua_pushnumber(L, (lua_Number) $1); SWIG_arg++;%}
// we must also provide typemaps for privitives by const reference:
// given a function:
// int intbyref(const int& i);
// SWIG assumes that this code will need a pointer to int to be passed in
// (this might be ok for objects by const ref, but not for numeric primitives)
// therefore we add a set of typemaps to fix this (for both in & out)
%typemap(in,checkfn="lua_isnumber") const int&($basetype temp)
%{ temp=($basetype)lua_tonumber(L,$input); $1=&temp;%}
%typemap(out) const int&
%{ lua_pushnumber(L, (lua_Number) *$1); SWIG_arg++;%}
// for the other numbers we can just use an apply statement to cover them
%apply const int & {const short&,const long&,
const unsigned int&,const unsigned short&,const unsigned long&,
const signed char&,const unsigned char&,
const float&,const double&};
/* enums have to be handled slightly differently
VC++ .net will not allow a cast from lua_Number(double) to enum directly.
*/
%typemap(in,checkfn="lua_isnumber") enum SWIGTYPE
%{$1 = ($type)(int)lua_tonumber(L, $input);%}
%typemap(out) enum SWIGTYPE
%{ lua_pushnumber(L, (lua_Number)(int)($1)); SWIG_arg++;%}
// and const refs
%typemap(in,checkfn="lua_isnumber") const enum SWIGTYPE &($basetype temp)
%{ temp=($basetype)(int)lua_tonumber(L,$input); $1=&temp;%}
%typemap(out) const enum SWIGTYPE &
%{ lua_pushnumber(L, (lua_Number) *$1); SWIG_arg++;%}
// boolean (which is a special type in lua)
// note: lua_toboolean() returns 1 or 0
// note: 1 & 0 are not booleans in lua, only true & false
%typemap(in,checkfn="lua_isboolean") bool
%{$1 = (lua_toboolean(L, $input)!=0);%}
%typemap(out) bool
%{ lua_pushboolean(L,(int)$1); SWIG_arg++;%}
// for const bool&, SWIG treats this as a const bool* so we must dereference it
%typemap(in,checkfn="lua_isboolean") const bool& (bool temp)
%{temp=lua_toboolean(L, $input) ? true : false;
$1=&temp;%}
%typemap(out) const bool&
%{ lua_pushboolean(L,(int)*$1); SWIG_arg++;%}
// strings (char* and char[])
%typemap(in,checkfn="lua_isstring") const char*, char*
%{$1 = ($ltype)lua_tostring(L, $input);%}
%typemap(in,checkfn="lua_isstring") const char[ANY], char[ANY]
%{$1 = ($ltype)lua_tostring(L, $input);%}
%typemap(out) const char*, char*
%{ lua_pushstring(L,(const char*)$1); SWIG_arg++;%}
%typemap(out) const char[ANY], char[ANY]
%{ lua_pushstring(L,(const char*)$1); SWIG_arg++;%}
// char's
// currently treating chars as small strings, not as numbers
// (however signed & unsigned char's are numbers...)
%typemap(in,checkfn="lua_isstring") char
%{$1 = (lua_tostring(L, $input))[0];%}
%typemap(out) char
%{ lua_pushfstring(L,"%c",$1); SWIG_arg++;%}
// by const ref
%typemap(in,checkfn="lua_isstring") const char& (char temp)
%{temp = (lua_tostring(L, $input))[0]; $1=&temp;%}
%typemap(out) const char&
%{ lua_pushfstring(L,"%c",*$1); SWIG_arg++;%}
// pointers and references
// under SWIG rules, it is ok, to have a pass in a lua nil,
// it should be converted to a SWIG NULL.
// This will only be allowed for pointers & arrays, not refs or by value
// the checkfn lua_isuserdata will only work for userdata
// the checkfn SWIG_isptrtype will work for both userdata and nil's
%typemap(in,checkfn="SWIG_isptrtype") SWIGTYPE*,SWIGTYPE[]
%{
if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,0))){
SWIG_fail_ptr("$symname",$argnum,$descriptor);
}
%}
%typemap(in,checkfn="lua_isuserdata") SWIGTYPE&
%{
if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,0))){
SWIG_fail_ptr("$symname",$argnum,$descriptor);
}
%}
// out is simple
%typemap(out) SWIGTYPE*,SWIGTYPE&
%{SWIG_NewPointerObj(L,$1,$descriptor,$owner); SWIG_arg++; %}
// dynamic casts
// this uses the SWIG_TypeDynamicCast() which relies on RTTI to find out what the pointer really is
// the we return it as the correct type
%typemap(out) SWIGTYPE *DYNAMIC,
SWIGTYPE &DYNAMIC
{
swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
SWIG_NewPointerObj(L,(void*)$1,ty,$owner); SWIG_arg++;
}
// passing objects by value
// SWIG_ConvertPtr wants an object pointer (the $&ltype argp)
// then dereferences it to get the object
%typemap(in,checkfn="lua_isuserdata") SWIGTYPE ($&ltype argp)
%{
if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&argp,$&descriptor,0))){
SWIG_fail_ptr("$symname",$argnum,$&descriptor);
}
$1 = *argp;
%}
// Also needed for object ptrs by const ref
// eg const A* ref_pointer(A* const& a);
// found in mixed_types.i
%typemap(in,checkfn="lua_isuserdata") SWIGTYPE* const &($*ltype temp)
%{temp=($*ltype)SWIG_MustGetPtr(L,$input,$*descriptor,0,$argnum,"$symname");
$1=&temp;%}
// Primitive types--return by value
// must make a new object, copy the data & return the new object
// Note: the brackets are {...} and not %{..%}, because we want them to be included in the wrapper
// this is because typemap(out) does not support local variables, like in typemap(in) does
// and we need the $&1_ltype resultptr; to be declared
#ifdef __cplusplus
%typemap(out) SWIGTYPE
{
$&1_ltype resultptr = new $1_ltype(($1_ltype &) $1);
SWIG_NewPointerObj(L,(void *) resultptr,$&1_descriptor,1); SWIG_arg++;
}
#else
%typemap(out) SWIGTYPE
{
$&1_ltype resultptr;
resultptr = ($&1_ltype) malloc(sizeof($1_type));
memmove(resultptr, &$1, sizeof($1_type));
SWIG_NewPointerObj(L,(void *) resultptr,$&1_descriptor,1); SWIG_arg++;
}
#endif
// member function pointer
// a member fn ptr is not 4 bytes like a normal pointer, but 8 bytes (at least on mingw)
// so the standard wrappering cannot be done
// nor can you cast a member function pointer to a void* (obviously)
// therefore a special wrappering functions SWIG_ConvertMember() & SWIG_NewMemberObj() were written
#ifdef __cplusplus
%typemap(in,checkfn="lua_isuserdata") SWIGTYPE (CLASS::*)
%{
if (!SWIG_IsOK(SWIG_ConvertMember(L,$input,(void*)(&$1),sizeof($type),$descriptor)))
SWIG_fail_ptr("$symname",$argnum,$descriptor);
%}
%typemap(out) SWIGTYPE (CLASS::*)
%{
SWIG_NewMemberObj(L,(void*)(&$1),sizeof($type),$descriptor); SWIG_arg++;
%}
#endif
// void (must be empty without the SWIG_arg++)
%typemap(out) void "";
/* void* is a special case
A function void fn(void*) should take any kind of pointer as a parameter (just like C/C++ does)
but if its an output, then it should be wrappered like any other SWIG object (using default typemap)
*/
%typemap(in,checkfn="SWIG_isptrtype") void*
%{$1=($1_ltype)SWIG_MustGetPtr(L,$input,0,0,$argnum,"$symname");%}
/* long long is another special case:
as lua only supports one numeric type (lua_Number), we will just
cast it to that & accept the loss of precision.
An alternative solution would be a long long struct or class
with the relevant operators.
*/
%apply long {long long, signed long long, unsigned long long};
%apply const long& {const long long&, const signed long long&, const unsigned long long&};
/* It is possible to also pass a lua_State* into a function, so
void fn(int a, float b, lua_State* s) is wrappable as
> fn(1,4.3) -- note: the state is implicitly passed in
*/
%typemap(in, numinputs=0) lua_State*
%{$1 = L;%}
/* -----------------------------------------------------------------------------
* typecheck rules
* ----------------------------------------------------------------------------- */
/* These are needed for the overloaded functions
These define the detection routines which will spot what
parmeters match which function
*/
// unfortunately lua only considers one type of number
// so all numbers (int,float,double) match
// you could add an advanced fn to get type & check if its integral
%typecheck(SWIG_TYPECHECK_INTEGER)
int, short, long,
unsigned int, unsigned short, unsigned long,
signed char, unsigned char,
long long, unsigned long long, signed long long,
const int &, const short &, const long &,
const unsigned int &, const unsigned short &, const unsigned long &,
const signed char&, const unsigned char&,
const long long &, const unsigned long long &,
enum SWIGTYPE, const enum SWIGTYPE&,
float, double, const float &, const double&
{
$1 = lua_isnumber(L,$input);
}
%typecheck(SWIG_TYPECHECK_BOOL)
bool, const bool &
{
$1 = lua_isboolean(L,$input);
}
// special check for a char (string of length 1)
%typecheck(SWIG_TYPECHECK_CHAR) char, const char& {
$1 = lua_isstring(L,$input) && (lua_strlen(L,$input)==1);
}
%typecheck(SWIG_TYPECHECK_STRING) char *, char[] {
$1 = lua_isstring(L,$input);
}
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE [] {
void *ptr;
if (SWIG_isptrtype(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $1_descriptor, 0)) {
$1 = 0;
} else {
$1 = 1;
}
}
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE & {
void *ptr;
if (lua_isuserdata(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $1_descriptor, 0)) {
$1 = 0;
} else {
$1 = 1;
}
}
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE {
void *ptr;
if (lua_isuserdata(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $&1_descriptor, 0)) {
$1 = 0;
} else {
$1 = 1;
}
}
%typecheck(SWIG_TYPECHECK_VOIDPTR) void * {
void *ptr;
if (SWIG_isptrtype(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, 0, 0)) {
$1 = 0;
} else {
$1 = 1;
}
}
// Also needed for object ptrs by const ref
// eg const A* ref_pointer(A* const& a);
// found in mixed_types.i
%typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE* const &
{
void *ptr;
if (lua_isuserdata(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $*descriptor, 0)) {
$1 = 0;
} else {
$1 = 1;
}
}
/* -----------------------------------------------------------------------------
* Others
* ----------------------------------------------------------------------------- */
// size_t (which is just a unsigned long)
%apply unsigned long { size_t };
%apply const unsigned long & { const size_t & };
/* -----------------------------------------------------------------------------
* Specials
* ----------------------------------------------------------------------------- */
// swig::LANGUAGE_OBJ was added to allow containers of native objects
// however its rather difficult to do this in lua, as you cannot hold pointers
// to native objects (they are held in the interpreter)
// therefore for now: just ignoring this feature
#ifdef __cplusplus
%ignore swig::LANGUAGE_OBJ;
//%inline %{
%{
namespace swig {
typedef struct{} LANGUAGE_OBJ;
}
%}
#endif // __cplusplus
@@ -0,0 +1,5 @@
%include <std_except.i>
%apply size_t { std::size_t };
%apply const size_t& { const std::size_t& };
@@ -0,0 +1 @@
%include <std/_std_deque.i>
@@ -0,0 +1,43 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* Typemaps used by the STL wrappers that throw exceptions.
* These typemaps are used when methods are declared with an STL exception
* specification, such as:
* size_t at() const throw (std::out_of_range);
*
* std_except.i
* ----------------------------------------------------------------------------- */
%{
#include <stdexcept>
%}
%include <exception.i>
namespace std
{
%ignore exception; // not sure if I should ignore this...
class exception
{
public:
exception() throw() { }
virtual ~exception() throw();
virtual const char* what() const throw();
};
}
// normally object whihc are thrown are returned to interpreter as errors
// (which potentally may have problems if they are not copied)
// therefore all classes based upon std::exception are converted to their strings & returned as errors
%typemap(throws) std::bad_exception "SWIG_exception(SWIG_RuntimeError, $1.what());"
%typemap(throws) std::domain_error "SWIG_exception(SWIG_ValueError, $1.what());"
%typemap(throws) std::exception "SWIG_exception(SWIG_SystemError, $1.what());"
%typemap(throws) std::invalid_argument "SWIG_exception(SWIG_ValueError, $1.what());"
%typemap(throws) std::length_error "SWIG_exception(SWIG_IndexError, $1.what());"
%typemap(throws) std::logic_error "SWIG_exception(SWIG_RuntimeError, $1.what());"
%typemap(throws) std::out_of_range "SWIG_exception(SWIG_IndexError, $1.what());"
%typemap(throws) std::overflow_error "SWIG_exception(SWIG_OverflowError, $1.what());"
%typemap(throws) std::range_error "SWIG_exception(SWIG_IndexError, $1.what());"
%typemap(throws) std::runtime_error "SWIG_exception(SWIG_RuntimeError, $1.what());"
%typemap(throws) std::underflow_error "SWIG_exception(SWIG_RuntimeError, $1.what());"
+63
View File
@@ -0,0 +1,63 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* std_map.i
*
* SWIG typemaps for std::map
* ----------------------------------------------------------------------------- */
%include <std_common.i>
// ------------------------------------------------------------------------
// std::map
// ------------------------------------------------------------------------
%{
#include <map>
#include <algorithm>
#include <stdexcept>
%}
// exported class
namespace std {
template<class K, class T> class map {
// add typemaps here
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef K key_type;
typedef T mapped_type;
map();
map(const map<K,T> &);
unsigned int size() const;
bool empty() const;
void clear();
%extend {
const T& get(const K& key) throw (std::out_of_range) {
std::map<K,T >::iterator i = self->find(key);
if (i != self->end())
return i->second;
else
throw std::out_of_range("key not found");
}
void set(const K& key, const T& x) {
(*self)[key] = x;
}
void del(const K& key) throw (std::out_of_range) {
std::map<K,T >::iterator i = self->find(key);
if (i != self->end())
self->erase(i);
else
throw std::out_of_range("key not found");
}
bool has_key(const K& key) {
std::map<K,T >::iterator i = self->find(key);
return i != self->end();
}
}
};
}
@@ -0,0 +1,45 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* std_pair.i
*
* std::pair typemaps for LUA
* ----------------------------------------------------------------------------- */
%{
#include <utility>
%}
/*
A really cut down version of the pair class.
this is not useful on its owns is it needs a %template definition with it
eg.
namespace std {
%template(IntPair) pair<int, int>;
%template(make_IntPair) make_pair<int, int>;
}
*/
namespace std {
template <class T, class U > struct pair {
typedef T first_type;
typedef U second_type;
pair();
pair(T first, U second);
pair(const pair& p);
T first;
U second;
};
template <class T, class U >
pair<T,U> make_pair(const T&,const U&);
}
@@ -0,0 +1,155 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* std_string.i
*
* std::string typemaps for LUA
* ----------------------------------------------------------------------------- */
%{
#include <string>
%}
/*
Only std::string and const std::string& are typemaped
they are converted to the Lua strings automatically
std::string& and std::string* are not
they must be explicitly managed (see below)
eg.
std::string test_value(std::string x) {
return x;
}
can be used as
s="hello world"
s2=test_value(s)
assert(s==s2)
*/
%naturalvar std::string;
/*
Bug report #1526022 by neomantra
Lua strings and std::string can contain embeded zero's
Therefore a standard out typemap should not be:
lua_pushstring(L,$1.c_str());
but
lua_pushlstring(L,$1.data(),$1.size());
Similarly for getting the string
$1 = (char*)lua_tostring(L, $input);
becomes
$1.assign(lua_tostring(L,$input),lua_strlen(L,$input));
Not using: lua_tolstring() as this is only found in Lua 5.1 & not 5.0.2
*/
%typemap(in,checkfn="lua_isstring") std::string
%{$1.assign(lua_tostring(L,$input),lua_strlen(L,$input));%}
%typemap(out) std::string
%{ lua_pushlstring(L,$1.data(),$1.size()); SWIG_arg++;%}
%typemap(in,checkfn="lua_isstring") const std::string& (std::string temp)
%{temp.assign(lua_tostring(L,$input),lua_strlen(L,$input)); $1=&temp;%}
%typemap(out) const std::string&
%{ lua_pushlstring(L,$1->data(),$1->size()); SWIG_arg++;%}
// for throwing of any kind of string, string ref's and string pointers
// we convert all to lua strings
%typemap(throws) std::string,const std::string&
%{ lua_pushlstring(L,$1.data(),$1.size()); SWIG_fail;%}
%typemap(throws) std::string*,const std::string*
%{ lua_pushlstring(L,$1->data(),$1->size()); SWIG_fail;%}
// and the typechecks
%typecheck(SWIG_TYPECHECK_STRING) std::string,const std::string& {
$1 = lua_isstring(L,$input);
}
/*
std::string& can be wrappered, but you must inform SWIG if it is in or out
eg:
void fn(std::string& str);
Is this an in/out/inout value?
Therefore you need the usual
%apply (std::string& INOUT) {(std::string& str)};
or
%apply std::string& INOUT {std::string& str};
typemaps to tell SWIG what to do.
*/
%typemap(in) std::string &INPUT=const std::string &;
%typemap(in, numinputs=0) std::string &OUTPUT (std::string temp)
%{ $1 = &temp; %}
%typemap(argout) std::string &OUTPUT
%{ lua_pushlstring(L,$1->data(),$1->size()); SWIG_arg++;%}
%typemap(in) std::string &INOUT =const std::string &;
%typemap(argout) std::string &INOUT = std::string &OUTPUT;
/*
For const std::string* and std::string* is not clear
is this a pointer or an array?
Therefore just leaving it as is
(there is some rough code below which could be used if needed
// SWIG wraps const ref's as pointer
// typemaps to deal with this and const ptrs
%typemap(in,checkfn="lua_isstring")
const std::string& INPUT(std::string temp),
const std::string* INPUT(std::string temp)
%{temp=(char*)lua_tostring(L, $input); $1=&temp;%}
%typemap(out) const std::string&, const std::string*
%{ lua_pushstring(L,$1->c_str()); SWIG_arg++;%}
// the non-const pointer version
%typemap(in) std::string *INPUT=const std::string *INPUT;
%typemap(in, numinputs=0) std::string *OUTPUT (std::string temp)
%{ $1 = &temp; %}
%typemap(argout) std::string *OUTPUT
%{ lua_pushstring(L,$1->c_str()); SWIG_arg++;%}
%typemap(in) std::string *INOUT = std::string *INPUT;
%typemap(argout) std::string *INOUT = std::string *OUTPUT;
*/
/*
A really cut down version of the string class
This provides basic mapping of lua strings <-> std::string
and little else
(the std::string has a lot of unneeded functions anyway)
note: no fn's taking the const string&
as this is overloaded by the const char* version
*/
namespace std {
class string {
public:
string();
string(const char*);
//string(const string&);
unsigned int size() const;
unsigned int length() const;
bool empty() const;
// no support for operator[]
const char* c_str()const;
const char* data()const;
// assign does not return a copy of this object
// (no point in a scripting language)
void assign(const char*);
//void assign(const string&);
// no support for all the other features
// its probably better to do it in lua
};
}
@@ -0,0 +1,134 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* std_vector.i
*
* std::vector typemaps for LUA
* ----------------------------------------------------------------------------- */
%{
#include <vector>
%}
%include <std_except.i> // the general exepctions
/*
A really cut down version of the vector class.
Note: this does not match the true std::vector class
but instead is an approximate, so that SWIG knows how to wrapper it.
(Eg, all access is by value, not ref, as SWIG turns refs to pointers)
And no support for iterators & insert/erase
It would be useful to have a vector<->Lua table conversion routine
*/
namespace std {
template<class T>
class vector {
public:
vector();
vector(unsigned int);
vector(const vector&);
vector(unsigned int,T);
unsigned int size() const;
unsigned int max_size() const;
bool empty() const;
void clear();
void push_back(T val);
void pop_back();
T front()const; // only read front & back
T back()const; // not write to them
// operator [] given later:
%extend // this is a extra bit of SWIG code
{
// [] is replaced by __getitem__ & __setitem__
// simply throws a string, which causes a lua error
T __getitem__(unsigned int idx) throw (std::out_of_range)
{
if (idx>=self->size())
throw std::out_of_range("in vector::__getitem__()");
return (*self)[idx];
}
void __setitem__(unsigned int idx,T val) throw (std::out_of_range)
{
if (idx>=self->size())
throw std::out_of_range("in vector::__setitem__()");
(*self)[idx]=val;
}
};
};
}
/*
Vector<->LuaTable fns
These look a bit like the array<->LuaTable fns
but are templated, not %defined
(you must have template support for STL)
*/
/*
%{
// reads a table into a vector of numbers
// lua numbers will be cast into the type required (rounding may occur)
// return 0 if non numbers found in the table
// returns new'ed ptr if ok
template<class T>
std::vector<T>* SWIG_read_number_vector(lua_State* L,int index)
{
int i=0;
std::vector<T>* vec=new std::vector<T>();
while(1)
{
lua_rawgeti(L,index,i+1);
if (!lua_isnil(L,-1))
{
lua_pop(L,1);
break; // finished
}
if (!lua_isnumber(L,-1))
{
lua_pop(L,1);
delete vec;
return 0; // error
}
vec->push_back((T)lua_tonumber(L,-1));
lua_pop(L,1);
++i;
}
return vec; // ok
}
// writes a vector of numbers out as a lua table
template<class T>
int SWIG_write_number_vector(lua_State* L,std::vector<T> *vec)
{
lua_newtable(L);
for(int i=0;i<vec->size();++i)
{
lua_pushnumber(L,(double)((*vec)[i]));
lua_rawseti(L,-2,i+1);// -1 is the number, -2 is the table
}
}
%}
// then the typemaps
%define SWIG_TYPEMAP_NUM_VECTOR(T)
// in
%typemap(in) std::vector<T> *INPUT
%{ $1 = SWIG_read_number_vector<T>(L,$input);
if (!$1) SWIG_fail;%}
%typemap(freearg) std::vector<T> *INPUT
%{ delete $1;%}
// out
%typemap(argout) std::vector<T> *OUTPUT
%{ SWIG_write_number_vector(L,$1); SWIG_arg++; %}
%enddef
*/
+13
View File
@@ -0,0 +1,13 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* stl.i
* ----------------------------------------------------------------------------- */
%include <std_common.i>
%include <std_string.i>
%include <std_vector.i>
%include <std_map.i>
%include <std_pair.i>
+541
View File
@@ -0,0 +1,541 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* typemaps.swg
*
* SWIG Library file containing the main typemap code to support Lua modules.
* ----------------------------------------------------------------------------- */
/* -----------------------------------------------------------------------------
* Basic inout typemaps
* ----------------------------------------------------------------------------- */
/*
These provide the basic ability for passing in & out of standard numeric data types
(int,long,float,double, etc)
The basic code looks like this:
%typemap(in,checkfn="lua_isnumber") int *INPUT(int temp), int &INPUT(int temp)
%{ temp = (int)lua_tonumber(L,$input);
$1 = &temp; %}
%typemap(in, numinputs=0) int *OUTPUT (int temp)
%{ $1 = &temp; %}
%typemap(argout) int *OUTPUT
%{ lua_pushnumber(L, (double) *$1); SWIG_arg++;%}
%typemap(in) int *INOUT = int *INPUT;
%typemap(argout) int *INOUT = int *OUTPUT;
However the code below is a mixture of #defines & such, so nowhere as easy to read
To make you code work correctly its not just a matter of %including this file
You also have to give SWIG the hints on which to use where
eg
extern int add_pointer(int* a1,int* a2); // a1 & a2 are pointer values to be added
extern void swap(int* s1, int* s2); // does the swap
You will need to either change the argument names
extern int add_pointer(int* INPUT,int* INPUT);
or provide a %apply statement
%apply int* INOUT{ int *s1, int *s2 };
// if SWIG sees int* s1, int* s2, assume they are inout params
*/
%define SWIG_NUMBER_TYPEMAP(TYPE)
%typemap(in,checkfn="lua_isnumber") TYPE *INPUT($*ltype temp), TYPE &INPUT($*ltype temp)
%{ temp = ($*ltype)lua_tonumber(L,$input);
$1 = &temp; %}
%typemap(in, numinputs=0) TYPE *OUTPUT ($*ltype temp)
%{ $1 = &temp; %}
%typemap(argout) TYPE *OUTPUT
%{ lua_pushnumber(L, (lua_Number) *$1); SWIG_arg++;%}
%typemap(in) TYPE *INOUT = TYPE *INPUT;
%typemap(argout) TYPE *INOUT = TYPE *OUTPUT;
%typemap(in) TYPE &OUTPUT = TYPE *OUTPUT;
%typemap(argout) TYPE &OUTPUT = TYPE *OUTPUT;
%typemap(in) TYPE &INOUT = TYPE *INPUT;
%typemap(argout) TYPE &INOUT = TYPE *OUTPUT;
// const version (the $*ltype is the basic number without ptr or const's)
%typemap(in,checkfn="lua_isnumber") const TYPE *INPUT($*ltype temp)
%{ temp = ($*ltype)lua_tonumber(L,$input);
$1 = &temp; %}
%enddef
// now the code
SWIG_NUMBER_TYPEMAP(int); SWIG_NUMBER_TYPEMAP(unsigned int); SWIG_NUMBER_TYPEMAP(signed int);
SWIG_NUMBER_TYPEMAP(short); SWIG_NUMBER_TYPEMAP(unsigned short); SWIG_NUMBER_TYPEMAP(signed short);
SWIG_NUMBER_TYPEMAP(long); SWIG_NUMBER_TYPEMAP(unsigned long); SWIG_NUMBER_TYPEMAP(signed long);
SWIG_NUMBER_TYPEMAP(float);
SWIG_NUMBER_TYPEMAP(double);
SWIG_NUMBER_TYPEMAP(enum SWIGTYPE);
// also for long longs's
SWIG_NUMBER_TYPEMAP(long long); SWIG_NUMBER_TYPEMAP(unsigned long long); SWIG_NUMBER_TYPEMAP(signed long long);
// note we dont do char, as a char* is probably a string not a ptr to a single char
/* -----------------------------------------------------------------------------
* Basic Array typemaps
* ----------------------------------------------------------------------------- */
/*
I have no idea why this kind of code does not exist in SWIG as standard,
but here is it.
This code will convert to/from 1D numeric arrays.
In order to reduce code bloat, there are a few macros
and quite a few functions defined
(unfortunately this makes it a lot less clear)
assuming we have functions
void process_array(int arr[3]); // nice fixed size array
void process_var_array(float arr[],int len); // variable sized array
void process_var_array_inout(double arr*,int len); // variable sized array
// data passed in & out
void process_enum_inout_array_var(enum Days *arrinout, int len); // using enums
void return_array_5(int arrout[5]); // out array only
in order to wrap them correctly requires a typemap
// inform SWIG of the correct typemap
// For fixed length, you must specify it as <type> INPUT[ANY]
%apply (int INPUT[ANY]) {(int arr[3])};
// variable length arrays are just the same
%apply (float INPUT[],int) {(float arr[],int len)};
// it is also ok, to map the TYPE* instead of a TYPE[]
%apply (double *INOUT,int) {(double arr*,int len)};
// for the enum's you must use enum SWIGTYPE
%apply (enum SWIGTYPE *INOUT,int) {(enum Days *arrinout, int len)};
// fixed length out if also fine
%apply (int OUTPUT[ANY]) {(int arrout[5])};
Generally, you could use %typemap(...)=...
but the %apply is neater & easier
a few things of note:
* all Lua tables are indexed from 1, all C/C++ arrays are indexed from 0
therefore t={6,5,3} -- t[1]==6, t[2]==5, t[3]==3
when passed to process_array(int arr[3]) becomes
arr[0]==6, arr[1]==5, arr[2]==3
* for OUTPUT arrays, no array need be passed in, the fn will return a Lua table
so for the above mentioned return_array_5() would look like
arr=return_array_5() -- no parameters passed in
* for INOUT arrays, a table must be passed in, and a new table will be returned
(this is consistant with the way that numbers are processed)
if you want just use
arr={...}
arr=process_var_array_inout(arr) -- arr is replaced by the new version
The following are not yet supported:
* variable length output only array (inout's work ok)
* multidimentional arrays
* arrays of objects/structs
* arrays of pointers
*/
/*
The internals of the array managment stuff
helper fns/macros
SWIG_ALLOC_ARRAY(TYPE,LEN) // returns a typed array TYPE[LEN]
SWIG_FREE_ARRAY(PTR) // delete the ptr (if not zero)
// counts the specified table & gets the size
// integer version
int SWIG_itable_size(lua_State* L, int index);
// other version
int SWIG_table_size(lua_State* L, int index);
SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE)
// this fn declares up 4 functions for helping to read/write tables
// these can then be called by the macros ...
// all assume the table is an integer indexes from 1
// but the C array is a indexed from 0
// created a fixed size array, reads the specified table
// and then fills the array with numbers
// returns ptr to the array if ok, or 0 for error
// (also pushes a error message to the stack)
TYPE* SWIG_get_NAME_num_array_fixed(lua_State* L, int index, int size);
// as per SWIG_get_NAME_num_array_fixed()
// but reads the entire table & creates an array of the correct size
// (if the table is empty, it returns an error rather than a zero length array)
TYPE* SWIG_get_NAME_num_array_var(lua_State* L, int index, int* size);
// writes a table to Lua with all the specified numbers
void SWIG_write_NAME_num_array(lua_State* L,TYPE *array,int size);
// read the specified table, and fills the array with numbers
// returns 1 of ok (only fails if it doesnt find numbers)
// helper fn (called by SWIG_get_NAME_num_array_*() fns)
int SWIG_read_NAME_num_array(lua_State* L,int index,TYPE *array,int size);
*/
/* Reported that you don't need to check for NULL for delete & free
There probably is some compiler that its not true for, so the code is left here just in case.
#ifdef __cplusplus
#define SWIG_ALLOC_ARRAY(TYPE,LEN) new TYPE[LEN]
#define SWIG_FREE_ARRAY(PTR) if(PTR){delete[] PTR;}
#else
#define SWIG_ALLOC_ARRAY(TYPE,LEN) (TYPE *)malloc(LEN*sizeof(TYPE))
#define SWIG_FREE_ARRAY(PTR) if(PTR){free(PTR);}
#endif
*/
%{
#ifdef __cplusplus /* generic alloc/dealloc fns*/
#define SWIG_ALLOC_ARRAY(TYPE,LEN) new TYPE[LEN]
#define SWIG_FREE_ARRAY(PTR) delete[] PTR;
#else
#define SWIG_ALLOC_ARRAY(TYPE,LEN) (TYPE *)malloc(LEN*sizeof(TYPE))
#define SWIG_FREE_ARRAY(PTR) free(PTR);
#endif
/* counting the size of arrays:*/
int SWIG_itable_size(lua_State* L, int index)
{
int n=0;
while(1){
lua_rawgeti(L,index,n+1);
if (lua_isnil(L,-1))break;
++n;
lua_pop(L,1);
}
lua_pop(L,1);
return n;
}
int SWIG_table_size(lua_State* L, int index)
{
int n=0;
lua_pushnil(L); /* first key*/
while (lua_next(L, index) != 0) {
++n;
lua_pop(L, 1); /* removes `value'; keeps `key' for next iteration*/
}
return n;
}
/* super macro to declare array typemap helper fns */
#define SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE)\
int SWIG_read_##NAME##_num_array(lua_State* L,int index,TYPE *array,int size){\
int i;\
for (i = 0; i < size; i++) {\
lua_rawgeti(L,index,i+1);\
if (lua_isnumber(L,-1)){\
array[i] = (TYPE)lua_tonumber(L,-1);\
} else {\
lua_pop(L,1);\
return 0;\
}\
lua_pop(L,1);\
}\
return 1;\
}\
static TYPE* SWIG_get_##NAME##_num_array_fixed(lua_State* L, int index, int size){\
TYPE *array;\
if (!lua_istable(L,index) || SWIG_itable_size(L,index) != size) {\
lua_pushfstring(L,"expected a table of size %d",size);\
return 0;\
}\
array=SWIG_ALLOC_ARRAY(TYPE,size);\
if (!SWIG_read_##NAME##_num_array(L,index,array,size)){\
lua_pushstring(L,"table must contain numbers");\
SWIG_FREE_ARRAY(array);\
return 0;\
}\
return array;\
}\
static TYPE* SWIG_get_##NAME##_num_array_var(lua_State* L, int index, int* size)\
{\
TYPE *array;\
if (!lua_istable(L,index)) {\
lua_pushstring(L,"expected a table");\
return 0;\
}\
*size=SWIG_itable_size(L,index);\
if (*size<1){\
lua_pushstring(L,"table appears to be empty");\
return 0;\
}\
array=SWIG_ALLOC_ARRAY(TYPE,*size);\
if (!SWIG_read_##NAME##_num_array(L,index,array,*size)){\
lua_pushstring(L,"table must contain numbers");\
SWIG_FREE_ARRAY(array);\
return 0;\
}\
return array;\
}\
void SWIG_write_##NAME##_num_array(lua_State* L,TYPE *array,int size){\
int i;\
lua_newtable(L);\
for (i = 0; i < size; i++){\
lua_pushnumber(L,(lua_Number)array[i]);\
lua_rawseti(L,-2,i+1);/* -1 is the number, -2 is the table*/ \
}\
}
%}
/*
This is one giant macro to define the typemaps & the helpers
for array handling
*/
%define SWIG_TYPEMAP_NUM_ARR(NAME,TYPE)
%{SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE);%}
// fixed size array's
%typemap(in) TYPE INPUT[ANY]
%{ $1 = SWIG_get_##NAME##_num_array_fixed(L,$input,$1_dim0);
if (!$1) SWIG_fail;%}
%typemap(freearg) TYPE INPUT[ANY]
%{ SWIG_FREE_ARRAY($1);%}
// variable size array's
%typemap(in) (TYPE *INPUT,int)
%{ $1 = SWIG_get_##NAME##_num_array_var(L,$input,&$2);
if (!$1) SWIG_fail;%}
%typemap(freearg) (TYPE *INPUT,int)
%{ SWIG_FREE_ARRAY($1);%}
// out fixed arrays
%typemap(in,numinputs=0) TYPE OUTPUT[ANY]
%{ $1 = SWIG_ALLOC_ARRAY(TYPE,$1_dim0); %}
%typemap(argout) TYPE OUTPUT[ANY]
%{ SWIG_write_##NAME##_num_array(L,$1,$1_dim0); SWIG_arg++; %}
%typemap(freearg) TYPE OUTPUT[ANY]
%{ SWIG_FREE_ARRAY($1); %}
// inout fixed arrays
%typemap(in) TYPE INOUT[ANY]=TYPE INPUT[ANY];
%typemap(argout) TYPE INOUT[ANY]=TYPE OUTPUT[ANY];
%typemap(freearg) TYPE INOUT[ANY]=TYPE INPUT[ANY];
// inout variable arrays
%typemap(in) (TYPE *INOUT,int)=(TYPE *INPUT,int);
%typemap(argout) (TYPE *INOUT,int)
%{ SWIG_write_##NAME##_num_array(L,$1,$2); SWIG_arg++; %}
%typemap(freearg) (TYPE *INOUT,int)=(TYPE *INPUT,int);
// TODO out variable arrays (is there a standard form for such things?)
%enddef
// the following line of code
// declares the C helper fns for the array typemaps
// as well as defining typemaps for
// fixed len arrays in & out, & variable length arrays in
SWIG_TYPEMAP_NUM_ARR(int,int);
SWIG_TYPEMAP_NUM_ARR(uint,unsigned int);
SWIG_TYPEMAP_NUM_ARR(short,short);
SWIG_TYPEMAP_NUM_ARR(ushort,unsigned short);
SWIG_TYPEMAP_NUM_ARR(long,long);
SWIG_TYPEMAP_NUM_ARR(ulong,unsigned long);
SWIG_TYPEMAP_NUM_ARR(float,float);
SWIG_TYPEMAP_NUM_ARR(double,double);
// again enums are a problem so they need their own type
// we use the int conversion routine & recast it
%typemap(in) enum SWIGTYPE INPUT[ANY]
%{ $1 = ($ltype)SWIG_get_int_num_array_fixed(L,$input,$1_dim0);
if (!$1) SWIG_fail;%}
%typemap(freearg) enum SWIGTYPE INPUT[ANY]
%{ SWIG_FREE_ARRAY($1);%}
// variable size array's
%typemap(in) (enum SWIGTYPE *INPUT,int)
%{ $1 = ($ltype)SWIG_get_int_num_array_var(L,$input,&$2);
if (!$1) SWIG_fail;%}
%typemap(freearg) (enum SWIGTYPE *INPUT,int)
%{ SWIG_FREE_ARRAY($1);%}
// out fixed arrays
%typemap(in,numinputs=0) enum SWIGTYPE OUTPUT[ANY]
%{ $1 = SWIG_ALLOC_ARRAY(enum SWIGTYPE,$1_dim0); %}
%typemap(argout) enum SWIGTYPE OUTPUT[ANY]
%{ SWIG_write_int_num_array(L,(int*)$1,$1_dim0); SWIG_arg++; %}
%typemap(freearg) enum SWIGTYPE OUTPUT[ANY]
%{ SWIG_FREE_ARRAY($1); %}
// inout fixed arrays
%typemap(in) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE INPUT[ANY];
%typemap(argout) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE OUTPUT[ANY];
%typemap(freearg) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE INPUT[ANY];
// inout variable arrays
%typemap(in) (enum SWIGTYPE *INOUT,int)=(enum SWIGTYPE *INPUT,int);
%typemap(argout) (enum SWIGTYPE *INOUT,int)
%{ SWIG_write_int_num_array(L,(int*)$1,$2); SWIG_arg++; %}
%typemap(freearg) (enum SWIGTYPE *INOUT,int)=(enum SWIGTYPE *INPUT,int);
/* Surprisingly pointer arrays are easier:
this is because all ptr arrays become void**
so only a few fns are needed & a few casts
The function defined are
// created a fixed size array, reads the specified table
// and then fills the array with pointers (checking the type)
// returns ptr to the array if ok, or 0 for error
// (also pushes a error message to the stack)
void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_type_info *type);
// as per SWIG_get_ptr_array_fixed()
// but reads the entire table & creates an array of the correct size
// (if the table is empty, it returns an error rather than a zero length array)
void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_type_info *type);
// writes a table to Lua with all the specified pointers
// all pointers have the ownership value 'own' (normally 0)
void SWIG_write_ptr_array(lua_State* L,void **array,int size,int own);
// read the specified table, and fills the array with ptrs
// returns 1 of ok (only fails if it doesnt find correct type of ptrs)
// helper fn (called by SWIG_get_ptr_array_*() fns)
int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_info *type);
The key thing to remember is that it is assumed that there is no
modification of pointers ownership in the arrays
eg A fn:
void pointers_in(TYPE* arr[],int len);
will make copies of the pointer into a temp array and then pass it into the fn
Lua does not remeber that this fn held the pointers, so it is not safe to keep
these pointers until later
eg A fn:
void pointers_out(TYPE* arr[3]);
will return a table containing three pointers
however these pointers are NOT owned by Lua, merely borrowed
so if the C/C++ frees then Lua is not aware
*/
%{
int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_info *type){
int i;
for (i = 0; i < size; i++) {
lua_rawgeti(L,index,i+1);
if (!lua_isuserdata(L,-1) || SWIG_ConvertPtr(L,-1,&array[i],type,0)==-1){
lua_pop(L,1);
return 0;
}
lua_pop(L,1);
}
return 1;
}
static void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_type_info *type){
void **array;
if (!lua_istable(L,index) || SWIG_itable_size(L,index) != size) {
lua_pushfstring(L,"expected a table of size %d",size);
return 0;
}
array=SWIG_ALLOC_ARRAY(void*,size);
if (!SWIG_read_ptr_array(L,index,array,size,type)){
lua_pushfstring(L,"table must contain pointers of type %s",type->name);
SWIG_FREE_ARRAY(array);
return 0;
}
return array;
}
static void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_type_info *type){
void **array;
if (!lua_istable(L,index)) {
lua_pushstring(L,"expected a table");
return 0;
}
*size=SWIG_itable_size(L,index);
if (*size<1){
lua_pushstring(L,"table appears to be empty");
return 0;
}
array=SWIG_ALLOC_ARRAY(void*,*size);
if (!SWIG_read_ptr_array(L,index,array,*size,type)){
lua_pushfstring(L,"table must contain pointers of type %s",type->name);
SWIG_FREE_ARRAY(array);
return 0;
}
return array;
}
void SWIG_write_ptr_array(lua_State* L,void **array,int size,swig_type_info *type,int own){
int i;
lua_newtable(L);
for (i = 0; i < size; i++){
SWIG_NewPointerObj(L,array[i],type,own);
lua_rawseti(L,-2,i+1);/* -1 is the number, -2 is the table*/
}
}
%}
// fixed size array's
%typemap(in) SWIGTYPE* INPUT[ANY]
%{ $1 = ($ltype)SWIG_get_ptr_array_fixed(L,$input,$1_dim0,$*1_descriptor);
if (!$1) SWIG_fail;%}
%typemap(freearg) SWIGTYPE* INPUT[ANY]
%{ SWIG_FREE_ARRAY($1);%}
// variable size array's
%typemap(in) (SWIGTYPE **INPUT,int)
%{ $1 = ($ltype)SWIG_get_ptr_array_var(L,$input,&$2,$*1_descriptor);
if (!$1) SWIG_fail;%}
%typemap(freearg) (SWIGTYPE **INPUT,int)
%{ SWIG_FREE_ARRAY($1);%}
// out fixed arrays
%typemap(in,numinputs=0) SWIGTYPE* OUTPUT[ANY]
%{ $1 = SWIG_ALLOC_ARRAY($*1_type,$1_dim0); %}
%typemap(argout) SWIGTYPE* OUTPUT[ANY]
%{ SWIG_write_ptr_array(L,(void**)$1,$1_dim0,$*1_descriptor,0); SWIG_arg++; %}
%typemap(freearg) SWIGTYPE* OUTPUT[ANY]
%{ SWIG_FREE_ARRAY($1); %}
// inout fixed arrays
%typemap(in) SWIGTYPE* INOUT[ANY]=SWIGTYPE* INPUT[ANY];
%typemap(argout) SWIGTYPE* INOUT[ANY]=SWIGTYPE* OUTPUT[ANY];
%typemap(freearg) SWIGTYPE* INOUT[ANY]=SWIGTYPE* INPUT[ANY];
// inout variable arrays
%typemap(in) (SWIGTYPE** INOUT,int)=(SWIGTYPE** INPUT,int);
%typemap(argout) (SWIGTYPE** INOUT,int)
%{ SWIG_write_ptr_array(L,(void**)$1,$2,$*1_descriptor,0); SWIG_arg++; %}
%typemap(freearg) (SWIGTYPE**INOUT,int)=(SWIGTYPE**INPUT,int);
/* -----------------------------------------------------------------------------
* Pointer-Pointer typemaps
* ----------------------------------------------------------------------------- */
/*
This code is to deal with the issue for pointer-pointer's
In particular for factory methods.
for example take the following code segment:
struct iMath; // some structure
int Create_Math(iMath** pptr); // its factory (assume it mallocs)
to use it you might have the following C code:
iMath* ptr;
int ok;
ok=Create_Math(&ptr);
// do things with ptr
//...
free(ptr);
With the following SWIG code
%apply SWIGTYPE** OUTPUT{iMath **pptr };
You can get natural wrappering in Lua as follows:
ok,ptr=Create_Math() -- ptr is a iMath* which is returned with the int
ptr=nil -- the iMath* will be GC'ed as normal
*/
%typemap(in,numinputs=0) SWIGTYPE** OUTPUT ($*ltype temp)
%{ $1 = &temp; %}
%typemap(argout) SWIGTYPE** OUTPUT
%{SWIG_NewPointerObj(L,*$1,$*descriptor,1); SWIG_arg++; %}
+46
View File
@@ -0,0 +1,46 @@
/* -----------------------------------------------------------------------------
* See the LICENSE file for information on copyright, usage and redistribution
* of SWIG, and the README file for authors - http://www.swig.org/release.html.
*
* wchar.i
*
* Typemaps for the wchar_t type
* These are mapped to a Lua string and are passed around by value.
*
* ----------------------------------------------------------------------------- */
// note: only support for pointer right now, not fixed length strings
// TODO: determine how long a const wchar_t* is so we can write wstr2str()
// & do the output typemap
%{
#include <stdlib.h>
wchar_t* str2wstr(const char* str, int len)
{
wchar_t* p;
if (str==0 || len<1) return 0;
p=(wchar*)malloc((len+1)*sizeof(wchar_t));
if (p==0) return 0;
if (mbstowcs(p, str, len)==-1)
{
free(p);
return 0;
}
p[len]=0;
return p;
}
%}
%typemap( in, checkfn="lua_isstring" ) wchar_t*
%{
$1 = str2wstr(lua_tostring( L, $input ),lua_strlen( L, $input ));
if ($1==0) {lua_pushfstring(L,"Error in converting to wchar (arg %d)",$input);goto fail;}
%}
%typemap( freearg ) wchar_t*
%{
free($1);
%}
%typemap(typecheck) wchar_t * = char *;