1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001, 2004 Free Software Foundation, Inc.
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
7 * This library 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 GNU
10 * Lesser General Public License for more details.
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 /* data initialization and C<->Scheme data conversion */
24 #include "libguile/gh.h"
31 /* data conversion C->scheme */
36 return scm_from_bool(x
);
41 return scm_from_long ((long) x
);
44 gh_ulong2scm (unsigned long x
)
46 return scm_from_ulong (x
);
51 return scm_from_long (x
);
54 gh_double2scm (double x
)
56 return scm_from_double (x
);
61 return SCM_MAKE_CHAR (c
);
64 gh_str2scm (const char *s
, size_t len
)
66 return scm_from_locale_stringn (s
, len
);
69 gh_str02scm (const char *s
)
71 return scm_from_locale_string (s
);
73 /* Copy LEN characters at SRC into the *existing* Scheme string DST,
74 starting at START. START is an index into DST; zero means the
75 beginning of the string.
77 If START + LEN is off the end of DST, signal an out-of-range
80 gh_set_substr (const char *src
, SCM dst
, long start
, size_t len
)
85 SCM_ASSERT (scm_is_string (dst
), dst
, SCM_ARG3
, "gh_set_substr");
87 dst_len
= scm_i_string_length (dst
);
88 SCM_ASSERT (start
+ len
<= dst_len
, dst
, SCM_ARG4
, "gh_set_substr");
90 dst_ptr
= scm_i_string_writable_chars (dst
);
91 memmove (dst_ptr
+ start
, src
, len
);
92 scm_i_string_stop_writing ();
93 scm_remember_upto_here_1 (dst
);
96 /* Return the symbol named SYMBOL_STR. */
98 gh_symbol2scm (const char *symbol_str
)
100 return scm_from_locale_symbol(symbol_str
);
104 gh_ints2scm (const int *d
, long n
)
107 SCM v
= scm_c_make_vector (n
, SCM_UNSPECIFIED
);
108 for (i
= 0; i
< n
; ++i
)
109 SCM_SIMPLE_VECTOR_SET (v
, i
, scm_from_int (d
[i
]));
115 gh_doubles2scm (const double *d
, long n
)
118 SCM v
= scm_c_make_vector (n
, SCM_UNSPECIFIED
);
120 for(i
= 0; i
< n
; i
++)
121 SCM_SIMPLE_VECTOR_SET (v
, i
, scm_from_double (d
[i
]));
127 gh_chars2byvect (const char *d
, long n
)
129 char *m
= scm_malloc (n
);
130 memcpy (m
, d
, n
* sizeof (char));
131 return scm_take_s8vector ((scm_t_int8
*)m
, n
);
135 gh_shorts2svect (const short *d
, long n
)
137 char *m
= scm_malloc (n
* sizeof (short));
138 memcpy (m
, d
, n
* sizeof (short));
139 assert (sizeof (scm_t_int16
) == sizeof (short));
140 return scm_take_s16vector ((scm_t_int16
*)m
, n
);
144 gh_longs2ivect (const long *d
, long n
)
146 char *m
= scm_malloc (n
* sizeof (long));
147 memcpy (m
, d
, n
* sizeof (long));
148 assert (sizeof (scm_t_int32
) == sizeof (long));
149 return scm_take_s32vector ((scm_t_int32
*)m
, n
);
153 gh_ulongs2uvect (const unsigned long *d
, long n
)
155 char *m
= scm_malloc (n
* sizeof (unsigned long));
156 memcpy (m
, d
, n
* sizeof (unsigned long));
157 assert (sizeof (scm_t_uint32
) == sizeof (unsigned long));
158 return scm_take_u32vector ((scm_t_uint32
*)m
, n
);
162 gh_floats2fvect (const float *d
, long n
)
164 char *m
= scm_malloc (n
* sizeof (float));
165 memcpy (m
, d
, n
* sizeof (float));
166 return scm_take_f32vector ((float *)m
, n
);
170 gh_doubles2dvect (const double *d
, long n
)
172 char *m
= scm_malloc (n
* sizeof (double));
173 memcpy (m
, d
, n
* sizeof (double));
174 return scm_take_f64vector ((double *)m
, n
);
177 /* data conversion scheme->C */
179 gh_scm2bool (SCM obj
)
181 return (scm_is_false (obj
)) ? 0 : 1;
184 gh_scm2ulong (SCM obj
)
186 return scm_to_ulong (obj
);
189 gh_scm2long (SCM obj
)
191 return scm_to_long (obj
);
196 return scm_to_int (obj
);
199 gh_scm2double (SCM obj
)
201 return scm_to_double (obj
);
204 gh_scm2char (SCM obj
)
205 #define FUNC_NAME "gh_scm2char"
207 SCM_VALIDATE_CHAR (SCM_ARG1
, obj
);
208 return SCM_CHAR (obj
);
212 /* Convert a vector, weak vector, string, substring or uniform vector
213 into an array of chars. If result array in arg 2 is NULL, malloc a
214 new one. If out of memory, return NULL. */
216 gh_scm2chars (SCM obj
, char *m
)
222 scm_wrong_type_arg (0, 0, obj
);
223 switch (SCM_TYP7 (obj
))
227 n
= SCM_SIMPLE_VECTOR_LENGTH (obj
);
228 for (i
= 0; i
< n
; ++i
)
230 val
= SCM_SIMPLE_VECTOR_REF (obj
, i
);
231 if (SCM_I_INUMP (val
))
233 v
= SCM_I_INUM (val
);
234 if (v
< -128 || v
> 255)
235 scm_out_of_range (0, obj
);
238 scm_wrong_type_arg (0, 0, obj
);
241 m
= (char *) malloc (n
* sizeof (char));
244 for (i
= 0; i
< n
; ++i
)
245 m
[i
] = SCM_I_INUM (SCM_SIMPLE_VECTOR_REF (obj
, i
));
248 if (scm_is_true (scm_s8vector_p (obj
)))
250 scm_t_array_handle handle
;
253 const scm_t_int8
*elts
;
255 elts
= scm_s8vector_elements (obj
, &handle
, &len
, &inc
);
257 scm_misc_error (NULL
, "only contiguous vectors are supported: ~a",
260 m
= (char *) malloc (len
);
262 memcpy (m
, elts
, len
);
263 scm_array_handle_release (&handle
);
271 n
= scm_i_string_length (obj
);
273 m
= (char *) malloc (n
* sizeof (char));
276 memcpy (m
, scm_i_string_chars (obj
), n
* sizeof (char));
280 scm_wrong_type_arg (0, 0, obj
);
286 scm2whatever (SCM obj
, void *m
, size_t size
)
288 scm_t_array_handle handle
;
293 elts
= scm_uniform_vector_elements (obj
, &handle
, &len
, &inc
);
296 scm_misc_error (NULL
, "only contiguous vectors can be converted: ~a",
300 m
= malloc (len
* sizeof (size
));
302 memcpy (m
, elts
, len
* size
);
304 scm_array_handle_release (&handle
);
309 #define SCM2WHATEVER(obj,pred,utype,mtype) \
310 if (scm_is_true (pred (obj))) \
312 assert (sizeof (utype) == sizeof (mtype)); \
313 return (mtype *)scm2whatever (obj, m, sizeof (utype)); \
316 /* Convert a vector, weak vector or uniform vector into an array of
317 shorts. If result array in arg 2 is NULL, malloc a new one. If
318 out of memory, return NULL. */
320 gh_scm2shorts (SCM obj
, short *m
)
326 scm_wrong_type_arg (0, 0, obj
);
328 SCM2WHATEVER (obj
, scm_s16vector_p
, scm_t_int16
, short)
330 switch (SCM_TYP7 (obj
))
334 n
= SCM_SIMPLE_VECTOR_LENGTH (obj
);
335 for (i
= 0; i
< n
; ++i
)
337 val
= SCM_SIMPLE_VECTOR_REF (obj
, i
);
338 if (SCM_I_INUMP (val
))
340 v
= SCM_I_INUM (val
);
341 if (v
< -32768 || v
> 65535)
342 scm_out_of_range (0, obj
);
345 scm_wrong_type_arg (0, 0, obj
);
348 m
= (short *) malloc (n
* sizeof (short));
351 for (i
= 0; i
< n
; ++i
)
352 m
[i
] = SCM_I_INUM (SCM_SIMPLE_VECTOR_REF (obj
, i
));
355 scm_wrong_type_arg (0, 0, obj
);
360 /* Convert a vector, weak vector or uniform vector into an array of
361 longs. If result array in arg 2 is NULL, malloc a new one. If out
362 of memory, return NULL. */
364 gh_scm2longs (SCM obj
, long *m
)
369 scm_wrong_type_arg (0, 0, obj
);
371 SCM2WHATEVER (obj
, scm_s32vector_p
, scm_t_int32
, long)
373 switch (SCM_TYP7 (obj
))
377 n
= SCM_SIMPLE_VECTOR_LENGTH (obj
);
378 for (i
= 0; i
< n
; ++i
)
380 val
= SCM_SIMPLE_VECTOR_REF (obj
, i
);
381 if (!SCM_I_INUMP (val
) && !SCM_BIGP (val
))
382 scm_wrong_type_arg (0, 0, obj
);
385 m
= (long *) malloc (n
* sizeof (long));
388 for (i
= 0; i
< n
; ++i
)
390 val
= SCM_SIMPLE_VECTOR_REF (obj
, i
);
391 m
[i
] = SCM_I_INUMP (val
)
397 scm_wrong_type_arg (0, 0, obj
);
402 /* Convert a vector, weak vector or uniform vector into an array of
403 floats. If result array in arg 2 is NULL, malloc a new one. If
404 out of memory, return NULL. */
406 gh_scm2floats (SCM obj
, float *m
)
411 scm_wrong_type_arg (0, 0, obj
);
413 /* XXX - f64vectors are rejected now.
415 SCM2WHATEVER (obj
, scm_f32vector_p
, float, float)
417 switch (SCM_TYP7 (obj
))
421 n
= SCM_SIMPLE_VECTOR_LENGTH (obj
);
422 for (i
= 0; i
< n
; ++i
)
424 val
= SCM_SIMPLE_VECTOR_REF (obj
, i
);
425 if (!SCM_I_INUMP (val
)
426 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
427 scm_wrong_type_arg (0, 0, val
);
430 m
= (float *) malloc (n
* sizeof (float));
433 for (i
= 0; i
< n
; ++i
)
435 val
= SCM_SIMPLE_VECTOR_REF (obj
, i
);
436 if (SCM_I_INUMP (val
))
437 m
[i
] = SCM_I_INUM (val
);
438 else if (SCM_BIGP (val
))
439 m
[i
] = scm_to_long (val
);
441 m
[i
] = SCM_REAL_VALUE (val
);
445 scm_wrong_type_arg (0, 0, obj
);
450 /* Convert a vector, weak vector or uniform vector into an array of
451 doubles. If result array in arg 2 is NULL, malloc a new one. If
452 out of memory, return NULL. */
454 gh_scm2doubles (SCM obj
, double *m
)
459 scm_wrong_type_arg (0, 0, obj
);
461 /* XXX - f32vectors are rejected now.
463 SCM2WHATEVER (obj
, scm_f64vector_p
, double, double)
465 switch (SCM_TYP7 (obj
))
469 n
= SCM_SIMPLE_VECTOR_LENGTH (obj
);
470 for (i
= 0; i
< n
; ++i
)
472 val
= SCM_SIMPLE_VECTOR_REF (obj
, i
);
473 if (!SCM_I_INUMP (val
)
474 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
475 scm_wrong_type_arg (0, 0, val
);
478 m
= (double *) malloc (n
* sizeof (double));
481 for (i
= 0; i
< n
; ++i
)
483 val
= SCM_SIMPLE_VECTOR_REF (obj
, i
);
484 if (SCM_I_INUMP (val
))
485 m
[i
] = SCM_I_INUM (val
);
486 else if (SCM_BIGP (val
))
487 m
[i
] = scm_to_long (val
);
489 m
[i
] = SCM_REAL_VALUE (val
);
494 scm_wrong_type_arg (0, 0, obj
);
499 /* string conversions between C and Scheme */
501 /* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
502 new copy of its contents, followed by a null byte. If lenp is
503 non-null, set *lenp to the string's length.
505 This function uses malloc to obtain storage for the copy; the
506 caller is responsible for freeing it. If out of memory, NULL is
509 Note that Scheme strings may contain arbitrary data, including null
510 characters. This means that null termination is not a reliable way
511 to determine the length of the returned value. However, the
512 function always copies the complete contents of STR, and sets
513 *LEN_P to the true length of the string (when LEN_P is non-null). */
515 gh_scm2newstr (SCM str
, size_t *lenp
)
519 /* We can't use scm_to_locale_stringn directly since it does not
520 guarantee null-termination when lenp is non-NULL.
523 ret_str
= scm_to_locale_string (str
);
525 *lenp
= scm_i_string_length (str
);
529 /* Copy LEN characters at START from the Scheme string SRC to memory
530 at DST. START is an index into SRC; zero means the beginning of
531 the string. DST has already been allocated by the caller.
533 If START + LEN is off the end of SRC, silently truncate the source
534 region to fit the string. If truncation occurs, the corresponding
535 area of DST is left unchanged. */
537 gh_get_substr (SCM src
, char *dst
, long start
, size_t len
)
539 size_t src_len
, effective_length
;
540 SCM_ASSERT (scm_is_string (src
), src
, SCM_ARG3
, "gh_get_substr");
542 src_len
= scm_i_string_length (src
);
543 effective_length
= (len
< src_len
) ? len
: src_len
;
544 memcpy (dst
+ start
, scm_i_string_chars (src
), effective_length
* sizeof (char));
545 /* FIXME: must signal an error if len > src_len */
546 scm_remember_upto_here_1 (src
);
550 /* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
551 pointer to a string with the symbol characters "identifier",
552 followed by a null byte. If lenp is non-null, set *lenp to the
555 This function uses malloc to obtain storage for the copy; the
556 caller is responsible for freeing it. If out of memory, NULL is
559 gh_symbol2newstr (SCM sym
, size_t *lenp
)
561 return gh_scm2newstr (scm_symbol_to_string (sym
), lenp
);
565 /* create a new vector of the given length, all initialized to the
568 gh_make_vector (SCM len
, SCM fill
)
570 return scm_make_vector (len
, fill
);
573 /* set the given element of the given vector to the given value */
575 gh_vector_set_x (SCM vec
, SCM pos
, SCM val
)
577 return scm_vector_set_x (vec
, pos
, val
);
580 /* retrieve the given element of the given vector */
582 gh_vector_ref (SCM vec
, SCM pos
)
584 return scm_vector_ref (vec
, pos
);
587 /* returns the length of the given vector */
589 gh_vector_length (SCM v
)
591 return (unsigned long) scm_c_vector_length (v
);
594 /* uniform vector support */
596 /* returns the length as a C unsigned long integer */
598 gh_uniform_vector_length (SCM v
)
600 return (unsigned long) scm_c_uniform_vector_length (v
);
603 /* gets the given element from a uniform vector; ilist is a list (or
604 possibly a single integer) of indices, and its length is the
605 dimension of the uniform vector */
607 gh_uniform_vector_ref (SCM v
, SCM ilist
)
609 return scm_uniform_vector_ref (v
, ilist
);
612 /* sets an individual element in a uniform vector */
614 /* gh_list_to_uniform_array ( */
616 /* Data lookups between C and Scheme
618 Look up a symbol with a given name, and return the object to which
619 it is bound. gh_lookup examines the Guile top level, and
620 gh_module_lookup checks the module namespace specified by the
623 The return value is the Scheme object to which SNAME is bound, or
624 SCM_UNDEFINED if SNAME is not bound in the given context.
628 gh_lookup (const char *sname
)
630 return gh_module_lookup (scm_current_module (), sname
);
635 gh_module_lookup (SCM module
, const char *sname
)
636 #define FUNC_NAME "gh_module_lookup"
640 SCM_VALIDATE_MODULE (SCM_ARG1
, module
);
642 sym
= scm_from_locale_symbol (sname
);
643 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_F
);
644 if (var
!= SCM_BOOL_F
)
645 return SCM_VARIABLE_REF (var
);
647 return SCM_UNDEFINED
;