PageRenderTime 93ms CodeModel.GetById 19ms RepoModel.GetById 3ms app.codeStats 0ms

/trunk/Lib/lua/luatypemaps.swg

#
Unknown | 389 lines | 325 code | 64 blank | 0 comment | 0 complexity | 3ce7a85025b85d8f00845adbec4f6d3e MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
  1. /* -----------------------------------------------------------------------------
  2. * luatypemaps.swg
  3. *
  4. * basic typemaps for Lua.
  5. * ----------------------------------------------------------------------------- */
  6. /* -----------------------------------------------------------------------------
  7. * standard typemaps
  8. * ----------------------------------------------------------------------------- */
  9. /* NEW LANGUAGE NOTE:
  10. the 'checkfn' param is something that I added for typemap(in)
  11. it is an optional fn call to check the type of the lua object
  12. the fn call must be of the form
  13. int checkfn(lua_State *L, int index);
  14. and return 1/0 depending upon if this is the correct type
  15. For the typemap(out), an additional SWIG_arg parmeter must be incremented
  16. to reflect the number of values returned (normally SWIG_arg++; will do)
  17. */
  18. // numbers
  19. %typemap(in,checkfn="lua_isnumber") int, short, long,
  20. signed char, float, double
  21. %{$1 = ($type)lua_tonumber(L, $input);%}
  22. // additional check for unsigned numbers, to not permit negative input
  23. %typemap(in,checkfn="lua_isnumber") unsigned int,
  24. unsigned short, unsigned long, unsigned char
  25. %{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative")
  26. $1 = ($type)lua_tonumber(L, $input);%}
  27. %typemap(out) int,short,long,
  28. unsigned int,unsigned short,unsigned long,
  29. signed char,unsigned char,
  30. float,double
  31. %{ lua_pushnumber(L, (lua_Number) $1); SWIG_arg++;%}
  32. // we must also provide typemaps for privitives by const reference:
  33. // given a function:
  34. // int intbyref(const int& i);
  35. // SWIG assumes that this code will need a pointer to int to be passed in
  36. // (this might be ok for objects by const ref, but not for numeric primitives)
  37. // therefore we add a set of typemaps to fix this (for both in & out)
  38. %typemap(in,checkfn="lua_isnumber") const int&($basetype temp)
  39. %{ temp=($basetype)lua_tonumber(L,$input); $1=&temp;%}
  40. %typemap(in,checkfn="lua_isnumber") const unsigned int&($basetype temp)
  41. %{SWIG_contract_assert((lua_tonumber(L,$input)>=0),"number must not be negative")
  42. temp=($basetype)lua_tonumber(L,$input); $1=&temp;%}
  43. %typemap(out) const int&, const unsigned int&
  44. %{ lua_pushnumber(L, (lua_Number) *$1); SWIG_arg++;%}
  45. // for the other numbers we can just use an apply statement to cover them
  46. %apply const int & {const short&,const long&,const signed char&,
  47. const float&,const double&};
  48. %apply const unsigned int & {const unsigned short&,const unsigned long&,
  49. const unsigned char&};
  50. /* enums have to be handled slightly differently
  51. VC++ .net will not allow a cast from lua_Number(double) to enum directly.
  52. */
  53. %typemap(in,checkfn="lua_isnumber") enum SWIGTYPE
  54. %{$1 = ($type)(int)lua_tonumber(L, $input);%}
  55. %typemap(out) enum SWIGTYPE
  56. %{ lua_pushnumber(L, (lua_Number)(int)($1)); SWIG_arg++;%}
  57. // and const refs
  58. %typemap(in,checkfn="lua_isnumber") const enum SWIGTYPE &($basetype temp)
  59. %{ temp=($basetype)(int)lua_tonumber(L,$input); $1=&temp;%}
  60. %typemap(out) const enum SWIGTYPE &
  61. %{ lua_pushnumber(L, (lua_Number) *$1); SWIG_arg++;%}
  62. // boolean (which is a special type in lua)
  63. // note: lua_toboolean() returns 1 or 0
  64. // note: 1 & 0 are not booleans in lua, only true & false
  65. %typemap(in,checkfn="lua_isboolean") bool
  66. %{$1 = (lua_toboolean(L, $input)!=0);%}
  67. %typemap(out) bool
  68. %{ lua_pushboolean(L,(int)($1!=0)); SWIG_arg++;%}
  69. // for const bool&, SWIG treats this as a const bool* so we must dereference it
  70. %typemap(in,checkfn="lua_isboolean") const bool& (bool temp)
  71. %{temp=(lua_toboolean(L, $input)!=0);
  72. $1=&temp;%}
  73. %typemap(out) const bool&
  74. %{ lua_pushboolean(L,(int)((*$1)!=0)); SWIG_arg++;%}
  75. // strings (char * and char[])
  76. %fragment("SWIG_lua_isnilstring", "header") {
  77. SWIGINTERN int SWIG_lua_isnilstring(lua_State *L, int idx) {
  78. int ret = lua_isstring(L, idx);
  79. if (!ret)
  80. ret = lua_isnil(L, idx);
  81. return ret;
  82. }
  83. }
  84. %typemap(in,checkfn="SWIG_lua_isnilstring",fragment="SWIG_lua_isnilstring") const char *, char *
  85. %{$1 = ($ltype)lua_tostring(L, $input);%}
  86. %typemap(in,checkfn="SWIG_lua_isnilstring",fragment="SWIG_lua_isnilstring") const char[ANY], char[ANY]
  87. %{$1 = ($ltype)lua_tostring(L, $input);%}
  88. %typemap(out) const char *, char *
  89. %{ lua_pushstring(L,(const char *)$1); SWIG_arg++;%}
  90. %typemap(out) const char[ANY], char[ANY]
  91. %{ lua_pushstring(L,(const char *)$1); SWIG_arg++;%}
  92. // char's
  93. // currently treating chars as small strings, not as numbers
  94. // (however signed & unsigned char's are numbers...)
  95. %typemap(in,checkfn="SWIG_lua_isnilstring",fragment="SWIG_lua_isnilstring") char
  96. %{$1 = (lua_tostring(L, $input))[0];%}
  97. %typemap(out) char
  98. %{ lua_pushfstring(L,"%c",$1); SWIG_arg++;%}
  99. // by const ref
  100. %typemap(in,checkfn="SWIG_lua_isnilstring",fragment="SWIG_lua_isnilstring") const char& (char temp)
  101. %{temp = (lua_tostring(L, $input))[0]; $1=&temp;%}
  102. %typemap(out) const char&
  103. %{ lua_pushfstring(L,"%c",*$1); SWIG_arg++;%}
  104. // pointers and references
  105. // under SWIG rules, it is ok, to have a pass in a lua nil,
  106. // it should be converted to a SWIG NULL.
  107. // This will only be allowed for pointers & arrays, not refs or by value
  108. // the checkfn lua_isuserdata will only work for userdata
  109. // the checkfn SWIG_isptrtype will work for both userdata and nil's
  110. %typemap(in,checkfn="SWIG_isptrtype") SWIGTYPE*,SWIGTYPE[]
  111. %{
  112. if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,$disown))){
  113. SWIG_fail_ptr("$symname",$argnum,$descriptor);
  114. }
  115. %}
  116. %typemap(in,checkfn="lua_isuserdata") SWIGTYPE&
  117. %{
  118. if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,$disown))){
  119. SWIG_fail_ptr("$symname",$argnum,$descriptor);
  120. }
  121. %}
  122. // out is simple
  123. %typemap(out) SWIGTYPE*,SWIGTYPE&
  124. %{SWIG_NewPointerObj(L,$1,$descriptor,$owner); SWIG_arg++; %}
  125. // dynamic casts
  126. // this uses the SWIG_TypeDynamicCast() which relies on RTTI to find out what the pointer really is
  127. // the we return it as the correct type
  128. %typemap(out) SWIGTYPE *DYNAMIC,
  129. SWIGTYPE &DYNAMIC
  130. {
  131. swig_type_info *ty = SWIG_TypeDynamicCast($1_descriptor, (void **) &$1);
  132. SWIG_NewPointerObj(L,(void*)$1,ty,$owner); SWIG_arg++;
  133. }
  134. // passing objects by value
  135. // SWIG_ConvertPtr wants an object pointer (the $&ltype argp)
  136. // then dereferences it to get the object
  137. %typemap(in,checkfn="lua_isuserdata") SWIGTYPE ($&ltype argp)
  138. %{
  139. if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&argp,$&descriptor,0))){
  140. SWIG_fail_ptr("$symname",$argnum,$&descriptor);
  141. }
  142. $1 = *argp;
  143. %}
  144. // Also needed for object ptrs by const ref
  145. // eg A* const& ref_pointer(A* const& a);
  146. // found in mixed_types.i
  147. %typemap(in,checkfn="lua_isuserdata") SWIGTYPE *const&($*ltype temp)
  148. %{temp=($*ltype)SWIG_MustGetPtr(L,$input,$*descriptor,0,$argnum,"$symname");
  149. $1=($1_ltype)&temp;%}
  150. %typemap(out) SWIGTYPE *const&
  151. %{SWIG_NewPointerObj(L,*$1,$*descriptor,$owner); SWIG_arg++; %}
  152. // DISOWN-ing typemaps
  153. // if you have an object pointer which must be disowned, use this typemap
  154. // eg. for void destroy_foo(Foo* toDie);
  155. // use %apply SWIGTYPE* DISOWN {Foo* toDie};
  156. // you could just use %delobject, but this is more flexible
  157. %typemap(in,checkfn="SWIG_isptrtype") SWIGTYPE* DISOWN,SWIGTYPE DISOWN[]
  158. %{ if (!SWIG_IsOK(SWIG_ConvertPtr(L,$input,(void**)&$1,$descriptor,SWIG_POINTER_DISOWN))){
  159. SWIG_fail_ptr("$symname",$argnum,$descriptor);
  160. }
  161. %}
  162. // Primitive types--return by value
  163. // must make a new object, copy the data & return the new object
  164. // Note: the brackets are {...} and not %{..%}, because we want them to be included in the wrapper
  165. // this is because typemap(out) does not support local variables, like in typemap(in) does
  166. // and we need the $&1_ltype resultptr; to be declared
  167. #ifdef __cplusplus
  168. %typemap(out) SWIGTYPE
  169. {
  170. $&1_ltype resultptr = new $1_ltype((const $1_ltype &) $1);
  171. SWIG_NewPointerObj(L,(void *) resultptr,$&1_descriptor,1); SWIG_arg++;
  172. }
  173. #else
  174. %typemap(out) SWIGTYPE
  175. {
  176. $&1_ltype resultptr;
  177. resultptr = ($&1_ltype) malloc(sizeof($1_type));
  178. memmove(resultptr, &$1, sizeof($1_type));
  179. SWIG_NewPointerObj(L,(void *) resultptr,$&1_descriptor,1); SWIG_arg++;
  180. }
  181. #endif
  182. // member function pointer
  183. // a member fn ptr is not 4 bytes like a normal pointer, but 8 bytes (at least on mingw)
  184. // so the standard wrappering cannot be done
  185. // nor can you cast a member function pointer to a void* (obviously)
  186. // therefore a special wrappering functions SWIG_ConvertMember() & SWIG_NewMemberObj() were written
  187. #ifdef __cplusplus
  188. %typemap(in,checkfn="lua_isuserdata") SWIGTYPE (CLASS::*)
  189. %{
  190. if (!SWIG_IsOK(SWIG_ConvertMember(L,$input,(void*)(&$1),sizeof($type),$descriptor)))
  191. SWIG_fail_ptr("$symname",$argnum,$descriptor);
  192. %}
  193. %typemap(out) SWIGTYPE (CLASS::*)
  194. %{
  195. SWIG_NewMemberObj(L,(void*)(&$1),sizeof($type),$descriptor); SWIG_arg++;
  196. %}
  197. #endif
  198. // void (must be empty without the SWIG_arg++)
  199. %typemap(out) void "";
  200. /* void* is a special case
  201. A function void fn(void*) should take any kind of pointer as a parameter (just like C/C++ does)
  202. but if its an output, then it should be wrappered like any other SWIG object (using default typemap)
  203. */
  204. %typemap(in,checkfn="SWIG_isptrtype") void*
  205. %{$1=($1_ltype)SWIG_MustGetPtr(L,$input,0,0,$argnum,"$symname");%}
  206. /* long long is another special case:
  207. as lua only supports one numeric type (lua_Number), we will just
  208. cast it to that & accept the loss of precision.
  209. An alternative solution would be a long long struct or class
  210. with the relevant operators.
  211. */
  212. %apply long {long long, signed long long, unsigned long long};
  213. %apply const long& {const long long&, const signed long long&, const unsigned long long&};
  214. /* It is possible to also pass a lua_State* into a function, so
  215. void fn(int a, float b, lua_State* s) is wrappable as
  216. > fn(1,4.3) -- note: the state is implicitly passed in
  217. */
  218. %typemap(in, numinputs=0) lua_State*
  219. %{$1 = L;%}
  220. /* -----------------------------------------------------------------------------
  221. * typecheck rules
  222. * ----------------------------------------------------------------------------- */
  223. /* These are needed for the overloaded functions
  224. These define the detection routines which will spot what
  225. parmeters match which function
  226. */
  227. // unfortunately lua only considers one type of number
  228. // so all numbers (int,float,double) match
  229. // you could add an advanced fn to get type & check if its integral
  230. %typecheck(SWIG_TYPECHECK_INTEGER)
  231. int, short, long,
  232. unsigned int, unsigned short, unsigned long,
  233. signed char, unsigned char,
  234. long long, unsigned long long, signed long long,
  235. const int &, const short &, const long &,
  236. const unsigned int &, const unsigned short &, const unsigned long &,
  237. const signed char&, const unsigned char&,
  238. const long long &, const unsigned long long &,
  239. enum SWIGTYPE, const enum SWIGTYPE&,
  240. float, double, const float &, const double&
  241. {
  242. $1 = lua_isnumber(L,$input);
  243. }
  244. %typecheck(SWIG_TYPECHECK_BOOL)
  245. bool, const bool &
  246. {
  247. $1 = lua_isboolean(L,$input);
  248. }
  249. // special check for a char (string of length 1)
  250. %typecheck(SWIG_TYPECHECK_CHAR,fragment="SWIG_lua_isnilstring") char, const char& {
  251. $1 = SWIG_lua_isnilstring(L,$input) && (lua_strlen(L,$input)==1);
  252. }
  253. %typecheck(SWIG_TYPECHECK_STRING,fragment="SWIG_lua_isnilstring") char *, char[] {
  254. $1 = SWIG_lua_isnilstring(L,$input);
  255. }
  256. %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *, SWIGTYPE [] {
  257. void *ptr;
  258. if (SWIG_isptrtype(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $1_descriptor, 0)) {
  259. $1 = 0;
  260. } else {
  261. $1 = 1;
  262. }
  263. }
  264. %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE & {
  265. void *ptr;
  266. if (lua_isuserdata(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $1_descriptor, 0)) {
  267. $1 = 0;
  268. } else {
  269. $1 = 1;
  270. }
  271. }
  272. %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE {
  273. void *ptr;
  274. if (lua_isuserdata(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $&1_descriptor, 0)) {
  275. $1 = 0;
  276. } else {
  277. $1 = 1;
  278. }
  279. }
  280. %typecheck(SWIG_TYPECHECK_VOIDPTR) void * {
  281. void *ptr;
  282. if (SWIG_isptrtype(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, 0, 0)) {
  283. $1 = 0;
  284. } else {
  285. $1 = 1;
  286. }
  287. }
  288. // Also needed for object ptrs by const ref
  289. // eg const A* ref_pointer(A* const& a);
  290. // found in mixed_types.i
  291. %typecheck(SWIG_TYPECHECK_POINTER) SWIGTYPE *const&
  292. {
  293. void *ptr;
  294. if (lua_isuserdata(L,$input)==0 || SWIG_ConvertPtr(L,$input, (void **) &ptr, $*descriptor, 0)) {
  295. $1 = 0;
  296. } else {
  297. $1 = 1;
  298. }
  299. }
  300. /* -----------------------------------------------------------------------------
  301. * Others
  302. * ----------------------------------------------------------------------------- */
  303. // Array reference typemaps
  304. %apply SWIGTYPE & { SWIGTYPE ((&)[ANY]) }
  305. /* const pointers */
  306. %apply SWIGTYPE * { SWIGTYPE *const }
  307. // size_t (which is just a unsigned long)
  308. %apply unsigned long { size_t };
  309. %apply const unsigned long & { const size_t & };
  310. /* -----------------------------------------------------------------------------
  311. * Specials
  312. * ----------------------------------------------------------------------------- */
  313. // swig::LANGUAGE_OBJ was added to allow containers of native objects
  314. // however its rather difficult to do this in lua, as you cannot hold pointers
  315. // to native objects (they are held in the interpreter)
  316. // therefore for now: just ignoring this feature
  317. #ifdef __cplusplus
  318. %ignore swig::LANGUAGE_OBJ;
  319. //%inline %{
  320. %{
  321. namespace swig {
  322. typedef struct{} LANGUAGE_OBJ;
  323. }
  324. %}
  325. #endif // __cplusplus