Home | History | Annotate | Download | only in php
      1 /* -----------------------------------------------------------------------------
      2  * typemaps.i.
      3  *
      4  * SWIG Typemap library for PHP.
      5  *
      6  * This library provides standard typemaps for modifying SWIG's behavior.
      7  * With enough entries in this file, I hope that very few people actually
      8  * ever need to write a typemap.
      9  *
     10  * Define macros to define the following typemaps:
     11  *
     12  * TYPE *INPUT.   Argument is passed in as native variable by value.
     13  * TYPE *OUTPUT.  Argument is returned as an array from the function call.
     14  * TYPE *INOUT.   Argument is passed in by value, and out as part of returned list
     15  * TYPE *REFERENCE.  Argument is passed in as native variable with value
     16  *                   semantics.  Variable value is changed with result.
     17  *                   Use like this:
     18  *                   int foo(int *REFERENCE);
     19  *
     20  *                   $a = 0;
     21  *                   $rc = foo($a);
     22  *
     23  *                   Even though $a looks like it's passed by value,
     24  *                   its value can be changed by foo().
     25  * ----------------------------------------------------------------------------- */
     26 
     27 %define BOOL_TYPEMAP(TYPE)
     28 %typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
     29 %{
     30   convert_to_boolean_ex($input);
     31   temp = Z_LVAL_PP($input) ? true : false;
     32   $1 = &temp;
     33 %}
     34 %typemap(argout) TYPE *INPUT, TYPE &INPUT "";
     35 %typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
     36 %typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
     37 {
     38   zval *o;
     39   MAKE_STD_ZVAL(o);
     40   ZVAL_BOOL(o,temp$argnum);
     41   t_output_helper( &$result, o );
     42 }
     43 %typemap(in) TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
     44 %{
     45   convert_to_boolean_ex($input);
     46   lvalue = (*$input)->value.lval ? true : false;
     47   $1 = &lvalue;
     48 %}
     49 %typemap(argout) TYPE *REFERENCE, TYPE &REFERENCE
     50 %{
     51   (*$arg)->value.lval = lvalue$argnum ? true : false;
     52   (*$arg)->type = IS_BOOL;
     53 %}
     54 %enddef
     55 
     56 %define DOUBLE_TYPEMAP(TYPE)
     57 %typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
     58 %{
     59   convert_to_double_ex($input);
     60   temp = (TYPE) Z_DVAL_PP($input);
     61   $1 = &temp;
     62 %}
     63 %typemap(argout) TYPE *INPUT, TYPE &INPUT "";
     64 %typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
     65 %typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
     66 {
     67   zval *o;
     68   MAKE_STD_ZVAL(o);
     69   ZVAL_DOUBLE(o,temp$argnum);
     70   t_output_helper( &$result, o );
     71 }
     72 %typemap(in) TYPE *REFERENCE (TYPE dvalue), TYPE &REFERENCE (TYPE dvalue)
     73 %{
     74   convert_to_double_ex($input);
     75   dvalue = (TYPE) (*$input)->value.dval;
     76   $1 = &dvalue;
     77 %}
     78 %typemap(argout) TYPE *REFERENCE, TYPE &REFERENCE
     79 %{
     80   $1->value.dval = (double)(lvalue$argnum);
     81   $1->type = IS_DOUBLE;
     82 %}
     83 %enddef
     84 
     85 %define INT_TYPEMAP(TYPE)
     86 %typemap(in) TYPE *INPUT(TYPE temp), TYPE &INPUT(TYPE temp)
     87 %{
     88   convert_to_long_ex($input);
     89   temp = (TYPE) Z_LVAL_PP($input);
     90   $1 = &temp;
     91 %}
     92 %typemap(argout) TYPE *INPUT, TYPE &INPUT "";
     93 %typemap(in,numinputs=0) TYPE *OUTPUT(TYPE temp), TYPE &OUTPUT(TYPE temp) "$1 = &temp;";
     94 %typemap(argout,fragment="t_output_helper") TYPE *OUTPUT, TYPE &OUTPUT
     95 {
     96   zval *o;
     97   MAKE_STD_ZVAL(o);
     98   ZVAL_LONG(o,temp$argnum);
     99   t_output_helper( &$result, o );
    100 }
    101 %typemap(in) TYPE *REFERENCE (TYPE lvalue), TYPE &REFERENCE (TYPE lvalue)
    102 %{
    103   convert_to_long_ex($input);
    104   lvalue = (TYPE) (*$input)->value.lval;
    105   $1 = &lvalue;
    106 %}
    107 %typemap(argout) TYPE *REFERENCE, TYPE &REFERENCE
    108 %{
    109   (*$arg)->value.lval = (long)(lvalue$argnum);
    110   (*$arg)->type = IS_LONG;
    111 %}
    112 %enddef
    113 
    114 BOOL_TYPEMAP(bool);
    115 
    116 DOUBLE_TYPEMAP(float);
    117 DOUBLE_TYPEMAP(double);
    118 
    119 INT_TYPEMAP(int);
    120 INT_TYPEMAP(short);
    121 INT_TYPEMAP(long);
    122 INT_TYPEMAP(unsigned int);
    123 INT_TYPEMAP(unsigned short);
    124 INT_TYPEMAP(unsigned long);
    125 INT_TYPEMAP(unsigned char);
    126 INT_TYPEMAP(signed char);
    127 
    128 INT_TYPEMAP(long long);
    129 %typemap(argout,fragment="t_output_helper") long long *OUTPUT
    130 {
    131   zval *o;
    132   MAKE_STD_ZVAL(o);
    133   if ((long long)LONG_MIN <= temp$argnum && temp$argnum <= (long long)LONG_MAX) {
    134     ZVAL_LONG(o, temp$argnum);
    135   } else {
    136     char temp[256];
    137     sprintf(temp, "%lld", (long long)temp$argnum);
    138     ZVAL_STRING(o, temp, 1);
    139   }
    140   t_output_helper( &$result, o );
    141 }
    142 %typemap(in) TYPE *REFERENCE (long long lvalue)
    143 %{
    144   CONVERT_LONG_LONG_IN(lvalue, long long, $input)
    145   $1 = &lvalue;
    146 %}
    147 %typemap(argout) long long *REFERENCE
    148 %{
    149   if ((long long)LONG_MIN <= lvalue$argnum && lvalue$argnum <= (long long)LONG_MAX) {
    150     (*$arg)->value.lval = (long)(lvalue$argnum);
    151     (*$arg)->type = IS_LONG;
    152   } else {
    153     char temp[256];
    154     sprintf(temp, "%lld", (long long)lvalue$argnum);
    155     ZVAL_STRING((*$arg), temp, 1);
    156   }
    157 %}
    158 %typemap(argout) long long &OUTPUT
    159 %{
    160   if ((long long)LONG_MIN <= *arg$argnum && *arg$argnum <= (long long)LONG_MAX) {
    161     ($result)->value.lval = (long)(*arg$argnum);
    162     ($result)->type = IS_LONG;
    163   } else {
    164     char temp[256];
    165     sprintf(temp, "%lld", (long long)(*arg$argnum));
    166     ZVAL_STRING($result, temp, 1);
    167   }
    168 %}
    169 INT_TYPEMAP(unsigned long long);
    170 %typemap(argout,fragment="t_output_helper") unsigned long long *OUTPUT
    171 {
    172   zval *o;
    173   MAKE_STD_ZVAL(o);
    174   if (temp$argnum <= (unsigned long long)LONG_MAX) {
    175     ZVAL_LONG(o, temp$argnum);
    176   } else {
    177     char temp[256];
    178     sprintf(temp, "%llu", (unsigned long long)temp$argnum);
    179     ZVAL_STRING(o, temp, 1);
    180   }
    181   t_output_helper( &$result, o );
    182 }
    183 %typemap(in) TYPE *REFERENCE (unsigned long long lvalue)
    184 %{
    185   CONVERT_UNSIGNED_LONG_LONG_IN(lvalue, unsigned long long, $input)
    186   $1 = &lvalue;
    187 %}
    188 %typemap(argout) unsigned long long *REFERENCE
    189 %{
    190   if (lvalue$argnum <= (unsigned long long)LONG_MAX) {
    191     (*$arg)->value.lval = (long)(lvalue$argnum);
    192     (*$arg)->type = IS_LONG;
    193   } else {
    194     char temp[256];
    195     sprintf(temp, "%llu", (unsigned long long)lvalue$argnum);
    196     ZVAL_STRING((*$arg), temp, 1);
    197   }
    198 %}
    199 %typemap(argout) unsigned long long &OUTPUT
    200 %{
    201   if (*arg$argnum <= (unsigned long long)LONG_MAX) {
    202     ($result)->value.lval = (long)(*arg$argnum);
    203     ($result)->type = IS_LONG;
    204   } else {
    205     char temp[256];
    206     sprintf(temp, "%llu", (unsigned long long)(*arg$argnum));
    207     ZVAL_STRING($result, temp, 1);
    208   }
    209 %}
    210 
    211 %typemap(in) bool *INOUT = bool *INPUT;
    212 %typemap(in) float *INOUT = float *INPUT;
    213 %typemap(in) double *INOUT = double *INPUT;
    214 
    215 %typemap(in) int *INOUT = int *INPUT;
    216 %typemap(in) short *INOUT = short *INPUT;
    217 %typemap(in) long *INOUT = long *INPUT;
    218 %typemap(in) long long *INOUT = long long *INPUT;
    219 %typemap(in) unsigned *INOUT = unsigned *INPUT;
    220 %typemap(in) unsigned short *INOUT = unsigned short *INPUT;
    221 %typemap(in) unsigned long *INOUT = unsigned long *INPUT;
    222 %typemap(in) unsigned char *INOUT = unsigned char *INPUT;
    223 %typemap(in) unsigned long long *INOUT = unsigned long long *INPUT;
    224 %typemap(in) signed char *INOUT = signed char *INPUT;
    225 
    226 %typemap(in) bool &INOUT = bool *INPUT;
    227 %typemap(in) float &INOUT = float *INPUT;
    228 %typemap(in) double &INOUT = double *INPUT;
    229 
    230 %typemap(in) int &INOUT = int *INPUT;
    231 %typemap(in) short &INOUT = short *INPUT;
    232 %typemap(in) long &INOUT = long *INPUT;
    233 %typemap(in) long long &INOUT = long long *INPUT;
    234 %typemap(in) long long &INPUT = long long *INPUT;
    235 %typemap(in) unsigned &INOUT = unsigned *INPUT;
    236 %typemap(in) unsigned short &INOUT = unsigned short *INPUT;
    237 %typemap(in) unsigned long &INOUT = unsigned long *INPUT;
    238 %typemap(in) unsigned char &INOUT = unsigned char *INPUT;
    239 %typemap(in) unsigned long long &INOUT = unsigned long long *INPUT;
    240 %typemap(in) unsigned long long &INPUT = unsigned long long *INPUT;
    241 %typemap(in) signed char &INOUT = signed char *INPUT;
    242 
    243 %typemap(argout) bool *INOUT = bool *OUTPUT;
    244 %typemap(argout) float *INOUT = float *OUTPUT;
    245 %typemap(argout) double *INOUT= double *OUTPUT;
    246 
    247 %typemap(argout) int *INOUT = int *OUTPUT;
    248 %typemap(argout) short *INOUT = short *OUTPUT;
    249 %typemap(argout) long *INOUT= long *OUTPUT;
    250 %typemap(argout) long long *INOUT= long long *OUTPUT;
    251 %typemap(argout) unsigned short *INOUT= unsigned short *OUTPUT;
    252 %typemap(argout) unsigned long *INOUT = unsigned long *OUTPUT;
    253 %typemap(argout) unsigned char *INOUT = unsigned char *OUTPUT;
    254 %typemap(argout) unsigned long long *INOUT = unsigned long long *OUTPUT;
    255 %typemap(argout) signed char *INOUT = signed char *OUTPUT;
    256 
    257 %typemap(argout) bool &INOUT = bool *OUTPUT;
    258 %typemap(argout) float &INOUT = float *OUTPUT;
    259 %typemap(argout) double &INOUT= double *OUTPUT;
    260 
    261 %typemap(argout) int &INOUT = int *OUTPUT;
    262 %typemap(argout) short &INOUT = short *OUTPUT;
    263 %typemap(argout) long &INOUT= long *OUTPUT;
    264 %typemap(argout) long long &INOUT= long long *OUTPUT;
    265 %typemap(argout) unsigned short &INOUT= unsigned short *OUTPUT;
    266 %typemap(argout) unsigned long &INOUT = unsigned long *OUTPUT;
    267 %typemap(argout) unsigned char &INOUT = unsigned char *OUTPUT;
    268 %typemap(argout) unsigned long long &INOUT = unsigned long long *OUTPUT;
    269 %typemap(argout) signed char &INOUT = signed char *OUTPUT;
    270 
    271 %typemap(in) char INPUT[ANY] ( char temp[$1_dim0] )
    272 %{
    273   convert_to_string_ex($input);
    274   strncpy(temp,Z_LVAL_PP($input),$1_dim0);
    275   $1 = temp;
    276 %}
    277 %typemap(in,numinputs=0) char OUTPUT[ANY] ( char temp[$1_dim0] )
    278   "$1 = temp;";
    279 %typemap(argout) char OUTPUT[ANY]
    280 {
    281   zval *o;
    282   MAKE_STD_ZVAL(o);
    283   ZVAL_STRINGL(o,temp$argnum,$1_dim0);
    284   t_output_helper( &$result, o );
    285 }
    286 
    287 %typemap(in,numinputs=0) void **OUTPUT (int force),
    288                          void *&OUTPUT (int force)
    289 %{
    290   /* If they pass NULL by reference, make it into a void*
    291      This bit should go in arginit if arginit support init-ing scripting args */
    292   if(SWIG_ConvertPtr(*$input, (void **) &$1, $1_descriptor, 0) < 0) {
    293     /* So... we didn't get a ref or ptr, but we'll accept NULL by reference */
    294     if (!((*$input)->type==IS_NULL && PZVAL_IS_REF(*$input))) {
    295       /* wasn't a pre/ref/thing, OR anything like an int thing */
    296       SWIG_PHP_Error(E_ERROR, "Type error in argument $arg of $symname.");
    297     }
    298   }
    299   force=0;
    300   if (arg1==NULL) {
    301 #ifdef __cplusplus
    302     ptr=new $*1_ltype;
    303 #else
    304     ptr=($*1_ltype) calloc(1,sizeof($*1_ltype));
    305 #endif
    306     $1=&ptr;
    307     /* have to passback arg$arg too */
    308     force=1;
    309   }
    310 %}
    311 
    312 %typemap(argout) void **OUTPUT,
    313                  void *&OUTPUT
    314 %{
    315   if (force$argnum) {  /* pass back arg$argnum through params ($arg) if we can */
    316     if (!PZVAL_IS_REF(*$arg)) {
    317       SWIG_PHP_Error(E_WARNING, "Parameter $argnum of $symname wasn't passed by reference");
    318     } else {
    319       SWIG_SetPointerZval(*$arg, (void *) ptr$argnum, $*1_descriptor, 1);
    320     }
    321   }
    322 %}
    323