1 /* Copyright (C) 1995,1996,1997,1998, 1999 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 */
48 /* data conversion C->scheme */
50 gh_int2scmb (int x
) /* this is being phased out */
62 return scm_long2num ((long) x
);
65 gh_ulong2scm (unsigned long x
)
67 return scm_ulong2num (x
);
72 return scm_long2num (x
);
75 gh_double2scm (double x
)
77 return scm_makdbl (x
, 0.0);
82 return SCM_MAKICHR (c
);
85 gh_str2scm (char *s
, int len
)
87 return scm_makfromstr (s
, len
, 0);
90 gh_str02scm (const char *s
)
92 return scm_makfrom0str (s
);
94 /* Copy LEN characters at SRC into the *existing* Scheme string DST,
95 starting at START. START is an index into DST; zero means the
96 beginning of the string.
98 If START + LEN is off the end of DST, signal an out-of-range
101 gh_set_substr (char *src
, SCM dst
, int start
, int len
)
104 unsigned long dst_len
;
105 unsigned long effective_length
;
107 SCM_ASSERT (SCM_STRINGP (dst
), dst
, SCM_ARG3
,
110 dst_ptr
= SCM_CHARS (dst
);
111 dst_len
= SCM_LENGTH (dst
);
112 SCM_ASSERT (len
>= 0 && (unsigned) len
<= dst_len
,
113 dst
, SCM_ARG4
, "gh_set_substr");
115 scm_protect_object (dst
);
116 effective_length
= ((unsigned) len
< dst_len
) ? len
: dst_len
;
117 memmove (dst_ptr
+ start
, src
, effective_length
);
118 scm_unprotect_object (dst
);
121 /* Return the symbol named SYMBOL_STR. */
123 gh_symbol2scm (const char *symbol_str
)
125 return SCM_CAR (scm_intern (symbol_str
, strlen (symbol_str
)));
129 gh_ints2scm (int *d
, int n
)
132 SCM v
= scm_make_vector(SCM_MAKINUM(n
), SCM_UNSPECIFIED
);
133 SCM
*velts
= SCM_VELTS(v
);
135 for (i
= 0; i
< n
; ++i
)
136 velts
[i
] = (d
[i
] >= SCM_MOST_NEGATIVE_FIXNUM
137 && d
[i
] <= SCM_MOST_POSITIVE_FIXNUM
139 : scm_long2big (d
[i
]));
144 gh_doubles2scm (double *d
, int n
)
147 SCM v
= scm_make_vector(SCM_MAKINUM(n
), SCM_UNSPECIFIED
);
148 SCM
*velts
= SCM_VELTS(v
);
150 for(i
= 0; i
< n
; i
++)
151 velts
[i
] = scm_makdbl(d
[i
], 0.0);
156 /* Do not use this function for building normal Scheme vectors, unless
157 you arrange for the elements to be protected from GC while you
158 initialize the vector. */
160 makvect (char* m
, int len
, int type
)
165 SCM_SETCHARS (ans
, m
);
166 SCM_SETLENGTH (ans
, len
, type
);
172 gh_chars2byvect (char *d
, int n
)
174 char *m
= scm_must_malloc (n
* sizeof (char), "vector");
175 memcpy (m
, d
, n
* sizeof (char));
176 return makvect (m
, n
, scm_tc7_byvect
);
180 gh_shorts2svect (short *d
, int n
)
182 char *m
= scm_must_malloc (n
* sizeof (short), "vector");
183 memcpy (m
, d
, n
* sizeof (short));
184 return makvect (m
, n
, scm_tc7_svect
);
188 gh_longs2ivect (long *d
, int n
)
190 char *m
= scm_must_malloc (n
* sizeof (long), "vector");
191 memcpy (m
, d
, n
* sizeof (long));
192 return makvect (m
, n
, scm_tc7_ivect
);
196 gh_ulongs2uvect (unsigned long *d
, int n
)
198 char *m
= scm_must_malloc (n
* sizeof (unsigned long), "vector");
199 memcpy (m
, d
, n
* sizeof (unsigned long));
200 return makvect (m
, n
, scm_tc7_uvect
);
206 gh_floats2fvect (float *d
, int n
)
208 char *m
= scm_must_malloc (n
* sizeof (float), "vector");
209 memcpy (m
, d
, n
* sizeof (float));
210 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
);
224 /* data conversion scheme->C */
226 gh_scm2bool (SCM obj
)
228 return ((obj
) == SCM_BOOL_F
) ? 0 : 1;
231 gh_scm2ulong (SCM obj
)
233 return scm_num2ulong (obj
, (char *) SCM_ARG1
, "gh_scm2ulong");
236 gh_scm2long (SCM obj
)
238 return scm_num2long (obj
, (char *) SCM_ARG1
, "gh_scm2long");
243 /* NOTE: possible loss of precision here */
244 return (int) scm_num2long (obj
, (char *) SCM_ARG1
, "gh_scm2int");
247 gh_scm2double (SCM obj
)
249 return scm_num2dbl (obj
, "gh_scm2double");
252 gh_scm2char (SCM obj
)
254 return SCM_ICHR (obj
);
257 /* Convert a vector, weak vector, string, substring or uniform vector
258 into an array of chars. If result array in arg 2 is NULL, malloc a
261 gh_scm2chars (SCM obj
, char *m
)
267 scm_wrong_type_arg (0, 0, obj
);
268 switch (SCM_TYP7 (obj
))
272 n
= SCM_LENGTH (obj
);
273 for (i
= 0; i
< n
; ++i
)
275 val
= SCM_VELTS (obj
)[i
];
279 if (v
< -128 || v
> 255)
280 scm_out_of_range (0, obj
);
283 scm_wrong_type_arg (0, 0, obj
);
286 m
= (char *) malloc (n
* sizeof (char));
287 for (i
= 0; i
< n
; ++i
)
288 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
294 case scm_tc7_substring
:
295 n
= SCM_LENGTH (obj
);
297 m
= (char *) malloc (n
* sizeof (char));
298 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (char));
301 scm_wrong_type_arg (0, 0, obj
);
306 /* Convert a vector, weak vector or uniform vector into an array of
307 shorts. If result array in arg 2 is NULL, malloc a new one. */
309 gh_scm2shorts (SCM obj
, short *m
)
315 scm_wrong_type_arg (0, 0, obj
);
316 switch (SCM_TYP7 (obj
))
320 n
= SCM_LENGTH (obj
);
321 for (i
= 0; i
< n
; ++i
)
323 val
= SCM_VELTS (obj
)[i
];
327 if (v
< -32768 || v
> 65535)
328 scm_out_of_range (0, obj
);
331 scm_wrong_type_arg (0, 0, obj
);
334 m
= (short *) malloc (n
* sizeof (short));
335 for (i
= 0; i
< n
; ++i
)
336 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
340 n
= SCM_LENGTH (obj
);
342 m
= (short *) malloc (n
* sizeof (short));
343 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (short));
347 scm_wrong_type_arg (0, 0, obj
);
352 /* Convert a vector, weak vector or uniform vector into an array of
353 longs. If result array in arg 2 is NULL, malloc a new one. */
355 gh_scm2longs (SCM obj
, long *m
)
360 scm_wrong_type_arg (0, 0, obj
);
361 switch (SCM_TYP7 (obj
))
365 n
= SCM_LENGTH (obj
);
366 for (i
= 0; i
< n
; ++i
)
368 val
= SCM_VELTS (obj
)[i
];
369 if (!SCM_INUMP (val
) && !SCM_BIGP (val
))
370 scm_wrong_type_arg (0, 0, obj
);
373 m
= (long *) malloc (n
* sizeof (long));
374 for (i
= 0; i
< n
; ++i
)
376 val
= SCM_VELTS (obj
)[i
];
377 m
[i
] = SCM_INUMP (val
) ? SCM_INUM (val
) : scm_num2long (val
, 0, 0);
383 n
= SCM_LENGTH (obj
);
385 m
= (long *) malloc (n
* sizeof (long));
386 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (long));
390 scm_wrong_type_arg (0, 0, obj
);
395 /* Convert a vector, weak vector or uniform vector into an array of
396 floats. If result array in arg 2 is NULL, malloc a new one. */
398 gh_scm2floats (SCM obj
, float *m
)
403 scm_wrong_type_arg (0, 0, obj
);
404 switch (SCM_TYP7 (obj
))
408 n
= SCM_LENGTH (obj
);
409 for (i
= 0; i
< n
; ++i
)
411 val
= SCM_VELTS (obj
)[i
];
413 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
414 scm_wrong_type_arg (0, 0, val
);
417 m
= (float *) malloc (n
* sizeof (float));
418 for (i
= 0; i
< n
; ++i
)
420 val
= SCM_VELTS (obj
)[i
];
422 m
[i
] = SCM_INUM (val
);
423 else if (SCM_BIGP (val
))
424 m
[i
] = scm_num2long (val
, 0, 0);
426 m
[i
] = SCM_REALPART (val
);
433 n
= SCM_LENGTH (obj
);
435 m
= (float *) malloc (n
* sizeof (float));
436 memcpy (m
, (float *) SCM_VELTS (obj
), n
* sizeof (float));
440 n
= SCM_LENGTH (obj
);
442 m
= (float*) malloc (n
* sizeof (float));
443 for (i
= 0; i
< n
; ++i
)
444 m
[i
] = ((double *) SCM_VELTS (obj
))[i
];
449 scm_wrong_type_arg (0, 0, obj
);
454 /* Convert a vector, weak vector or uniform vector into an array of
455 doubles. If result array in arg 2 is NULL, malloc a new one. */
457 gh_scm2doubles (SCM obj
, double *m
)
462 scm_wrong_type_arg (0, 0, obj
);
463 switch (SCM_TYP7 (obj
))
467 n
= SCM_LENGTH (obj
);
468 for (i
= 0; i
< n
; ++i
)
470 val
= SCM_VELTS (obj
)[i
];
472 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
473 scm_wrong_type_arg (0, 0, val
);
476 m
= (double *) malloc (n
* sizeof (double));
477 for (i
= 0; i
< n
; ++i
)
479 val
= SCM_VELTS (obj
)[i
];
481 m
[i
] = SCM_INUM (val
);
482 else if (SCM_BIGP (val
))
483 m
[i
] = scm_num2long (val
, 0, 0);
485 m
[i
] = SCM_REALPART (val
);
492 n
= SCM_LENGTH (obj
);
494 m
= (double *) malloc (n
* sizeof (double));
495 for (i
= 0; i
< n
; ++i
)
496 m
[i
] = ((float *) SCM_VELTS (obj
))[i
];
500 n
= SCM_LENGTH (obj
);
502 m
= (double*) malloc (n
* sizeof (double));
503 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (double));
508 scm_wrong_type_arg (0, 0, obj
);
513 /* string conversions between C and Scheme */
515 /* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
516 new copy of its contents, followed by a null byte. If lenp is
517 non-null, set *lenp to the string's length.
519 This function uses malloc to obtain storage for the copy; the
520 caller is responsible for freeing it.
522 Note that Scheme strings may contain arbitrary data, including null
523 characters. This means that null termination is not a reliable way
524 to determine the length of the returned value. However, the
525 function always copies the complete contents of STR, and sets
526 *LEN_P to the true length of the string (when LEN_P is non-null). */
528 gh_scm2newstr (SCM str
, int *lenp
)
533 SCM_ASSERT (SCM_ROSTRINGP (str
), str
, SCM_ARG3
,
536 /* protect str from GC while we copy off its data */
537 scm_protect_object (str
);
539 len
= SCM_LENGTH (str
);
541 ret_str
= (char *) scm_must_malloc ((len
+ 1) * sizeof (char),
543 /* so we copy tmp_str to ret_str, which is what we will allocate */
544 memcpy (ret_str
, SCM_ROCHARS (str
), len
); /* test ROCHARS here -twp */
545 /* now make sure we null-terminate it */
548 scm_unprotect_object (str
);
559 /* Copy LEN characters at START from the Scheme string SRC to memory
560 at DST. START is an index into SRC; zero means the beginning of
561 the string. DST has already been allocated by the caller.
563 If START + LEN is off the end of SRC, silently truncate the source
564 region to fit the string. If truncation occurs, the corresponding
565 area of DST is left unchanged. */
567 gh_get_substr (SCM src
, char *dst
, int start
, int len
)
569 int src_len
, effective_length
;
570 SCM_ASSERT (SCM_ROSTRINGP (src
), src
, SCM_ARG3
,
573 scm_protect_object (src
);
574 src_len
= SCM_LENGTH (src
);
575 effective_length
= (len
< src_len
) ? len
: src_len
;
576 memcpy (dst
+ start
, SCM_ROCHARS (src
), effective_length
* sizeof (char));
577 /* FIXME: must signal an error if len > src_len */
578 scm_unprotect_object (src
);
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
,
598 /* protect str from GC while we copy off its data */
599 scm_protect_object (sym
);
601 len
= SCM_LENGTH (sym
);
603 ret_str
= (char *) scm_must_malloc ((len
+ 1) * sizeof (char),
605 /* so we copy tmp_str to ret_str, which is what we will allocate */
606 memcpy (ret_str
, SCM_CHARS (sym
), len
);
607 /* now make sure we null-terminate it */
610 scm_unprotect_object (sym
);
621 /* create a new vector of the given length, all initialized to the
624 gh_make_vector (SCM len
, SCM fill
)
626 return scm_make_vector (len
, fill
);
629 /* set the given element of the given vector to the given value */
631 gh_vector_set_x (SCM vec
, SCM pos
, SCM val
)
633 return scm_vector_set_x (vec
, pos
, val
);
636 /* retrieve the given element of the given vector */
638 gh_vector_ref (SCM vec
, SCM pos
)
640 return scm_vector_ref (vec
, pos
);
643 /* returns the length of the given vector */
645 gh_vector_length (SCM v
)
647 return gh_scm2ulong (scm_vector_length (v
));
651 /* uniform vector support */
653 /* returns the length as a C unsigned long integer */
655 gh_uniform_vector_length (SCM v
)
657 return gh_scm2ulong (scm_uniform_vector_length (v
));
660 /* gets the given element from a uniform vector; ilist is a list (or
661 possibly a single integer) of indices, and its length is the
662 dimension of the uniform vector */
664 gh_uniform_vector_ref (SCM v
, SCM ilist
)
666 return scm_uniform_vector_ref (v
, ilist
);
669 /* sets an individual element in a uniform vector */
671 /* gh_list_to_uniform_array ( */
674 /* Data lookups between C and Scheme
676 Look up a symbol with a given name, and return the object to which
677 it is bound. gh_lookup examines the Guile top level, and
678 gh_module_lookup checks the module namespace specified by the
681 The return value is the Scheme object to which SNAME is bound, or
682 SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME:
683 should this be SCM_UNSPECIFIED? Can a symbol ever legitimately be
684 bound to SCM_UNDEFINED or SCM_UNSPECIFIED? What is the difference?
688 gh_lookup (char *sname
)
690 return gh_module_lookup (SCM_BOOL_F
, sname
);
694 gh_module_lookup (SCM vec
, char *sname
)
696 SCM sym
= gh_symbol2scm (sname
);
697 if ((scm_symbol_bound_p (vec
, sym
)) == SCM_BOOL_T
)
698 return scm_symbol_binding (vec
, sym
);
700 return SCM_UNDEFINED
;