PageRenderTime 50ms CodeModel.GetById 38ms app.highlight 3ms RepoModel.GetById 1ms app.codeStats 0ms

/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