* benchmark-guile.in: Copied from check-guile.in and adapted for
[bpt/guile.git] / libguile / convert.i.c
CommitLineData
1fa86ca5
SJ
1/* this file is #include'd (x times) by convert.c */
2
1fa86ca5 3/* Convert a vector, weak vector, (if possible string, substring), list
edb810bb
SJ
4 or uniform vector into an C array. If the result array in argument 2
5 is NULL, malloc() a new one. If out of memory, return NULL. */
1fa86ca5
SJ
6#define FUNC_NAME SCM2CTYPES_FN
7CTYPE *
8SCM2CTYPES (SCM obj, CTYPE *data)
9{
10 long i, n;
11 SCM val;
12
13 SCM_ASSERT (SCM_NIMP (obj) || SCM_NFALSEP (scm_list_p (obj)),
14 obj, SCM_ARG1, FUNC_NAME);
15
edb810bb 16 /* list conversion */
1fa86ca5
SJ
17 if (SCM_NFALSEP (scm_list_p (obj)))
18 {
edb810bb 19 /* traverse the given list and validate the range of each member */
1fa86ca5
SJ
20 SCM list = obj;
21 for (n = 0; SCM_NFALSEP (scm_pair_p (list)); list = SCM_CDR (list), n++)
22 {
23 val = SCM_CAR (list);
edb810bb
SJ
24#if SIZEOF_CTYPE && SIZEOF_CTYPE < SIZEOF_SCM_T_BITS
25 /* check integer ranges */
1fa86ca5
SJ
26 if (SCM_INUMP (val))
27 {
edb810bb
SJ
28 scm_t_signed_bits v = SCM_INUM (val);
29 CTYPE c = (CTYPE) v;
30 SCM_ASSERT_RANGE (SCM_ARG1, val, v != (scm_t_signed_bits) c);
1fa86ca5 31 }
edb810bb
SJ
32 /* check big number ranges */
33 else if (SCM_BIGP (val))
34 {
35 scm_t_signed_bits v = scm_num2long (val, SCM_ARG1, FUNC_NAME);
36 CTYPE c = (CTYPE) v;
37 SCM_ASSERT_RANGE (SCM_ARG1, val, v != (scm_t_signed_bits) c);
38 }
39 else
40 /* check float types */
41#elif defined (FLOATTYPE)
42 /* real values, big numbers and immediate values are valid
43 for float conversions */
44 if (!SCM_REALP (val) && !SCM_BIGP (val) && !SCM_INUMP (val))
1fa86ca5 45#else
edb810bb
SJ
46 if (!SCM_BIGP (val) && !SCM_INUMP (val))
47#endif /* FLOATTYPE */
48 SCM_WRONG_TYPE_ARG (SCM_ARG1, val);
1fa86ca5 49 }
edb810bb
SJ
50
51 /* allocate new memory if necessary */
1fa86ca5 52 if (data == NULL)
97820583
SJ
53 if ((data = (CTYPE *) malloc (n * sizeof (CTYPE))) == NULL)
54 return NULL;
1fa86ca5 55
edb810bb 56 /* traverse the list once more and convert each member */
1fa86ca5
SJ
57 list = obj;
58 for (i = 0; SCM_NFALSEP (scm_pair_p (list)); list = SCM_CDR (list), i++)
59 {
60 val = SCM_CAR (list);
61 if (SCM_INUMP (val))
edb810bb 62 data[i] = (CTYPE) SCM_INUM (val);
1fa86ca5
SJ
63 else if (SCM_BIGP (val))
64 data[i] = (CTYPE) scm_num2long (val, SCM_ARG1, FUNC_NAME);
edb810bb 65#if defined (FLOATTYPE)
1fa86ca5
SJ
66 else
67 data[i] = (CTYPE) SCM_REAL_VALUE (val);
68#endif
69 }
70 return data;
71 }
72
edb810bb 73 /* other conversions */
1fa86ca5
SJ
74 switch (SCM_TYP7 (obj))
75 {
edb810bb 76 /* vectors and weak vectors */
1fa86ca5
SJ
77 case scm_tc7_vector:
78 case scm_tc7_wvect:
79 n = SCM_VECTOR_LENGTH (obj);
edb810bb 80 /* traverse the given vector and validate each member */
1fa86ca5
SJ
81 for (i = 0; i < n; i++)
82 {
83 val = SCM_VELTS (obj)[i];
edb810bb
SJ
84#if SIZEOF_CTYPE && SIZEOF_CTYPE < SIZEOF_SCM_T_BITS
85 /* check integer ranges */
1fa86ca5
SJ
86 if (SCM_INUMP (val))
87 {
edb810bb
SJ
88 scm_t_signed_bits v = SCM_INUM (val);
89 CTYPE c = (CTYPE) v;
90 SCM_ASSERT_RANGE (SCM_ARG1, val, v != (scm_t_signed_bits) c);
1fa86ca5 91 }
edb810bb
SJ
92 /* check big number ranges */
93 else if (SCM_BIGP (val))
94 {
95 scm_t_signed_bits v = scm_num2long (val, SCM_ARG1, FUNC_NAME);
96 CTYPE c = (CTYPE) v;
97 SCM_ASSERT_RANGE (SCM_ARG1, val, v != (scm_t_signed_bits) c);
98 }
1fa86ca5 99 else
edb810bb
SJ
100 /* check float types */
101#elif defined (FLOATTYPE)
102 /* real values, big numbers and immediate values are valid
103 for float conversions */
104 if (!SCM_REALP (val) && !SCM_BIGP (val) && !SCM_INUMP (val))
1fa86ca5 105#else
edb810bb
SJ
106 if (!SCM_BIGP (val) && !SCM_INUMP (val))
107#endif /* FLOATTYPE */
108 SCM_WRONG_TYPE_ARG (SCM_ARG1, val);
1fa86ca5 109 }
edb810bb
SJ
110
111 /* allocate new memory if necessary */
1fa86ca5 112 if (data == NULL)
97820583
SJ
113 if ((data = (CTYPE *) malloc (n * sizeof (CTYPE))) == NULL)
114 return NULL;
edb810bb
SJ
115
116 /* traverse the vector once more and convert each member */
1fa86ca5
SJ
117 for (i = 0; i < n; i++)
118 {
119 val = SCM_VELTS (obj)[i];
120 if (SCM_INUMP (val))
121 data[i] = (CTYPE) SCM_INUM (val);
122 else if (SCM_BIGP (val))
123 data[i] = (CTYPE) scm_num2long (val, SCM_ARG1, FUNC_NAME);
edb810bb 124#if defined (FLOATTYPE)
1fa86ca5
SJ
125 else
126 data[i] = (CTYPE) SCM_REAL_VALUE (val);
127#endif
128 }
129 break;
130
131#ifdef HAVE_ARRAYS
edb810bb
SJ
132 /* array conversions (uniform vectors) */
133 case ARRAYTYPE:
134#ifdef ARRAYTYPE_OPTIONAL
135 case ARRAYTYPE_OPTIONAL:
1fa86ca5
SJ
136#endif
137 n = SCM_UVECTOR_LENGTH (obj);
edb810bb
SJ
138
139 /* allocate new memory if necessary */
1fa86ca5 140 if (data == NULL)
97820583
SJ
141 if ((data = (CTYPE *) malloc (n * sizeof (CTYPE))) == NULL)
142 return NULL;
edb810bb
SJ
143
144#ifdef FLOATTYPE_OPTIONAL
145 /* float <-> double conversions */
146 if (SCM_TYP7 (obj) == ARRAYTYPE_OPTIONAL)
1fa86ca5
SJ
147 {
148 for (i = 0; i < n; i++)
edb810bb 149 data[i] = ((FLOATTYPE_OPTIONAL *) SCM_UVECTOR_BASE (obj))[i];
1fa86ca5
SJ
150 }
151 else
152#endif
97820583
SJ
153#if SIZEOF_CTYPE != SIZEOF_ARRAYTYPE
154 /* copy array element by element */
155 for (i = 0; i < n; i++)
156 data[i] = (CTYPE) ((ARRAYCTYPE *) SCM_UVECTOR_BASE (obj))[i];
157#else
edb810bb 158 /* copy whole array */
1fa86ca5 159 memcpy (data, (CTYPE *) SCM_UVECTOR_BASE (obj), n * sizeof (CTYPE));
97820583 160#endif
1fa86ca5
SJ
161 break;
162#endif /* HAVE_ARRAYS */
163
edb810bb 164#if SIZEOF_CTYPE == 1
1fa86ca5
SJ
165 case scm_tc7_string:
166 n = SCM_STRING_LENGTH (obj);
167 if (data == NULL)
edb810bb
SJ
168 if ((data = (CTYPE *) malloc (n * sizeof (CTYPE))) == NULL)
169 return NULL;
1fa86ca5
SJ
170 memcpy (data, SCM_STRING_CHARS (obj), n * sizeof (CTYPE));
171 break;
edb810bb 172#endif
1fa86ca5
SJ
173
174 default:
175 SCM_WRONG_TYPE_ARG (SCM_ARG1, obj);
176 }
177 return data;
178}
179#undef FUNC_NAME
180
181
182#if HAVE_ARRAYS
183
184/* Converts a C array into a uniform vector, returns SCM_UNDEFINED if out
185 of memory. */
186#define FUNC_NAME CTYPES2UVECT_FN
187SCM
188CTYPES2UVECT (const CTYPE *data, long n)
189{
97820583
SJ
190#if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
191 UVECTCTYPE *v;
192 long i;
193#else
1fa86ca5 194 char *v;
97820583 195#endif
1fa86ca5 196
edb810bb 197 SCM_ASSERT_RANGE (SCM_ARG2, scm_long2num (n),
1fa86ca5 198 n > 0 && n <= SCM_UVECTOR_MAX_LENGTH);
97820583
SJ
199#if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
200 v = scm_gc_malloc (n * SIZEOF_UVECTTYPE, "uvect");
201 for (i = 0; i < n; i++)
202 v[i] = (UVECTCTYPE) data[i];
203#else
edb810bb 204 v = scm_gc_malloc (n * sizeof (CTYPE), "uvect");
1fa86ca5 205 memcpy (v, data, n * sizeof (CTYPE));
97820583 206#endif
228a24ef 207 return scm_cell (SCM_MAKE_UVECTOR_TAG (n, UVECTTYPE), (scm_t_bits) v);
1fa86ca5
SJ
208}
209#undef FUNC_NAME
210
edb810bb
SJ
211#ifdef UVECTTYPE_OPTIONAL
212#define FUNC_NAME CTYPES2UVECT_FN_OPTIONAL
1fa86ca5 213SCM
edb810bb 214CTYPES2UVECT_OPTIONAL (const unsigned CTYPE *data, long n)
1fa86ca5 215{
97820583
SJ
216#if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
217 unsigned UVECTCTYPE *v;
218 long i;
219#else
1fa86ca5 220 char *v;
97820583 221#endif
1fa86ca5
SJ
222
223 SCM_ASSERT_RANGE (SCM_ARG2, scm_long2num (n),
224 n > 0 && n <= SCM_UVECTOR_MAX_LENGTH);
97820583
SJ
225#if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
226 v = scm_gc_malloc (n * SIZEOF_UVECTTYPE, "uvect");
227 for (i = 0; i < n; i++)
228 v[i] = (unsigned UVECTCTYPE) data[i];
229#else
230 v = scm_gc_malloc (n * sizeof (CTYPE), "uvect");
231 memcpy (v, data, n * sizeof (CTYPE));
232#endif
228a24ef
DH
233 return scm_cell (SCM_MAKE_UVECTOR_TAG (n, UVECTTYPE_OPTIONAL),
234 (scm_t_bits) v);
1fa86ca5
SJ
235}
236#undef FUNC_NAME
edb810bb 237#endif /* UVECTTYPE_OPTIONAL */
1fa86ca5
SJ
238
239#endif /* HAVE_ARRAYS */
240
edb810bb 241
1fa86ca5
SJ
242/* Converts a C array into a vector. */
243#define FUNC_NAME CTYPES2SCM_FN
244SCM
245CTYPES2SCM (const CTYPE *data, long n)
246{
247 long i;
248 SCM v, *velts;
249
250 SCM_ASSERT_RANGE (SCM_ARG2, scm_long2num (n),
251 n > 0 && n <= SCM_VECTOR_MAX_LENGTH);
252 v = scm_c_make_vector (n, SCM_UNSPECIFIED);
253 velts = SCM_VELTS (v);
254 for (i = 0; i < n; i++)
edb810bb 255#ifdef FLOATTYPE
1fa86ca5 256 velts[i] = scm_make_real ((double) data[i]);
1fa86ca5 257#else
edb810bb 258 velts[i] = SCM_MAKINUM (data[i]);
1fa86ca5
SJ
259#endif
260 return v;
261}
262#undef FUNC_NAME
263
264/* cleanup of conditionals */
265#undef SCM2CTYPES
266#undef SCM2CTYPES_FN
267#undef CTYPES2SCM
268#undef CTYPES2SCM_FN
269#undef CTYPE
270#undef CTYPES2UVECT
271#undef CTYPES2UVECT_FN
1fa86ca5 272#undef UVECTTYPE
edb810bb
SJ
273#ifdef UVECTTYPE_OPTIONAL
274#undef CTYPES2UVECT_OPTIONAL
275#undef CTYPES2UVECT_FN_OPTIONAL
276#undef UVECTTYPE_OPTIONAL
1fa86ca5 277#endif
edb810bb 278#undef SIZEOF_CTYPE
97820583
SJ
279#undef SIZEOF_UVECTTYPE
280#undef SIZEOF_ARRAYTYPE
edb810bb
SJ
281#undef ARRAYTYPE
282#ifdef ARRAYTYPE_OPTIONAL
283#undef ARRAYTYPE_OPTIONAL
1fa86ca5 284#endif
edb810bb
SJ
285#ifdef FLOATTYPE
286#undef FLOATTYPE
1fa86ca5 287#endif
edb810bb
SJ
288#ifdef FLOATTYPE_OPTIONAL
289#undef FLOATTYPE_OPTIONAL
1fa86ca5 290#endif
97820583
SJ
291#ifdef UVECTCTYPE
292#undef UVECTCTYPE
293#endif
294#ifdef ARRAYCTYPE
295#undef ARRAYCTYPE
296#endif
1fa86ca5
SJ
297
298/*
299 Local Variables:
300 c-file-style: "gnu"
301 End:
302*/