[go: up one dir, main page]

File: list-vector.i

package info (click to toggle)
swig1.3 1.3.11-1
  • links: PTS
  • area: main
  • in suites: woody
  • size: 6,852 kB
  • ctags: 4,764
  • sloc: ansic: 20,489; cpp: 10,052; sh: 7,256; yacc: 2,669; makefile: 2,381; python: 873; java: 762; tcl: 686; perl: 474; lisp: 444; ruby: 370; php: 367
file content (180 lines) | stat: -rw-r--r-- 6,512 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* list-vector.i --- Guile typemaps for converting between -*- c -*- arrays
		     and Scheme lists or vectors  

   Copyright (C) 2001 Matthias Koeppe <mkoeppe@mail.math.uni-magdeburg.de>

   $Header: /cvs/projects/SWIG/Lib/guile/Attic/list-vector.i,v 1.1.2.3.2.6 2001/12/17 22:17:20 mkoeppe Exp $
*/

/* Here is a macro that will define typemaps for converting between C
   arrays and Scheme lists or vectors when passing arguments to the C
   function.

   TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE)
   
   Supported calling conventions:

   func(int VECTORLENINPUT, [const] C_TYPE *VECTORINPUT)  or
   func([const] C_TYPE *VECTORINPUT, int VECTORLENINPUT)

       Scheme wrapper will take one argument, a vector.  A temporary C
       array of elements of type C_TYPE will be allocated and filled
       with the elements of the vectors, converted to C with the
       SCM_TO_C function.  Length and address of the array are passed
       to the C function.

       SCM_TYPE is used to describe the Scheme type of the elements in
       the Guile procedure documentation.
   
   func(int LISTLENINPUT, [const] C_TYPE *LISTINPUT) or
   func([const] C_TYPE *LISTINPUT, int LISTLENINPUT)

       Likewise, but the Scheme wrapper will take one argument, a list.

   func(int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT) or
   func(C_TYPE **VECTOROUTPUT, int *VECTORLENOUTPUT)

       Scheme wrapper will take no arguments.  Addresses of an integer
       and a C_TYPE * variable will be passed to the C function.  The
       C function is expected to return address and length of a
       freshly allocated array of elements of type C_TYPE through
       these pointers.  The elements of this array are converted to
       Scheme with the C_TO_SCM function and returned as a Scheme
       vector. 

       If the function has a void return value, the vector constructed
       by this typemap becomes the return value of the Scheme wrapper.
       Otherwise, the function returns multiple values.  (See
       Doc/internals.html on how to deal with multiple values.)

   func(int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT) or
   func(C_TYPE **LISTOUTPUT, int *LISTLENOUTPUT)

       Likewise, but the Scheme wrapper will return a list instead of
       a vector.

   Multiple parallel lists and vectors (sharing one length argument
   each) are also supported.  */

%define TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(C_TYPE, SCM_TO_C, C_TO_SCM, SCM_TYPE)

  /* input */
     
     /* We make use of the new multi-dispatch typemaps here. */
     
     %typemap(in, doc="($arg <vector of <" #SCM_TYPE ">>)")
       (int VECTORLENINPUT, C_TYPE *VECTORINPUT)
     {
       SCM_VALIDATE_VECTOR($argnum, $input);
       $1 = gh_vector_length($input);
       if ($1 > 0) {
	 int i;
	 $2 = SWIG_malloc(sizeof(C_TYPE) * $1);
	 for (i = 0; i<$1; i++) {
	   SCM elt = gh_vector_ref($input, gh_int2scm(i));
	   $2[i] = SCM_TO_C(elt);
	 }
       }
       else $2 = NULL;
     }
	 
     %typemap(in, doc="($arg <list of <" #SCM_TYPE ">>)")
       (int LISTLENINPUT, C_TYPE *LISTINPUT)
     {
       SCM_VALIDATE_LIST($argnum, $input);
       $1 = gh_length($input);
       if ($1 > 0) {
	 int i;
	 SCM rest;
	 $2 = SWIG_malloc(sizeof(C_TYPE) * $1);
	 for (i = 0, rest = $input;
	      i<$1;
	      i++, rest = gh_cdr(rest)) {
	   SCM elt = gh_car(rest);
	   $2[i] = SCM_TO_C(elt);
	 }
       }
       else $2 = NULL;
     }

     /* Do not check for NULL pointers (override checks). */

     %typemap(check) C_TYPE *VECTORINPUT, 
		     const C_TYPE *VECTORINPUT,
		     C_TYPE *LISTINPUT, 
		     const C_TYPE *LISTINPUT
       "/* no check for NULL pointer */";

     /* Discard the temporary array after the call. */

     %typemap(freearg) C_TYPE *VECTORINPUT, 
		       const C_TYPE *VECTORINPUT,
		       C_TYPE *LISTINPUT, 
		       const C_TYPE *LISTINPUT
       {if ($1!=NULL) SWIG_free($1);}

  /* output */

     /* First we make temporary variables ARRAYLENTEMP and ARRAYTEMP,
	whose addresses we pass to the C function.  We ignore both
	arguments for Scheme. */

     %typemap(ignore) (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT)
                        (int arraylentemp, C_TYPE *arraytemp),
                      (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
                        (int arraylentemp, C_TYPE *arraytemp)
     %{
       $1 = &arraylentemp;
       $2 = &arraytemp;
     %}

     /* In the ARGOUT typemaps, we convert the array into a vector or
        a list and append it to the results. */

     %typemap(argout, doc="($arg <vector of <" #SCM_TYPE ">>)") 
          (int *VECTORLENOUTPUT, C_TYPE **VECTOROUTPUT)
     {
       int i;
       SCM res = gh_make_vector(gh_int2scm(*$1),
				SCM_BOOL_F);
       for (i = 0; i<*$1; i++) {
	 SCM elt = C_TO_SCM((*$2)[i]);
	 gh_vector_set_x(res, gh_int2scm(i), elt);
       }
       if (*$2!=NULL) free(*$2);
       SWIG_APPEND_VALUE(res);
     }

     %typemap(argout, doc="($arg <list of <" #SCM_TYPE ">>)")
          (int *LISTLENOUTPUT, C_TYPE **LISTOUTPUT)
     {
       int i;
       SCM res = SCM_EOL;
       for (i = (*$1) - 1; i>=0; i--) {
	 SCM elt = C_TO_SCM((*$2)[i]);
	 res = gh_cons(elt, res);
       }
       if (*$2!=NULL) free(*$2);
       SWIG_APPEND_VALUE(res);
     }

%enddef

/* We use the macro to define typemaps for some standard types. */

TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(bool, gh_scm2bool, gh_bool2scm, boolean);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char, gh_scm2char, gh_char2scm, char);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned char, gh_scm2char, gh_char2scm, char);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(int, gh_scm2int, gh_int2scm, integer);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(short, gh_scm2int, gh_int2scm, integer);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(long, gh_scm2long, gh_long2scm, integer);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(ptrdiff_t, gh_scm2long, gh_long2scm, integer);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned int, gh_scm2ulong, gh_ulong2scm, integer);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned short, gh_scm2ulong, gh_ulong2scm, integer);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(unsigned long, gh_scm2ulong, gh_ulong2scm, integer);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(size_t, gh_scm2ulong, gh_ulong2scm, integer);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(float, gh_scm2double, gh_double2scm, real);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(double, gh_scm2double, gh_double2scm, real);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(char *, SWIG_scm2str, gh_str02scm, string);
TYPEMAP_LIST_VECTOR_INPUT_OUTPUT(const char *, SWIG_scm2str, gh_str02scm, string);