1 /* this file is #include'd (x times) by convert.c */
3 /* FIXME: Should we use exported wrappers for malloc (and free), which
4 * allow windows DLLs to call the correct freeing function? */
7 /* Convert a vector, weak vector, (if possible string, substring), list
8 or uniform vector into an C array. If the result array in argument 2
9 is NULL, malloc() a new one. If out of memory, return NULL. */
10 #define FUNC_NAME SCM2CTYPES_FN
12 SCM2CTYPES (SCM obj
, CTYPE
*data
)
17 SCM_ASSERT (SCM_NIMP (obj
) || SCM_NFALSEP (scm_list_p (obj
)),
18 obj
, SCM_ARG1
, FUNC_NAME
);
21 if (SCM_NFALSEP (scm_list_p (obj
)))
23 /* traverse the given list and validate the range of each member */
25 for (n
= 0; SCM_NFALSEP (scm_pair_p (list
)); list
= SCM_CDR (list
), n
++)
28 #if SIZEOF_CTYPE && SIZEOF_CTYPE < SIZEOF_SCM_T_BITS
29 /* check integer ranges */
32 scm_t_signed_bits v
= SCM_INUM (val
);
34 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
36 /* check big number ranges */
37 else if (SCM_BIGP (val
))
39 scm_t_signed_bits v
= scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
41 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
44 /* check float types */
45 #elif defined (FLOATTYPE)
46 /* real values, big numbers and immediate values are valid
47 for float conversions */
48 if (!SCM_REALP (val
) && !SCM_BIGP (val
) && !SCM_INUMP (val
))
50 if (!SCM_BIGP (val
) && !SCM_INUMP (val
))
51 #endif /* FLOATTYPE */
52 SCM_WRONG_TYPE_ARG (SCM_ARG1
, val
);
55 /* allocate new memory if necessary */
57 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
60 /* traverse the list once more and convert each member */
62 for (i
= 0; SCM_NFALSEP (scm_pair_p (list
)); list
= SCM_CDR (list
), i
++)
66 data
[i
] = (CTYPE
) SCM_INUM (val
);
67 else if (SCM_BIGP (val
))
68 data
[i
] = (CTYPE
) scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
69 #if defined (FLOATTYPE)
71 data
[i
] = (CTYPE
) SCM_REAL_VALUE (val
);
77 /* other conversions */
78 switch (SCM_TYP7 (obj
))
80 /* vectors and weak vectors */
83 n
= SCM_VECTOR_LENGTH (obj
);
84 /* traverse the given vector and validate each member */
85 for (i
= 0; i
< n
; i
++)
87 val
= SCM_VELTS (obj
)[i
];
88 #if SIZEOF_CTYPE && SIZEOF_CTYPE < SIZEOF_SCM_T_BITS
89 /* check integer ranges */
92 scm_t_signed_bits v
= SCM_INUM (val
);
94 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
96 /* check big number ranges */
97 else if (SCM_BIGP (val
))
99 scm_t_signed_bits v
= scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
101 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
104 /* check float types */
105 #elif defined (FLOATTYPE)
106 /* real values, big numbers and immediate values are valid
107 for float conversions */
108 if (!SCM_REALP (val
) && !SCM_BIGP (val
) && !SCM_INUMP (val
))
110 if (!SCM_BIGP (val
) && !SCM_INUMP (val
))
111 #endif /* FLOATTYPE */
112 SCM_WRONG_TYPE_ARG (SCM_ARG1
, val
);
115 /* allocate new memory if necessary */
117 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
120 /* traverse the vector once more and convert each member */
121 for (i
= 0; i
< n
; i
++)
123 val
= SCM_VELTS (obj
)[i
];
125 data
[i
] = (CTYPE
) SCM_INUM (val
);
126 else if (SCM_BIGP (val
))
127 data
[i
] = (CTYPE
) scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
128 #if defined (FLOATTYPE)
130 data
[i
] = (CTYPE
) SCM_REAL_VALUE (val
);
136 /* array conversions (uniform vectors) */
138 #ifdef ARRAYTYPE_OPTIONAL
139 case ARRAYTYPE_OPTIONAL
:
141 n
= SCM_UVECTOR_LENGTH (obj
);
143 /* allocate new memory if necessary */
145 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
148 #ifdef FLOATTYPE_OPTIONAL
149 /* float <-> double conversions */
150 if (SCM_TYP7 (obj
) == ARRAYTYPE_OPTIONAL
)
152 for (i
= 0; i
< n
; i
++)
153 data
[i
] = ((FLOATTYPE_OPTIONAL
*) SCM_UVECTOR_BASE (obj
))[i
];
157 #if SIZEOF_CTYPE != SIZEOF_ARRAYTYPE
158 /* copy array element by element */
159 for (i
= 0; i
< n
; i
++)
160 data
[i
] = (CTYPE
) ((ARRAYCTYPE
*) SCM_UVECTOR_BASE (obj
))[i
];
162 /* copy whole array */
163 memcpy (data
, (CTYPE
*) SCM_UVECTOR_BASE (obj
), n
* sizeof (CTYPE
));
166 #endif /* HAVE_ARRAYS */
168 #if SIZEOF_CTYPE == 1
170 n
= SCM_STRING_LENGTH (obj
);
172 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
174 memcpy (data
, SCM_STRING_CHARS (obj
), n
* sizeof (CTYPE
));
179 SCM_WRONG_TYPE_ARG (SCM_ARG1
, obj
);
188 /* Converts a C array into a uniform vector, returns SCM_UNDEFINED if out
190 #define FUNC_NAME CTYPES2UVECT_FN
192 CTYPES2UVECT (const CTYPE
*data
, long n
)
194 #if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
201 SCM_ASSERT_RANGE (SCM_ARG2
, scm_long2num (n
),
202 n
> 0 && n
<= SCM_UVECTOR_MAX_LENGTH
);
203 #if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
204 v
= scm_gc_malloc (n
* SIZEOF_UVECTTYPE
, "uvect");
205 for (i
= 0; i
< n
; i
++)
206 v
[i
] = (UVECTCTYPE
) data
[i
];
208 v
= scm_gc_malloc (n
* sizeof (CTYPE
), "uvect");
209 memcpy (v
, data
, n
* sizeof (CTYPE
));
211 return scm_cell (SCM_MAKE_UVECTOR_TAG (n
, UVECTTYPE
), (scm_t_bits
) v
);
215 #ifdef UVECTTYPE_OPTIONAL
216 #define FUNC_NAME CTYPES2UVECT_FN_OPTIONAL
218 CTYPES2UVECT_OPTIONAL (const unsigned CTYPE
*data
, long n
)
220 #if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
221 unsigned UVECTCTYPE
*v
;
227 SCM_ASSERT_RANGE (SCM_ARG2
, scm_long2num (n
),
228 n
> 0 && n
<= SCM_UVECTOR_MAX_LENGTH
);
229 #if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
230 v
= scm_gc_malloc (n
* SIZEOF_UVECTTYPE
, "uvect");
231 for (i
= 0; i
< n
; i
++)
232 v
[i
] = (unsigned UVECTCTYPE
) data
[i
];
234 v
= scm_gc_malloc (n
* sizeof (CTYPE
), "uvect");
235 memcpy (v
, data
, n
* sizeof (CTYPE
));
237 return scm_cell (SCM_MAKE_UVECTOR_TAG (n
, UVECTTYPE_OPTIONAL
),
241 #endif /* UVECTTYPE_OPTIONAL */
243 #endif /* HAVE_ARRAYS */
246 /* Converts a C array into a vector. */
247 #define FUNC_NAME CTYPES2SCM_FN
249 CTYPES2SCM (const CTYPE
*data
, long n
)
254 SCM_ASSERT_RANGE (SCM_ARG2
, scm_long2num (n
),
255 n
> 0 && n
<= SCM_VECTOR_MAX_LENGTH
);
256 v
= scm_c_make_vector (n
, SCM_UNSPECIFIED
);
257 velts
= SCM_VELTS (v
);
258 for (i
= 0; i
< n
; i
++)
260 velts
[i
] = scm_make_real ((double) data
[i
]);
262 velts
[i
] = SCM_MAKINUM (data
[i
]);
268 /* cleanup of conditionals */
275 #undef CTYPES2UVECT_FN
277 #ifdef UVECTTYPE_OPTIONAL
278 #undef CTYPES2UVECT_OPTIONAL
279 #undef CTYPES2UVECT_FN_OPTIONAL
280 #undef UVECTTYPE_OPTIONAL
283 #undef SIZEOF_UVECTTYPE
284 #undef SIZEOF_ARRAYTYPE
286 #ifdef ARRAYTYPE_OPTIONAL
287 #undef ARRAYTYPE_OPTIONAL
292 #ifdef FLOATTYPE_OPTIONAL
293 #undef FLOATTYPE_OPTIONAL