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