/tags/rel-1-3-25/SWIG/Lib/perl5/typemaps.i
Swig | 592 lines | 375 code | 46 blank | 171 comment | 0 complexity | c6232f9113ed10a6f25ea69da02e9bd2 MD5 | raw file
Possible License(s): LGPL-2.1, Cube, GPL-3.0, 0BSD, GPL-2.0
1// 2// SWIG Typemap library 3// Dave Beazley 4// May 5, 1997 5// 6// Perl5 implementation 7// 8// This library provides standard typemaps for modifying SWIG's behavior. 9// With enough entries in this file, I hope that very few people actually 10// ever need to write a typemap. 11// 12 13/* 14The SWIG typemap library provides a language independent mechanism for 15supporting output arguments, input values, and other C function 16calling mechanisms. The primary use of the library is to provide a 17better interface to certain C function--especially those involving 18pointers. 19*/ 20 21// INPUT typemaps. 22// These remap a C pointer to be an "INPUT" value which is passed by value 23// instead of reference. 24 25 26/* 27The following methods can be applied to turn a pointer into a simple 28"input" value. That is, instead of passing a pointer to an object, 29you would use a real value instead. 30 31 int *INPUT 32 short *INPUT 33 long *INPUT 34 long long *INPUT 35 unsigned int *INPUT 36 unsigned short *INPUT 37 unsigned long *INPUT 38 unsigned long long *INPUT 39 unsigned char *INPUT 40 bool *INPUT 41 float *INPUT 42 double *INPUT 43 44To use these, suppose you had a C function like this : 45 46 double fadd(double *a, double *b) { 47 return *a+*b; 48 } 49 50You could wrap it with SWIG as follows : 51 52 %include typemaps.i 53 double fadd(double *INPUT, double *INPUT); 54 55or you can use the %apply directive : 56 57 %include typemaps.i 58 %apply double *INPUT { double *a, double *b }; 59 double fadd(double *a, double *b); 60 61*/ 62 63%define INPUT_TYPEMAP(type, converter) 64%typemap(in) type *INPUT(type temp), type &INPUT(type temp) { 65 temp = (type) converter($input); 66 $1 = &temp; 67} 68%typemap(typecheck) type *INPUT = type; 69%typemap(typecheck) type &INPUT = type; 70%enddef 71 72INPUT_TYPEMAP(float, SvNV); 73INPUT_TYPEMAP(double, SvNV); 74INPUT_TYPEMAP(int, SvIV); 75INPUT_TYPEMAP(long, SvIV); 76INPUT_TYPEMAP(short, SvIV); 77INPUT_TYPEMAP(signed char, SvIV); 78INPUT_TYPEMAP(unsigned int, SvUV); 79INPUT_TYPEMAP(unsigned long, SvUV); 80INPUT_TYPEMAP(unsigned short, SvUV); 81INPUT_TYPEMAP(unsigned char, SvUV); 82INPUT_TYPEMAP(bool, SvIV); 83 84 85%typemap(in) long long *INPUT($*1_ltype temp), long long &INPUT($*1_ltype temp) { 86 temp = strtoll(SvPV($input,PL_na), 0, 0); 87 $1 = &temp; 88} 89%typemap(typecheck) long long *INPUT = long long; 90%typemap(typecheck) long long &INPUT = long long; 91 92%typemap(in) unsigned long long *INPUT($*1_ltype temp), unsigned long long &INPUT($*1_ltype temp) { 93 temp = strtoull(SvPV($input,PL_na), 0, 0); 94 $1 = &temp; 95} 96%typemap(typecheck) unsigned long long *INPUT = unsigned long long; 97%typemap(typecheck) unsigned long long &INPUT = unsigned long long; 98 99 100#undef INPUT_TYPEMAP 101 102// OUTPUT typemaps. These typemaps are used for parameters that 103// are output only. The output value is appended to the result as 104// a list element. 105 106/* 107The following methods can be applied to turn a pointer into an "output" 108value. When calling a function, no input value would be given for 109a parameter, but an output value would be returned. In the case of 110multiple output values, functions will return a Perl array. 111 112 int *OUTPUT 113 short *OUTPUT 114 long *OUTPUT 115 long long *OUTPUT 116 unsigned int *OUTPUT 117 unsigned short *OUTPUT 118 unsigned long *OUTPUT 119 unsigned long long *OUTPUT 120 unsigned char *OUTPUT 121 bool *OUTPUT 122 float *OUTPUT 123 double *OUTPUT 124 125For example, suppose you were trying to wrap the modf() function in the 126C math library which splits x into integral and fractional parts (and 127returns the integer part in one of its parameters).: 128 129 double modf(double x, double *ip); 130 131You could wrap it with SWIG as follows : 132 133 %include typemaps.i 134 double modf(double x, double *OUTPUT); 135 136or you can use the %apply directive : 137 138 %include typemaps.i 139 %apply double *OUTPUT { double *ip }; 140 double modf(double x, double *ip); 141 142The Perl output of the function would be an array containing both 143output values. 144 145*/ 146 147// Force the argument to be ignored. 148 149%typemap(in,numinputs=0) int *OUTPUT(int temp), int &OUTPUT(int temp), 150 short *OUTPUT(short temp), short &OUTPUT(short temp), 151 long *OUTPUT(long temp), long &OUTPUT(long temp), 152 unsigned int *OUTPUT(unsigned int temp), unsigned int &OUTPUT(unsigned int temp), 153 unsigned short *OUTPUT(unsigned short temp), unsigned short &OUTPUT(unsigned short temp), 154 unsigned long *OUTPUT(unsigned long temp), unsigned long &OUTPUT(unsigned long temp), 155 unsigned char *OUTPUT(unsigned char temp), unsigned char &OUTPUT(unsigned char temp), 156 signed char *OUTPUT(signed char temp), signed char &OUTPUT(signed char temp), 157 bool *OUTPUT(bool temp), bool &OUTPUT(bool temp), 158 float *OUTPUT(float temp), float &OUTPUT(float temp), 159 double *OUTPUT(double temp), double &OUTPUT(double temp), 160 long long *OUTPUT($*1_ltype temp), long long &OUTPUT($*1_ltype temp), 161 unsigned long long *OUTPUT($*1_ltype temp), unsigned long long &OUTPUT($*1_ltype temp) 162"$1 = &temp;"; 163 164%typemap(argout) int *OUTPUT, int &OUTPUT, 165 short *OUTPUT, short &OUTPUT, 166 long *OUTPUT, long &OUTPUT, 167 signed char *OUTPUT, signed char &OUTPUT, 168 bool *OUTPUT, bool &OUTPUT 169{ 170 if (argvi >= items) { 171 EXTEND(sp,1); 172 } 173 $result = sv_newmortal(); 174 sv_setiv($result,(IV) *($1)); 175 argvi++; 176} 177 178%typemap(argout) unsigned int *OUTPUT, unsigned int &OUTPUT, 179 unsigned short *OUTPUT, unsigned short &OUTPUT, 180 unsigned long *OUTPUT, unsigned long &OUTPUT, 181 unsigned char *OUTPUT, unsigned char &OUTPUT 182{ 183 if (argvi >= items) { 184 EXTEND(sp,1); 185 } 186 $result = sv_newmortal(); 187 sv_setuv($result,(UV) *($1)); 188 argvi++; 189} 190 191 192 193%typemap(argout) float *OUTPUT, float &OUTPUT, 194 double *OUTPUT, double &OUTPUT 195{ 196 if (argvi >= items) { 197 EXTEND(sp,1); 198 } 199 $result = sv_newmortal(); 200 sv_setnv($result,(double) *($1)); 201 argvi++; 202} 203 204%typemap(argout) long long *OUTPUT, long long &OUTPUT { 205 char temp[256]; 206 if (argvi >= items) { 207 EXTEND(sp,1); 208 } 209 sprintf(temp,"%lld", (long long)*($1)); 210 $result = sv_newmortal(); 211 sv_setpv($result,temp); 212 argvi++; 213} 214 215%typemap(argout) unsigned long long *OUTPUT, unsigned long long &OUTPUT { 216 char temp[256]; 217 if (argvi >= items) { 218 EXTEND(sp,1); 219 } 220 sprintf(temp,"%llu", (unsigned long long)*($1)); 221 $result = sv_newmortal(); 222 sv_setpv($result,temp); 223 argvi++; 224} 225 226// INOUT 227// Mappings for an argument that is both an input and output 228// parameter 229 230/* 231The following methods can be applied to make a function parameter both 232an input and output value. This combines the behavior of both the 233"INPUT" and "OUTPUT" methods described earlier. Output values are 234returned in the form of a Perl array. 235 236 int *INOUT 237 short *INOUT 238 long *INOUT 239 long long *INOUT 240 unsigned int *INOUT 241 unsigned short *INOUT 242 unsigned long *INOUT 243 unsigned long long *INOUT 244 unsigned char *INOUT 245 bool *INOUT 246 float *INOUT 247 double *INOUT 248 249For example, suppose you were trying to wrap the following function : 250 251 void neg(double *x) { 252 *x = -(*x); 253 } 254 255You could wrap it with SWIG as follows : 256 257 %include typemaps.i 258 void neg(double *INOUT); 259 260or you can use the %apply directive : 261 262 %include typemaps.i 263 %apply double *INOUT { double *x }; 264 void neg(double *x); 265 266Unlike C, this mapping does not directly modify the input value. 267Rather, the modified input value shows up as the return value of the 268function. Thus, to apply this function to a Perl variable you might 269do this : 270 271 $x = neg($x); 272 273*/ 274 275%typemap(in) int *INOUT = int *INPUT; 276%typemap(in) short *INOUT = short *INPUT; 277%typemap(in) long *INOUT = long *INPUT; 278%typemap(in) unsigned *INOUT = unsigned *INPUT; 279%typemap(in) unsigned short *INOUT = unsigned short *INPUT; 280%typemap(in) unsigned long *INOUT = unsigned long *INPUT; 281%typemap(in) unsigned char *INOUT = unsigned char *INPUT; 282%typemap(in) signed char *INOUT = signed char *INPUT; 283%typemap(in) bool *INOUT = bool *INPUT; 284%typemap(in) float *INOUT = float *INPUT; 285%typemap(in) double *INOUT = double *INPUT; 286%typemap(in) long long *INOUT = long long *INPUT; 287%typemap(in) unsigned long long *INOUT = unsigned long long *INPUT; 288 289%typemap(in) int &INOUT = int &INPUT; 290%typemap(in) short &INOUT = short &INPUT; 291%typemap(in) long &INOUT = long &INPUT; 292%typemap(in) unsigned &INOUT = unsigned &INPUT; 293%typemap(in) unsigned short &INOUT = unsigned short &INPUT; 294%typemap(in) unsigned long &INOUT = unsigned long &INPUT; 295%typemap(in) unsigned char &INOUT = unsigned char &INPUT; 296%typemap(in) signed char &INOUT = signed char &INPUT; 297%typemap(in) bool &INOUT = bool &INPUT; 298%typemap(in) float &INOUT = float &INPUT; 299%typemap(in) double &INOUT = double &INPUT; 300%typemap(in) long long &INOUT = long long &INPUT; 301%typemap(in) unsigned long long &INOUT = unsigned long long &INPUT; 302 303 304%typemap(argout) int *INOUT = int *OUTPUT; 305%typemap(argout) short *INOUT = short *OUTPUT; 306%typemap(argout) long *INOUT = long *OUTPUT; 307%typemap(argout) unsigned *INOUT = unsigned *OUTPUT; 308%typemap(argout) unsigned short *INOUT = unsigned short *OUTPUT; 309%typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT; 310%typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT; 311%typemap(argout) signed char *INOUT = signed char *OUTPUT; 312%typemap(argout) bool *INOUT = bool *OUTPUT; 313%typemap(argout) float *INOUT = float *OUTPUT; 314%typemap(argout) double *INOUT = double *OUTPUT; 315%typemap(argout) long long *INOUT = long long *OUTPUT; 316%typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT; 317 318 319%typemap(argout) int &INOUT = int &OUTPUT; 320%typemap(argout) short &INOUT = short &OUTPUT; 321%typemap(argout) long &INOUT = long &OUTPUT; 322%typemap(argout) unsigned &INOUT = unsigned &OUTPUT; 323%typemap(argout) unsigned short &INOUT = unsigned short &OUTPUT; 324%typemap(argout) unsigned long &INOUT = unsigned long &OUTPUT; 325%typemap(argout) unsigned char &INOUT = unsigned char &OUTPUT; 326%typemap(argout) signed char &INOUT = signed char &OUTPUT; 327%typemap(argout) bool &INOUT = bool &OUTPUT; 328%typemap(argout) float &INOUT = float &OUTPUT; 329%typemap(argout) double &INOUT = double &OUTPUT; 330%typemap(argout) long long &INOUT = long long &OUTPUT; 331%typemap(argout) unsigned long long &INOUT = unsigned long long &OUTPUT; 332 333// REFERENCE 334// Accept Perl references as pointers 335 336/* 337The following methods make Perl references work like simple C 338pointers. References can only be used for simple input/output 339values, not C arrays however. It should also be noted that 340REFERENCES are specific to Perl and not supported in other 341scripting languages at this time. 342 343 int *REFERENCE 344 short *REFERENCE 345 long *REFERENCE 346 unsigned int *REFERENCE 347 unsigned short *REFERENCE 348 unsigned long *REFERENCE 349 unsigned char *REFERENCE 350 float *REFERENCE 351 double *REFERENCE 352 353For example, suppose you were trying to wrap the following function : 354 355 void neg(double *x) { 356 *x = -(*x); 357 } 358 359You could wrap it with SWIG as follows : 360 361 %include typemaps.i 362 void neg(double *REFERENCE); 363 364or you can use the %apply directive : 365 366 %include typemaps.i 367 %apply double *REFERENCE { double *x }; 368 void neg(double *x); 369 370Unlike the INOUT mapping described previous, this approach directly 371modifies the value of a Perl reference. Thus, you could use it 372as follows : 373 374 $x = 3; 375 neg(\$x); 376 print "$x\n"; # Should print out -3. 377 378*/ 379 380%typemap(in) double *REFERENCE (double dvalue), double &REFERENCE(double dvalue) 381{ 382 SV *tempsv; 383 if (!SvROK($input)) { 384 SWIG_croak("expected a reference"); 385 } 386 tempsv = SvRV($input); 387 if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { 388 printf("Received %d\n", SvTYPE(tempsv)); 389 SWIG_croak("Expected a double reference."); 390 } 391 dvalue = SvNV(tempsv); 392 $1 = &dvalue; 393} 394 395%typemap(in) float *REFERENCE (float dvalue), float &REFERENCE(float dvalue) 396{ 397 SV *tempsv; 398 if (!SvROK($input)) { 399 SWIG_croak("expected a reference"); 400 } 401 tempsv = SvRV($input); 402 if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) { 403 SWIG_croak("expected a double reference"); 404 } 405 dvalue = (float) SvNV(tempsv); 406 $1 = &dvalue; 407} 408 409%typemap(in) int *REFERENCE (int dvalue), int &REFERENCE (int dvalue) 410{ 411 SV *tempsv; 412 if (!SvROK($input)) { 413 SWIG_croak("expected a reference"); 414 } 415 tempsv = SvRV($input); 416 if (!SvIOK(tempsv)) { 417 SWIG_croak("expected a integer reference"); 418 } 419 dvalue = SvIV(tempsv); 420 $1 = &dvalue; 421} 422 423%typemap(in) short *REFERENCE (short dvalue), short &REFERENCE(short dvalue) 424{ 425 SV *tempsv; 426 if (!SvROK($input)) { 427 SWIG_croak("expected a reference"); 428 } 429 tempsv = SvRV($input); 430 if (!SvIOK(tempsv)) { 431 SWIG_croak("expected a integer reference"); 432 } 433 dvalue = (short) SvIV(tempsv); 434 $1 = &dvalue; 435} 436%typemap(in) long *REFERENCE (long dvalue), long &REFERENCE(long dvalue) 437{ 438 SV *tempsv; 439 if (!SvROK($input)) { 440 SWIG_croak("expected a reference"); 441 } 442 tempsv = SvRV($input); 443 if (!SvIOK(tempsv)) { 444 SWIG_croak("expected a integer reference"); 445 } 446 dvalue = (long) SvIV(tempsv); 447 $1 = &dvalue; 448} 449%typemap(in) unsigned int *REFERENCE (unsigned int dvalue), unsigned int &REFERENCE(unsigned int dvalue) 450{ 451 SV *tempsv; 452 if (!SvROK($input)) { 453 SWIG_croak("expected a reference"); 454 } 455 tempsv = SvRV($input); 456 if (!SvIOK(tempsv)) { 457 SWIG_croak("expected a integer reference"); 458 } 459 dvalue = (unsigned int) SvUV(tempsv); 460 $1 = &dvalue; 461} 462%typemap(in) unsigned short *REFERENCE (unsigned short dvalue), unsigned short &REFERENCE(unsigned short dvalue) 463{ 464 SV *tempsv; 465 if (!SvROK($input)) { 466 SWIG_croak("expected a reference"); 467 } 468 tempsv = SvRV($input); 469 if (!SvIOK(tempsv)) { 470 SWIG_croak("expected a integer reference"); 471 } 472 dvalue = (unsigned short) SvUV(tempsv); 473 $1 = &dvalue; 474} 475%typemap(in) unsigned long *REFERENCE (unsigned long dvalue), unsigned long &REFERENCE(unsigned long dvalue) 476{ 477 SV *tempsv; 478 if (!SvROK($input)) { 479 SWIG_croak("expected a reference"); 480 } 481 tempsv = SvRV($input); 482 if (!SvIOK(tempsv)) { 483 SWIG_croak("expected a integer reference"); 484 } 485 dvalue = (unsigned long) SvUV(tempsv); 486 $1 = &dvalue; 487} 488 489%typemap(in) unsigned char *REFERENCE (unsigned char dvalue), unsigned char &REFERENCE(unsigned char dvalue) 490{ 491 SV *tempsv; 492 if (!SvROK($input)) { 493 SWIG_croak("expected a reference"); 494 } 495 tempsv = SvRV($input); 496 if (!SvIOK(tempsv)) { 497 SWIG_croak("expected a integer reference"); 498 } 499 dvalue = (unsigned char) SvUV(tempsv); 500 $1 = &dvalue; 501} 502 503%typemap(in) signed char *REFERENCE (signed char dvalue), signed char &REFERENCE(signed char dvalue) 504{ 505 SV *tempsv; 506 if (!SvROK($input)) { 507 SWIG_croak("expected a reference"); 508 } 509 tempsv = SvRV($input); 510 if (!SvIOK(tempsv)) { 511 SWIG_croak("expected a integer reference"); 512 } 513 dvalue = (signed char) SvIV(tempsv); 514 $1 = &dvalue; 515} 516 517%typemap(in) bool *REFERENCE (bool dvalue), bool &REFERENCE(bool dvalue) 518{ 519 SV *tempsv; 520 if (!SvROK($input)) { 521 SWIG_croak("expected a reference"); 522 } 523 tempsv = SvRV($input); 524 if (!SvIOK(tempsv)) { 525 SWIG_croak("expected a integer reference"); 526 } 527 dvalue = (bool) SvIV(tempsv); 528 $1 = &dvalue; 529} 530 531%typemap(argout) double *REFERENCE, double &REFERENCE, 532 float *REFERENCE, float &REFERENCE 533{ 534 SV *tempsv; 535 tempsv = SvRV($arg); 536 if (!$1) SWIG_croak("expected a reference"); 537 sv_setnv(tempsv, (double) *$1); 538} 539 540%typemap(argout) int *REFERENCE, int &REFERENCE, 541 short *REFERENCE, short &REFERENCE, 542 long *REFERENCE, long &REFERENCE, 543 signed char *REFERENCE, unsigned char &REFERENCE, 544 bool *REFERENCE, bool &REFERENCE 545{ 546 SV *tempsv; 547 tempsv = SvRV($input); 548 if (!$1) SWIG_croak("expected a reference"); 549 sv_setiv(tempsv, (IV) *$1); 550} 551 552%typemap(argout) unsigned int *REFERENCE, unsigned int &REFERENCE, 553 unsigned short *REFERENCE, unsigned short &REFERENCE, 554 unsigned long *REFERENCE, unsigned long &REFERENCE, 555 unsigned char *REFERENCE, unsigned char &REFERENCE 556{ 557 SV *tempsv; 558 tempsv = SvRV($input); 559 if (!$1) SWIG_croak("expected a reference"); 560 sv_setuv(tempsv, (UV) *$1); 561} 562 563/* Overloading information */ 564 565%typemap(typecheck) double *INOUT = double; 566%typemap(typecheck) bool *INOUT = bool; 567%typemap(typecheck) signed char *INOUT = signed char; 568%typemap(typecheck) unsigned char *INOUT = unsigned char; 569%typemap(typecheck) unsigned long *INOUT = unsigned long; 570%typemap(typecheck) unsigned short *INOUT = unsigned short; 571%typemap(typecheck) unsigned int *INOUT = unsigned int; 572%typemap(typecheck) long *INOUT = long; 573%typemap(typecheck) short *INOUT = short; 574%typemap(typecheck) int *INOUT = int; 575%typemap(typecheck) float *INOUT = float; 576%typemap(typecheck) long long *INOUT = long long; 577%typemap(typecheck) unsigned long long *INOUT = unsigned long long; 578 579%typemap(typecheck) double &INOUT = double; 580%typemap(typecheck) bool &INOUT = bool; 581%typemap(typecheck) signed char &INOUT = signed char; 582%typemap(typecheck) unsigned char &INOUT = unsigned char; 583%typemap(typecheck) unsigned long &INOUT = unsigned long; 584%typemap(typecheck) unsigned short &INOUT = unsigned short; 585%typemap(typecheck) unsigned int &INOUT = unsigned int; 586%typemap(typecheck) long &INOUT = long; 587%typemap(typecheck) short &INOUT = short; 588%typemap(typecheck) int &INOUT = int; 589%typemap(typecheck) float &INOUT = float; 590%typemap(typecheck) long long &INOUT = long long; 591%typemap(typecheck) unsigned long long &INOUT = unsigned long long; 592