80a0c30ffaef4262c2f655d07dacde2ea61cd84f
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 */
58 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
62 /* traverse the list once more and convert each member */
64 for (i
= 0; SCM_NFALSEP (scm_pair_p (list
)); list
= SCM_CDR (list
), i
++)
68 data
[i
] = (CTYPE
) SCM_INUM (val
);
69 else if (SCM_BIGP (val
))
70 data
[i
] = (CTYPE
) scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
71 #if defined (FLOATTYPE)
73 data
[i
] = (CTYPE
) SCM_REAL_VALUE (val
);
79 /* other conversions */
80 switch (SCM_TYP7 (obj
))
82 /* vectors and weak vectors */
85 n
= SCM_VECTOR_LENGTH (obj
);
86 /* traverse the given vector and validate each member */
87 for (i
= 0; i
< n
; i
++)
89 val
= SCM_VELTS (obj
)[i
];
90 #if SIZEOF_CTYPE && SIZEOF_CTYPE < SIZEOF_SCM_T_BITS
91 /* check integer ranges */
94 scm_t_signed_bits v
= SCM_INUM (val
);
96 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
98 /* check big number ranges */
99 else if (SCM_BIGP (val
))
101 scm_t_signed_bits v
= scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
103 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
106 /* check float types */
107 #elif defined (FLOATTYPE)
108 /* real values, big numbers and immediate values are valid
109 for float conversions */
110 if (!SCM_REALP (val
) && !SCM_BIGP (val
) && !SCM_INUMP (val
))
112 if (!SCM_BIGP (val
) && !SCM_INUMP (val
))
113 #endif /* FLOATTYPE */
114 SCM_WRONG_TYPE_ARG (SCM_ARG1
, val
);
117 /* allocate new memory if necessary */
120 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
124 /* traverse the vector once more and convert each member */
125 for (i
= 0; i
< n
; i
++)
127 val
= SCM_VELTS (obj
)[i
];
129 data
[i
] = (CTYPE
) SCM_INUM (val
);
130 else if (SCM_BIGP (val
))
131 data
[i
] = (CTYPE
) scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
132 #if defined (FLOATTYPE)
134 data
[i
] = (CTYPE
) SCM_REAL_VALUE (val
);
140 /* array conversions (uniform vectors) */
142 #ifdef ARRAYTYPE_OPTIONAL
143 case ARRAYTYPE_OPTIONAL
:
145 n
= SCM_UVECTOR_LENGTH (obj
);
147 /* allocate new memory if necessary */
150 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
154 #ifdef FLOATTYPE_OPTIONAL
155 /* float <-> double conversions */
156 if (SCM_TYP7 (obj
) == ARRAYTYPE_OPTIONAL
)
158 for (i
= 0; i
< n
; i
++)
159 data
[i
] = ((FLOATTYPE_OPTIONAL
*) SCM_UVECTOR_BASE (obj
))[i
];
163 /* copy whole array */
164 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
)
196 SCM_ASSERT_RANGE (SCM_ARG2
, scm_long2num (n
),
197 n
> 0 && n
<= SCM_UVECTOR_MAX_LENGTH
);
198 v
= scm_gc_malloc (n
* sizeof (CTYPE
), "uvect");
199 memcpy (v
, data
, n
* sizeof (CTYPE
));
200 return scm_alloc_cell (SCM_MAKE_UVECTOR_TAG (n
, UVECTTYPE
), (scm_t_bits
) v
);
204 #ifdef UVECTTYPE_OPTIONAL
205 #define FUNC_NAME CTYPES2UVECT_FN_OPTIONAL
207 CTYPES2UVECT_OPTIONAL (const unsigned CTYPE
*data
, long n
)
211 SCM_ASSERT_RANGE (SCM_ARG2
, scm_long2num (n
),
212 n
> 0 && n
<= SCM_UVECTOR_MAX_LENGTH
);
213 v
= scm_gc_malloc (n
* sizeof (unsigned CTYPE
) * n
, "uvect");
214 memcpy (v
, data
, n
* sizeof (unsigned CTYPE
));
215 return scm_alloc_cell (SCM_MAKE_UVECTOR_TAG (n
, UVECTTYPE_OPTIONAL
),
219 #endif /* UVECTTYPE_OPTIONAL */
221 #endif /* HAVE_ARRAYS */
224 /* Converts a C array into a vector. */
225 #define FUNC_NAME CTYPES2SCM_FN
227 CTYPES2SCM (const CTYPE
*data
, long n
)
232 SCM_ASSERT_RANGE (SCM_ARG2
, scm_long2num (n
),
233 n
> 0 && n
<= SCM_VECTOR_MAX_LENGTH
);
234 v
= scm_c_make_vector (n
, SCM_UNSPECIFIED
);
235 velts
= SCM_VELTS (v
);
236 for (i
= 0; i
< n
; i
++)
238 velts
[i
] = scm_make_real ((double) data
[i
]);
240 velts
[i
] = SCM_MAKINUM (data
[i
]);
246 /* cleanup of conditionals */
253 #undef CTYPES2UVECT_FN
255 #ifdef UVECTTYPE_OPTIONAL
256 #undef CTYPES2UVECT_OPTIONAL
257 #undef CTYPES2UVECT_FN_OPTIONAL
258 #undef UVECTTYPE_OPTIONAL
262 #ifdef ARRAYTYPE_OPTIONAL
263 #undef ARRAYTYPE_OPTIONAL
268 #ifdef FLOATTYPE_OPTIONAL
269 #undef FLOATTYPE_OPTIONAL