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