Home | History | Annotate | Download | only in lua
      1 /* -----------------------------------------------------------------------------
      2  * typemaps.swg
      3  *
      4  * SWIG Library file containing the main typemap code to support Lua modules.
      5  * ----------------------------------------------------------------------------- */
      6 
      7 /* -----------------------------------------------------------------------------
      8  *                          Basic inout typemaps
      9  * ----------------------------------------------------------------------------- */
     10 /*
     11 These provide the basic ability for passing in & out of standard numeric data types
     12 (int,long,float,double, etc)
     13 
     14 The basic code looks like this:
     15 
     16 %typemap(in,checkfn="lua_isnumber") int *INPUT(int temp), int &INPUT(int temp)
     17 %{ temp = (int)lua_tonumber(L,$input);
     18    $1 = &temp; %}
     19 
     20 %typemap(in, numinputs=0) int *OUTPUT (int temp)
     21 %{ $1 = &temp; %}
     22 
     23 %typemap(argout) int *OUTPUT
     24 %{  lua_pushnumber(L, (double) *$1); SWIG_arg++;%}
     25 
     26 %typemap(in) int *INOUT = int *INPUT;
     27 %typemap(argout) int *INOUT = int *OUTPUT;
     28 
     29 However the code below is a mixture of #defines & such, so nowhere as easy to read
     30 
     31 To make you code work correctly its not just a matter of %including this file
     32 You also have to give SWIG the hints on which to use where
     33 
     34 eg
     35 extern int add_pointer(int* a1,int* a2); // a1 & a2 are pointer values to be added
     36 extern void swap(int* s1, int* s2);	// does the swap
     37 
     38 You will need to either change the argument names
     39 extern int add_pointer(int* INPUT,int* INPUT);
     40 
     41 or provide a %apply statement
     42 
     43 %apply int* INOUT{ int *s1, int *s2 };
     44 	// if SWIG sees int* s1, int* s2, assume they are inout params
     45 */
     46 
     47 
     48 %define SWIG_NUMBER_TYPEMAP(TYPE)
     49 %typemap(in,checkfn="lua_isnumber")	TYPE *INPUT($*ltype temp), TYPE &INPUT($*ltype temp)
     50 %{ temp = ($*ltype)lua_tonumber(L,$input);
     51    $1 = &temp; %}
     52 %typemap(in, numinputs=0) TYPE *OUTPUT ($*ltype temp)
     53 %{ $1 = &temp; %}
     54 %typemap(argout) TYPE *OUTPUT
     55 %{  lua_pushnumber(L, (lua_Number) *$1); SWIG_arg++;%}
     56 %typemap(in) TYPE *INOUT = TYPE *INPUT;
     57 %typemap(argout) TYPE *INOUT = TYPE *OUTPUT;
     58 %typemap(in) TYPE &OUTPUT = TYPE *OUTPUT;
     59 %typemap(argout) TYPE &OUTPUT = TYPE *OUTPUT;
     60 %typemap(in) TYPE &INOUT = TYPE *INPUT;
     61 %typemap(argout) TYPE &INOUT = TYPE *OUTPUT;
     62 // const version (the $*ltype is the basic number without ptr or const's)
     63 %typemap(in,checkfn="lua_isnumber")	const TYPE *INPUT($*ltype temp)
     64 %{ temp = ($*ltype)lua_tonumber(L,$input);
     65    $1 = &temp; %}
     66 %enddef
     67 
     68 // now the code
     69 SWIG_NUMBER_TYPEMAP(unsigned char); SWIG_NUMBER_TYPEMAP(signed char);
     70 
     71 SWIG_NUMBER_TYPEMAP(short); SWIG_NUMBER_TYPEMAP(unsigned short); SWIG_NUMBER_TYPEMAP(signed short);
     72 SWIG_NUMBER_TYPEMAP(int); SWIG_NUMBER_TYPEMAP(unsigned int); SWIG_NUMBER_TYPEMAP(signed int);
     73 SWIG_NUMBER_TYPEMAP(long); SWIG_NUMBER_TYPEMAP(unsigned long); SWIG_NUMBER_TYPEMAP(signed long);
     74 SWIG_NUMBER_TYPEMAP(float);
     75 SWIG_NUMBER_TYPEMAP(double);
     76 SWIG_NUMBER_TYPEMAP(enum SWIGTYPE);
     77 // also for long longs's
     78 SWIG_NUMBER_TYPEMAP(long long); SWIG_NUMBER_TYPEMAP(unsigned long long); SWIG_NUMBER_TYPEMAP(signed long long);
     79 
     80 // note we dont do char, as a char* is probably a string not a ptr to a single char
     81 
     82 // similar for booleans
     83 %typemap(in,checkfn="lua_isboolean") bool *INPUT(bool temp), bool &INPUT(bool temp)
     84 %{ temp = (lua_toboolean(L,$input)!=0);
     85    $1 = &temp; %}
     86 
     87 %typemap(in, numinputs=0) bool *OUTPUT (bool temp),bool &OUTPUT (bool temp)
     88 %{ $1 = &temp; %}
     89 
     90 %typemap(argout) bool *OUTPUT,bool &OUTPUT
     91 %{  lua_pushboolean(L, (int)((*$1)!=0)); SWIG_arg++;%}
     92 
     93 %typemap(in) bool *INOUT = bool *INPUT;
     94 %typemap(argout) bool *INOUT = bool *OUTPUT;
     95 %typemap(in) bool &INOUT = bool &INPUT;
     96 %typemap(argout) bool &INOUT = bool &OUTPUT;
     97 
     98 /* -----------------------------------------------------------------------------
     99  *                          Basic Array typemaps
    100  * ----------------------------------------------------------------------------- */
    101 /*
    102 I have no idea why this kind of code does not exist in SWIG as standard,
    103 but here is it.
    104 This code will convert to/from 1D numeric arrays.
    105 In order to reduce code bloat, there are a few macros
    106 and quite a few functions defined
    107 (unfortunately this makes it a lot less clear)
    108 
    109 assuming we have functions
    110 void process_array(int arr[3]);	// nice fixed size array
    111 void process_var_array(float arr[],int len);	// variable sized array
    112 void process_var_array_inout(double* arr,int len);	// variable sized array
    113 			// data passed in & out
    114 void process_enum_inout_array_var(enum Days *arrinout, int len);	// using enums
    115 void return_array_5(int arrout[5]);	// out array only
    116 
    117 in order to wrap them correctly requires a typemap
    118 
    119 // inform SWIG of the correct typemap
    120 // For fixed length, you must specify it as <type> INPUT[ANY]
    121 %apply (int INPUT[ANY]) {(int arr[3])};
    122 // variable length arrays are just the same
    123 %apply (float INPUT[],int) {(float arr[],int len)};
    124 // it is also ok, to map the TYPE* instead of a TYPE[]
    125 %apply (double *INOUT,int) {(double arr*,int len)};
    126 // for the enum's you must use enum SWIGTYPE
    127 %apply (enum SWIGTYPE *INOUT,int) {(enum Days *arrinout, int len)};
    128 // fixed length out if also fine
    129 %apply (int OUTPUT[ANY]) {(int arrout[5])};
    130 
    131 Generally, you could use %typemap(...)=...
    132 but the %apply is neater & easier
    133 
    134 a few things of note:
    135 * all Lua tables are indexed from 1, all C/C++ arrays are indexed from 0
    136 	therefore t={6,5,3} -- t[1]==6, t[2]==5, t[3]==3
    137 	when passed to process_array(int arr[3]) becomes
    138 	arr[0]==6, arr[1]==5, arr[2]==3
    139 * for OUTPUT arrays, no array need be passed in, the fn will return a Lua table
    140 	so for the above mentioned return_array_5() would look like
    141 	arr=return_array_5() -- no parameters passed in
    142 * for INOUT arrays, a table must be passed in, and a new table will be returned
    143 	(this is consistent with the way that numbers are processed)
    144 	if you want just use
    145 	arr={...}
    146 	arr=process_var_array_inout(arr)	-- arr is replaced by the new version
    147 
    148 The following are not yet supported:
    149 * variable length output only array (inout works ok)
    150 * multidimensional arrays
    151 * arrays of objects/structs
    152 * arrays of pointers
    153 
    154 */
    155 
    156 /*
    157 The internals of the array management stuff
    158 helper fns/macros
    159 SWIG_ALLOC_ARRAY(TYPE,LEN)	// returns a typed array TYPE[LEN]
    160 SWIG_FREE_ARRAY(PTR)		// delete the ptr (if not zero)
    161 
    162 // counts the specified table & gets the size
    163 // integer version
    164 int SWIG_itable_size(lua_State* L, int index);
    165 // other version
    166 int SWIG_table_size(lua_State* L, int index);
    167 
    168 SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE)
    169 // this fn declares up 4 functions for helping to read/write tables
    170 // these can then be called by the macros ...
    171 // all assume the table is an integer indexes from 1
    172 // but the C array is a indexed from 0
    173 	// created a fixed size array, reads the specified table
    174 	// and then fills the array with numbers
    175 	// returns ptr to the array if ok, or 0 for error
    176 	// (also pushes a error message to the stack)
    177 TYPE* SWIG_get_NAME_num_array_fixed(lua_State* L, int index, int size);
    178 	// as per SWIG_get_NAME_num_array_fixed()
    179 	// but reads the entire table & creates an array of the correct size
    180 	// (if the table is empty, it returns an error rather than a zero length array)
    181 TYPE* SWIG_get_NAME_num_array_var(lua_State* L, int index, int* size);
    182 	// writes a table to Lua with all the specified numbers
    183 void SWIG_write_NAME_num_array(lua_State* L,TYPE *array,int size);
    184 	// read the specified table, and fills the array with numbers
    185 	// returns 1 of ok (only fails if it doesnt find numbers)
    186 	// helper fn (called by SWIG_get_NAME_num_array_*() fns)
    187 int SWIG_read_NAME_num_array(lua_State* L,int index,TYPE *array,int size);
    188 
    189 */
    190 
    191 /* Reported that you don't need to check for NULL for delete & free
    192 There probably is some compiler that its not true for, so the code is left here just in case.
    193 #ifdef __cplusplus
    194 #define SWIG_ALLOC_ARRAY(TYPE,LEN) 	new TYPE[LEN]
    195 #define SWIG_FREE_ARRAY(PTR)		if(PTR){delete[] PTR;}
    196 #else
    197 #define SWIG_ALLOC_ARRAY(TYPE,LEN) 	(TYPE *)malloc(LEN*sizeof(TYPE))
    198 #define SWIG_FREE_ARRAY(PTR)		if(PTR){free(PTR);}
    199 #endif
    200 */
    201 %{
    202 #ifdef __cplusplus	/* generic alloc/dealloc fns*/
    203 #define SWIG_ALLOC_ARRAY(TYPE,LEN) 	new TYPE[LEN]
    204 #define SWIG_FREE_ARRAY(PTR)		delete[] PTR
    205 #else
    206 #define SWIG_ALLOC_ARRAY(TYPE,LEN) 	(TYPE *)malloc(LEN*sizeof(TYPE))
    207 #define SWIG_FREE_ARRAY(PTR)		free(PTR)
    208 #endif
    209 /* counting the size of arrays:*/
    210 SWIGINTERN int SWIG_itable_size(lua_State* L, int index)
    211 {
    212 	int n=0;
    213 	while(1){
    214 		lua_rawgeti(L,index,n+1);
    215 		if (lua_isnil(L,-1))break;
    216 		++n;
    217 		lua_pop(L,1);
    218 	}
    219 	lua_pop(L,1);
    220 	return n;
    221 }
    222 
    223 SWIGINTERN int SWIG_table_size(lua_State* L, int index)
    224 {
    225 	int n=0;
    226 	lua_pushnil(L);  /* first key*/
    227 	while (lua_next(L, index) != 0) {
    228 		++n;
    229 		lua_pop(L, 1);  /* removes `value'; keeps `key' for next iteration*/
    230 	}
    231 	return n;
    232 }
    233 
    234 /* super macro to declare array typemap helper fns */
    235 #define SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE)\
    236 	SWIGINTERN int SWIG_read_##NAME##_num_array(lua_State* L,int index,TYPE *array,int size){\
    237 		int i;\
    238 		for (i = 0; i < size; i++) {\
    239 			lua_rawgeti(L,index,i+1);\
    240 			if (lua_isnumber(L,-1)){\
    241 				array[i] = (TYPE)lua_tonumber(L,-1);\
    242 			} else {\
    243 				lua_pop(L,1);\
    244 				return 0;\
    245 			}\
    246 			lua_pop(L,1);\
    247 		}\
    248 		return 1;\
    249 	}\
    250 	SWIGINTERN TYPE* SWIG_get_##NAME##_num_array_fixed(lua_State* L, int index, int size){\
    251 		TYPE *array;\
    252 		if (!lua_istable(L,index) || SWIG_itable_size(L,index) != size) {\
    253 			SWIG_Lua_pushferrstring(L,"expected a table of size %d",size);\
    254 			return 0;\
    255 		}\
    256 		array=SWIG_ALLOC_ARRAY(TYPE,size);\
    257 		if (!SWIG_read_##NAME##_num_array(L,index,array,size)){\
    258 			SWIG_Lua_pusherrstring(L,"table must contain numbers");\
    259 			SWIG_FREE_ARRAY(array);\
    260 			return 0;\
    261 		}\
    262 		return array;\
    263 	}\
    264 	SWIGINTERN TYPE* SWIG_get_##NAME##_num_array_var(lua_State* L, int index, int* size)\
    265 	{\
    266 		TYPE *array;\
    267 		if (!lua_istable(L,index)) {\
    268 			SWIG_Lua_pusherrstring(L,"expected a table");\
    269 			return 0;\
    270 		}\
    271 		*size=SWIG_itable_size(L,index);\
    272 		if (*size<1){\
    273 			SWIG_Lua_pusherrstring(L,"table appears to be empty");\
    274 			return 0;\
    275 		}\
    276 		array=SWIG_ALLOC_ARRAY(TYPE,*size);\
    277 		if (!SWIG_read_##NAME##_num_array(L,index,array,*size)){\
    278 			SWIG_Lua_pusherrstring(L,"table must contain numbers");\
    279 			SWIG_FREE_ARRAY(array);\
    280 			return 0;\
    281 		}\
    282 		return array;\
    283 	}\
    284 	SWIGINTERN void SWIG_write_##NAME##_num_array(lua_State* L,TYPE *array,int size){\
    285 		int i;\
    286 		lua_newtable(L);\
    287 		for (i = 0; i < size; i++){\
    288 			lua_pushnumber(L,(lua_Number)array[i]);\
    289 			lua_rawseti(L,-2,i+1);/* -1 is the number, -2 is the table*/ \
    290 		}\
    291 	}
    292 %}
    293 
    294 /*
    295 This is one giant macro to define the typemaps & the helpers
    296 for array handling
    297 */
    298 %define SWIG_TYPEMAP_NUM_ARR(NAME,TYPE)
    299 %{SWIG_DECLARE_TYPEMAP_ARR_FN(NAME,TYPE);%}
    300 
    301 // fixed size array's
    302 %typemap(in) TYPE INPUT[ANY]
    303 %{	$1 = SWIG_get_##NAME##_num_array_fixed(L,$input,$1_dim0);
    304 	if (!$1) SWIG_fail;%}
    305 
    306 %typemap(freearg) TYPE INPUT[ANY]
    307 %{	SWIG_FREE_ARRAY($1);%}
    308 
    309 // variable size array's
    310 %typemap(in) (TYPE *INPUT,int)
    311 %{	$1 = SWIG_get_##NAME##_num_array_var(L,$input,&$2);
    312 	if (!$1) SWIG_fail;%}
    313 
    314 %typemap(freearg) (TYPE *INPUT,int)
    315 %{	SWIG_FREE_ARRAY($1);%}
    316 
    317 // out fixed arrays
    318 %typemap(in,numinputs=0) TYPE OUTPUT[ANY]
    319 %{  $1 = SWIG_ALLOC_ARRAY(TYPE,$1_dim0); %}
    320 
    321 %typemap(argout) TYPE OUTPUT[ANY]
    322 %{	SWIG_write_##NAME##_num_array(L,$1,$1_dim0); SWIG_arg++; %}
    323 
    324 %typemap(freearg) TYPE OUTPUT[ANY]
    325 %{	SWIG_FREE_ARRAY($1); %}
    326 
    327 // inout fixed arrays
    328 %typemap(in) TYPE INOUT[ANY]=TYPE INPUT[ANY];
    329 %typemap(argout) TYPE INOUT[ANY]=TYPE OUTPUT[ANY];
    330 %typemap(freearg) TYPE INOUT[ANY]=TYPE INPUT[ANY];
    331 // inout variable arrays
    332 %typemap(in) (TYPE *INOUT,int)=(TYPE *INPUT,int);
    333 %typemap(argout) (TYPE *INOUT,int)
    334 %{	SWIG_write_##NAME##_num_array(L,$1,$2); SWIG_arg++; %}
    335 %typemap(freearg) (TYPE *INOUT,int)=(TYPE *INPUT,int);
    336 
    337 // TODO out variable arrays (is there a standard form for such things?)
    338 
    339 // referencing so that (int *INPUT,int) and (int INPUT[],int) are the same
    340 %typemap(in) (TYPE INPUT[],int)=(TYPE *INPUT,int);
    341 %typemap(freearg) (TYPE INPUT[],int)=(TYPE *INPUT,int);
    342 
    343 %enddef
    344 
    345 // the following line of code
    346 // declares the C helper fns for the array typemaps
    347 // as well as defining typemaps for
    348 // fixed len arrays in & out, & variable length arrays in
    349 
    350 SWIG_TYPEMAP_NUM_ARR(schar,signed char);
    351 SWIG_TYPEMAP_NUM_ARR(uchar,unsigned char);
    352 SWIG_TYPEMAP_NUM_ARR(int,int);
    353 SWIG_TYPEMAP_NUM_ARR(uint,unsigned int);
    354 SWIG_TYPEMAP_NUM_ARR(short,short);
    355 SWIG_TYPEMAP_NUM_ARR(ushort,unsigned short);
    356 SWIG_TYPEMAP_NUM_ARR(long,long);
    357 SWIG_TYPEMAP_NUM_ARR(ulong,unsigned long);
    358 SWIG_TYPEMAP_NUM_ARR(float,float);
    359 SWIG_TYPEMAP_NUM_ARR(double,double);
    360 
    361 // again enums are a problem so they need their own type
    362 // we use the int conversion routine & recast it
    363 %typemap(in) enum SWIGTYPE INPUT[ANY]
    364 %{	$1 = ($ltype)SWIG_get_int_num_array_fixed(L,$input,$1_dim0);
    365 	if (!$1) SWIG_fail;%}
    366 
    367 %typemap(freearg) enum SWIGTYPE INPUT[ANY]
    368 %{	SWIG_FREE_ARRAY($1);%}
    369 
    370 // variable size arrays
    371 %typemap(in) (enum SWIGTYPE *INPUT,int)
    372 %{	$1 = ($ltype)SWIG_get_int_num_array_var(L,$input,&$2);
    373 	if (!$1) SWIG_fail;%}
    374 
    375 %typemap(freearg) (enum SWIGTYPE *INPUT,int)
    376 %{	SWIG_FREE_ARRAY($1);%}
    377 
    378 // out fixed arrays
    379 %typemap(in,numinputs=0) enum SWIGTYPE OUTPUT[ANY]
    380 %{  $1 = SWIG_ALLOC_ARRAY(enum SWIGTYPE,$1_dim0); %}
    381 
    382 %typemap(argout) enum SWIGTYPE OUTPUT[ANY]
    383 %{	SWIG_write_int_num_array(L,(int*)$1,$1_dim0); SWIG_arg++; %}
    384 
    385 %typemap(freearg) enum SWIGTYPE OUTPUT[ANY]
    386 %{	SWIG_FREE_ARRAY($1); %}
    387 
    388 // inout fixed arrays
    389 %typemap(in) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE INPUT[ANY];
    390 %typemap(argout) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE OUTPUT[ANY];
    391 %typemap(freearg) enum SWIGTYPE INOUT[ANY]=enum SWIGTYPE INPUT[ANY];
    392 // inout variable arrays
    393 %typemap(in) (enum SWIGTYPE *INOUT,int)=(enum SWIGTYPE *INPUT,int);
    394 %typemap(argout) (enum SWIGTYPE *INOUT,int)
    395 %{	SWIG_write_int_num_array(L,(int*)$1,$2); SWIG_arg++; %}
    396 %typemap(freearg) (enum SWIGTYPE *INOUT,int)=(enum SWIGTYPE *INPUT,int);
    397 
    398 
    399 /* Surprisingly pointer arrays are easier:
    400 this is because all ptr arrays become void**
    401 so only a few fns are needed & a few casts
    402 
    403 The function defined are
    404 	// created a fixed size array, reads the specified table
    405 	// and then fills the array with pointers (checking the type)
    406 	// returns ptr to the array if ok, or 0 for error
    407 	// (also pushes a error message to the stack)
    408 void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_type_info *type);
    409 	// as per SWIG_get_ptr_array_fixed()
    410 	// but reads the entire table & creates an array of the correct size
    411 	// (if the table is empty, it returns an error rather than a zero length array)
    412 void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_type_info *type);
    413 	// writes a table to Lua with all the specified pointers
    414 	// all pointers have the ownership value 'own' (normally 0)
    415 void SWIG_write_ptr_array(lua_State* L,void **array,int size,int own);
    416 	// read the specified table, and fills the array with ptrs
    417 	// returns 1 of ok (only fails if it doesn't find correct type of ptrs)
    418 	// helper fn (called by SWIG_get_ptr_array_*() fns)
    419 int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_info *type);
    420 
    421 The key thing to remember is that it is assumed that there is no
    422 modification of pointers ownership in the arrays
    423 
    424 eg A fn:
    425 void pointers_in(TYPE* arr[],int len);
    426 will make copies of the pointer into a temp array and then pass it into the fn
    427 Lua does not remember that this fn held the pointers, so it is not safe to keep
    428 these pointers until later
    429 
    430 eg A fn:
    431 void pointers_out(TYPE* arr[3]);
    432 will return a table containing three pointers
    433 however these pointers are NOT owned by Lua, merely borrowed
    434 so if the C/C++ frees then Lua is not aware
    435 
    436 */
    437 
    438 %{
    439 SWIGINTERN int SWIG_read_ptr_array(lua_State* L,int index,void **array,int size,swig_type_info *type){
    440 	int i;
    441 	for (i = 0; i < size; i++) {
    442 		lua_rawgeti(L,index,i+1);
    443 		if (!lua_isuserdata(L,-1) || SWIG_ConvertPtr(L,-1,&array[i],type,0)==-1){
    444 			lua_pop(L,1);
    445 			return 0;
    446 		}
    447 		lua_pop(L,1);
    448 	}
    449 	return 1;
    450 }
    451 SWIGINTERN void** SWIG_get_ptr_array_fixed(lua_State* L, int index, int size,swig_type_info *type){
    452 	void **array;
    453 	if (!lua_istable(L,index) || SWIG_itable_size(L,index) != size) {
    454 		SWIG_Lua_pushferrstring(L,"expected a table of size %d",size);
    455 		return 0;
    456 	}
    457 	array=SWIG_ALLOC_ARRAY(void*,size);
    458 	if (!SWIG_read_ptr_array(L,index,array,size,type)){
    459 		SWIG_Lua_pushferrstring(L,"table must contain pointers of type %s",type->name);
    460 		SWIG_FREE_ARRAY(array);
    461 		return 0;
    462 	}
    463 	return array;
    464 }
    465 SWIGINTERN void** SWIG_get_ptr_array_var(lua_State* L, int index, int* size,swig_type_info *type){
    466 	void **array;
    467 	if (!lua_istable(L,index)) {
    468 		SWIG_Lua_pusherrstring(L,"expected a table");
    469 		return 0;
    470 	}
    471 	*size=SWIG_itable_size(L,index);
    472 	if (*size<1){
    473 		SWIG_Lua_pusherrstring(L,"table appears to be empty");
    474 		return 0;
    475 	}
    476 	array=SWIG_ALLOC_ARRAY(void*,*size);
    477 	if (!SWIG_read_ptr_array(L,index,array,*size,type)){
    478 		SWIG_Lua_pushferrstring(L,"table must contain pointers of type %s",type->name);
    479 		SWIG_FREE_ARRAY(array);
    480 		return 0;
    481 	}
    482 	return array;
    483 }
    484 SWIGINTERN void SWIG_write_ptr_array(lua_State* L,void **array,int size,swig_type_info *type,int own){
    485 	int i;
    486 	lua_newtable(L);
    487 	for (i = 0; i < size; i++){
    488 		SWIG_NewPointerObj(L,array[i],type,own);
    489 		lua_rawseti(L,-2,i+1);/* -1 is the number, -2 is the table*/
    490 	}
    491 }
    492 %}
    493 
    494 // fixed size array's
    495 %typemap(in) SWIGTYPE* INPUT[ANY]
    496 %{	$1 = ($ltype)SWIG_get_ptr_array_fixed(L,$input,$1_dim0,$*1_descriptor);
    497 	if (!$1) SWIG_fail;%}
    498 
    499 %typemap(freearg) SWIGTYPE* INPUT[ANY]
    500 %{	SWIG_FREE_ARRAY($1);%}
    501 
    502 // variable size array's
    503 %typemap(in) (SWIGTYPE **INPUT,int)
    504 %{	$1 = ($ltype)SWIG_get_ptr_array_var(L,$input,&$2,$*1_descriptor);
    505 	if (!$1) SWIG_fail;%}
    506 
    507 %typemap(freearg) (SWIGTYPE **INPUT,int)
    508 %{	SWIG_FREE_ARRAY($1);%}
    509 
    510 // out fixed arrays
    511 %typemap(in,numinputs=0) SWIGTYPE* OUTPUT[ANY]
    512 %{  $1 = SWIG_ALLOC_ARRAY($*1_type,$1_dim0); %}
    513 
    514 %typemap(argout) SWIGTYPE* OUTPUT[ANY]
    515 %{	SWIG_write_ptr_array(L,(void**)$1,$1_dim0,$*1_descriptor,0); SWIG_arg++; %}
    516 
    517 %typemap(freearg) SWIGTYPE* OUTPUT[ANY]
    518 %{	SWIG_FREE_ARRAY($1); %}
    519 
    520 // inout fixed arrays
    521 %typemap(in) SWIGTYPE* INOUT[ANY]=SWIGTYPE* INPUT[ANY];
    522 %typemap(argout) SWIGTYPE* INOUT[ANY]=SWIGTYPE* OUTPUT[ANY];
    523 %typemap(freearg) SWIGTYPE* INOUT[ANY]=SWIGTYPE* INPUT[ANY];
    524 // inout variable arrays
    525 %typemap(in) (SWIGTYPE** INOUT,int)=(SWIGTYPE** INPUT,int);
    526 %typemap(argout) (SWIGTYPE** INOUT,int)
    527 %{	SWIG_write_ptr_array(L,(void**)$1,$2,$*1_descriptor,0); SWIG_arg++; %}
    528 %typemap(freearg) (SWIGTYPE**INOUT,int)=(SWIGTYPE**INPUT,int);
    529 
    530 /* -----------------------------------------------------------------------------
    531  *                          Pointer-Pointer typemaps
    532  * ----------------------------------------------------------------------------- */
    533 /*
    534 This code is to deal with the issue for pointer-pointer's
    535 In particular for factory methods.
    536 
    537 for example take the following code segment:
    538 
    539 struct iMath;    // some structure
    540 int Create_Math(iMath** pptr); // its factory (assume it mallocs)
    541 
    542 to use it you might have the following C code:
    543 
    544 iMath* ptr;
    545 int ok;
    546 ok=Create_Math(&ptr);
    547 // do things with ptr
    548 //...
    549 free(ptr);
    550 
    551 With the following SWIG code
    552 %apply SWIGTYPE** OUTPUT{iMath **pptr };
    553 
    554 You can get natural wrapping in Lua as follows:
    555 ok,ptr=Create_Math() -- ptr is a iMath* which is returned with the int
    556 ptr=nil -- the iMath* will be GC'ed as normal
    557 */
    558 
    559 %typemap(in,numinputs=0) SWIGTYPE** OUTPUT ($*ltype temp)
    560 %{ temp = ($*ltype)0;
    561    $1 = &temp; %}
    562 %typemap(argout) SWIGTYPE** OUTPUT
    563 %{SWIG_NewPointerObj(L,*$1,$*descriptor,1); SWIG_arg++; %}
    564 
    565