revert the ill-considered part of the 2001-05-24 changes
[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
1be6b49c 82gh_str2scm (const char *s, size_t 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
c014a02e 98gh_set_substr (char *src, SCM dst, long start, size_t len)
ee2a8b9b 99{
2c92112b 100 char *dst_ptr;
1be6b49c
ML
101 size_t dst_len;
102 size_t 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);
1be6b49c 108 SCM_ASSERT (len >= 0 && len <= dst_len,
fd88bd7c
JB
109 dst, SCM_ARG4, "gh_set_substr");
110
1be6b49c 111 effective_length = (len < dst_len) ? len : dst_len;
fd88bd7c 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
c014a02e 124gh_ints2scm (const int *d, long n)
b774ee1f 125{
c014a02e 126 long 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)
1be6b49c 131 velts[i] = (SCM_FIXABLE (d[i]) ? SCM_MAKINUM (d[i]) : scm_i_long2big (d[i]));
8f379a8f 132
0acef67a 133 return v;
3ffc7a36
MD
134}
135
136SCM
c014a02e 137gh_doubles2scm (const double *d, long n)
3ffc7a36 138{
c014a02e 139 long 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
1be6b49c 153makvect (char *m, size_t len, int type)
0acef67a
JB
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
c014a02e 165gh_chars2byvect (const char *d, long 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
c014a02e 173gh_shorts2svect (const short *d, long 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
c014a02e 181gh_longs2ivect (const long *d, long 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
c014a02e 189gh_ulongs2uvect (const unsigned long *d, long 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
c014a02e 197gh_floats2fvect (const float *d, long 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
c014a02e 205gh_doubles2dvect (const double *d, long 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{
1be6b49c 232 return (int) scm_num2int (obj, SCM_ARG1, "gh_scm2int");
ee2a8b9b
JB
233}
234double
235gh_scm2double (SCM obj)
236{
237 return scm_num2dbl (obj, "gh_scm2double");
238}
239char
240gh_scm2char (SCM obj)
0e1d5b0a 241#define FUNC_NAME "gh_scm2char"
ee2a8b9b 242{
0e1d5b0a 243 SCM_VALIDATE_CHAR (SCM_ARG1, obj);
7866a09b 244 return SCM_CHAR (obj);
ee2a8b9b 245}
fd336365 246#undef FUNC_NAME
ee2a8b9b 247
3ffc7a36
MD
248/* Convert a vector, weak vector, string, substring or uniform vector
249 into an array of chars. If result array in arg 2 is NULL, malloc a
d3dd80ab 250 new one. If out of memory, return NULL. */
3ffc7a36
MD
251char *
252gh_scm2chars (SCM obj, char *m)
f3a2c4cf 253{
c014a02e
ML
254 long i, n;
255 long v;
f3a2c4cf 256 SCM val;
1a548472 257 if (SCM_IMP (obj))
f3a2c4cf
MD
258 scm_wrong_type_arg (0, 0, obj);
259 switch (SCM_TYP7 (obj))
260 {
261 case scm_tc7_vector:
262 case scm_tc7_wvect:
9fd38a3d 263 n = SCM_VECTOR_LENGTH (obj);
f3a2c4cf
MD
264 for (i = 0; i < n; ++i)
265 {
266 val = SCM_VELTS (obj)[i];
267 if (SCM_INUMP (val))
3ffc7a36
MD
268 {
269 v = SCM_INUM (val);
270 if (v < -128 || v > 255)
271 scm_out_of_range (0, obj);
272 }
f3a2c4cf 273 else
3ffc7a36
MD
274 scm_wrong_type_arg (0, 0, obj);
275 }
276 if (m == 0)
277 m = (char *) malloc (n * sizeof (char));
d3dd80ab
MG
278 if (m == NULL)
279 return NULL;
3ffc7a36
MD
280 for (i = 0; i < n; ++i)
281 m[i] = SCM_INUM (SCM_VELTS (obj)[i]);
282 break;
afe5177e 283#ifdef HAVE_ARRAYS
3ffc7a36 284 case scm_tc7_byvect:
b5c2579a
DH
285 n = SCM_UVECTOR_LENGTH (obj);
286 if (m == 0)
287 m = (char *) malloc (n * sizeof (char));
d3dd80ab
MG
288 if (m == NULL)
289 return NULL;
b5c2579a
DH
290 memcpy (m, SCM_VELTS (obj), n * sizeof (char));
291 break;
afe5177e 292#endif
3ffc7a36
MD
293 case scm_tc7_string:
294 case scm_tc7_substring:
b5c2579a 295 n = SCM_STRING_LENGTH (obj);
3ffc7a36
MD
296 if (m == 0)
297 m = (char *) malloc (n * sizeof (char));
d3dd80ab
MG
298 if (m == NULL)
299 return NULL;
3ffc7a36
MD
300 memcpy (m, SCM_VELTS (obj), n * sizeof (char));
301 break;
302 default:
303 scm_wrong_type_arg (0, 0, obj);
304 }
305 return m;
306}
307
308/* Convert a vector, weak vector or uniform vector into an array of
d3dd80ab
MG
309 shorts. If result array in arg 2 is NULL, malloc a new one. If
310 out of memory, return NULL. */
3ffc7a36
MD
311short *
312gh_scm2shorts (SCM obj, short *m)
313{
c014a02e
ML
314 long i, n;
315 long v;
3ffc7a36 316 SCM val;
1a548472 317 if (SCM_IMP (obj))
3ffc7a36
MD
318 scm_wrong_type_arg (0, 0, obj);
319 switch (SCM_TYP7 (obj))
320 {
321 case scm_tc7_vector:
322 case scm_tc7_wvect:
9fd38a3d 323 n = SCM_VECTOR_LENGTH (obj);
3ffc7a36
MD
324 for (i = 0; i < n; ++i)
325 {
326 val = SCM_VELTS (obj)[i];
327 if (SCM_INUMP (val))
f3a2c4cf 328 {
3ffc7a36
MD
329 v = SCM_INUM (val);
330 if (v < -32768 || v > 65535)
331 scm_out_of_range (0, obj);
f3a2c4cf 332 }
3ffc7a36
MD
333 else
334 scm_wrong_type_arg (0, 0, obj);
335 }
336 if (m == 0)
337 m = (short *) malloc (n * sizeof (short));
d3dd80ab
MG
338 if (m == NULL)
339 return NULL;
3ffc7a36
MD
340 for (i = 0; i < n; ++i)
341 m[i] = SCM_INUM (SCM_VELTS (obj)[i]);
342 break;
afe5177e 343#ifdef HAVE_ARRAYS
3ffc7a36 344 case scm_tc7_svect:
9fd38a3d 345 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
346 if (m == 0)
347 m = (short *) malloc (n * sizeof (short));
d3dd80ab
MG
348 if (m == NULL)
349 return NULL;
3ffc7a36
MD
350 memcpy (m, SCM_VELTS (obj), n * sizeof (short));
351 break;
afe5177e 352#endif
3ffc7a36
MD
353 default:
354 scm_wrong_type_arg (0, 0, obj);
355 }
356 return m;
357}
358
359/* Convert a vector, weak vector or uniform vector into an array of
d3dd80ab
MG
360 longs. If result array in arg 2 is NULL, malloc a new one. If out
361 of memory, return NULL. */
3ffc7a36
MD
362long *
363gh_scm2longs (SCM obj, long *m)
364{
c014a02e 365 long i, n;
3ffc7a36 366 SCM val;
1a548472 367 if (SCM_IMP (obj))
3ffc7a36
MD
368 scm_wrong_type_arg (0, 0, obj);
369 switch (SCM_TYP7 (obj))
370 {
371 case scm_tc7_vector:
372 case scm_tc7_wvect:
9fd38a3d 373 n = SCM_VECTOR_LENGTH (obj);
3ffc7a36
MD
374 for (i = 0; i < n; ++i)
375 {
376 val = SCM_VELTS (obj)[i];
0c95b57d 377 if (!SCM_INUMP (val) && !SCM_BIGP (val))
3ffc7a36
MD
378 scm_wrong_type_arg (0, 0, obj);
379 }
380 if (m == 0)
381 m = (long *) malloc (n * sizeof (long));
d3dd80ab
MG
382 if (m == NULL)
383 return NULL;
3ffc7a36
MD
384 for (i = 0; i < n; ++i)
385 {
386 val = SCM_VELTS (obj)[i];
e4b265d8
DH
387 m[i] = SCM_INUMP (val)
388 ? SCM_INUM (val)
389 : scm_num2long (val, 0, NULL);
3ffc7a36
MD
390 }
391 break;
afe5177e 392#ifdef HAVE_ARRAYS
3ffc7a36
MD
393 case scm_tc7_ivect:
394 case scm_tc7_uvect:
9fd38a3d 395 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
396 if (m == 0)
397 m = (long *) malloc (n * sizeof (long));
d3dd80ab
MG
398 if (m == NULL)
399 return NULL;
3ffc7a36
MD
400 memcpy (m, SCM_VELTS (obj), n * sizeof (long));
401 break;
afe5177e 402#endif
3ffc7a36
MD
403 default:
404 scm_wrong_type_arg (0, 0, obj);
405 }
406 return m;
407}
408
409/* Convert a vector, weak vector or uniform vector into an array of
d3dd80ab
MG
410 floats. If result array in arg 2 is NULL, malloc a new one. If
411 out of memory, return NULL. */
3ffc7a36
MD
412float *
413gh_scm2floats (SCM obj, float *m)
414{
c014a02e 415 long i, n;
3ffc7a36 416 SCM val;
1a548472 417 if (SCM_IMP (obj))
3ffc7a36
MD
418 scm_wrong_type_arg (0, 0, obj);
419 switch (SCM_TYP7 (obj))
420 {
421 case scm_tc7_vector:
422 case scm_tc7_wvect:
9fd38a3d 423 n = SCM_VECTOR_LENGTH (obj);
3ffc7a36
MD
424 for (i = 0; i < n; ++i)
425 {
426 val = SCM_VELTS (obj)[i];
427 if (!SCM_INUMP (val)
0c95b57d 428 && !(SCM_BIGP (val) || SCM_REALP (val)))
3ffc7a36
MD
429 scm_wrong_type_arg (0, 0, val);
430 }
431 if (m == 0)
432 m = (float *) malloc (n * sizeof (float));
d3dd80ab
MG
433 if (m == NULL)
434 return NULL;
3ffc7a36
MD
435 for (i = 0; i < n; ++i)
436 {
437 val = SCM_VELTS (obj)[i];
438 if (SCM_INUMP (val))
439 m[i] = SCM_INUM (val);
440 else if (SCM_BIGP (val))
e4b265d8 441 m[i] = scm_num2long (val, 0, NULL);
3ffc7a36 442 else
eb42e2f0 443 m[i] = SCM_REAL_VALUE (val);
f3a2c4cf
MD
444 }
445 break;
afe5177e 446#ifdef HAVE_ARRAYS
f3a2c4cf 447 case scm_tc7_fvect:
9fd38a3d 448 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
449 if (m == 0)
450 m = (float *) malloc (n * sizeof (float));
d3dd80ab
MG
451 if (m == NULL)
452 return NULL;
3ffc7a36 453 memcpy (m, (float *) SCM_VELTS (obj), n * sizeof (float));
f3a2c4cf 454 break;
16d35552 455
f3a2c4cf 456 case scm_tc7_dvect:
9fd38a3d 457 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
458 if (m == 0)
459 m = (float*) malloc (n * sizeof (float));
d3dd80ab
MG
460 if (m == NULL)
461 return NULL;
f3a2c4cf 462 for (i = 0; i < n; ++i)
3ffc7a36
MD
463 m[i] = ((double *) SCM_VELTS (obj))[i];
464 break;
465#endif
466 default:
467 scm_wrong_type_arg (0, 0, obj);
468 }
469 return m;
470}
471
472/* Convert a vector, weak vector or uniform vector into an array of
d3dd80ab
MG
473 doubles. If result array in arg 2 is NULL, malloc a new one. If
474 out of memory, return NULL. */
3ffc7a36
MD
475double *
476gh_scm2doubles (SCM obj, double *m)
477{
c014a02e 478 long i, n;
3ffc7a36 479 SCM val;
1a548472 480 if (SCM_IMP (obj))
3ffc7a36
MD
481 scm_wrong_type_arg (0, 0, obj);
482 switch (SCM_TYP7 (obj))
483 {
484 case scm_tc7_vector:
485 case scm_tc7_wvect:
9fd38a3d 486 n = SCM_VECTOR_LENGTH (obj);
3ffc7a36
MD
487 for (i = 0; i < n; ++i)
488 {
489 val = SCM_VELTS (obj)[i];
490 if (!SCM_INUMP (val)
0c95b57d 491 && !(SCM_BIGP (val) || SCM_REALP (val)))
3ffc7a36
MD
492 scm_wrong_type_arg (0, 0, val);
493 }
494 if (m == 0)
495 m = (double *) malloc (n * sizeof (double));
d3dd80ab
MG
496 if (m == NULL)
497 return NULL;
3ffc7a36
MD
498 for (i = 0; i < n; ++i)
499 {
500 val = SCM_VELTS (obj)[i];
501 if (SCM_INUMP (val))
502 m[i] = SCM_INUM (val);
503 else if (SCM_BIGP (val))
e4b265d8 504 m[i] = scm_num2long (val, 0, NULL);
3ffc7a36 505 else
eb42e2f0 506 m[i] = SCM_REAL_VALUE (val);
3ffc7a36
MD
507 }
508 break;
afe5177e 509#ifdef HAVE_ARRAYS
3ffc7a36 510 case scm_tc7_fvect:
9fd38a3d 511 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
512 if (m == 0)
513 m = (double *) malloc (n * sizeof (double));
d3dd80ab
MG
514 if (m == NULL)
515 return NULL;
3ffc7a36
MD
516 for (i = 0; i < n; ++i)
517 m[i] = ((float *) SCM_VELTS (obj))[i];
518 break;
16d35552 519
3ffc7a36 520 case scm_tc7_dvect:
9fd38a3d 521 n = SCM_UVECTOR_LENGTH (obj);
3ffc7a36
MD
522 if (m == 0)
523 m = (double*) malloc (n * sizeof (double));
d3dd80ab
MG
524 if (m == NULL)
525 return NULL;
3ffc7a36 526 memcpy (m, SCM_VELTS (obj), n * sizeof (double));
f3a2c4cf
MD
527 break;
528#endif
529 default:
530 scm_wrong_type_arg (0, 0, obj);
531 }
532 return m;
533}
534
ee2a8b9b
JB
535/* string conversions between C and Scheme */
536
537/* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
538 new copy of its contents, followed by a null byte. If lenp is
539 non-null, set *lenp to the string's length.
540
541 This function uses malloc to obtain storage for the copy; the
d3dd80ab
MG
542 caller is responsible for freeing it. If out of memory, NULL is
543 returned.
ee2a8b9b
JB
544
545 Note that Scheme strings may contain arbitrary data, including null
546 characters. This means that null termination is not a reliable way
547 to determine the length of the returned value. However, the
548 function always copies the complete contents of STR, and sets
549 *LEN_P to the true length of the string (when LEN_P is non-null). */
550char *
1be6b49c 551gh_scm2newstr (SCM str, size_t *lenp)
ee2a8b9b
JB
552{
553 char *ret_str;
1be6b49c 554 size_t len;
ee2a8b9b 555
9fd38a3d 556 SCM_ASSERT (SCM_STRINGP (str), str, SCM_ARG3, "gh_scm2newstr");
ee2a8b9b 557
9fd38a3d 558 len = SCM_STRING_LENGTH (str);
ee2a8b9b 559
d3dd80ab
MG
560 ret_str = (char *) malloc ((len + 1) * sizeof (char));
561 if (ret_str == NULL)
562 return NULL;
ee2a8b9b 563 /* so we copy tmp_str to ret_str, which is what we will allocate */
34f0f2b8 564 memcpy (ret_str, SCM_STRING_CHARS (str), len);
5d2b97cd 565 scm_remember_upto_here_1 (str);
ee2a8b9b
JB
566 /* now make sure we null-terminate it */
567 ret_str[len] = '\0';
568
ee2a8b9b
JB
569 if (lenp != NULL)
570 {
571 *lenp = len;
572 }
573
574 return ret_str;
575}
576
577
578/* Copy LEN characters at START from the Scheme string SRC to memory
579 at DST. START is an index into SRC; zero means the beginning of
580 the string. DST has already been allocated by the caller.
581
582 If START + LEN is off the end of SRC, silently truncate the source
583 region to fit the string. If truncation occurs, the corresponding
584 area of DST is left unchanged. */
585void
c014a02e 586gh_get_substr (SCM src, char *dst, long start, size_t len)
ee2a8b9b 587{
1be6b49c 588 size_t src_len, effective_length;
9fd38a3d 589 SCM_ASSERT (SCM_STRINGP (src), src, SCM_ARG3, "gh_get_substr");
ee2a8b9b 590
9fd38a3d 591 src_len = SCM_STRING_LENGTH (src);
ee2a8b9b 592 effective_length = (len < src_len) ? len : src_len;
34f0f2b8 593 memcpy (dst + start, SCM_STRING_CHARS (src), effective_length * sizeof (char));
ee2a8b9b 594 /* FIXME: must signal an error if len > src_len */
5d2b97cd 595 scm_remember_upto_here_1 (src);
ee2a8b9b
JB
596}
597
598
599/* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
600 pointer to a string with the symbol characters "identifier",
601 followed by a null byte. If lenp is non-null, set *lenp to the
602 string's length.
603
604 This function uses malloc to obtain storage for the copy; the
d3dd80ab
MG
605 caller is responsible for freeing it. If out of memory, NULL is
606 returned.*/
ee2a8b9b 607char *
1be6b49c 608gh_symbol2newstr (SCM sym, size_t *lenp)
ee2a8b9b
JB
609{
610 char *ret_str;
1be6b49c 611 size_t len;
ee2a8b9b 612
b24b5e13 613 SCM_ASSERT (SCM_SYMBOLP (sym), sym, SCM_ARG3, "gh_scm2newsymbol");
ee2a8b9b 614
9fd38a3d 615 len = SCM_SYMBOL_LENGTH (sym);
ee2a8b9b 616
d3dd80ab
MG
617 ret_str = (char *) malloc ((len + 1) * sizeof (char));
618 if (ret_str == NULL)
619 return NULL;
b24b5e13 620 /* so we copy sym to ret_str, which is what we will allocate */
86c991c2 621 memcpy (ret_str, SCM_SYMBOL_CHARS (sym), len);
5d2b97cd 622 scm_remember_upto_here_1 (sym);
ee2a8b9b
JB
623 /* now make sure we null-terminate it */
624 ret_str[len] = '\0';
625
ee2a8b9b
JB
626 if (lenp != NULL)
627 {
628 *lenp = len;
629 }
630
631 return ret_str;
632}
633
634
635/* create a new vector of the given length, all initialized to the
636 given value */
e5eece74
MG
637SCM
638gh_make_vector (SCM len, SCM fill)
ee2a8b9b 639{
a8741caa 640 return scm_make_vector (len, fill);
ee2a8b9b
JB
641}
642
643/* set the given element of the given vector to the given value */
644SCM
956328d2 645gh_vector_set_x (SCM vec, SCM pos, SCM val)
ee2a8b9b
JB
646{
647 return scm_vector_set_x (vec, pos, val);
648}
649
650/* retrieve the given element of the given vector */
651SCM
e5eece74 652gh_vector_ref (SCM vec, SCM pos)
ee2a8b9b
JB
653{
654 return scm_vector_ref (vec, pos);
655}
656
657/* returns the length of the given vector */
c014a02e 658unsigned long
ee2a8b9b
JB
659gh_vector_length (SCM v)
660{
c014a02e 661 return (unsigned long) SCM_VECTOR_LENGTH (v);
ee2a8b9b 662}
35379308 663
afe5177e 664#ifdef HAVE_ARRAYS
ef5d3ae1
MG
665/* uniform vector support */
666
667/* returns the length as a C unsigned long integer */
c014a02e 668unsigned long
ef5d3ae1
MG
669gh_uniform_vector_length (SCM v)
670{
c014a02e 671 return (unsigned long) SCM_UVECTOR_LENGTH (v);
ef5d3ae1
MG
672}
673
674/* gets the given element from a uniform vector; ilist is a list (or
675 possibly a single integer) of indices, and its length is the
676 dimension of the uniform vector */
677SCM
678gh_uniform_vector_ref (SCM v, SCM ilist)
679{
680 return scm_uniform_vector_ref (v, ilist);
681}
682
683/* sets an individual element in a uniform vector */
684/* SCM */
685/* gh_list_to_uniform_array ( */
afe5177e 686#endif
ef5d3ae1 687
35379308
JB
688/* Data lookups between C and Scheme
689
690 Look up a symbol with a given name, and return the object to which
691 it is bound. gh_lookup examines the Guile top level, and
692 gh_module_lookup checks the module namespace specified by the
693 `vec' argument.
694
695 The return value is the Scheme object to which SNAME is bound, or
07de6c47
MV
696 SCM_UNDEFINED if SNAME is not bound in the given context.
697 */
35379308
JB
698
699SCM
bcee10dd 700gh_lookup (const char *sname)
35379308 701{
abc235ad 702 return gh_module_lookup (scm_current_module (), sname);
35379308
JB
703}
704
abc235ad 705
35379308 706SCM
abc235ad
MV
707gh_module_lookup (SCM module, const char *sname)
708#define FUNC_NAME "gh_module_lookup"
35379308 709{
86d31dfe 710 SCM sym, var;
abc235ad
MV
711
712 SCM_VALIDATE_MODULE (SCM_ARG1, module);
713
714 sym = gh_symbol2scm (sname);
86d31dfe
MV
715 var = scm_sym2var (sym, scm_module_lookup_closure (module), SCM_BOOL_F);
716 if (var != SCM_BOOL_F)
717 return SCM_VARIABLE_REF (var);
35379308
JB
718 else
719 return SCM_UNDEFINED;
720}
abc235ad 721#undef FUNC_NAME
89e00824
ML
722
723/*
724 Local Variables:
725 c-file-style: "gnu"
726 End:
727*/