Home | History | Annotate | Download | only in typemaps
      1 /*  ------------------------------------------------------------
      2  *
      3  * Define the IN/OUTPUT typemaps assuming the output parameters are
      4  * returned in a list, i.e., they are not directly modified.
      5  *
      6  * The user should provide the %append_output(result, obj) method,
      7  * via a macro, which append a particular object to the result.
      8  *
      9  *
     10  * In Tcl, for example, the file is used as:
     11  *
     12  *   #define %append_output(obj) Tcl_ListObjAppendElement(interp,Tcl_GetObjResult(interp),obj);
     13  *   %include <typemaps/inoutlist.swg>
     14  *
     15  * while in Python it is used as:
     16  *
     17  *   #define %append_output(obj) $result = SWIG_Python_AppendResult($result, obj)
     18  *   %include <typemaps/inoutlist.swg>
     19  *
     20  * where the method SWIG_Python_AppendResult is defined inside the
     21  * %append_output fragment.
     22  *
     23  * If you forget to define %append_output, this file will generate
     24  * an error.
     25  *
     26  * ------------------------------------------------------------ */
     27 
     28 
     29 //
     30 // Uncomment the following definition if you don't want the in/out
     31 // typemaps by default, ie, you prefer to use typemaps.i.
     32 //
     33 //#define SWIG_INOUT_NODEF
     34 
     35 //
     36 // Use the following definition to enable the INPUT parameters to
     37 // accept both 'by value' and 'pointer' objects.
     38 //
     39 #define SWIG_INPUT_ACCEPT_PTRS
     40 
     41 // ------------------------------------------------------------------------
     42 // Pointer handling
     43 //
     44 // These mappings provide support for input/output arguments and common
     45 // uses for C/C++ pointers.
     46 // ------------------------------------------------------------------------
     47 
     48 // INPUT typemaps.
     49 // These remap a C pointer to be an "INPUT" value which is passed by value
     50 // instead of reference.
     51 
     52 /*
     53 The following methods can be applied to turn a pointer into a simple
     54 "input" value.  That is, instead of passing a pointer to an object,
     55 you would use a real value instead.
     56 
     57 To use these, suppose you had a C function like this :
     58 
     59         double fadd(double *a, double *b) {
     60                return *a+*b;
     61         }
     62 
     63 You could wrap it with SWIG as follows :
     64 
     65         double fadd(double *INPUT, double *INPUT);
     66 
     67 or you can use the %apply directive :
     68 
     69         %apply double *INPUT { double *a, double *b };
     70         double fadd(double *a, double *b);
     71 
     72 */
     73 #if defined(SWIG_INPUT_ACCEPT_PTRS)
     74 #define %check_input_ptr(input,arg,desc,disown) (SWIG_IsOK((res = SWIG_ConvertPtr(input,%as_voidptrptr(arg),desc,disown))))
     75 #else
     76 #define %check_input_ptr(input,arg,desc,disown) (SWIG_IsOK((res = SWIG_ERROR)))
     77 #endif
     78 
     79 %define %_value_input_typemap(code, asval_meth, asval_frag, Type)
     80   %typemap(in,noblock=1,fragment=asval_frag) Type *INPUT ($*ltype temp, int res = 0) {
     81     if (!%check_input_ptr($input,&$1,$descriptor,$disown)) {
     82       Type val;
     83       int ecode = asval_meth($input, &val);
     84       if (!SWIG_IsOK(ecode)) {
     85 	%argument_fail(ecode, "$*ltype",$symname, $argnum);
     86       }
     87       temp = %static_cast(val, $*ltype);
     88       $1 = &temp;
     89       res = SWIG_AddTmpMask(ecode);
     90     }
     91   }
     92   %typemap(in,noblock=1,fragment=asval_frag) Type &INPUT($*ltype temp, int res = 0) {
     93     if (!%check_input_ptr($input,&$1,$descriptor,$disown)) {
     94       Type val;
     95       int ecode = asval_meth($input, &val);
     96       if (!SWIG_IsOK(ecode)) {
     97 	%argument_fail(ecode, "$*ltype",$symname, $argnum);
     98       }
     99       temp = %static_cast(val, $*ltype);
    100       $1 = &temp;
    101       res = SWIG_AddTmpMask(ecode);
    102     }
    103   }
    104   %typemap(freearg,noblock=1,match="in") Type *INPUT, Type &INPUT {
    105     if (SWIG_IsNewObj(res$argnum)) %delete($1);
    106   }
    107   %typemap(typecheck,noblock=1,precedence=code,fragment=asval_frag) Type *INPUT, Type &INPUT {
    108     void *ptr = 0;
    109     int res = asval_meth($input, 0);
    110     $1 = SWIG_CheckState(res);
    111     if (!$1) {
    112       $1 = %check_input_ptr($input,&ptr,$1_descriptor,0);
    113     }
    114   }
    115 %enddef
    116 
    117 %define %_ptr_input_typemap(code,asptr_meth,asptr_frag,Type)
    118   %typemap(in,noblock=1,fragment=asptr_frag) Type *INPUT(int res = 0) {
    119     res = asptr_meth($input, &$1);
    120     if (!SWIG_IsOK(res)) {
    121       %argument_fail(res,"$type",$symname, $argnum);
    122     }
    123     res = SWIG_AddTmpMask(res);
    124   }
    125   %typemap(in,noblock=1,fragment=asptr_frag) Type &INPUT(int res = 0) {
    126     res = asptr_meth($input, &$1);
    127     if (!SWIG_IsOK(res)) {
    128       %argument_fail(res,"$type",$symname, $argnum);
    129     }
    130     if (!$1) {
    131       %argument_nullref("$type",$symname, $argnum);
    132     }
    133     res = SWIG_AddTmpMask(res);
    134   }
    135   %typemap(freearg,noblock=1,match="in") Type *INPUT, Type &INPUT {
    136     if (SWIG_IsNewObj(res$argnum)) %delete($1);
    137   }
    138   %typemap(typecheck,noblock=1,precedence=code,fragment=asptr_frag) Type *INPUT, Type &INPUT {
    139     int res = asptr_meth($input, (Type**)0);
    140     $1 = SWIG_CheckState(res);
    141   }
    142 %enddef
    143 
    144 // OUTPUT typemaps.   These typemaps are used for parameters that
    145 // are output only.   The output value is appended to the result as
    146 // a list element.
    147 
    148 /*
    149 The following methods can be applied to turn a pointer into an "output"
    150 value.  When calling a function, no input value would be given for
    151 a parameter, but an output value would be returned.  In the case of
    152 multiple output values, they are returned in the form of a list.
    153 
    154 
    155 For example, suppose you were trying to wrap the modf() function in the
    156 C math library which splits x into integral and fractional parts (and
    157 returns the integer part in one of its parameters):
    158 
    159         double modf(double x, double *ip);
    160 
    161 You could wrap it with SWIG as follows :
    162 
    163         double modf(double x, double *OUTPUT);
    164 
    165 or you can use the %apply directive :
    166 
    167         %apply double *OUTPUT { double *ip };
    168         double modf(double x, double *ip);
    169 
    170 The output of the function would be a list containing both output
    171 values.
    172 
    173 */
    174 
    175 %define %_value_output_typemap(from_meth, from_frag, Type)
    176  %typemap(in,numinputs=0,noblock=1)
    177    Type *OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ),
    178    Type &OUTPUT ($*1_ltype temp, int res = SWIG_TMPOBJ) {
    179    $1 = &temp;
    180  }
    181  %typemap(argout,noblock=1,fragment=from_frag) Type *OUTPUT, Type &OUTPUT {
    182    if (SWIG_IsTmpObj(res$argnum)) {
    183      %append_output(from_meth((*$1)));
    184    } else {
    185      int new_flags = SWIG_IsNewObj(res$argnum) ? (SWIG_POINTER_OWN | %newpointer_flags) : %newpointer_flags;
    186      %append_output(SWIG_NewPointerObj((void*)($1), $1_descriptor, new_flags));
    187    }
    188  }
    189 %enddef
    190 
    191 
    192 // INOUT
    193 // Mappings for an argument that is both an input and output
    194 // parameter
    195 
    196 /*
    197 The following methods can be applied to make a function parameter both
    198 an input and output value.  This combines the behavior of both the
    199 "INPUT" and "OUTPUT" methods described earlier.  Output values are
    200 returned in the form of a list.
    201 
    202 For example, suppose you were trying to wrap the following function :
    203 
    204         void neg(double *x) {
    205              *x = -(*x);
    206         }
    207 
    208 You could wrap it with SWIG as follows :
    209 
    210         void neg(double *INOUT);
    211 
    212 or you can use the %apply directive :
    213 
    214         %apply double *INOUT { double *x };
    215         void neg(double *x);
    216 
    217 Unlike C, this mapping does not directly modify the input value.
    218 Rather, the modified input value shows up as the return value of the
    219 function.  Thus, to apply this function to a variable you might do
    220 this :
    221 
    222        x = neg(x)
    223 
    224 Note : previous versions of SWIG used the symbol 'BOTH' to mark
    225 input/output arguments.   This is still supported, but will be slowly
    226 phased out in future releases.
    227 
    228 */
    229 
    230 %define %_value_inout_typemap(Type)
    231  %typemap(in) Type *INOUT = Type *INPUT;
    232  %typemap(in) Type &INOUT = Type &INPUT;
    233  %typemap(typecheck) Type *INOUT = Type *INPUT;
    234  %typemap(typecheck) Type &INOUT = Type &INPUT;
    235  %typemap(argout) Type *INOUT = Type *OUTPUT;
    236  %typemap(argout) Type &INOUT = Type &OUTPUT;
    237 %enddef
    238 
    239 
    240 %define %_ptr_inout_typemap(Type)
    241  %_value_inout_typemap(%arg(Type))
    242  %typemap(typecheck) Type *INOUT = Type *INPUT;
    243  %typemap(typecheck) Type &INOUT = Type &INPUT;
    244  %typemap(freearg) Type *INOUT = Type *INPUT;
    245  %typemap(freearg) Type &INOUT = Type &INPUT;
    246 %enddef
    247 
    248 #ifndef SWIG_INOUT_NODEF
    249 
    250 %define %value_input_typemap(code,asval_meth, asval_frag, Type...)
    251   %_value_input_typemap(%arg(code),%arg(asval_meth),%arg(asval_frag),%arg(Type))
    252 %enddef
    253 
    254 %define %ptr_input_typemap(code,asval_meth,asval_frag,Type...)
    255   %_ptr_input_typemap(%arg(code),%arg(asval_meth),%arg(asval_frag),%arg(Type))
    256 %enddef
    257 
    258 %define %value_output_typemap(from_meth,from_frag,Type...)
    259   %_value_output_typemap(%arg(from_meth),%arg(from_frag),%arg(Type))
    260 %enddef
    261 
    262 #define %value_inout_typemap(Type...) %_value_inout_typemap(%arg(Type))
    263 #define %ptr_inout_typemap(Type...) %_ptr_inout_typemap(%arg(Type))
    264 
    265 #else /* You need to include typemaps.i */
    266 
    267 
    268 #define %value_output_typemap(Type...)
    269 #define %value_input_typemap(Type...)
    270 #define %value_inout_typemap(Type...)
    271 #define %ptr_input_typemap(Type...)
    272 #define %ptr_inout_typemap(Type...)
    273 
    274 #endif /* SWIG_INOUT_DEFAULT */
    275 
    276 /*----------------------------------------------------------------------
    277   Front ends.
    278 
    279   use the following macros to define your own IN/OUTPUT/INOUT typemaps
    280 
    281   ------------------------------------------------------------------------*/
    282 %define %typemaps_inout(Code, AsValMeth, FromMeth, AsValFrag, FromFrag, Type...)
    283   %_value_input_typemap(%arg(Code), %arg(AsValMeth),
    284 			    %arg(AsValFrag), %arg(Type));
    285   %_value_output_typemap(%arg(FromMeth), %arg(FromFrag), %arg(Type));
    286   %_value_inout_typemap(%arg(Type));
    287 %enddef
    288 
    289 %define %typemaps_inoutn(Code,Type...)
    290   %typemaps_inout(%arg(Code),
    291 		 %arg(SWIG_AsVal(Type)),
    292 		 %arg(SWIG_From(Type)),
    293 		 %arg(SWIG_AsVal_frag(Type)),
    294 		 %arg(SWIG_From_frag(Type)),
    295 		 %arg(Type));
    296 %enddef
    297