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 gh_int2scmb (int x
) /* this is being phased out */
65 return scm_long2num ((long) x
);
68 gh_ulong2scm (unsigned long x
)
70 return scm_ulong2num (x
);
75 return scm_long2num (x
);
78 gh_double2scm (double x
)
80 return scm_makdbl (x
, 0.0);
85 return SCM_MAKE_CHAR (c
);
88 gh_str2scm (const char *s
, int len
)
90 return scm_makfromstr (s
, len
, 0);
93 gh_str02scm (const char *s
)
95 return scm_makfrom0str (s
);
97 /* Copy LEN characters at SRC into the *existing* Scheme string DST,
98 starting at START. START is an index into DST; zero means the
99 beginning of the string.
101 If START + LEN is off the end of DST, signal an out-of-range
104 gh_set_substr (char *src
, SCM dst
, int start
, int len
)
107 unsigned long dst_len
;
108 unsigned long effective_length
;
110 SCM_ASSERT (SCM_STRINGP (dst
), dst
, SCM_ARG3
,
113 dst_ptr
= SCM_CHARS (dst
);
114 dst_len
= SCM_LENGTH (dst
);
115 SCM_ASSERT (len
>= 0 && (unsigned) len
<= dst_len
,
116 dst
, SCM_ARG4
, "gh_set_substr");
118 scm_protect_object (dst
);
119 effective_length
= ((unsigned) len
< dst_len
) ? len
: dst_len
;
120 memmove (dst_ptr
+ start
, src
, effective_length
);
121 scm_unprotect_object (dst
);
124 /* Return the symbol named SYMBOL_STR. */
126 gh_symbol2scm (const char *symbol_str
)
128 return SCM_CAR (scm_intern (symbol_str
, strlen (symbol_str
)));
132 gh_ints2scm (int *d
, int n
)
135 SCM v
= scm_make_vector(SCM_MAKINUM(n
), SCM_UNSPECIFIED
);
136 SCM
*velts
= SCM_VELTS(v
);
138 for (i
= 0; i
< n
; ++i
)
139 velts
[i
] = (d
[i
] >= SCM_MOST_NEGATIVE_FIXNUM
140 && d
[i
] <= SCM_MOST_POSITIVE_FIXNUM
142 : scm_long2big (d
[i
]));
147 gh_doubles2scm (double *d
, int n
)
150 SCM v
= scm_make_vector(SCM_MAKINUM(n
), SCM_UNSPECIFIED
);
151 SCM
*velts
= SCM_VELTS(v
);
153 for(i
= 0; i
< n
; i
++)
154 velts
[i
] = scm_makdbl(d
[i
], 0.0);
159 /* Do not use this function for building normal Scheme vectors, unless
160 you arrange for the elements to be protected from GC while you
161 initialize the vector. */
163 makvect (char* m
, int len
, int type
)
168 SCM_SETCHARS (ans
, m
);
169 SCM_SETLENGTH (ans
, len
, type
);
175 gh_chars2byvect (char *d
, int n
)
177 char *m
= scm_must_malloc (n
* sizeof (char), "vector");
178 memcpy (m
, d
, n
* sizeof (char));
179 return makvect (m
, n
, scm_tc7_byvect
);
183 gh_shorts2svect (short *d
, int n
)
185 char *m
= scm_must_malloc (n
* sizeof (short), "vector");
186 memcpy (m
, d
, n
* sizeof (short));
187 return makvect (m
, n
, scm_tc7_svect
);
191 gh_longs2ivect (long *d
, int n
)
193 char *m
= scm_must_malloc (n
* sizeof (long), "vector");
194 memcpy (m
, d
, n
* sizeof (long));
195 return makvect (m
, n
, scm_tc7_ivect
);
199 gh_ulongs2uvect (unsigned long *d
, int n
)
201 char *m
= scm_must_malloc (n
* sizeof (unsigned long), "vector");
202 memcpy (m
, d
, n
* sizeof (unsigned long));
203 return makvect (m
, n
, scm_tc7_uvect
);
207 gh_floats2fvect (float *d
, int n
)
209 char *m
= scm_must_malloc (n
* sizeof (float), "vector");
210 memcpy (m
, d
, n
* sizeof (float));
211 return makvect (m
, n
, scm_tc7_fvect
);
215 gh_doubles2dvect (double *d
, int n
)
217 char *m
= scm_must_malloc (n
* sizeof (double), "vector");
218 memcpy (m
, d
, n
* sizeof (double));
219 return makvect (m
, n
, scm_tc7_dvect
);
223 /* data conversion scheme->C */
225 gh_scm2bool (SCM obj
)
227 return (SCM_FALSEP (obj
)) ? 0 : 1;
230 gh_scm2ulong (SCM obj
)
232 return scm_num2ulong (obj
, (char *) SCM_ARG1
, "gh_scm2ulong");
235 gh_scm2long (SCM obj
)
237 return scm_num2long (obj
, (char *) SCM_ARG1
, "gh_scm2long");
242 /* NOTE: possible loss of precision here */
243 return (int) scm_num2long (obj
, (char *) SCM_ARG1
, "gh_scm2int");
246 gh_scm2double (SCM obj
)
248 return scm_num2dbl (obj
, "gh_scm2double");
251 gh_scm2char (SCM obj
)
253 return SCM_CHAR (obj
);
256 /* Convert a vector, weak vector, string, substring or uniform vector
257 into an array of chars. If result array in arg 2 is NULL, malloc a
260 gh_scm2chars (SCM obj
, char *m
)
266 scm_wrong_type_arg (0, 0, obj
);
267 switch (SCM_TYP7 (obj
))
271 n
= SCM_LENGTH (obj
);
272 for (i
= 0; i
< n
; ++i
)
274 val
= SCM_VELTS (obj
)[i
];
278 if (v
< -128 || v
> 255)
279 scm_out_of_range (0, obj
);
282 scm_wrong_type_arg (0, 0, obj
);
285 m
= (char *) malloc (n
* sizeof (char));
286 for (i
= 0; i
< n
; ++i
)
287 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
293 case scm_tc7_substring
:
294 n
= SCM_LENGTH (obj
);
296 m
= (char *) malloc (n
* sizeof (char));
297 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (char));
300 scm_wrong_type_arg (0, 0, obj
);
305 /* Convert a vector, weak vector or uniform vector into an array of
306 shorts. If result array in arg 2 is NULL, malloc a new one. */
308 gh_scm2shorts (SCM obj
, short *m
)
314 scm_wrong_type_arg (0, 0, obj
);
315 switch (SCM_TYP7 (obj
))
319 n
= SCM_LENGTH (obj
);
320 for (i
= 0; i
< n
; ++i
)
322 val
= SCM_VELTS (obj
)[i
];
326 if (v
< -32768 || v
> 65535)
327 scm_out_of_range (0, obj
);
330 scm_wrong_type_arg (0, 0, obj
);
333 m
= (short *) malloc (n
* sizeof (short));
334 for (i
= 0; i
< n
; ++i
)
335 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
339 n
= SCM_LENGTH (obj
);
341 m
= (short *) malloc (n
* sizeof (short));
342 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (short));
346 scm_wrong_type_arg (0, 0, obj
);
351 /* Convert a vector, weak vector or uniform vector into an array of
352 longs. If result array in arg 2 is NULL, malloc a new one. */
354 gh_scm2longs (SCM obj
, long *m
)
359 scm_wrong_type_arg (0, 0, obj
);
360 switch (SCM_TYP7 (obj
))
364 n
= SCM_LENGTH (obj
);
365 for (i
= 0; i
< n
; ++i
)
367 val
= SCM_VELTS (obj
)[i
];
368 if (!SCM_INUMP (val
) && !SCM_BIGP (val
))
369 scm_wrong_type_arg (0, 0, obj
);
372 m
= (long *) malloc (n
* sizeof (long));
373 for (i
= 0; i
< n
; ++i
)
375 val
= SCM_VELTS (obj
)[i
];
376 m
[i
] = SCM_INUMP (val
) ? SCM_INUM (val
) : scm_num2long (val
, 0, 0);
382 n
= SCM_LENGTH (obj
);
384 m
= (long *) malloc (n
* sizeof (long));
385 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (long));
389 scm_wrong_type_arg (0, 0, obj
);
394 /* Convert a vector, weak vector or uniform vector into an array of
395 floats. If result array in arg 2 is NULL, malloc a new one. */
397 gh_scm2floats (SCM obj
, float *m
)
402 scm_wrong_type_arg (0, 0, obj
);
403 switch (SCM_TYP7 (obj
))
407 n
= SCM_LENGTH (obj
);
408 for (i
= 0; i
< n
; ++i
)
410 val
= SCM_VELTS (obj
)[i
];
412 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
413 scm_wrong_type_arg (0, 0, val
);
416 m
= (float *) malloc (n
* sizeof (float));
417 for (i
= 0; i
< n
; ++i
)
419 val
= SCM_VELTS (obj
)[i
];
421 m
[i
] = SCM_INUM (val
);
422 else if (SCM_BIGP (val
))
423 m
[i
] = scm_num2long (val
, 0, 0);
425 m
[i
] = SCM_REALPART (val
);
430 n
= SCM_LENGTH (obj
);
432 m
= (float *) malloc (n
* sizeof (float));
433 memcpy (m
, (float *) SCM_VELTS (obj
), n
* sizeof (float));
437 n
= SCM_LENGTH (obj
);
439 m
= (float*) malloc (n
* sizeof (float));
440 for (i
= 0; i
< n
; ++i
)
441 m
[i
] = ((double *) SCM_VELTS (obj
))[i
];
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. */
453 gh_scm2doubles (SCM obj
, double *m
)
458 scm_wrong_type_arg (0, 0, obj
);
459 switch (SCM_TYP7 (obj
))
463 n
= SCM_LENGTH (obj
);
464 for (i
= 0; i
< n
; ++i
)
466 val
= SCM_VELTS (obj
)[i
];
468 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
469 scm_wrong_type_arg (0, 0, val
);
472 m
= (double *) malloc (n
* sizeof (double));
473 for (i
= 0; i
< n
; ++i
)
475 val
= SCM_VELTS (obj
)[i
];
477 m
[i
] = SCM_INUM (val
);
478 else if (SCM_BIGP (val
))
479 m
[i
] = scm_num2long (val
, 0, 0);
481 m
[i
] = SCM_REALPART (val
);
486 n
= SCM_LENGTH (obj
);
488 m
= (double *) malloc (n
* sizeof (double));
489 for (i
= 0; i
< n
; ++i
)
490 m
[i
] = ((float *) SCM_VELTS (obj
))[i
];
494 n
= SCM_LENGTH (obj
);
496 m
= (double*) malloc (n
* sizeof (double));
497 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (double));
501 scm_wrong_type_arg (0, 0, obj
);
506 /* string conversions between C and Scheme */
508 /* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
509 new copy of its contents, followed by a null byte. If lenp is
510 non-null, set *lenp to the string's length.
512 This function uses malloc to obtain storage for the copy; the
513 caller is responsible for freeing it.
515 Note that Scheme strings may contain arbitrary data, including null
516 characters. This means that null termination is not a reliable way
517 to determine the length of the returned value. However, the
518 function always copies the complete contents of STR, and sets
519 *LEN_P to the true length of the string (when LEN_P is non-null). */
521 gh_scm2newstr (SCM str
, int *lenp
)
526 SCM_ASSERT (SCM_ROSTRINGP (str
), str
, SCM_ARG3
,
529 /* protect str from GC while we copy off its data */
530 scm_protect_object (str
);
532 len
= SCM_LENGTH (str
);
534 ret_str
= (char *) scm_must_malloc ((len
+ 1) * sizeof (char),
536 /* so we copy tmp_str to ret_str, which is what we will allocate */
537 memcpy (ret_str
, SCM_ROCHARS (str
), len
); /* test ROCHARS here -twp */
538 /* now make sure we null-terminate it */
541 scm_unprotect_object (str
);
552 /* Copy LEN characters at START from the Scheme string SRC to memory
553 at DST. START is an index into SRC; zero means the beginning of
554 the string. DST has already been allocated by the caller.
556 If START + LEN is off the end of SRC, silently truncate the source
557 region to fit the string. If truncation occurs, the corresponding
558 area of DST is left unchanged. */
560 gh_get_substr (SCM src
, char *dst
, int start
, int len
)
562 int src_len
, effective_length
;
563 SCM_ASSERT (SCM_ROSTRINGP (src
), src
, SCM_ARG3
,
566 scm_protect_object (src
);
567 src_len
= SCM_LENGTH (src
);
568 effective_length
= (len
< src_len
) ? len
: src_len
;
569 memcpy (dst
+ start
, SCM_ROCHARS (src
), effective_length
* sizeof (char));
570 /* FIXME: must signal an error if len > src_len */
571 scm_unprotect_object (src
);
575 /* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
576 pointer to a string with the symbol characters "identifier",
577 followed by a null byte. If lenp is non-null, set *lenp to the
580 This function uses malloc to obtain storage for the copy; the
581 caller is responsible for freeing it. */
583 gh_symbol2newstr (SCM sym
, int *lenp
)
588 SCM_ASSERT (SCM_SYMBOLP (sym
), sym
, SCM_ARG3
,
591 /* protect str from GC while we copy off its data */
592 scm_protect_object (sym
);
594 len
= SCM_LENGTH (sym
);
596 ret_str
= (char *) scm_must_malloc ((len
+ 1) * sizeof (char),
598 /* so we copy tmp_str to ret_str, which is what we will allocate */
599 memcpy (ret_str
, SCM_CHARS (sym
), len
);
600 /* now make sure we null-terminate it */
603 scm_unprotect_object (sym
);
614 /* create a new vector of the given length, all initialized to the
617 gh_make_vector (SCM len
, SCM fill
)
619 return scm_make_vector (len
, fill
);
622 /* set the given element of the given vector to the given value */
624 gh_vector_set_x (SCM vec
, SCM pos
, SCM val
)
626 return scm_vector_set_x (vec
, pos
, val
);
629 /* retrieve the given element of the given vector */
631 gh_vector_ref (SCM vec
, SCM pos
)
633 return scm_vector_ref (vec
, pos
);
636 /* returns the length of the given vector */
638 gh_vector_length (SCM v
)
640 return gh_scm2ulong (scm_vector_length (v
));
644 /* uniform vector support */
646 /* returns the length as a C unsigned long integer */
648 gh_uniform_vector_length (SCM v
)
650 return gh_scm2ulong (scm_uniform_vector_length (v
));
653 /* gets the given element from a uniform vector; ilist is a list (or
654 possibly a single integer) of indices, and its length is the
655 dimension of the uniform vector */
657 gh_uniform_vector_ref (SCM v
, SCM ilist
)
659 return scm_uniform_vector_ref (v
, ilist
);
662 /* sets an individual element in a uniform vector */
664 /* gh_list_to_uniform_array ( */
667 /* Data lookups between C and Scheme
669 Look up a symbol with a given name, and return the object to which
670 it is bound. gh_lookup examines the Guile top level, and
671 gh_module_lookup checks the module namespace specified by the
674 The return value is the Scheme object to which SNAME is bound, or
675 SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME:
676 should this be SCM_UNSPECIFIED? Can a symbol ever legitimately be
677 bound to SCM_UNDEFINED or SCM_UNSPECIFIED? What is the difference?
681 gh_lookup (char *sname
)
683 return gh_module_lookup (SCM_BOOL_F
, sname
);
687 gh_module_lookup (SCM vec
, char *sname
)
689 SCM sym
= gh_symbol2scm (sname
);
690 if (SCM_TRUE_P (scm_symbol_bound_p (vec
, sym
)))
691 return scm_symbol_binding (vec
, sym
);
693 return SCM_UNDEFINED
;