Home | History | Annotate | Download | only in guile
      1 /* -----------------------------------------------------------------------------
      2  * pointer-in-out.i
      3  *
      4  * Guile typemaps for passing pointers indirectly
      5  * ----------------------------------------------------------------------------- */
      6 
      7 /* Here is a macro that will define typemaps for passing C pointers indirectly.
      8 
      9    TYPEMAP_POINTER_INPUT_OUTPUT(PTRTYPE, SCM_TYPE)
     10 
     11    Supported calling conventions (in this example, PTRTYPE is int *):
     12 
     13    func(int **INPUT)
     14 
     15        Scheme wrapper will take one argument, a wrapped C pointer.
     16        The address of a variable containing this pointer will be
     17        passed to the function.
     18 
     19    func(int **INPUT_CONSUMED)
     20 
     21        Likewise, but mark the pointer object as not garbage
     22        collectable.
     23 
     24    func(int **INPUT_DESTROYED)
     25 
     26        Likewise, but mark the pointer object as destroyed.
     27 
     28    func(int **OUTPUT)
     29 
     30        Scheme wrapper will take no arguments.  The address of an int *
     31        variable will be passed to the function.  The function is
     32        expected to modify the variable; its value is wrapped and
     33        becomes an extra return value.  (See the documentation on how
     34        to deal with multiple values.)
     35 
     36    func(int **OUTPUT_NONCOLLECTABLE)
     37 
     38        Likewise, but make the pointer object not garbage collectable.
     39 
     40    func(int **BOTH)
     41    func(int **INOUT)
     42 
     43        This annotation combines INPUT and OUTPUT.
     44 
     45 */
     46 
     47 %define TYPEMAP_POINTER_INPUT_OUTPUT(PTRTYPE, SCM_TYPE)
     48 
     49 %typemap(in, doc="$NAME is of type <" #SCM_TYPE ">") PTRTYPE *INPUT(PTRTYPE temp)
     50 {
     51     if (SWIG_ConvertPtr($input, (void **) &temp, $*descriptor, 0)) {
     52 	scm_wrong_type_arg(FUNC_NAME, $argnum, $input);
     53     }
     54     $1 = &temp;
     55 }
     56 
     57 %typemap(in, doc="$NAME is of type <" #SCM_TYPE "> and is consumed by the function") PTRTYPE *INPUT_CONSUMED(PTRTYPE temp)
     58 {
     59     if (SWIG_ConvertPtr($input, (void **) &temp, $*descriptor, 0)) {
     60 	scm_wrong_type_arg(FUNC_NAME, $argnum, $input);
     61     }
     62     SWIG_Guile_MarkPointerNoncollectable($input);
     63     $1 = &temp;
     64 }
     65 
     66 %typemap(in, doc="$NAME is of type <" #SCM_TYPE "> and is consumed by the function") PTRTYPE *INPUT_DESTROYED(PTRTYPE temp)
     67 {
     68     if (SWIG_ConvertPtr($input, (void **) &temp, $*descriptor, 0)) {
     69 	scm_wrong_type_arg(FUNC_NAME, $argnum, $input);
     70     }
     71     SWIG_Guile_MarkPointerDestroyed($input);
     72     $1 = &temp;
     73 }
     74 
     75 %typemap(in, numinputs=0) PTRTYPE *OUTPUT(PTRTYPE temp),
     76                           PTRTYPE *OUTPUT_NONCOLLECTABLE(PTRTYPE temp)
     77      "$1 = &temp;";
     78 
     79 %typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT
     80      "SWIG_APPEND_VALUE(SWIG_NewPointerObj(*$1, $*descriptor, 1));";
     81 
     82 %typemap(argout, doc="<" #SCM_TYPE ">") PTRTYPE *OUTPUT_NONCOLLECTABLE
     83      "SWIG_APPEND_VALUE(SWIG_NewPointerObj(*$1, $*descriptor, 0));";
     84 
     85 %typemap(in) PTRTYPE *BOTH = PTRTYPE *INPUT;
     86 %typemap(argout) PTRTYPE *BOTH = PTRTYPE *OUTPUT;
     87 %typemap(in) PTRTYPE *INOUT = PTRTYPE *INPUT;
     88 %typemap(argout) PTRTYPE *INOUT = PTRTYPE *OUTPUT;
     89 
     90 /* As a special convenience measure, also attach docs involving
     91    SCM_TYPE to the standard pointer typemaps */
     92 
     93 %typemap(in, doc="$NAME is of type <" #SCM_TYPE ">") PTRTYPE {
     94   if (SWIG_ConvertPtr($input, (void **) &$1, $descriptor, 0))
     95     scm_wrong_type_arg(FUNC_NAME, $argnum, $input);
     96 }
     97 
     98 %typemap(out, doc="<" #SCM_TYPE ">") PTRTYPE {
     99     $result = SWIG_NewPointerObj ($1, $descriptor, $owner);
    100 }
    101 
    102 %enddef
    103