1 /* Copyright (C) 1995,1996,1997,1998, 1999, 2000 Free Software Foundation, Inc.
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)
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.
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
14 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
15 * Boston, MA 02111-1307 USA
17 * As a special exception, the Free Software Foundation gives permission
18 * for additional uses of the text contained in its release of GUILE.
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.
26 * This exception does not however invalidate any other reasons why
27 * the executable file might be covered by the GNU General Public License.
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.
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.
39 * If you do not wish that, delete this exception notice. */
42 /* data initialization and C<->Scheme data conversion */
46 #include "libguile/gh.h"
51 /* data conversion C->scheme */
53 #if (SCM_DEBUG_DEPRECATED == 0)
56 gh_int2scmb (int x
) /* this is being phased out */
61 #endif /* SCM_DEBUG_DEPRECATED == 0 */
71 return scm_long2num ((long) x
);
74 gh_ulong2scm (unsigned long x
)
76 return scm_ulong2num (x
);
81 return scm_long2num (x
);
84 gh_double2scm (double x
)
86 return scm_make_real (x
);
91 return SCM_MAKE_CHAR (c
);
94 gh_str2scm (const char *s
, int len
)
96 return scm_makfromstr (s
, len
, 0);
99 gh_str02scm (const char *s
)
101 return scm_makfrom0str (s
);
103 /* Copy LEN characters at SRC into the *existing* Scheme string DST,
104 starting at START. START is an index into DST; zero means the
105 beginning of the string.
107 If START + LEN is off the end of DST, signal an out-of-range
110 gh_set_substr (char *src
, SCM dst
, int start
, int len
)
113 unsigned long dst_len
;
114 unsigned long effective_length
;
116 SCM_ASSERT (SCM_STRINGP (dst
), dst
, SCM_ARG3
, "gh_set_substr");
118 dst_ptr
= SCM_STRING_CHARS (dst
);
119 dst_len
= SCM_STRING_LENGTH (dst
);
120 SCM_ASSERT (len
>= 0 && (unsigned) len
<= dst_len
,
121 dst
, SCM_ARG4
, "gh_set_substr");
123 effective_length
= ((unsigned) len
< dst_len
) ? len
: dst_len
;
124 memmove (dst_ptr
+ start
, src
, effective_length
);
128 /* Return the symbol named SYMBOL_STR. */
130 gh_symbol2scm (const char *symbol_str
)
132 return SCM_CAR (scm_intern (symbol_str
, strlen (symbol_str
)));
136 gh_ints2scm (int *d
, int n
)
139 SCM v
= scm_make_vector(SCM_MAKINUM(n
), SCM_UNSPECIFIED
);
140 SCM
*velts
= SCM_VELTS(v
);
142 for (i
= 0; i
< n
; ++i
)
143 velts
[i
] = (d
[i
] >= SCM_MOST_NEGATIVE_FIXNUM
144 && d
[i
] <= SCM_MOST_POSITIVE_FIXNUM
146 : scm_long2big (d
[i
]));
151 gh_doubles2scm (const double *d
, int n
)
154 SCM v
= scm_make_vector(SCM_MAKINUM(n
), SCM_UNSPECIFIED
);
155 SCM
*velts
= SCM_VELTS(v
);
157 for(i
= 0; i
< n
; i
++)
158 velts
[i
] = scm_make_real (d
[i
]);
163 /* Do not use this function for building normal Scheme vectors, unless
164 you arrange for the elements to be protected from GC while you
165 initialize the vector. */
167 makvect (char* m
, int len
, int type
)
172 SCM_SET_UVECTOR_BASE (ans
, m
);
173 SCM_SET_UVECTOR_LENGTH (ans
, len
, type
);
179 gh_chars2byvect (const char *d
, int n
)
181 char *m
= scm_must_malloc (n
* sizeof (char), "vector");
182 memcpy (m
, d
, n
* sizeof (char));
183 return makvect (m
, n
, scm_tc7_byvect
);
187 gh_shorts2svect (const short *d
, int n
)
189 char *m
= scm_must_malloc (n
* sizeof (short), "vector");
190 memcpy (m
, d
, n
* sizeof (short));
191 return makvect (m
, n
, scm_tc7_svect
);
195 gh_longs2ivect (const long *d
, int n
)
197 char *m
= scm_must_malloc (n
* sizeof (long), "vector");
198 memcpy (m
, d
, n
* sizeof (long));
199 return makvect (m
, n
, scm_tc7_ivect
);
203 gh_ulongs2uvect (const unsigned long *d
, int n
)
205 char *m
= scm_must_malloc (n
* sizeof (unsigned long), "vector");
206 memcpy (m
, d
, n
* sizeof (unsigned long));
207 return makvect (m
, n
, scm_tc7_uvect
);
211 gh_floats2fvect (const float *d
, int n
)
213 char *m
= scm_must_malloc (n
* sizeof (float), "vector");
214 memcpy (m
, d
, n
* sizeof (float));
215 return makvect (m
, n
, scm_tc7_fvect
);
219 gh_doubles2dvect (const double *d
, int n
)
221 char *m
= scm_must_malloc (n
* sizeof (double), "vector");
222 memcpy (m
, d
, n
* sizeof (double));
223 return makvect (m
, n
, scm_tc7_dvect
);
227 /* data conversion scheme->C */
229 gh_scm2bool (SCM obj
)
231 return (SCM_FALSEP (obj
)) ? 0 : 1;
234 gh_scm2ulong (SCM obj
)
236 return scm_num2ulong (obj
, (char *) SCM_ARG1
, "gh_scm2ulong");
239 gh_scm2long (SCM obj
)
241 return scm_num2long (obj
, (char *) SCM_ARG1
, "gh_scm2long");
246 /* NOTE: possible loss of precision here */
247 return (int) scm_num2long (obj
, (char *) SCM_ARG1
, "gh_scm2int");
250 gh_scm2double (SCM obj
)
252 return scm_num2dbl (obj
, "gh_scm2double");
255 gh_scm2char (SCM obj
)
256 #define FUNC_NAME "gh_scm2char"
258 SCM_VALIDATE_CHAR (SCM_ARG1
, obj
);
259 return SCM_CHAR (obj
);
263 /* Convert a vector, weak vector, string, substring or uniform vector
264 into an array of chars. If result array in arg 2 is NULL, malloc a
267 gh_scm2chars (SCM obj
, char *m
)
273 scm_wrong_type_arg (0, 0, obj
);
274 switch (SCM_TYP7 (obj
))
278 n
= SCM_VECTOR_LENGTH (obj
);
279 for (i
= 0; i
< n
; ++i
)
281 val
= SCM_VELTS (obj
)[i
];
285 if (v
< -128 || v
> 255)
286 scm_out_of_range (0, obj
);
289 scm_wrong_type_arg (0, 0, obj
);
292 m
= (char *) malloc (n
* sizeof (char));
293 for (i
= 0; i
< n
; ++i
)
294 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
298 n
= SCM_UVECTOR_LENGTH (obj
);
300 m
= (char *) malloc (n
* sizeof (char));
301 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (char));
305 case scm_tc7_substring
:
306 n
= SCM_STRING_LENGTH (obj
);
308 m
= (char *) malloc (n
* sizeof (char));
309 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (char));
312 scm_wrong_type_arg (0, 0, obj
);
317 /* Convert a vector, weak vector or uniform vector into an array of
318 shorts. If result array in arg 2 is NULL, malloc a new one. */
320 gh_scm2shorts (SCM obj
, short *m
)
326 scm_wrong_type_arg (0, 0, obj
);
327 switch (SCM_TYP7 (obj
))
331 n
= SCM_VECTOR_LENGTH (obj
);
332 for (i
= 0; i
< n
; ++i
)
334 val
= SCM_VELTS (obj
)[i
];
338 if (v
< -32768 || v
> 65535)
339 scm_out_of_range (0, obj
);
342 scm_wrong_type_arg (0, 0, obj
);
345 m
= (short *) malloc (n
* sizeof (short));
346 for (i
= 0; i
< n
; ++i
)
347 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
351 n
= SCM_UVECTOR_LENGTH (obj
);
353 m
= (short *) malloc (n
* sizeof (short));
354 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (short));
358 scm_wrong_type_arg (0, 0, obj
);
363 /* Convert a vector, weak vector or uniform vector into an array of
364 longs. If result array in arg 2 is NULL, malloc a new one. */
366 gh_scm2longs (SCM obj
, long *m
)
371 scm_wrong_type_arg (0, 0, obj
);
372 switch (SCM_TYP7 (obj
))
376 n
= SCM_VECTOR_LENGTH (obj
);
377 for (i
= 0; i
< n
; ++i
)
379 val
= SCM_VELTS (obj
)[i
];
380 if (!SCM_INUMP (val
) && !SCM_BIGP (val
))
381 scm_wrong_type_arg (0, 0, obj
);
384 m
= (long *) malloc (n
* sizeof (long));
385 for (i
= 0; i
< n
; ++i
)
387 val
= SCM_VELTS (obj
)[i
];
388 m
[i
] = SCM_INUMP (val
) ? SCM_INUM (val
) : scm_num2long (val
, 0, 0);
394 n
= SCM_UVECTOR_LENGTH (obj
);
396 m
= (long *) malloc (n
* sizeof (long));
397 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (long));
401 scm_wrong_type_arg (0, 0, obj
);
406 /* Convert a vector, weak vector or uniform vector into an array of
407 floats. If result array in arg 2 is NULL, malloc a new one. */
409 gh_scm2floats (SCM obj
, float *m
)
414 scm_wrong_type_arg (0, 0, obj
);
415 switch (SCM_TYP7 (obj
))
419 n
= SCM_VECTOR_LENGTH (obj
);
420 for (i
= 0; i
< n
; ++i
)
422 val
= SCM_VELTS (obj
)[i
];
424 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
425 scm_wrong_type_arg (0, 0, val
);
428 m
= (float *) malloc (n
* sizeof (float));
429 for (i
= 0; i
< n
; ++i
)
431 val
= SCM_VELTS (obj
)[i
];
433 m
[i
] = SCM_INUM (val
);
434 else if (SCM_BIGP (val
))
435 m
[i
] = scm_num2long (val
, 0, 0);
437 m
[i
] = SCM_REAL_VALUE (val
);
442 n
= SCM_UVECTOR_LENGTH (obj
);
444 m
= (float *) malloc (n
* sizeof (float));
445 memcpy (m
, (float *) SCM_VELTS (obj
), n
* sizeof (float));
449 n
= SCM_UVECTOR_LENGTH (obj
);
451 m
= (float*) malloc (n
* sizeof (float));
452 for (i
= 0; i
< n
; ++i
)
453 m
[i
] = ((double *) SCM_VELTS (obj
))[i
];
457 scm_wrong_type_arg (0, 0, obj
);
462 /* Convert a vector, weak vector or uniform vector into an array of
463 doubles. If result array in arg 2 is NULL, malloc a new one. */
465 gh_scm2doubles (SCM obj
, double *m
)
470 scm_wrong_type_arg (0, 0, obj
);
471 switch (SCM_TYP7 (obj
))
475 n
= SCM_VECTOR_LENGTH (obj
);
476 for (i
= 0; i
< n
; ++i
)
478 val
= SCM_VELTS (obj
)[i
];
480 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
481 scm_wrong_type_arg (0, 0, val
);
484 m
= (double *) malloc (n
* sizeof (double));
485 for (i
= 0; i
< n
; ++i
)
487 val
= SCM_VELTS (obj
)[i
];
489 m
[i
] = SCM_INUM (val
);
490 else if (SCM_BIGP (val
))
491 m
[i
] = scm_num2long (val
, 0, 0);
493 m
[i
] = SCM_REAL_VALUE (val
);
498 n
= SCM_UVECTOR_LENGTH (obj
);
500 m
= (double *) malloc (n
* sizeof (double));
501 for (i
= 0; i
< n
; ++i
)
502 m
[i
] = ((float *) SCM_VELTS (obj
))[i
];
506 n
= SCM_UVECTOR_LENGTH (obj
);
508 m
= (double*) malloc (n
* sizeof (double));
509 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (double));
513 scm_wrong_type_arg (0, 0, obj
);
518 /* string conversions between C and Scheme */
520 /* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
521 new copy of its contents, followed by a null byte. If lenp is
522 non-null, set *lenp to the string's length.
524 This function uses malloc to obtain storage for the copy; the
525 caller is responsible for freeing it.
527 Note that Scheme strings may contain arbitrary data, including null
528 characters. This means that null termination is not a reliable way
529 to determine the length of the returned value. However, the
530 function always copies the complete contents of STR, and sets
531 *LEN_P to the true length of the string (when LEN_P is non-null). */
533 gh_scm2newstr (SCM str
, int *lenp
)
538 SCM_ASSERT (SCM_STRINGP (str
), str
, SCM_ARG3
, "gh_scm2newstr");
540 len
= SCM_STRING_LENGTH (str
);
542 ret_str
= (char *) scm_must_malloc ((len
+ 1) * sizeof (char),
544 /* so we copy tmp_str to ret_str, which is what we will allocate */
545 memcpy (ret_str
, SCM_STRING_CHARS (str
), len
);
546 /* from now on we don't mind if str gets GC collected. */
548 /* now make sure we null-terminate it */
561 /* Copy LEN characters at START from the Scheme string SRC to memory
562 at DST. START is an index into SRC; zero means the beginning of
563 the string. DST has already been allocated by the caller.
565 If START + LEN is off the end of SRC, silently truncate the source
566 region to fit the string. If truncation occurs, the corresponding
567 area of DST is left unchanged. */
569 gh_get_substr (SCM src
, char *dst
, int start
, int len
)
571 int src_len
, effective_length
;
572 SCM_ASSERT (SCM_STRINGP (src
), src
, SCM_ARG3
, "gh_get_substr");
574 src_len
= SCM_STRING_LENGTH (src
);
575 effective_length
= (len
< src_len
) ? len
: src_len
;
576 memcpy (dst
+ start
, SCM_STRING_CHARS (src
), effective_length
* sizeof (char));
577 /* FIXME: must signal an error if len > src_len */
582 /* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
583 pointer to a string with the symbol characters "identifier",
584 followed by a null byte. If lenp is non-null, set *lenp to the
587 This function uses malloc to obtain storage for the copy; the
588 caller is responsible for freeing it. */
590 gh_symbol2newstr (SCM sym
, int *lenp
)
595 SCM_ASSERT (SCM_SYMBOLP (sym
), sym
, SCM_ARG3
, "gh_scm2newsymbol");
597 len
= SCM_SYMBOL_LENGTH (sym
);
599 ret_str
= (char *) scm_must_malloc ((len
+ 1) * sizeof (char),
601 /* so we copy sym to ret_str, which is what we will allocate */
602 memcpy (ret_str
, SCM_SYMBOL_CHARS (sym
), len
);
603 /* from now on we don't mind if sym gets GC collected. */
605 /* now make sure we null-terminate it */
617 /* create a new vector of the given length, all initialized to the
620 gh_make_vector (SCM len
, SCM fill
)
622 return scm_make_vector (len
, fill
);
625 /* set the given element of the given vector to the given value */
627 gh_vector_set_x (SCM vec
, SCM pos
, SCM val
)
629 return scm_vector_set_x (vec
, pos
, val
);
632 /* retrieve the given element of the given vector */
634 gh_vector_ref (SCM vec
, SCM pos
)
636 return scm_vector_ref (vec
, pos
);
639 /* returns the length of the given vector */
641 gh_vector_length (SCM v
)
643 return gh_scm2ulong (scm_vector_length (v
));
647 /* uniform vector support */
649 /* returns the length as a C unsigned long integer */
651 gh_uniform_vector_length (SCM v
)
653 return gh_scm2ulong (scm_uniform_vector_length (v
));
656 /* gets the given element from a uniform vector; ilist is a list (or
657 possibly a single integer) of indices, and its length is the
658 dimension of the uniform vector */
660 gh_uniform_vector_ref (SCM v
, SCM ilist
)
662 return scm_uniform_vector_ref (v
, ilist
);
665 /* sets an individual element in a uniform vector */
667 /* gh_list_to_uniform_array ( */
670 /* Data lookups between C and Scheme
672 Look up a symbol with a given name, and return the object to which
673 it is bound. gh_lookup examines the Guile top level, and
674 gh_module_lookup checks the module namespace specified by the
677 The return value is the Scheme object to which SNAME is bound, or
678 SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME:
679 should this be SCM_UNSPECIFIED? Can a symbol ever legitimately be
680 bound to SCM_UNDEFINED or SCM_UNSPECIFIED? What is the difference?
684 gh_lookup (const char *sname
)
686 return gh_module_lookup (SCM_BOOL_F
, sname
);
690 gh_module_lookup (SCM vec
, const char *sname
)
692 SCM sym
= gh_symbol2scm (sname
);
693 if (SCM_EQ_P (scm_symbol_bound_p (vec
, sym
), SCM_BOOL_T
))
694 return scm_symbol_binding (vec
, sym
);
696 return SCM_UNDEFINED
;