1 /* this file is #include'd (x times) by convert.c */
3 /* Convert a vector, weak vector, (if possible string, substring), list
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. */
6 #define FUNC_NAME SCM2CTYPES_FN
8 SCM2CTYPES (SCM obj
, CTYPE
*data
)
13 SCM_ASSERT (SCM_NIMP (obj
) || SCM_NFALSEP (scm_list_p (obj
)),
14 obj
, SCM_ARG1
, FUNC_NAME
);
17 if (SCM_NFALSEP (scm_list_p (obj
)))
19 /* traverse the given list and validate the range of each member */
21 for (n
= 0; SCM_NFALSEP (scm_pair_p (list
)); list
= SCM_CDR (list
), n
++)
24 #if SIZEOF_CTYPE && SIZEOF_CTYPE < SIZEOF_SCM_T_BITS
25 /* check integer ranges */
28 scm_t_signed_bits v
= SCM_INUM (val
);
30 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
32 /* check big number ranges */
33 else if (SCM_BIGP (val
))
35 scm_t_signed_bits v
= scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
37 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
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
))
46 if (!SCM_BIGP (val
) && !SCM_INUMP (val
))
47 #endif /* FLOATTYPE */
48 SCM_WRONG_TYPE_ARG (SCM_ARG1
, val
);
51 /* allocate new memory if necessary */
53 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
56 /* traverse the list once more and convert each member */
58 for (i
= 0; SCM_NFALSEP (scm_pair_p (list
)); list
= SCM_CDR (list
), i
++)
62 data
[i
] = (CTYPE
) SCM_INUM (val
);
63 else if (SCM_BIGP (val
))
64 data
[i
] = (CTYPE
) scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
65 #if defined (FLOATTYPE)
67 data
[i
] = (CTYPE
) SCM_REAL_VALUE (val
);
73 /* other conversions */
74 switch (SCM_TYP7 (obj
))
76 /* vectors and weak vectors */
79 n
= SCM_VECTOR_LENGTH (obj
);
80 /* traverse the given vector and validate each member */
81 for (i
= 0; i
< n
; i
++)
83 val
= SCM_VELTS (obj
)[i
];
84 #if SIZEOF_CTYPE && SIZEOF_CTYPE < SIZEOF_SCM_T_BITS
85 /* check integer ranges */
88 scm_t_signed_bits v
= SCM_INUM (val
);
90 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
92 /* check big number ranges */
93 else if (SCM_BIGP (val
))
95 scm_t_signed_bits v
= scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
97 SCM_ASSERT_RANGE (SCM_ARG1
, val
, v
!= (scm_t_signed_bits
) c
);
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
))
106 if (!SCM_BIGP (val
) && !SCM_INUMP (val
))
107 #endif /* FLOATTYPE */
108 SCM_WRONG_TYPE_ARG (SCM_ARG1
, val
);
111 /* allocate new memory if necessary */
113 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
116 /* traverse the vector once more and convert each member */
117 for (i
= 0; i
< n
; i
++)
119 val
= SCM_VELTS (obj
)[i
];
121 data
[i
] = (CTYPE
) SCM_INUM (val
);
122 else if (SCM_BIGP (val
))
123 data
[i
] = (CTYPE
) scm_num2long (val
, SCM_ARG1
, FUNC_NAME
);
124 #if defined (FLOATTYPE)
126 data
[i
] = (CTYPE
) SCM_REAL_VALUE (val
);
132 /* array conversions (uniform vectors) */
134 #ifdef ARRAYTYPE_OPTIONAL
135 case ARRAYTYPE_OPTIONAL
:
137 n
= SCM_UVECTOR_LENGTH (obj
);
139 /* allocate new memory if necessary */
141 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
144 #ifdef FLOATTYPE_OPTIONAL
145 /* float <-> double conversions */
146 if (SCM_TYP7 (obj
) == ARRAYTYPE_OPTIONAL
)
148 for (i
= 0; i
< n
; i
++)
149 data
[i
] = ((FLOATTYPE_OPTIONAL
*) SCM_UVECTOR_BASE (obj
))[i
];
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
];
158 /* copy whole array */
159 memcpy (data
, (CTYPE
*) SCM_UVECTOR_BASE (obj
), n
* sizeof (CTYPE
));
162 #endif /* HAVE_ARRAYS */
164 #if SIZEOF_CTYPE == 1
166 n
= SCM_STRING_LENGTH (obj
);
168 if ((data
= (CTYPE
*) malloc (n
* sizeof (CTYPE
))) == NULL
)
170 memcpy (data
, SCM_STRING_CHARS (obj
), n
* sizeof (CTYPE
));
175 SCM_WRONG_TYPE_ARG (SCM_ARG1
, obj
);
184 /* Converts a C array into a uniform vector, returns SCM_UNDEFINED if out
186 #define FUNC_NAME CTYPES2UVECT_FN
188 CTYPES2UVECT (const CTYPE
*data
, long n
)
190 #if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
197 SCM_ASSERT_RANGE (SCM_ARG2
, scm_long2num (n
),
198 n
> 0 && n
<= SCM_UVECTOR_MAX_LENGTH
);
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
];
204 v
= scm_gc_malloc (n
* sizeof (CTYPE
), "uvect");
205 memcpy (v
, data
, n
* sizeof (CTYPE
));
207 return scm_cell (SCM_MAKE_UVECTOR_TAG (n
, UVECTTYPE
), (scm_t_bits
) v
);
211 #ifdef UVECTTYPE_OPTIONAL
212 #define FUNC_NAME CTYPES2UVECT_FN_OPTIONAL
214 CTYPES2UVECT_OPTIONAL (const unsigned CTYPE
*data
, long n
)
216 #if SIZEOF_CTYPE != SIZEOF_UVECTTYPE
217 unsigned UVECTCTYPE
*v
;
223 SCM_ASSERT_RANGE (SCM_ARG2
, scm_long2num (n
),
224 n
> 0 && n
<= SCM_UVECTOR_MAX_LENGTH
);
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
];
230 v
= scm_gc_malloc (n
* sizeof (CTYPE
), "uvect");
231 memcpy (v
, data
, n
* sizeof (CTYPE
));
233 return scm_cell (SCM_MAKE_UVECTOR_TAG (n
, UVECTTYPE_OPTIONAL
),
237 #endif /* UVECTTYPE_OPTIONAL */
239 #endif /* HAVE_ARRAYS */
242 /* Converts a C array into a vector. */
243 #define FUNC_NAME CTYPES2SCM_FN
245 CTYPES2SCM (const CTYPE
*data
, long n
)
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
);
254 for (i
= 0; i
< n
; i
++)
256 SCM_VECTOR_SET (v
, i
, scm_make_real ((double) data
[i
]));
258 SCM_VECTOR_SET (v
, i
, SCM_MAKINUM (data
[i
]));
264 /* cleanup of conditionals */
271 #undef CTYPES2UVECT_FN
273 #ifdef UVECTTYPE_OPTIONAL
274 #undef CTYPES2UVECT_OPTIONAL
275 #undef CTYPES2UVECT_FN_OPTIONAL
276 #undef UVECTTYPE_OPTIONAL
279 #undef SIZEOF_UVECTTYPE
280 #undef SIZEOF_ARRAYTYPE
282 #ifdef ARRAYTYPE_OPTIONAL
283 #undef ARRAYTYPE_OPTIONAL
288 #ifdef FLOATTYPE_OPTIONAL
289 #undef FLOATTYPE_OPTIONAL