* gc.h, gc.c (scm_gc_sweep): Issue deprecation warning when
[bpt/guile.git] / libguile / convert.i.c
CommitLineData
1fa86ca5
SJ
1/* this file is #include'd (x times) by convert.c */
2
3/* FIXME: Should we use exported wrappers for malloc (and free), which
4 * allow windows DLLs to call the correct freeing function? */
5
6
7/* Convert a vector, weak vector, (if possible string, substring), list
8 or uniform vector into an C array. If result array in argument 2 is
9 NULL, malloc() a new one. If out of memory, return NULL. */
10#define FUNC_NAME SCM2CTYPES_FN
11CTYPE *
12SCM2CTYPES (SCM obj, CTYPE *data)
13{
14 long i, n;
15 SCM val;
16
17 SCM_ASSERT (SCM_NIMP (obj) || SCM_NFALSEP (scm_list_p (obj)),
18 obj, SCM_ARG1, FUNC_NAME);
19
20 if (SCM_NFALSEP (scm_list_p (obj)))
21 {
22 SCM list = obj;
23 for (n = 0; SCM_NFALSEP (scm_pair_p (list)); list = SCM_CDR (list), n++)
24 {
25 val = SCM_CAR (list);
26#if defined (CTYPEMIN) && defined (CTYPEMAX)
27 if (SCM_INUMP (val))
28 {
29 long v = SCM_INUM (val);
30 SCM_ASSERT_RANGE (SCM_ARG1, obj, v >= CTYPEMIN && v <= CTYPEMAX);
31 }
32 else
33#elif defined (FLOATTYPE1)
34 if (!SCM_INUMP (val) && !(SCM_BIGP (val) || SCM_REALP (val)))
35#else
36 if (!SCM_INUMP (val) && !SCM_BIGP (val))
37#endif
38 SCM_WRONG_TYPE_ARG (SCM_ARG1, obj);
39 }
40 if (data == NULL)
41 data = (CTYPE *) malloc (n * sizeof (CTYPE));
42 if (data == NULL)
43 return NULL;
44
45 list = obj;
46 for (i = 0; SCM_NFALSEP (scm_pair_p (list)); list = SCM_CDR (list), i++)
47 {
48 val = SCM_CAR (list);
49 if (SCM_INUMP (val))
50 data[i] = SCM_INUM (val);
51 else if (SCM_BIGP (val))
52 data[i] = (CTYPE) scm_num2long (val, SCM_ARG1, FUNC_NAME);
53#ifdef FLOATTYPE1
54 else
55 data[i] = (CTYPE) SCM_REAL_VALUE (val);
56#endif
57 }
58 return data;
59 }
60
61 switch (SCM_TYP7 (obj))
62 {
63 case scm_tc7_vector:
64 case scm_tc7_wvect:
65 n = SCM_VECTOR_LENGTH (obj);
66 for (i = 0; i < n; i++)
67 {
68 val = SCM_VELTS (obj)[i];
69
70#if defined (CTYPEMIN) && defined (CTYPEMAX)
71 if (SCM_INUMP (val))
72 {
73 long v = SCM_INUM (val);
74 SCM_ASSERT_RANGE (SCM_ARG1, obj, v >= CTYPEMIN && v <= CTYPEMAX);
75 }
76 else
77#elif defined (FLOATTYPE1)
78 if (!SCM_INUMP (val) && !(SCM_BIGP (val) || SCM_REALP (val)))
79#else
80 if (!SCM_INUMP (val) && !SCM_BIGP (val))
81#endif
82 SCM_WRONG_TYPE_ARG (SCM_ARG1, obj);
83 }
84 if (data == NULL)
85 data = (CTYPE *) malloc (n * sizeof (CTYPE));
86 if (data == NULL)
87 return NULL;
88 for (i = 0; i < n; i++)
89 {
90 val = SCM_VELTS (obj)[i];
91 if (SCM_INUMP (val))
92 data[i] = (CTYPE) SCM_INUM (val);
93 else if (SCM_BIGP (val))
94 data[i] = (CTYPE) scm_num2long (val, SCM_ARG1, FUNC_NAME);
95#ifdef FLOATTYPE1
96 else
97 data[i] = (CTYPE) SCM_REAL_VALUE (val);
98#endif
99 }
100 break;
101
102#ifdef HAVE_ARRAYS
103 case ARRAYTYPE1:
104#ifdef ARRAYTYPE2
105 case ARRAYTYPE2:
106#endif
107 n = SCM_UVECTOR_LENGTH (obj);
108 if (data == NULL)
109 data = (CTYPE *) malloc (n * sizeof (CTYPE));
110 if (data == NULL)
111 return NULL;
112#ifdef FLOATTYPE2
113 if (SCM_TYP7 (obj) == ARRAYTYPE2)
114 {
115 for (i = 0; i < n; i++)
116 data[i] = ((FLOATTYPE2 *) SCM_UVECTOR_BASE (obj))[i];
117 }
118 else
119#endif
120 memcpy (data, (CTYPE *) SCM_UVECTOR_BASE (obj), n * sizeof (CTYPE));
121 break;
122#endif /* HAVE_ARRAYS */
123
124#ifdef STRINGTYPE
125 case scm_tc7_string:
126 n = SCM_STRING_LENGTH (obj);
127 if (data == NULL)
128 data = (CTYPE *) malloc (n * sizeof (CTYPE));
129 if (data == NULL)
130 return NULL;
131 memcpy (data, SCM_STRING_CHARS (obj), n * sizeof (CTYPE));
132 break;
133#endif /* STRINGTYPE */
134
135 default:
136 SCM_WRONG_TYPE_ARG (SCM_ARG1, obj);
137 }
138 return data;
139}
140#undef FUNC_NAME
141
142
143#if HAVE_ARRAYS
144
145/* Converts a C array into a uniform vector, returns SCM_UNDEFINED if out
146 of memory. */
147#define FUNC_NAME CTYPES2UVECT_FN
148SCM
149CTYPES2UVECT (const CTYPE *data, long n)
150{
151 char *v;
152
153 SCM_ASSERT_RANGE (SCM_ARG2, scm_long2num (n),
154 n > 0 && n <= SCM_UVECTOR_MAX_LENGTH);
4c9419ac 155 v = scm_gc_malloc (sizeof (CTYPE) * n, "vector");
1fa86ca5
SJ
156 memcpy (v, data, n * sizeof (CTYPE));
157 return scm_alloc_cell (SCM_MAKE_UVECTOR_TAG (n, UVECTTYPE), (scm_t_bits) v);
158}
159#undef FUNC_NAME
160
161#ifdef UVECTTYPE2
162#define FUNC_NAME CTYPES2UVECT_FN2
163SCM
164CTYPES2UVECT2 (const unsigned CTYPE *data, long n)
165{
166 char *v;
167
168 SCM_ASSERT_RANGE (SCM_ARG2, scm_long2num (n),
169 n > 0 && n <= SCM_UVECTOR_MAX_LENGTH);
4c9419ac 170 v = scm_gc_malloc (sizeof (unsigned CTYPE) * n, "vector");
1fa86ca5
SJ
171 memcpy (v, data, n * sizeof (unsigned CTYPE));
172 return scm_alloc_cell (SCM_MAKE_UVECTOR_TAG (n, UVECTTYPE2), (scm_t_bits) v);
173}
174#undef FUNC_NAME
175#endif /* UVECTTYPE2 */
176
177#endif /* HAVE_ARRAYS */
178
179/* Converts a C array into a vector. */
180#define FUNC_NAME CTYPES2SCM_FN
181SCM
182CTYPES2SCM (const CTYPE *data, long n)
183{
184 long i;
185 SCM v, *velts;
186
187 SCM_ASSERT_RANGE (SCM_ARG2, scm_long2num (n),
188 n > 0 && n <= SCM_VECTOR_MAX_LENGTH);
189 v = scm_c_make_vector (n, SCM_UNSPECIFIED);
190 velts = SCM_VELTS (v);
191 for (i = 0; i < n; i++)
192#ifdef FLOATTYPE1
193 velts[i] = scm_make_real ((double) data[i]);
194#elif defined (CTYPEFIXABLE)
195 velts[i] = SCM_MAKINUM (data[i]);
196#else
197 velts[i] = (SCM_FIXABLE (data[i]) ? SCM_MAKINUM (data[i]) :
198 scm_i_long2big (data[i]));
199#endif
200 return v;
201}
202#undef FUNC_NAME
203
204/* cleanup of conditionals */
205#undef SCM2CTYPES
206#undef SCM2CTYPES_FN
207#undef CTYPES2SCM
208#undef CTYPES2SCM_FN
209#undef CTYPE
210#undef CTYPES2UVECT
211#undef CTYPES2UVECT_FN
212#ifdef CTYPEFIXABLE
213#undef CTYPEFIXABLE
214#endif
215#undef UVECTTYPE
216#ifdef UVECTTYPE2
217#undef CTYPES2UVECT2
218#undef CTYPES2UVECT_FN2
219#undef UVECTTYPE2
220#endif
221#ifdef CTYPEMIN
222#undef CTYPEMIN
223#endif
224#ifdef CTYPEMAX
225#undef CTYPEMAX
226#endif
227#undef ARRAYTYPE1
228#ifdef ARRAYTYPE2
229#undef ARRAYTYPE2
230#endif
231#ifdef FLOATTYPE1
232#undef FLOATTYPE1
233#endif
234#ifdef FLOATTYPE2
235#undef FLOATTYPE2
236#endif
237#ifdef STRINGTYPE
238#undef STRINGTYPE
239#endif
240
241/*
242 Local Variables:
243 c-file-style: "gnu"
244 End:
245*/