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