Home | History | Annotate | Download | only in perl5
      1 /* -----------------------------------------------------------------------------
      2  * reference.i
      3  *
      4  * Accept Perl references as pointers
      5  * ----------------------------------------------------------------------------- */
      6 
      7 /*
      8 The following methods make Perl references work like simple C
      9 pointers.  References can only be used for simple input/output
     10 values, not C arrays however.  It should also be noted that
     11 REFERENCES are specific to Perl and not supported in other
     12 scripting languages at this time.
     13 
     14          int            *REFERENCE
     15          short          *REFERENCE
     16          long           *REFERENCE
     17          unsigned int   *REFERENCE
     18          unsigned short *REFERENCE
     19          unsigned long  *REFERENCE
     20          unsigned char  *REFERENCE
     21          float          *REFERENCE
     22          double         *REFERENCE
     23 
     24 For example, suppose you were trying to wrap the following function :
     25 
     26         void neg(double *x) {
     27              *x = -(*x);
     28         }
     29 
     30 You could wrap it with SWIG as follows :
     31 
     32         %include reference.i
     33         void neg(double *REFERENCE);
     34 
     35 or you can use the %apply directive :
     36 
     37         %include reference.i
     38         %apply double *REFERENCE { double *x };
     39         void neg(double *x);
     40 
     41 Unlike the INOUT mapping described in typemaps.i, this approach directly
     42 modifies the value of a Perl reference.  Thus, you could use it
     43 as follows :
     44 
     45        $x = 3;
     46        neg(\$x);
     47        print "$x\n";         # Should print out -3.
     48 
     49 */
     50 
     51 %typemap(in) double *REFERENCE (double dvalue), double &REFERENCE(double dvalue)
     52 {
     53   SV *tempsv;
     54   if (!SvROK($input)) {
     55     SWIG_croak("expected a reference");
     56   }
     57   tempsv = SvRV($input);
     58   if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) {
     59 	printf("Received %d\n", SvTYPE(tempsv));
     60 	SWIG_croak("Expected a double reference.");
     61   }
     62   dvalue = SvNV(tempsv);
     63   $1 = &dvalue;
     64 }
     65 
     66 %typemap(in) float *REFERENCE (float dvalue), float &REFERENCE(float dvalue)
     67 {
     68   SV *tempsv;
     69   if (!SvROK($input)) {
     70     SWIG_croak("expected a reference");
     71   }
     72   tempsv = SvRV($input);
     73   if ((!SvNOK(tempsv)) && (!SvIOK(tempsv))) {
     74     SWIG_croak("expected a double reference");
     75   }
     76   dvalue = (float) SvNV(tempsv);
     77   $1 = &dvalue;
     78 }
     79 
     80 %typemap(in) int *REFERENCE (int dvalue), int &REFERENCE (int dvalue)
     81 {
     82   SV *tempsv;
     83   if (!SvROK($input)) {
     84     SWIG_croak("expected a reference");
     85   }
     86   tempsv = SvRV($input);
     87   if (!SvIOK(tempsv)) {
     88     SWIG_croak("expected an integer reference");
     89   }
     90   dvalue = SvIV(tempsv);
     91   $1 = &dvalue;
     92 }
     93 
     94 %typemap(in) short *REFERENCE (short dvalue), short &REFERENCE(short dvalue)
     95 {
     96   SV *tempsv;
     97   if (!SvROK($input)) {
     98     SWIG_croak("expected a reference");
     99   }
    100   tempsv = SvRV($input);
    101   if (!SvIOK(tempsv)) {
    102     SWIG_croak("expected an integer reference");
    103   }
    104   dvalue = (short) SvIV(tempsv);
    105   $1 = &dvalue;
    106 }
    107 %typemap(in) long *REFERENCE (long dvalue), long &REFERENCE(long dvalue)
    108 {
    109   SV *tempsv;
    110   if (!SvROK($input)) {
    111     SWIG_croak("expected a reference");
    112   }
    113   tempsv = SvRV($input);
    114   if (!SvIOK(tempsv)) {
    115     SWIG_croak("expected an integer reference");
    116   }
    117   dvalue = (long) SvIV(tempsv);
    118   $1 = &dvalue;
    119 }
    120 %typemap(in) unsigned int *REFERENCE (unsigned int dvalue), unsigned int &REFERENCE(unsigned int dvalue)
    121 {
    122   SV *tempsv;
    123   if (!SvROK($input)) {
    124     SWIG_croak("expected a reference");
    125   }
    126   tempsv = SvRV($input);
    127   if (!SvIOK(tempsv)) {
    128     SWIG_croak("expected an integer reference");
    129   }
    130   dvalue = (unsigned int) SvUV(tempsv);
    131   $1 = &dvalue;
    132 }
    133 %typemap(in) unsigned short *REFERENCE (unsigned short dvalue), unsigned short &REFERENCE(unsigned short dvalue)
    134 {
    135   SV *tempsv;
    136   if (!SvROK($input)) {
    137     SWIG_croak("expected a reference");
    138   }
    139   tempsv = SvRV($input);
    140   if (!SvIOK(tempsv)) {
    141     SWIG_croak("expected an integer reference");
    142   }
    143   dvalue = (unsigned short) SvUV(tempsv);
    144   $1 = &dvalue;
    145 }
    146 %typemap(in) unsigned long *REFERENCE (unsigned long dvalue), unsigned long &REFERENCE(unsigned long dvalue)
    147 {
    148   SV *tempsv;
    149   if (!SvROK($input)) {
    150     SWIG_croak("expected a reference");
    151   }
    152   tempsv = SvRV($input);
    153   if (!SvIOK(tempsv)) {
    154     SWIG_croak("expected an integer reference");
    155   }
    156   dvalue = (unsigned long) SvUV(tempsv);
    157   $1 = &dvalue;
    158 }
    159 
    160 %typemap(in) unsigned char *REFERENCE (unsigned char dvalue), unsigned char &REFERENCE(unsigned char dvalue)
    161 {
    162   SV *tempsv;
    163   if (!SvROK($input)) {
    164     SWIG_croak("expected a reference");
    165   }
    166   tempsv = SvRV($input);
    167   if (!SvIOK(tempsv)) {
    168     SWIG_croak("expected an integer reference");
    169   }
    170   dvalue = (unsigned char) SvUV(tempsv);
    171   $1 = &dvalue;
    172 }
    173 
    174 %typemap(in) signed char *REFERENCE (signed char dvalue), signed char &REFERENCE(signed char dvalue)
    175 {
    176   SV *tempsv;
    177   if (!SvROK($input)) {
    178     SWIG_croak("expected a reference");
    179   }
    180   tempsv = SvRV($input);
    181   if (!SvIOK(tempsv)) {
    182     SWIG_croak("expected an integer reference");
    183   }
    184   dvalue = (signed char) SvIV(tempsv);
    185   $1 = &dvalue;
    186 }
    187 
    188 %typemap(in) bool *REFERENCE (bool dvalue), bool &REFERENCE(bool dvalue)
    189 {
    190   SV *tempsv;
    191   if (!SvROK($input)) {
    192     SWIG_croak("expected a reference");
    193   }
    194   tempsv = SvRV($input);
    195   if (!SvIOK(tempsv)) {
    196     SWIG_croak("expected an integer reference");
    197   }
    198   dvalue = SvIV(tempsv) ? true : false;
    199   $1 = &dvalue;
    200 }
    201 
    202 %typemap(typecheck) int *REFERENCE, int &REFERENCE,
    203                     short *REFERENCE, short &REFERENCE,
    204                     long *REFERENCE, long  &REFERENCE,
    205                     signed char *REFERENCE, signed char &REFERENCE,
    206                     bool *REFERENCE, bool &REFERENCE
    207 {
    208   $1 = SvROK($input) && SvIOK(SvRV($input));
    209 }
    210 %typemap(typecheck) double *REFERENCE, double &REFERENCE,
    211                     float *REFERENCE, float &REFERENCE
    212 {
    213   $1 = SvROK($input);
    214   if($1) {
    215     SV *tmpsv = SvRV($input);
    216     $1 = SvNOK(tmpsv) || SvIOK(tmpsv);
    217   }
    218 }
    219 %typemap(typecheck) unsigned int   *REFERENCE, unsigned int &REFERENCE,
    220                     unsigned short *REFERENCE, unsigned short &REFERENCE,
    221                     unsigned long  *REFERENCE, unsigned long &REFERENCE,
    222                     unsigned char  *REFERENCE, unsigned char &REFERENCE
    223 {
    224   $1 = SvROK($input);
    225   if($1) {
    226     SV *tmpsv = SvRV($input);
    227     $1 = SvUOK(tmpsv) || SvIOK(tmpsv);
    228   }
    229 }
    230 
    231 %typemap(argout) double *REFERENCE, double &REFERENCE,
    232                  float  *REFERENCE, float &REFERENCE
    233 {
    234   SV *tempsv;
    235   tempsv = SvRV($arg);
    236   if (!$1) SWIG_croak("expected a reference");
    237   sv_setnv(tempsv, (double) *$1);
    238 }
    239 
    240 %typemap(argout)       int            *REFERENCE, int &REFERENCE,
    241                        short          *REFERENCE, short &REFERENCE,
    242                        long           *REFERENCE, long  &REFERENCE,
    243                        signed char    *REFERENCE, signed char &REFERENCE,
    244                        bool           *REFERENCE, bool &REFERENCE
    245 {
    246   SV *tempsv;
    247   tempsv = SvRV($input);
    248   if (!$1) SWIG_croak("expected a reference");
    249   sv_setiv(tempsv, (IV) *$1);
    250 }
    251 
    252 %typemap(argout)       unsigned int   *REFERENCE, unsigned int &REFERENCE,
    253                        unsigned short *REFERENCE, unsigned short &REFERENCE,
    254                        unsigned long  *REFERENCE, unsigned long &REFERENCE,
    255                        unsigned char  *REFERENCE, unsigned char &REFERENCE
    256 {
    257   SV *tempsv;
    258   tempsv = SvRV($input);
    259   if (!$1) SWIG_croak("expected a reference");
    260   sv_setuv(tempsv, (UV) *$1);
    261 }
    262