Home | History | Annotate | Download | only in guile
      1 /* -----------------------------------------------------------------------------
      2  * list_vector.i
      3  *
      4  * Guile typemaps for converting between arrays and Scheme lists or vectors
      5  * ----------------------------------------------------------------------------- */
      6 
      7 /* Here is a macro that will define typemaps for converting between C
      8    arrays and Scheme lists or vectors when passing arguments to the C
      9    function.
     10 
     11    TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE)
     12 
     13    Supported calling conventions:
     14 
     15    func(int VECTORLENINPUT, [const] C_TYPE *VECTORINPUT)
     16 
     17        Scheme wrapper will take one argument, a vector.  A temporary C
     18        array of elements of type C_TYPE will be allocated and filled
     19        with the elements of the vectors, converted to C with the
     20        SCM_TO_C function.  Length and address of the array are passed
     21        to the C function.
     22 
     23        SCM_TYPE is used to describe the Scheme type of the elements in
     24        the Guile procedure documentation.
     25 
     26    func(int LISTLENINPUT, [const] C_TYPE *LISTINPUT)
     27 
     28        Likewise, but the Scheme wrapper will take one argument, a list.
     29 
     30    func(int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT)
     31 
     32        Scheme wrapper will take no arguments.  Addresses of an integer
     33        and a C_TYPE * variable will be passed to the C function.  The
     34        C function is expected to return address and length of a
     35        freshly allocated array of elements of type C_TYPE through
     36        these pointers.  The elements of this array are converted to
     37        Scheme with the C_TO_SCM function and returned as a Scheme
     38        vector.
     39 
     40        If the function has a void return value, the vector constructed
     41        by this typemap becomes the return value of the Scheme wrapper.
     42        Otherwise, the function returns multiple values.  (See
     43        the documentation on how to deal with multiple values.)
     44 
     45    func(int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
     46 
     47        Likewise, but the Scheme wrapper will return a list instead of
     48        a vector.
     49 
     50    It is also allowed to use "size_t LISTLENINPUT" rather than "int
     51    LISTLENINPUT".  */
     52 
     53 %define TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE)
     54 
     55   /* input */
     56 
     57      /* We make use of the new multi-dispatch typemaps here. */
     58 
     59      %typemap(in, doc="$NAME is a vector of " #SCM_TYPE " values")
     60        (int VECTORLENINPUT, C_TYPE *VECTORINPUT),
     61        (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT)
     62      {
     63        SCM_VALIDATE_VECTOR($argnum, $input);
     64        $1 = scm_c_vector_length($input);
     65        if ($1 > 0) {
     66 	 $1_ltype i;
     67 	 $2 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) * $1);
     68 	 for (i = 0; i<$1; i++) {
     69 	   SCM swig_scm_value = scm_vector_ref($input, scm_from_long(i));
     70 	   $2[i] = SCM_TO_C_EXPR;
     71 	 }
     72        }
     73        else $2 = NULL;
     74      }
     75 
     76      %typemap(in, doc="$NAME is a list of " #SCM_TYPE " values")
     77        (int LISTLENINPUT, C_TYPE *LISTINPUT),
     78        (size_t LISTLENINPUT, C_TYPE *LISTINPUT)
     79      {
     80        SCM_VALIDATE_LIST($argnum, $input);
     81        $1 = scm_to_ulong(scm_length($input));
     82        if ($1 > 0) {
     83 	 $1_ltype i;
     84 	 SCM rest;
     85 	 $2 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE) * $1);
     86 	 for (i = 0, rest = $input;
     87 	      i<$1;
     88 	      i++, rest = SCM_CDR(rest)) {
     89 	   SCM swig_scm_value = SCM_CAR(rest);
     90 	   $2[i] = SCM_TO_C_EXPR;
     91 	 }
     92        }
     93        else $2 = NULL;
     94      }
     95 
     96      /* Do not check for NULL pointers (override checks). */
     97 
     98      %typemap(check) (int VECTORLENINPUT, C_TYPE *VECTORINPUT),
     99                      (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT),
    100                      (int LISTLENINPUT, C_TYPE *LISTINPUT),
    101                      (size_t LISTLENINPUT, C_TYPE *LISTINPUT)
    102        "/* no check for NULL pointer */";
    103 
    104      /* Discard the temporary array after the call. */
    105 
    106      %typemap(freearg) (int VECTORLENINPUT, C_TYPE *VECTORINPUT),
    107                      (size_t VECTORLENINPUT, C_TYPE *VECTORINPUT),
    108                      (int LISTLENINPUT, C_TYPE *LISTINPUT),
    109                      (size_t LISTLENINPUT, C_TYPE *LISTINPUT)
    110        {if ($2!=NULL) SWIG_free($2);}
    111 
    112 %enddef
    113 
    114   /* output */
    115 
    116 %define TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE)
    117 
    118      /* First we make temporary variables ARRAYLENTEMP and ARRAYTEMP,
    119 	whose addresses we pass to the C function.  We ignore both
    120 	arguments for Scheme. */
    121 
    122      %typemap(in,numinputs=0) (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT)
    123                         (int arraylentemp, C_TYPE *arraytemp),
    124                       (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
    125                         (int arraylentemp, C_TYPE *arraytemp),
    126 		      (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT)
    127                         (size_t arraylentemp, C_TYPE *arraytemp),
    128                       (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
    129                         (size_t arraylentemp, C_TYPE *arraytemp)
    130      %{
    131        $1 = &arraylentemp;
    132        $2 = &arraytemp;
    133      %}
    134 
    135      /* In the ARGOUT typemaps, we convert the array into a vector or
    136         a list and append it to the results. */
    137 
    138      %typemap(argout, doc="$NAME (a vector of " #SCM_TYPE " values)")
    139           (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT),
    140 	  (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT)
    141      {
    142        $*1_ltype i;
    143        SCM res = scm_make_vector(scm_from_long(*$1),
    144 				SCM_BOOL_F);
    145        for (i = 0; i<*$1; i++) {
    146 	 C_TYPE swig_c_value = (*$2)[i];
    147 	 SCM elt = C_TO_SCM_EXPR;
    148 	 scm_vector_set_x(res, scm_from_long(i), elt);
    149        }
    150        SWIG_APPEND_VALUE(res);
    151      }
    152 
    153      %typemap(argout, doc="$NAME (a list of " #SCM_TYPE " values)")
    154           (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT),
    155 	  (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
    156      {
    157        int i;
    158        SCM res = SCM_EOL;
    159        for (i = ((int)(*$1)) - 1; i>=0; i--) {
    160          C_TYPE swig_c_value = (*$2)[i];
    161 	 SCM elt = C_TO_SCM_EXPR;
    162 	 res = scm_cons(elt, res);
    163        }
    164        SWIG_APPEND_VALUE(res);
    165      }
    166 
    167      /* In the FREEARG typemaps, get rid of the C vector.
    168         (This can be overridden if you want to keep the C vector.) */
    169 
    170      %typemap(freearg)
    171           (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT),
    172 	  (size_t *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT),
    173 	  (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT),
    174 	  (size_t *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
    175      {
    176         if ((*$2)!=NULL) free(*$2);
    177      }
    178 
    179 %enddef
    180 
    181 %define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_TYPE)
    182   TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE)
    183   TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE)
    184 %enddef
    185 
    186 %define TYPEMAP_LIST_VECTOR_INPUT(C_TYPE, SCM_TO_C, SCM_TYPE)
    187   TYPEMAP_LIST_VECTOR_INPUT_WITH_EXPR
    188      (C_TYPE, SCM_TO_C(swig_scm_value), SCM_TYPE)
    189 %enddef
    190 
    191 %define TYPEMAP_LIST_VECTOR_OUTPUT(C_TYPE, C_TO_SCM, SCM_TYPE)
    192   TYPEMAP_LIST_VECTOR_OUTPUT_WITH_EXPR
    193      (C_TYPE, C_TO_SCM(swig_c_value), SCM_TYPE)
    194 %enddef
    195 
    196 %define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE)
    197   TYPEMAP_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR
    198      (C_TYPE, SCM_TO_C(swig_scm_value), C_TO_SCM(swig_c_value), SCM_TYPE)
    199 %enddef
    200 
    201 /* We use the macro to define typemaps for some standard types. */
    202 
    203 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(bool, scm_is_true, scm_from_bool, boolean);
    204 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char, SCM_CHAR, SCM_MAKE_CHAR, char);
    205 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned char, SCM_CHAR, SCM_MAKE_CHAR, char);
    206 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(int, scm_to_int, scm_from_long, integer);
    207 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(short, scm_to_int, scm_from_long, integer);
    208 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(long, scm_to_long, scm_from_long, integer);
    209 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, scm_to_long, scm_from_long, integer);
    210 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned int, scm_to_ulong, scm_from_ulong, integer);
    211 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned short, scm_to_ulong, scm_from_ulong, integer);
    212 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned long, scm_to_ulong, scm_from_ulong, integer);
    213 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(size_t, scm_to_ulong, scm_from_ulong, integer);
    214 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(float, scm_to_double, scm_from_double, real);
    215 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(double, scm_to_double, scm_from_double, real);
    216 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, SWIG_str02scm, string);
    217 TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, SWIG_str02scm, string);
    218 
    219 /* For the char *, free all strings after converting */
    220 
    221      %typemap(freearg)
    222           (int *VECTORLENOUTPUT, char ***VECTOROUTPUT),
    223 	  (size_t *VECTORLENOUTPUT, char ***VECTOROUTPUT),
    224 	  (int *LISTLENOUTPUT, char ***LISTOUTPUT),
    225     (size_t *LISTLENOUTPUT, char ***LISTOUTPUT),
    226     (int *VECTORLENOUTPUT, const char ***VECTOROUTPUT),
    227     (size_t *VECTORLENOUTPUT, const char ***VECTOROUTPUT),
    228     (int *LISTLENOUTPUT, const char ***LISTOUTPUT),
    229     (size_t *LISTLENOUTPUT, const char ***LISTOUTPUT)
    230     {
    231 	 if ((*$2)!=NULL) {
    232 	     int i;
    233 	     for (i = 0; i < *$1; i++) {
    234 		 if ((*$2)[i] != NULL) free((*$2)[i]);
    235 	     }
    236 	     free(*$2);
    237 	 }
    238      }
    239 
    240 %typemap(freearg) (int VECTORLENINPUT, char **VECTORINPUT),
    241     (size_t VECTORLENINPUT, char **VECTORINPUT),
    242     (int LISTLENINPUT, char **LISTINPUT),
    243     (size_t LISTLENINPUT, char **LISTINPUT),
    244     (int VECTORLENINPUT, const char **VECTORINPUT),
    245     (size_t VECTORLENINPUT, const char **VECTORINPUT),
    246     (int LISTLENINPUT, const char **LISTINPUT),
    247     (size_t LISTLENINPUT, const char **LISTINPUT)
    248 {
    249     if (($2)!=NULL) {
    250 	int i;
    251 	for (i = 0; i< $1; i++)
    252 	    if (($2)[i] != NULL) free(($2)[i]);
    253 	free($2);
    254     }
    255 }
    256 
    257 
    258 /* Following is a macro that emits typemaps that are much more
    259    flexible.  (They are also messier.)  It supports multiple parallel
    260    lists and vectors (sharing one length argument each).
    261 
    262    TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE)
    263 
    264    Supported calling conventions:
    265 
    266    func(int PARALLEL_VECTORLENINPUT, [const] C_TYPE *PARALLEL_VECTORINPUT, ...)  or
    267    func([const] C_TYPE *PARALLEL_VECTORINPUT, ..., int PARALLEL_VECTORLENINPUT)
    268 
    269    func(int PARALLEL_LISTLENINPUT, [const] C_TYPE *PARALLEL_LISTINPUT, ...) or
    270    func([const] C_TYPE *PARALLEL_LISTINPUT, ..., int PARALLEL_LISTLENINPUT)
    271 
    272    func(int *PARALLEL_VECTORLENOUTPUT, C_TYPE **PARALLEL_VECTOROUTPUT, ...) or
    273    func(C_TYPE **PARALLEL_VECTOROUTPUT, int *PARALLEL_VECTORLENOUTPUT, ...)
    274 
    275    func(int *PARALLEL_LISTLENOUTPUT, C_TYPE **PARALLEL_LISTOUTPUT) or
    276    func(C_TYPE **PARALLEL_LISTOUTPUT, int *PARALLEL_LISTLENOUTPUT)
    277 
    278    It is also allowed to use "size_t PARALLEL_LISTLENINPUT" rather than "int
    279    PARALLEL_LISTLENINPUT".  */
    280 
    281 %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE)
    282 
    283   /* input */
    284 
    285      /* Passing data is a little complicated here; just remember:
    286 	IGNORE typemaps come first, then IN, then CHECK.  But if
    287 	IGNORE is given, IN won't be used for this type.
    288 
    289 	We need to "ignore" one of the parameters because there shall
    290 	be only one argument on the Scheme side.  Here we only
    291 	initialize the array length to 0 but save its address for a
    292 	later change.  */
    293 
    294      %typemap(in,numinputs=0) int PARALLEL_VECTORLENINPUT (int *_global_vector_length),
    295 		      size_t PARALLEL_VECTORLENINPUT (size_t *_global_vector_length)
    296      {
    297        $1 = 0;
    298        _global_vector_length = &$1;
    299      }
    300 
    301      %typemap(in,numinputs=0) int PARALLEL_LISTLENINPUT (int *_global_list_length),
    302 		      size_t PARALLEL_LISTLENINPUT (size_t *_global_list_length)
    303      {
    304        $1 = 0;
    305        _global_list_length = &$1;
    306      }
    307 
    308      /* All the work is done in IN. */
    309 
    310      %typemap(in, doc="$NAME is a vector of " #SCM_TYPE " values")
    311 		  C_TYPE *PARALLEL_VECTORINPUT,
    312 		  const C_TYPE *PARALLEL_VECTORINPUT
    313      {
    314        SCM_VALIDATE_VECTOR($argnum, $input);
    315        *_global_vector_length = scm_c_vector_length($input);
    316        if (*_global_vector_length > 0) {
    317 	 int i;
    318 	 $1 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE)
    319 			       * (*_global_vector_length));
    320 	 for (i = 0; i<*_global_vector_length; i++) {
    321 	   SCM swig_scm_value = scm_vector_ref($input, scm_from_long(i));
    322 	   $1[i] = SCM_TO_C_EXPR;
    323 	 }
    324        }
    325        else $1 = NULL;
    326      }
    327 
    328      %typemap(in, doc="$NAME is a list of " #SCM_TYPE " values")
    329 		  C_TYPE *PARALLEL_LISTINPUT,
    330 		  const C_TYPE *PARALLEL_LISTINPUT
    331      {
    332        SCM_VALIDATE_LIST($argnum, $input);
    333        *_global_list_length = scm_to_ulong(scm_length($input));
    334        if (*_global_list_length > 0) {
    335 	 int i;
    336 	 SCM rest;
    337 	 $1 = (C_TYPE *) SWIG_malloc(sizeof(C_TYPE)
    338 			       * (*_global_list_length));
    339 	 for (i = 0, rest = $input;
    340 	      i<*_global_list_length;
    341 	      i++, rest = SCM_CDR(rest)) {
    342 	   SCM swig_scm_value = SCM_CAR(rest);
    343 	   $1[i] = SCM_TO_C_EXPR;
    344 	 }
    345        }
    346        else $1 = NULL;
    347      }
    348 
    349      /* Don't check for NULL pointers (override checks). */
    350 
    351      %typemap(check) C_TYPE *PARALLEL_VECTORINPUT,
    352 		     const C_TYPE *PARALLEL_VECTORINPUT,
    353 		     C_TYPE *PARALLEL_LISTINPUT,
    354 		     const C_TYPE *PARALLEL_LISTINPUT
    355        "/* no check for NULL pointer */";
    356 
    357      /* Discard the temporary array after the call. */
    358 
    359      %typemap(freearg) C_TYPE *PARALLEL_VECTORINPUT,
    360 		       const C_TYPE *PARALLEL_VECTORINPUT,
    361 		       C_TYPE *PARALLEL_LISTINPUT,
    362 		       const C_TYPE *PARALLEL_LISTINPUT
    363        {if ($1!=NULL) SWIG_free($1);}
    364 
    365 %enddef
    366 
    367 %define TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE)
    368 
    369   /* output */
    370 
    371      /* First we make a temporary variable ARRAYLENTEMP, use its
    372         address as the ...LENOUTPUT argument for the C function and
    373         "ignore" the ...LENOUTPUT argument for Scheme.  */
    374 
    375      %typemap(in,numinputs=0) int *PARALLEL_VECTORLENOUTPUT (int _global_arraylentemp),
    376 		      size_t *PARALLEL_VECTORLENOUTPUT (size_t _global_arraylentemp),
    377 		      int *PARALLEL_LISTLENOUTPUT   (int _global_arraylentemp),
    378 		      size_t *PARALLEL_LISTLENOUTPUT   (size_t _global_arraylentemp)
    379        "$1 = &_global_arraylentemp;";
    380 
    381      /* We also need to ignore the ...OUTPUT argument. */
    382 
    383      %typemap(in,numinputs=0) C_TYPE **PARALLEL_VECTOROUTPUT (C_TYPE *arraytemp),
    384 		      C_TYPE **PARALLEL_LISTOUTPUT   (C_TYPE *arraytemp)
    385        "$1 = &arraytemp;";
    386 
    387      /* In the ARGOUT typemaps, we convert the array into a vector or
    388         a list and append it to the results. */
    389 
    390      %typemap(argout, doc="$NAME (a vector of " #SCM_TYPE " values)")
    391 		      C_TYPE **PARALLEL_VECTOROUTPUT
    392      {
    393        int i;
    394        SCM res = scm_make_vector(scm_from_long(_global_arraylentemp),
    395 				SCM_BOOL_F);
    396        for (i = 0; i<_global_arraylentemp; i++) {
    397          C_TYPE swig_c_value = (*$1)[i];
    398 	 SCM elt = C_TO_SCM_EXPR;
    399 	 scm_vector_set_x(res, scm_from_long(i), elt);
    400        }
    401        SWIG_APPEND_VALUE(res);
    402      }
    403 
    404      %typemap(argout, doc="$NAME (a list of " #SCM_TYPE " values)")
    405 		      C_TYPE **PARALLEL_LISTOUTPUT
    406      {
    407        int i;
    408        SCM res = SCM_EOL;
    409        if (_global_arraylentemp > 0) {
    410          for (i = _global_arraylentemp - 1; i>=0; i--) {
    411 	   C_TYPE swig_c_value = (*$1)[i];
    412 	   SCM elt = C_TO_SCM_EXPR;
    413 	   res = scm_cons(elt, res);
    414          }
    415        }
    416        SWIG_APPEND_VALUE(res);
    417      }
    418 
    419      /* In the FREEARG typemaps, get rid of the C vector.
    420         (This can be overridden if you want to keep the C vector.) */
    421 
    422      %typemap(freearg) C_TYPE **PARALLEL_VECTOROUTPUT,
    423 		       C_TYPE **PARALLEL_LISTOUTPUT
    424      {
    425         if ((*$1)!=NULL) free(*$1);
    426      }
    427 
    428 %enddef
    429 
    430 %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, C_TO_SCM_EXPR, SCM_TYPE)
    431   TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR(C_TYPE, SCM_TO_C_EXPR, SCM_TYPE)
    432   TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR(C_TYPE, C_TO_SCM_EXPR, SCM_TYPE)
    433 %enddef
    434 
    435 %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT(C_TYPE, SCM_TO_C, SCM_TYPE)
    436   TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_WITH_EXPR
    437      (C_TYPE, SCM_TO_C(swig_scm_value), SCM_TYPE)
    438 %enddef
    439 
    440 %define TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT(C_TYPE, C_TO_SCM, SCM_TYPE)
    441   TYPEMAP_PARALLEL_LIST_VECTOR_OUTPUT_WITH_EXPR
    442      (C_TYPE, C_TO_SCM(swig_c_value), SCM_TYPE)
    443 %enddef
    444 
    445 %define TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE)
    446   TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT_WITH_EXPR
    447     (C_TYPE, SCM_TO_C(swig_scm_value), C_TO_SCM(swig_c_value), SCM_TYPE)
    448 %enddef
    449 
    450 /* We use the macro to define typemaps for some standard types. */
    451 
    452 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(bool, scm_is_true, scm_from_bool, boolean);
    453 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(char, SCM_CHAR, SCM_MAKE_CHAR, char);
    454 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned char, SCM_CHAR, SCM_MAKE_CHAR, char);
    455 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(int, scm_to_int, scm_from_long, integer);
    456 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(short, scm_to_int, scm_from_long, integer);
    457 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(long, scm_to_long, scm_from_long, integer);
    458 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, scm_to_long, scm_from_long, integer);
    459 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned int, scm_to_ulong, scm_from_ulong, integer);
    460 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned short, scm_to_ulong, scm_from_ulong, integer);
    461 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(unsigned long, scm_to_ulong, scm_from_ulong, integer);
    462 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(size_t, scm_to_ulong, scm_from_ulong, integer);
    463 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(float, scm_to_double, scm_from_double, real);
    464 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(double, scm_to_double, scm_from_double, real);
    465 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, SWIG_str02scm, string);
    466 TYPEMAP_PARALLEL_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, SWIG_str02scm, string);
    467 
    468 %typemap(freearg) char **PARALLEL_LISTINPUT, char **PARALLEL_VECTORINPUT,
    469     const char **PARALLEL_LISTINPUT, const char **PARALLEL_VECTORINPUT
    470 {
    471     if (($1)!=NULL) {
    472 	int i;
    473 	for (i = 0; i<*_global_list_length; i++)
    474 	    if (($1)[i] != NULL) SWIG_free(($1)[i]);
    475 	SWIG_free($1);
    476     }
    477 }
    478 
    479 %typemap(freearg) char ***PARALLEL_LISTOUTPUT, char ***PARALLEL_VECTOROUTPUT,
    480     const char ***PARALLEL_LISTOUTPUT, const char ***PARALLEL_VECTOROUTPUT
    481 {
    482     if ((*$1)!=NULL) {
    483 	int i;
    484 	for (i = 0; i<_global_arraylentemp; i++)
    485 	    if ((*$1)[i] != NULL) free((*$1)[i]);
    486 	free(*$1);
    487     }
    488 }
    489