Merge from mvo-vcell-cleanup-1-branch.
[bpt/guile.git] / libguile / gh_data.c
CommitLineData
80dee77b 1/* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc.
ee2a8b9b
JB
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2, or (at your option)
5 * any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this software; see the file COPYING. If not, write to
82892bed
JB
14 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15 * Boston, MA 02111-1307 USA
ee2a8b9b
JB
16 *
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
19 *
20 * The exception is that, if you link the GUILE library with other files
21 * to produce an executable, this does not by itself cause the
22 * resulting executable to be covered by the GNU General Public License.
23 * Your use of that executable is in no way restricted on account of
24 * linking the GUILE library code into it.
25 *
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
28 *
29 * This exception applies only to the code released by the
30 * Free Software Foundation under the name GUILE. If you copy
31 * code from other Free Software Foundation releases into a copy of
32 * GUILE, as the General Public License permits, the exception does
33 * not apply to the code that you add in this way. To avoid misleading
34 * anyone as to the status of such modified files, you must delete
35 * this exception notice from them.
36 *
37 * If you write modifications of your own for GUILE, it is your choice
38 * whether to permit this exception to apply to your modifications.
82892bed 39 * If you do not wish that, delete this exception notice. */
ee2a8b9b
JB
40\f
41
42/* data initialization and C<->Scheme data conversion */
43
a0599745 44#include "libguile/gh.h"
bd9e24b3
GH
45#ifdef HAVE_STRING_H
46#include <string.h>
47#endif
ee2a8b9b
JB
48
49/* data conversion C->scheme */
bcee10dd 50
dbb3005d
MG
51SCM
52gh_bool2scm (int x)
ee2a8b9b 53{
156dcb09 54 return SCM_BOOL(x);
ee2a8b9b
JB
55}
56SCM
57gh_int2scm (int x)
58{
59 return scm_long2num ((long) x);
60}
61SCM
62gh_ulong2scm (unsigned long x)
63{
64 return scm_ulong2num (x);
65}
66SCM
67gh_long2scm (long x)
68{
69 return scm_long2num (x);
70}
71SCM
72gh_double2scm (double x)
73{
f8de44c1 74 return scm_make_real (x);
ee2a8b9b
JB
75}
76SCM
77gh_char2scm (char c)
78{
7866a09b 79 return SCM_MAKE_CHAR (c);
ee2a8b9b
JB
80}
81SCM
70d63753 82gh_str2scm (const char *s, int len)
ee2a8b9b
JB
83{
84 return scm_makfromstr (s, len, 0);
85}
86SCM
6e706938 87gh_str02scm (const char *s)
ee2a8b9b
JB
88{
89 return scm_makfrom0str (s);
90}
91/* Copy LEN characters at SRC into the *existing* Scheme string DST,
92 starting at START. START is an index into DST; zero means the
93 beginning of the string.
94
95 If START + LEN is off the end of DST, signal an out-of-range
96 error. */
97void
98gh_set_substr (char *src, SCM dst, int start, int len)
99{
2c92112b 100 char *dst_ptr;
fd88bd7c
JB
101 unsigned long dst_len;
102 unsigned long effective_length;
ee2a8b9b 103
b24b5e13 104 SCM_ASSERT (SCM_STRINGP (dst), dst, SCM_ARG3, "gh_set_substr");
fd88bd7c 105
86c991c2 106 dst_ptr = SCM_STRING_CHARS (dst);
9fd38a3d 107 dst_len = SCM_STRING_LENGTH (dst);
fd88bd7c
JB
108 SCM_ASSERT (len >= 0 && (unsigned) len <= dst_len,
109 dst, SCM_ARG4, "gh_set_substr");
110
fd88bd7c
JB
111 effective_length = ((unsigned) len < dst_len) ? len : dst_len;
112 memmove (dst_ptr + start, src, effective_length);
5d2b97cd 113 scm_remember_upto_here_1 (dst);
ee2a8b9b
JB
114}
115
116/* Return the symbol named SYMBOL_STR. */
117SCM
4921140c 118gh_symbol2scm (const char *symbol_str)
ee2a8b9b 119{
38ae064c 120 return scm_str2symbol(symbol_str);
ee2a8b9b
JB
121}
122
b774ee1f 123SCM
80dee77b 124gh_ints2scm (const int *d, int n)
b774ee1f 125{
b774ee1f 126 int i;
00ffa0e7 127 SCM v = scm_c_make_vector (n, SCM_UNSPECIFIED);
0acef67a
JB
128 SCM *velts = SCM_VELTS(v);
129
b774ee1f 130 for (i = 0; i < n; ++i)
8f379a8f
DH
131 velts[i] = (SCM_FIXABLE (d[i]) ? SCM_MAKINUM (d[i]) : scm_long2big (d[i]));
132
0acef67a 133 return v;
3ffc7a36
MD
134}
135
136SCM
bcee10dd 137gh_doubles2scm (const double *d, int n)
3ffc7a36 138{
3ffc7a36 139 int i;
00ffa0e7 140 SCM v = scm_c_make_vector (n, SCM_UNSPECIFIED);
0acef67a
JB
141 SCM *velts = SCM_VELTS(v);
142
143 for(i = 0; i < n; i++)
f8de44c1 144 velts[i] = scm_make_real (d[i]);
0acef67a
JB
145 return v;
146}
147
afe5177e 148#ifdef HAVE_ARRAYS
0acef67a
JB
149/* Do not use this function for building normal Scheme vectors, unless
150 you arrange for the elements to be protected from GC while you
151 initialize the vector. */
152static SCM
153makvect (char* m, int len, int type)
154{
155 SCM ans;
156 SCM_NEWCELL (ans);
157 SCM_DEFER_INTS;
6a0476fd 158 SCM_SET_UVECTOR_BASE (ans, m);
93778877 159 SCM_SET_UVECTOR_LENGTH (ans, len, type);
0acef67a
JB
160 SCM_ALLOW_INTS;
161 return ans;
b774ee1f
MD
162}
163
3ffc7a36 164SCM
bcee10dd 165gh_chars2byvect (const char *d, int n)
3ffc7a36
MD
166{
167 char *m = scm_must_malloc (n * sizeof (char), "vector");
168 memcpy (m, d, n * sizeof (char));
169 return makvect (m, n, scm_tc7_byvect);
170}
171
172SCM
bcee10dd 173gh_shorts2svect (const short *d, int n)
3ffc7a36
MD
174{
175 char *m = scm_must_malloc (n * sizeof (short), "vector");
176 memcpy (m, d, n * sizeof (short));
177 return makvect (m, n, scm_tc7_svect);
178}
179
b774ee1f 180SCM
bcee10dd 181gh_longs2ivect (const long *d, int n)
b774ee1f
MD
182{
183 char *m = scm_must_malloc (n * sizeof (long), "vector");
184 memcpy (m, d, n * sizeof (long));
185 return makvect (m, n, scm_tc7_ivect);
186}
187
188SCM
bcee10dd 189gh_ulongs2uvect (const unsigned long *d, int n)
b774ee1f
MD
190{
191 char *m = scm_must_malloc (n * sizeof (unsigned long), "vector");
192 memcpy (m, d, n * sizeof (unsigned long));
193 return makvect (m, n, scm_tc7_uvect);
194}
195
196SCM
bcee10dd 197gh_floats2fvect (const float *d, int n)
b774ee1f 198{
3ffc7a36
MD
199 char *m = scm_must_malloc (n * sizeof (float), "vector");
200 memcpy (m, d, n * sizeof (float));
201 return makvect (m, n, scm_tc7_fvect);
b774ee1f
MD
202}
203
f3a2c4cf 204SCM
bcee10dd 205gh_doubles2dvect (const double *d, int n)
f3a2c4cf 206{
f3a2c4cf
MD
207 char *m = scm_must_malloc (n * sizeof (double), "vector");
208 memcpy (m, d, n * sizeof (double));
b774ee1f 209 return makvect (m, n, scm_tc7_dvect);
f3a2c4cf
MD
210}
211#endif
ee2a8b9b
JB
212
213/* data conversion scheme->C */
214int
215gh_scm2bool (SCM obj)
216{
fbd485ba 217 return (SCM_FALSEP (obj)) ? 0 : 1;
ee2a8b9b
JB
218}
219unsigned long
220gh_scm2ulong (SCM obj)
221{
e4b265d8 222 return scm_num2ulong (obj, SCM_ARG1, "gh_scm2ulong");
ee2a8b9b
JB
223}
224long
225gh_scm2long (SCM obj)
226{
e4b265d8 227 return scm_num2long (obj, SCM_ARG1, "gh_scm2long");
ee2a8b9b
JB
228}
229int
230gh_scm2int (SCM obj)
231{
232 /* NOTE: possible loss of precision here */
e4b265d8 233 return (int) scm_num2long (obj, SCM_ARG1, "gh_scm2int");
ee2a8b9b
JB
234}
235double
236gh_scm2double (SCM obj)
237{
238 return scm_num2dbl (obj, "gh_scm2double");
239}
240char
241gh_scm2char (SCM obj)
0e1d5b0a 242#define FUNC_NAME "gh_scm2char"
ee2a8b9b 243{
0e1d5b0a 244 SCM_VALIDATE_CHAR (SCM_ARG1, obj);
7866a09b 245 return SCM_CHAR (obj);
ee2a8b9b 246}
fd336365 247#undef FUNC_NAME
ee2a8b9b 248
3ffc7a36
MD
249/* Convert a vector, weak vector, string, substring or uniform vector
250 into an array of chars. If result array in arg 2 is NULL, malloc a
d3dd80ab 251 new one. If out of memory, return NULL. */
3ffc7a36
MD
252char *
253gh_scm2chars (SCM obj, char *m)
f3a2c4cf
MD
254{
255 int i, n;
3ffc7a36 256 long v;
f3a2c4cf 257 SCM val;
1a548472 258 if (SCM_IMP (obj))
f3a2c4cf
MD
259 scm_wrong_type_arg (0, 0, obj);
260 switch (SCM_TYP7 (obj))
261 {
262 case scm_tc7_vector:
263 case scm_tc7_wvect:
9fd38a3d 264 n = SCM_VECTOR_LENGTH (obj);
f3a2c4cf
MD
265 for (i = 0; i < n; ++i)
266 {
267 val = SCM_VELTS (obj)[i];
268 if (SCM_INUMP (val))
3ffc7a36
MD
269 {
270 v = SCM_INUM (val);
271 if (v < -128 || v > 255)
272 scm_out_of_range (0, obj);
273 }
f3a2c4cf 274 else
3ffc7a36
MD
275 scm_wrong_type_arg (0, 0, obj);
276 }
277 if (m == 0)
278 m = (char *) malloc (n * sizeof (char));
d3dd80ab
MG
279 if (m == NULL)
280 return NULL;
3ffc7a36
MD
281 for (i = 0; i < n; ++i)
282 m[i] = SCM_INUM (SCM_VELTS (obj)[i]);
283 break;
afe5177e 284#ifdef HAVE_ARRAYS
3ffc7a36 285 case scm_tc7_byvect:
b5c2579a
DH
286 n = SCM_UVECTOR_LENGTH (obj);
287 if (m == 0)
288 m = (char *) malloc (n * sizeof (char));
d3dd80ab
MG
289 if (m == NULL)
290 return NULL;
b5c2579a
DH
291 memcpy (m, SCM_VELTS (obj), n * sizeof (char));
292 break;
afe5177e 293#endif
3ffc7a36
MD
294 case scm_tc7_string:
295 case scm_tc7_substring:
b5c2579a 296 n = SCM_STRING_LENGTH (obj);
3ffc7a36
MD
297 if (m == 0)
298 m = (char *) malloc (n * sizeof (char));
d3dd80ab
MG
299 if (m == NULL)
300 return NULL;
3ffc7a36
MD
301 memcpy (m, SCM_VELTS (obj), n * sizeof (char));
302 break;
303 default:
304 scm_wrong_type_arg (0, 0, obj);
305 }
306 return m;
307}
308
309/* Convert a vector, weak vector or uniform vector into an array of
d3dd80ab
MG
310 shorts. If result array in arg 2 is NULL, malloc a new one. If
311 out of memory, return NULL. */
3ffc7a36
MD
312short *
313gh_scm2shorts (SCM obj, short *m)
314{
315 int i, n;
316 long v;
317 SCM val;
1a548472 318 if (SCM_IMP (obj))
3ffc7a36
MD
319 scm_wrong_type_arg (0, 0, obj);
320 switch (SCM_TYP7 (obj))
321 {
322 case scm_tc7_vector:
323 case scm_tc7_wvect:
9fd38a3d 324 n = SCM_VECTOR_LENGTH (obj);
3ffc7a36
MD
325 for (i = 0; i < n; ++i)
326 {
327 val = SCM_VELTS (obj)[i];
328 if (SCM_INUMP (val))
f3a2c4cf 329 {
3ffc7a36
MD
330 v = SCM_INUM (val);
331 if (v < -32768 || v > 65535)
332 scm_out_of_range (0, obj);
f3a2c4cf 333 }
3ffc7a36
MD
334 else
335 scm_wrong_type_arg (0, 0, obj);
336 }
337 if (m == 0)
338 m = (short *) malloc (n * sizeof (short));
d3dd80ab
MG
339 if (m == NULL)
340 return NULL;
3ffc7a36
MD
341 for (i = 0; i < n; ++i)
342 m[i] = SCM_INUM (SCM_VELTS (obj)[i]);
343 break;
afe5177e 344#ifdef HAVE_ARRAYS
3ffc7a36 345 case scm_tc7_svect:
9fd38a3d 346 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
347 if (m == 0)
348 m = (short *) malloc (n * sizeof (short));
d3dd80ab
MG
349 if (m == NULL)
350 return NULL;
3ffc7a36
MD
351 memcpy (m, SCM_VELTS (obj), n * sizeof (short));
352 break;
afe5177e 353#endif
3ffc7a36
MD
354 default:
355 scm_wrong_type_arg (0, 0, obj);
356 }
357 return m;
358}
359
360/* Convert a vector, weak vector or uniform vector into an array of
d3dd80ab
MG
361 longs. If result array in arg 2 is NULL, malloc a new one. If out
362 of memory, return NULL. */
3ffc7a36
MD
363long *
364gh_scm2longs (SCM obj, long *m)
365{
366 int i, n;
367 SCM val;
1a548472 368 if (SCM_IMP (obj))
3ffc7a36
MD
369 scm_wrong_type_arg (0, 0, obj);
370 switch (SCM_TYP7 (obj))
371 {
372 case scm_tc7_vector:
373 case scm_tc7_wvect:
9fd38a3d 374 n = SCM_VECTOR_LENGTH (obj);
3ffc7a36
MD
375 for (i = 0; i < n; ++i)
376 {
377 val = SCM_VELTS (obj)[i];
0c95b57d 378 if (!SCM_INUMP (val) && !SCM_BIGP (val))
3ffc7a36
MD
379 scm_wrong_type_arg (0, 0, obj);
380 }
381 if (m == 0)
382 m = (long *) malloc (n * sizeof (long));
d3dd80ab
MG
383 if (m == NULL)
384 return NULL;
3ffc7a36
MD
385 for (i = 0; i < n; ++i)
386 {
387 val = SCM_VELTS (obj)[i];
e4b265d8
DH
388 m[i] = SCM_INUMP (val)
389 ? SCM_INUM (val)
390 : scm_num2long (val, 0, NULL);
3ffc7a36
MD
391 }
392 break;
afe5177e 393#ifdef HAVE_ARRAYS
3ffc7a36
MD
394 case scm_tc7_ivect:
395 case scm_tc7_uvect:
9fd38a3d 396 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
397 if (m == 0)
398 m = (long *) malloc (n * sizeof (long));
d3dd80ab
MG
399 if (m == NULL)
400 return NULL;
3ffc7a36
MD
401 memcpy (m, SCM_VELTS (obj), n * sizeof (long));
402 break;
afe5177e 403#endif
3ffc7a36
MD
404 default:
405 scm_wrong_type_arg (0, 0, obj);
406 }
407 return m;
408}
409
410/* Convert a vector, weak vector or uniform vector into an array of
d3dd80ab
MG
411 floats. If result array in arg 2 is NULL, malloc a new one. If
412 out of memory, return NULL. */
3ffc7a36
MD
413float *
414gh_scm2floats (SCM obj, float *m)
415{
416 int i, n;
417 SCM val;
1a548472 418 if (SCM_IMP (obj))
3ffc7a36
MD
419 scm_wrong_type_arg (0, 0, obj);
420 switch (SCM_TYP7 (obj))
421 {
422 case scm_tc7_vector:
423 case scm_tc7_wvect:
9fd38a3d 424 n = SCM_VECTOR_LENGTH (obj);
3ffc7a36
MD
425 for (i = 0; i < n; ++i)
426 {
427 val = SCM_VELTS (obj)[i];
428 if (!SCM_INUMP (val)
0c95b57d 429 && !(SCM_BIGP (val) || SCM_REALP (val)))
3ffc7a36
MD
430 scm_wrong_type_arg (0, 0, val);
431 }
432 if (m == 0)
433 m = (float *) malloc (n * sizeof (float));
d3dd80ab
MG
434 if (m == NULL)
435 return NULL;
3ffc7a36
MD
436 for (i = 0; i < n; ++i)
437 {
438 val = SCM_VELTS (obj)[i];
439 if (SCM_INUMP (val))
440 m[i] = SCM_INUM (val);
441 else if (SCM_BIGP (val))
e4b265d8 442 m[i] = scm_num2long (val, 0, NULL);
3ffc7a36 443 else
eb42e2f0 444 m[i] = SCM_REAL_VALUE (val);
f3a2c4cf
MD
445 }
446 break;
afe5177e 447#ifdef HAVE_ARRAYS
f3a2c4cf 448 case scm_tc7_fvect:
9fd38a3d 449 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
450 if (m == 0)
451 m = (float *) malloc (n * sizeof (float));
d3dd80ab
MG
452 if (m == NULL)
453 return NULL;
3ffc7a36 454 memcpy (m, (float *) SCM_VELTS (obj), n * sizeof (float));
f3a2c4cf 455 break;
16d35552 456
f3a2c4cf 457 case scm_tc7_dvect:
9fd38a3d 458 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
459 if (m == 0)
460 m = (float*) malloc (n * sizeof (float));
d3dd80ab
MG
461 if (m == NULL)
462 return NULL;
f3a2c4cf 463 for (i = 0; i < n; ++i)
3ffc7a36
MD
464 m[i] = ((double *) SCM_VELTS (obj))[i];
465 break;
466#endif
467 default:
468 scm_wrong_type_arg (0, 0, obj);
469 }
470 return m;
471}
472
473/* Convert a vector, weak vector or uniform vector into an array of
d3dd80ab
MG
474 doubles. If result array in arg 2 is NULL, malloc a new one. If
475 out of memory, return NULL. */
3ffc7a36
MD
476double *
477gh_scm2doubles (SCM obj, double *m)
478{
479 int i, n;
480 SCM val;
1a548472 481 if (SCM_IMP (obj))
3ffc7a36
MD
482 scm_wrong_type_arg (0, 0, obj);
483 switch (SCM_TYP7 (obj))
484 {
485 case scm_tc7_vector:
486 case scm_tc7_wvect:
9fd38a3d 487 n = SCM_VECTOR_LENGTH (obj);
3ffc7a36
MD
488 for (i = 0; i < n; ++i)
489 {
490 val = SCM_VELTS (obj)[i];
491 if (!SCM_INUMP (val)
0c95b57d 492 && !(SCM_BIGP (val) || SCM_REALP (val)))
3ffc7a36
MD
493 scm_wrong_type_arg (0, 0, val);
494 }
495 if (m == 0)
496 m = (double *) malloc (n * sizeof (double));
d3dd80ab
MG
497 if (m == NULL)
498 return NULL;
3ffc7a36
MD
499 for (i = 0; i < n; ++i)
500 {
501 val = SCM_VELTS (obj)[i];
502 if (SCM_INUMP (val))
503 m[i] = SCM_INUM (val);
504 else if (SCM_BIGP (val))
e4b265d8 505 m[i] = scm_num2long (val, 0, NULL);
3ffc7a36 506 else
eb42e2f0 507 m[i] = SCM_REAL_VALUE (val);
3ffc7a36
MD
508 }
509 break;
afe5177e 510#ifdef HAVE_ARRAYS
3ffc7a36 511 case scm_tc7_fvect:
9fd38a3d 512 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
513 if (m == 0)
514 m = (double *) malloc (n * sizeof (double));
d3dd80ab
MG
515 if (m == NULL)
516 return NULL;
3ffc7a36
MD
517 for (i = 0; i < n; ++i)
518 m[i] = ((float *) SCM_VELTS (obj))[i];
519 break;
16d35552 520
3ffc7a36 521 case scm_tc7_dvect:
9fd38a3d 522 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
523 if (m == 0)
524 m = (double*) malloc (n * sizeof (double));
d3dd80ab
MG
525 if (m == NULL)
526 return NULL;
3ffc7a36 527 memcpy (m, SCM_VELTS (obj), n * sizeof (double));
f3a2c4cf
MD
528 break;
529#endif
530 default:
531 scm_wrong_type_arg (0, 0, obj);
532 }
533 return m;
534}
535
ee2a8b9b
JB
536/* string conversions between C and Scheme */
537
538/* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
539 new copy of its contents, followed by a null byte. If lenp is
540 non-null, set *lenp to the string's length.
541
542 This function uses malloc to obtain storage for the copy; the
d3dd80ab
MG
543 caller is responsible for freeing it. If out of memory, NULL is
544 returned.
ee2a8b9b
JB
545
546 Note that Scheme strings may contain arbitrary data, including null
547 characters. This means that null termination is not a reliable way
548 to determine the length of the returned value. However, the
549 function always copies the complete contents of STR, and sets
550 *LEN_P to the true length of the string (when LEN_P is non-null). */
551char *
552gh_scm2newstr (SCM str, int *lenp)
553{
554 char *ret_str;
555 int len;
556
9fd38a3d 557 SCM_ASSERT (SCM_STRINGP (str), str, SCM_ARG3, "gh_scm2newstr");
ee2a8b9b 558
9fd38a3d 559 len = SCM_STRING_LENGTH (str);
ee2a8b9b 560
d3dd80ab
MG
561 ret_str = (char *) malloc ((len + 1) * sizeof (char));
562 if (ret_str == NULL)
563 return NULL;
ee2a8b9b 564 /* so we copy tmp_str to ret_str, which is what we will allocate */
34f0f2b8 565 memcpy (ret_str, SCM_STRING_CHARS (str), len);
5d2b97cd 566 scm_remember_upto_here_1 (str);
ee2a8b9b
JB
567 /* now make sure we null-terminate it */
568 ret_str[len] = '\0';
569
ee2a8b9b
JB
570 if (lenp != NULL)
571 {
572 *lenp = len;
573 }
574
575 return ret_str;
576}
577
578
579/* Copy LEN characters at START from the Scheme string SRC to memory
580 at DST. START is an index into SRC; zero means the beginning of
581 the string. DST has already been allocated by the caller.
582
583 If START + LEN is off the end of SRC, silently truncate the source
584 region to fit the string. If truncation occurs, the corresponding
585 area of DST is left unchanged. */
586void
587gh_get_substr (SCM src, char *dst, int start, int len)
588{
589 int src_len, effective_length;
9fd38a3d 590 SCM_ASSERT (SCM_STRINGP (src), src, SCM_ARG3, "gh_get_substr");
ee2a8b9b 591
9fd38a3d 592 src_len = SCM_STRING_LENGTH (src);
ee2a8b9b 593 effective_length = (len < src_len) ? len : src_len;
34f0f2b8 594 memcpy (dst + start, SCM_STRING_CHARS (src), effective_length * sizeof (char));
ee2a8b9b 595 /* FIXME: must signal an error if len > src_len */
5d2b97cd 596 scm_remember_upto_here_1 (src);
ee2a8b9b
JB
597}
598
599
600/* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
601 pointer to a string with the symbol characters "identifier",
602 followed by a null byte. If lenp is non-null, set *lenp to the
603 string's length.
604
605 This function uses malloc to obtain storage for the copy; the
d3dd80ab
MG
606 caller is responsible for freeing it. If out of memory, NULL is
607 returned.*/
ee2a8b9b
JB
608char *
609gh_symbol2newstr (SCM sym, int *lenp)
610{
611 char *ret_str;
612 int len;
613
b24b5e13 614 SCM_ASSERT (SCM_SYMBOLP (sym), sym, SCM_ARG3, "gh_scm2newsymbol");
ee2a8b9b 615
9fd38a3d 616 len = SCM_SYMBOL_LENGTH (sym);
ee2a8b9b 617
d3dd80ab
MG
618 ret_str = (char *) malloc ((len + 1) * sizeof (char));
619 if (ret_str == NULL)
620 return NULL;
b24b5e13 621 /* so we copy sym to ret_str, which is what we will allocate */
86c991c2 622 memcpy (ret_str, SCM_SYMBOL_CHARS (sym), len);
5d2b97cd 623 scm_remember_upto_here_1 (sym);
ee2a8b9b
JB
624 /* now make sure we null-terminate it */
625 ret_str[len] = '\0';
626
ee2a8b9b
JB
627 if (lenp != NULL)
628 {
629 *lenp = len;
630 }
631
632 return ret_str;
633}
634
635
636/* create a new vector of the given length, all initialized to the
637 given value */
e5eece74
MG
638SCM
639gh_make_vector (SCM len, SCM fill)
ee2a8b9b 640{
a8741caa 641 return scm_make_vector (len, fill);
ee2a8b9b
JB
642}
643
644/* set the given element of the given vector to the given value */
645SCM
956328d2 646gh_vector_set_x (SCM vec, SCM pos, SCM val)
ee2a8b9b
JB
647{
648 return scm_vector_set_x (vec, pos, val);
649}
650
651/* retrieve the given element of the given vector */
652SCM
e5eece74 653gh_vector_ref (SCM vec, SCM pos)
ee2a8b9b
JB
654{
655 return scm_vector_ref (vec, pos);
656}
657
658/* returns the length of the given vector */
659unsigned long
660gh_vector_length (SCM v)
661{
662 return gh_scm2ulong (scm_vector_length (v));
663}
35379308 664
afe5177e 665#ifdef HAVE_ARRAYS
ef5d3ae1
MG
666/* uniform vector support */
667
668/* returns the length as a C unsigned long integer */
669unsigned long
670gh_uniform_vector_length (SCM v)
671{
672 return gh_scm2ulong (scm_uniform_vector_length (v));
673}
674
675/* gets the given element from a uniform vector; ilist is a list (or
676 possibly a single integer) of indices, and its length is the
677 dimension of the uniform vector */
678SCM
679gh_uniform_vector_ref (SCM v, SCM ilist)
680{
681 return scm_uniform_vector_ref (v, ilist);
682}
683
684/* sets an individual element in a uniform vector */
685/* SCM */
686/* gh_list_to_uniform_array ( */
afe5177e 687#endif
ef5d3ae1 688
35379308
JB
689/* Data lookups between C and Scheme
690
691 Look up a symbol with a given name, and return the object to which
692 it is bound. gh_lookup examines the Guile top level, and
693 gh_module_lookup checks the module namespace specified by the
694 `vec' argument.
695
696 The return value is the Scheme object to which SNAME is bound, or
07de6c47
MV
697 SCM_UNDEFINED if SNAME is not bound in the given context.
698 */
35379308
JB
699
700SCM
bcee10dd 701gh_lookup (const char *sname)
35379308 702{
abc235ad 703 return gh_module_lookup (scm_current_module (), sname);
35379308
JB
704}
705
abc235ad 706
35379308 707SCM
abc235ad
MV
708gh_module_lookup (SCM module, const char *sname)
709#define FUNC_NAME "gh_module_lookup"
35379308 710{
86d31dfe 711 SCM sym, var;
abc235ad
MV
712
713 SCM_VALIDATE_MODULE (SCM_ARG1, module);
714
715 sym = gh_symbol2scm (sname);
86d31dfe
MV
716 var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
717 if (var != SCM_BOOL_F)
718 return SCM_VARIABLE_REF (var);
35379308
JB
719 else
720 return SCM_UNDEFINED;
721}
abc235ad 722#undef FUNC_NAME
89e00824
ML
723
724/*
725 Local Variables:
726 c-file-style: "gnu"
727 End:
728*/