* vectors.c, vectors.h (scm_make_vector): Removed third argument.
[bpt/guile.git] / libguile / gh_data.c
CommitLineData
1e598865 1/* Copyright (C) 1995,1996,1997 Free Software Foundation, Inc.
ee2a8b9b
JB
2
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
ee2a8b9b
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
ee2a8b9b
JB
41\f
42
43/* data initialization and C<->Scheme data conversion */
44
45#include <stdio.h>
46
47#include <gh.h>
48
49/* data conversion C->scheme */
50SCM
dbb3005d
MG
51gh_int2scmb (int x) /* this is being phased out */
52{
53 return (x ? SCM_BOOL_T : SCM_BOOL_F);
54}
55SCM
56gh_bool2scm (int x)
ee2a8b9b
JB
57{
58 return (x ? SCM_BOOL_T : SCM_BOOL_F);
59}
60SCM
61gh_int2scm (int x)
62{
63 return scm_long2num ((long) x);
64}
65SCM
66gh_ulong2scm (unsigned long x)
67{
68 return scm_ulong2num (x);
69}
70SCM
71gh_long2scm (long x)
72{
73 return scm_long2num (x);
74}
75SCM
76gh_double2scm (double x)
77{
78 return scm_makdbl (x, 0.0);
79}
80SCM
81gh_char2scm (char c)
82{
2c92112b 83 return SCM_MAKICHR (c);
ee2a8b9b
JB
84}
85SCM
86gh_str2scm (char *s, int len)
87{
88 return scm_makfromstr (s, len, 0);
89}
90SCM
91gh_str02scm (char *s)
92{
93 return scm_makfrom0str (s);
94}
95/* Copy LEN characters at SRC into the *existing* Scheme string DST,
96 starting at START. START is an index into DST; zero means the
97 beginning of the string.
98
99 If START + LEN is off the end of DST, signal an out-of-range
100 error. */
101void
102gh_set_substr (char *src, SCM dst, int start, int len)
103{
2c92112b
AG
104 char *dst_ptr;
105 unsigned long dst_len, effective_length;
ee2a8b9b
JB
106
107 SCM_ASSERT (SCM_NIMP (dst) && SCM_STRINGP (dst), dst, SCM_ARG3,
108 "gh_set_substr");
109 scm_protect_object (dst);
110 dst_ptr = SCM_CHARS (dst);
111 dst_len = SCM_LENGTH (dst);
112 effective_length = (len < dst_len) ? len : dst_len;
113 memcpy (dst_ptr + start, src, effective_length);
114 /* FIXME: must signal an error if len > dst_len */
115 scm_unprotect_object (dst);
116}
117
118/* Return the symbol named SYMBOL_STR. */
119SCM
120gh_symbol2scm (char *symbol_str)
121{
122 return SCM_CAR (scm_intern (symbol_str, strlen (symbol_str)));
123}
124
f3a2c4cf
MD
125SCM
126gh_doubles2scm (double *d, int n)
127{
128 SCM ans;
129 SCM *m = (SCM*) scm_must_malloc (n * sizeof (SCM), "vector");
130 int i;
131 for (i = 0; i < n; ++i)
132 m[i] = scm_makdbl (d[i], 0.0);
133 SCM_NEWCELL (ans);
134 SCM_DEFER_INTS;
135 SCM_SETCHARS (ans, m);
136 SCM_SETLENGTH (ans, n, scm_tc7_vector);
137 SCM_ALLOW_INTS;
138 return ans;
139}
140
141#ifdef SCM_FLOATS
142SCM
143gh_doubles2dvect (double *d, int n)
144{
145 SCM ans;
146 char *m = scm_must_malloc (n * sizeof (double), "vector");
147 memcpy (m, d, n * sizeof (double));
148 SCM_NEWCELL (ans);
149 SCM_DEFER_INTS;
150 SCM_SETCHARS (ans, m);
151 SCM_SETLENGTH (ans, n, scm_tc7_dvect);
152 SCM_ALLOW_INTS;
153 return ans;
154}
155#endif
ee2a8b9b
JB
156
157/* data conversion scheme->C */
158int
159gh_scm2bool (SCM obj)
160{
161 return ((obj) == SCM_BOOL_F) ? 0 : 1;
162}
163unsigned long
164gh_scm2ulong (SCM obj)
165{
166 return scm_num2ulong (obj, (char *) SCM_ARG1, "gh_scm2ulong");
167}
168long
169gh_scm2long (SCM obj)
170{
171 return scm_num2long (obj, (char *) SCM_ARG1, "gh_scm2long");
172}
173int
174gh_scm2int (SCM obj)
175{
176 /* NOTE: possible loss of precision here */
177 return (int) scm_num2long (obj, (char *) SCM_ARG1, "gh_scm2int");
178}
179double
180gh_scm2double (SCM obj)
181{
182 return scm_num2dbl (obj, "gh_scm2double");
183}
184char
185gh_scm2char (SCM obj)
186{
187 return SCM_ICHR (obj);
188}
189
f3a2c4cf
MD
190/* Convert a vector, weak vector or uniform vector into a malloced
191 array of doubles. */
192double*
193gh_scm2doubles (SCM obj)
194{
195 int i, n;
196 double *m;
197 SCM val;
198 if (!SCM_NIMP (obj))
199 scm_wrong_type_arg (0, 0, obj);
200 switch (SCM_TYP7 (obj))
201 {
202 case scm_tc7_vector:
203 case scm_tc7_wvect:
204 n = SCM_LENGTH (obj);
205 m = (double*) malloc (n * sizeof (double));
206 for (i = 0; i < n; ++i)
207 {
208 val = SCM_VELTS (obj)[i];
209 if (SCM_INUMP (val))
210 m[i] = SCM_INUM (val);
211 else if (SCM_NIMP (val) && SCM_REALP (val))
212 m[i] = SCM_REALPART (val);
213 else
214 {
215 free (m);
216 scm_wrong_type_arg (0, 0, val);
217 }
218 }
219 break;
220#ifdef SCM_FLOATS
221#ifdef SCM_SINGLES
222 case scm_tc7_fvect:
223 n = SCM_LENGTH (obj);
224 m = (double*) malloc (n * sizeof (double));
225 for (i = 0; i < n; ++i)
226 m[i] = ((float*) SCM_VELTS (obj))[i];
227 break;
228#endif
229 case scm_tc7_dvect:
230 n = SCM_LENGTH (obj);
231 m = (double*) malloc (n * sizeof (double));
232 for (i = 0; i < n; ++i)
233 m[i] = ((double*) SCM_VELTS (obj))[i];
234 break;
235#endif
236 default:
237 scm_wrong_type_arg (0, 0, obj);
238 }
239 return m;
240}
241
ee2a8b9b
JB
242/* string conversions between C and Scheme */
243
244/* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
245 new copy of its contents, followed by a null byte. If lenp is
246 non-null, set *lenp to the string's length.
247
248 This function uses malloc to obtain storage for the copy; the
249 caller is responsible for freeing it.
250
251 Note that Scheme strings may contain arbitrary data, including null
252 characters. This means that null termination is not a reliable way
253 to determine the length of the returned value. However, the
254 function always copies the complete contents of STR, and sets
255 *LEN_P to the true length of the string (when LEN_P is non-null). */
256char *
257gh_scm2newstr (SCM str, int *lenp)
258{
259 char *ret_str;
260 int len;
261
66d1e129 262 SCM_ASSERT (SCM_NIMP (str) && SCM_ROSTRINGP (str), str, SCM_ARG3,
ee2a8b9b
JB
263 "gh_scm2newstr");
264
265 /* protect str from GC while we copy off its data */
266 scm_protect_object (str);
267
268 len = SCM_LENGTH (str);
269
9b1b00fe
JB
270 ret_str = (char *) scm_must_malloc ((len + 1) * sizeof (char),
271 "gh_scm2newstr");
ee2a8b9b 272 /* so we copy tmp_str to ret_str, which is what we will allocate */
66d1e129 273 memcpy (ret_str, SCM_ROCHARS (str), len); /* test ROCHARS here -twp */
ee2a8b9b
JB
274 /* now make sure we null-terminate it */
275 ret_str[len] = '\0';
276
277 scm_unprotect_object (str);
278
279 if (lenp != NULL)
280 {
281 *lenp = len;
282 }
283
284 return ret_str;
285}
286
287
288/* Copy LEN characters at START from the Scheme string SRC to memory
289 at DST. START is an index into SRC; zero means the beginning of
290 the string. DST has already been allocated by the caller.
291
292 If START + LEN is off the end of SRC, silently truncate the source
293 region to fit the string. If truncation occurs, the corresponding
294 area of DST is left unchanged. */
295void
296gh_get_substr (SCM src, char *dst, int start, int len)
297{
298 int src_len, effective_length;
66d1e129 299 SCM_ASSERT (SCM_NIMP (src) && SCM_ROSTRINGP (src), src, SCM_ARG3,
ee2a8b9b
JB
300 "gh_get_substr");
301
302 scm_protect_object (src);
303 src_len = SCM_LENGTH (src);
304 effective_length = (len < src_len) ? len : src_len;
66d1e129 305 memcpy (dst + start, SCM_ROCHARS (src), effective_length * sizeof (char));
ee2a8b9b
JB
306 /* FIXME: must signal an error if len > src_len */
307 scm_unprotect_object (src);
308}
309
310
311/* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
312 pointer to a string with the symbol characters "identifier",
313 followed by a null byte. If lenp is non-null, set *lenp to the
314 string's length.
315
316 This function uses malloc to obtain storage for the copy; the
317 caller is responsible for freeing it. */
318char *
319gh_symbol2newstr (SCM sym, int *lenp)
320{
321 char *ret_str;
322 int len;
323
324 SCM_ASSERT (SCM_NIMP (sym) && SCM_SYMBOLP (sym), sym, SCM_ARG3,
325 "gh_scm2newsymbol");
326
327 /* protect str from GC while we copy off its data */
328 scm_protect_object (sym);
329
330 len = SCM_LENGTH (sym);
331
9b1b00fe
JB
332 ret_str = (char *) scm_must_malloc ((len + 1) * sizeof (char),
333 "gh_symbol2newstr");
ee2a8b9b
JB
334 /* so we copy tmp_str to ret_str, which is what we will allocate */
335 memcpy (ret_str, SCM_CHARS (sym), len);
336 /* now make sure we null-terminate it */
337 ret_str[len] = '\0';
338
339 scm_unprotect_object (sym);
340
341 if (lenp != NULL)
342 {
343 *lenp = len;
344 }
345
346 return ret_str;
347}
348
349
350/* create a new vector of the given length, all initialized to the
351 given value */
e5eece74
MG
352SCM
353gh_make_vector (SCM len, SCM fill)
ee2a8b9b 354{
e5eece74
MG
355 /* scm_make_vector() takes a third boolean argument which should be
356 set to SCM_BOOL_T when you are dealing with multi-dimensional
357 arrays; gh_make_vector() does not do multi-dimensional arrays */
358 return scm_make_vector(len, fill, SCM_BOOL_F);
ee2a8b9b
JB
359}
360
361/* set the given element of the given vector to the given value */
362SCM
956328d2 363gh_vector_set_x (SCM vec, SCM pos, SCM val)
ee2a8b9b
JB
364{
365 return scm_vector_set_x (vec, pos, val);
366}
367
368/* retrieve the given element of the given vector */
369SCM
e5eece74 370gh_vector_ref (SCM vec, SCM pos)
ee2a8b9b
JB
371{
372 return scm_vector_ref (vec, pos);
373}
374
375/* returns the length of the given vector */
376unsigned long
377gh_vector_length (SCM v)
378{
379 return gh_scm2ulong (scm_vector_length (v));
380}
35379308 381
ef5d3ae1
MG
382
383/* uniform vector support */
384
385/* returns the length as a C unsigned long integer */
386unsigned long
387gh_uniform_vector_length (SCM v)
388{
389 return gh_scm2ulong (scm_uniform_vector_length (v));
390}
391
392/* gets the given element from a uniform vector; ilist is a list (or
393 possibly a single integer) of indices, and its length is the
394 dimension of the uniform vector */
395SCM
396gh_uniform_vector_ref (SCM v, SCM ilist)
397{
398 return scm_uniform_vector_ref (v, ilist);
399}
400
401/* sets an individual element in a uniform vector */
402/* SCM */
403/* gh_list_to_uniform_array ( */
404
405
35379308
JB
406/* Data lookups between C and Scheme
407
408 Look up a symbol with a given name, and return the object to which
409 it is bound. gh_lookup examines the Guile top level, and
410 gh_module_lookup checks the module namespace specified by the
411 `vec' argument.
412
413 The return value is the Scheme object to which SNAME is bound, or
414 SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME:
415 should this be SCM_UNSPECIFIED? Can a symbol ever legitimately be
416 bound to SCM_UNDEFINED or SCM_UNSPECIFIED? What is the difference?
417 -twp] */
418
419SCM
420gh_lookup (char *sname)
421{
422 return gh_module_lookup (SCM_BOOL_F, sname);
423}
424
425SCM
426gh_module_lookup (SCM vec, char *sname)
427{
428 SCM sym = gh_symbol2scm (sname);
429 if ((scm_symbol_bound_p (vec, sym)) == SCM_BOOL_T)
430 return scm_symbol_binding (vec, sym);
431 else
432 return SCM_UNDEFINED;
433}