1 /* Copyright (C) 1995,1996,1997,1998,1999,2000,2001 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 */
44 #include "libguile/gh.h"
49 /* data conversion C->scheme */
59 return scm_long2num ((long) x
);
62 gh_ulong2scm (unsigned long x
)
64 return scm_ulong2num (x
);
69 return scm_long2num (x
);
72 gh_double2scm (double x
)
74 return scm_make_real (x
);
79 return SCM_MAKE_CHAR (c
);
82 gh_str2scm (const char *s
, size_t len
)
84 return scm_makfromstr (s
, len
, 0);
87 gh_str02scm (const char *s
)
89 return scm_makfrom0str (s
);
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.
95 If START + LEN is off the end of DST, signal an out-of-range
98 gh_set_substr (char *src
, SCM dst
, long start
, size_t len
)
102 size_t effective_length
;
104 SCM_ASSERT (SCM_STRINGP (dst
), dst
, SCM_ARG3
, "gh_set_substr");
106 dst_ptr
= SCM_STRING_CHARS (dst
);
107 dst_len
= SCM_STRING_LENGTH (dst
);
108 SCM_ASSERT (len
>= 0 && len
<= dst_len
,
109 dst
, SCM_ARG4
, "gh_set_substr");
111 effective_length
= (len
< dst_len
) ? len
: dst_len
;
112 memmove (dst_ptr
+ start
, src
, effective_length
);
113 scm_remember_upto_here_1 (dst
);
116 /* Return the symbol named SYMBOL_STR. */
118 gh_symbol2scm (const char *symbol_str
)
120 return scm_str2symbol(symbol_str
);
124 gh_ints2scm (const int *d
, long n
)
127 SCM v
= scm_c_make_vector (n
, SCM_UNSPECIFIED
);
128 SCM
*velts
= SCM_VELTS(v
);
130 for (i
= 0; i
< n
; ++i
)
131 velts
[i
] = (SCM_FIXABLE (d
[i
]) ? SCM_MAKINUM (d
[i
]) : scm_i_long2big (d
[i
]));
137 gh_doubles2scm (const double *d
, long n
)
140 SCM v
= scm_c_make_vector (n
, SCM_UNSPECIFIED
);
141 SCM
*velts
= SCM_VELTS(v
);
143 for(i
= 0; i
< n
; i
++)
144 velts
[i
] = scm_make_real (d
[i
]);
149 /* Do not use this function for building normal Scheme vectors, unless
150 you arrange for the elements to be protected from GC while you
151 initialize the vector. */
153 makvect (char *m
, size_t len
, int type
)
158 SCM_SET_UVECTOR_BASE (ans
, m
);
159 SCM_SET_UVECTOR_LENGTH (ans
, len
, type
);
165 gh_chars2byvect (const char *d
, long n
)
167 char *m
= scm_must_malloc (n
* sizeof (char), "vector");
168 memcpy (m
, d
, n
* sizeof (char));
169 return makvect (m
, n
, scm_tc7_byvect
);
173 gh_shorts2svect (const short *d
, long n
)
175 char *m
= scm_must_malloc (n
* sizeof (short), "vector");
176 memcpy (m
, d
, n
* sizeof (short));
177 return makvect (m
, n
, scm_tc7_svect
);
181 gh_longs2ivect (const long *d
, long n
)
183 char *m
= scm_must_malloc (n
* sizeof (long), "vector");
184 memcpy (m
, d
, n
* sizeof (long));
185 return makvect (m
, n
, scm_tc7_ivect
);
189 gh_ulongs2uvect (const unsigned long *d
, long n
)
191 char *m
= scm_must_malloc (n
* sizeof (unsigned long), "vector");
192 memcpy (m
, d
, n
* sizeof (unsigned long));
193 return makvect (m
, n
, scm_tc7_uvect
);
197 gh_floats2fvect (const float *d
, long n
)
199 char *m
= scm_must_malloc (n
* sizeof (float), "vector");
200 memcpy (m
, d
, n
* sizeof (float));
201 return makvect (m
, n
, scm_tc7_fvect
);
205 gh_doubles2dvect (const double *d
, long n
)
207 char *m
= scm_must_malloc (n
* sizeof (double), "vector");
208 memcpy (m
, d
, n
* sizeof (double));
209 return makvect (m
, n
, scm_tc7_dvect
);
213 /* data conversion scheme->C */
215 gh_scm2bool (SCM obj
)
217 return (SCM_FALSEP (obj
)) ? 0 : 1;
220 gh_scm2ulong (SCM obj
)
222 return scm_num2ulong (obj
, SCM_ARG1
, "gh_scm2ulong");
225 gh_scm2long (SCM obj
)
227 return scm_num2long (obj
, SCM_ARG1
, "gh_scm2long");
232 return (int) scm_num2int (obj
, SCM_ARG1
, "gh_scm2int");
235 gh_scm2double (SCM obj
)
237 return scm_num2dbl (obj
, "gh_scm2double");
240 gh_scm2char (SCM obj
)
241 #define FUNC_NAME "gh_scm2char"
243 SCM_VALIDATE_CHAR (SCM_ARG1
, obj
);
244 return SCM_CHAR (obj
);
248 /* Convert a vector, weak vector, string, substring or uniform vector
249 into an array of chars. If result array in arg 2 is NULL, malloc a
250 new one. If out of memory, return NULL. */
252 gh_scm2chars (SCM obj
, char *m
)
258 scm_wrong_type_arg (0, 0, obj
);
259 switch (SCM_TYP7 (obj
))
263 n
= SCM_VECTOR_LENGTH (obj
);
264 for (i
= 0; i
< n
; ++i
)
266 val
= SCM_VELTS (obj
)[i
];
270 if (v
< -128 || v
> 255)
271 scm_out_of_range (0, obj
);
274 scm_wrong_type_arg (0, 0, obj
);
277 m
= (char *) malloc (n
* sizeof (char));
280 for (i
= 0; i
< n
; ++i
)
281 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
285 n
= SCM_UVECTOR_LENGTH (obj
);
287 m
= (char *) malloc (n
* sizeof (char));
290 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (char));
294 case scm_tc7_substring
:
295 n
= SCM_STRING_LENGTH (obj
);
297 m
= (char *) malloc (n
* sizeof (char));
300 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (char));
303 scm_wrong_type_arg (0, 0, obj
);
308 /* Convert a vector, weak vector or uniform vector into an array of
309 shorts. If result array in arg 2 is NULL, malloc a new one. If
310 out of memory, return NULL. */
312 gh_scm2shorts (SCM obj
, short *m
)
318 scm_wrong_type_arg (0, 0, obj
);
319 switch (SCM_TYP7 (obj
))
323 n
= SCM_VECTOR_LENGTH (obj
);
324 for (i
= 0; i
< n
; ++i
)
326 val
= SCM_VELTS (obj
)[i
];
330 if (v
< -32768 || v
> 65535)
331 scm_out_of_range (0, obj
);
334 scm_wrong_type_arg (0, 0, obj
);
337 m
= (short *) malloc (n
* sizeof (short));
340 for (i
= 0; i
< n
; ++i
)
341 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
345 n
= SCM_UVECTOR_LENGTH (obj
);
347 m
= (short *) malloc (n
* sizeof (short));
350 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (short));
354 scm_wrong_type_arg (0, 0, obj
);
359 /* Convert a vector, weak vector or uniform vector into an array of
360 longs. If result array in arg 2 is NULL, malloc a new one. If out
361 of memory, return NULL. */
363 gh_scm2longs (SCM obj
, long *m
)
368 scm_wrong_type_arg (0, 0, obj
);
369 switch (SCM_TYP7 (obj
))
373 n
= SCM_VECTOR_LENGTH (obj
);
374 for (i
= 0; i
< n
; ++i
)
376 val
= SCM_VELTS (obj
)[i
];
377 if (!SCM_INUMP (val
) && !SCM_BIGP (val
))
378 scm_wrong_type_arg (0, 0, obj
);
381 m
= (long *) malloc (n
* sizeof (long));
384 for (i
= 0; i
< n
; ++i
)
386 val
= SCM_VELTS (obj
)[i
];
387 m
[i
] = SCM_INUMP (val
)
389 : scm_num2long (val
, 0, NULL
);
395 n
= SCM_UVECTOR_LENGTH (obj
);
397 m
= (long *) malloc (n
* sizeof (long));
400 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (long));
404 scm_wrong_type_arg (0, 0, obj
);
409 /* Convert a vector, weak vector or uniform vector into an array of
410 floats. If result array in arg 2 is NULL, malloc a new one. If
411 out of memory, return NULL. */
413 gh_scm2floats (SCM obj
, float *m
)
418 scm_wrong_type_arg (0, 0, obj
);
419 switch (SCM_TYP7 (obj
))
423 n
= SCM_VECTOR_LENGTH (obj
);
424 for (i
= 0; i
< n
; ++i
)
426 val
= SCM_VELTS (obj
)[i
];
428 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
429 scm_wrong_type_arg (0, 0, val
);
432 m
= (float *) malloc (n
* sizeof (float));
435 for (i
= 0; i
< n
; ++i
)
437 val
= SCM_VELTS (obj
)[i
];
439 m
[i
] = SCM_INUM (val
);
440 else if (SCM_BIGP (val
))
441 m
[i
] = scm_num2long (val
, 0, NULL
);
443 m
[i
] = SCM_REAL_VALUE (val
);
448 n
= SCM_UVECTOR_LENGTH (obj
);
450 m
= (float *) malloc (n
* sizeof (float));
453 memcpy (m
, (float *) SCM_VELTS (obj
), n
* sizeof (float));
457 n
= SCM_UVECTOR_LENGTH (obj
);
459 m
= (float*) malloc (n
* sizeof (float));
462 for (i
= 0; i
< n
; ++i
)
463 m
[i
] = ((double *) SCM_VELTS (obj
))[i
];
467 scm_wrong_type_arg (0, 0, obj
);
472 /* Convert a vector, weak vector or uniform vector into an array of
473 doubles. If result array in arg 2 is NULL, malloc a new one. If
474 out of memory, return NULL. */
476 gh_scm2doubles (SCM obj
, double *m
)
481 scm_wrong_type_arg (0, 0, obj
);
482 switch (SCM_TYP7 (obj
))
486 n
= SCM_VECTOR_LENGTH (obj
);
487 for (i
= 0; i
< n
; ++i
)
489 val
= SCM_VELTS (obj
)[i
];
491 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
492 scm_wrong_type_arg (0, 0, val
);
495 m
= (double *) malloc (n
* sizeof (double));
498 for (i
= 0; i
< n
; ++i
)
500 val
= SCM_VELTS (obj
)[i
];
502 m
[i
] = SCM_INUM (val
);
503 else if (SCM_BIGP (val
))
504 m
[i
] = scm_num2long (val
, 0, NULL
);
506 m
[i
] = SCM_REAL_VALUE (val
);
511 n
= SCM_UVECTOR_LENGTH (obj
);
513 m
= (double *) malloc (n
* sizeof (double));
516 for (i
= 0; i
< n
; ++i
)
517 m
[i
] = ((float *) SCM_VELTS (obj
))[i
];
521 n
= SCM_UVECTOR_LENGTH (obj
);
523 m
= (double*) malloc (n
* sizeof (double));
526 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (double));
530 scm_wrong_type_arg (0, 0, obj
);
535 /* string conversions between C and Scheme */
537 /* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
538 new copy of its contents, followed by a null byte. If lenp is
539 non-null, set *lenp to the string's length.
541 This function uses malloc to obtain storage for the copy; the
542 caller is responsible for freeing it. If out of memory, NULL is
545 Note that Scheme strings may contain arbitrary data, including null
546 characters. This means that null termination is not a reliable way
547 to determine the length of the returned value. However, the
548 function always copies the complete contents of STR, and sets
549 *LEN_P to the true length of the string (when LEN_P is non-null). */
551 gh_scm2newstr (SCM str
, size_t *lenp
)
556 SCM_ASSERT (SCM_STRINGP (str
), str
, SCM_ARG3
, "gh_scm2newstr");
558 len
= SCM_STRING_LENGTH (str
);
560 ret_str
= (char *) malloc ((len
+ 1) * sizeof (char));
563 /* so we copy tmp_str to ret_str, which is what we will allocate */
564 memcpy (ret_str
, SCM_STRING_CHARS (str
), len
);
565 scm_remember_upto_here_1 (str
);
566 /* now make sure we null-terminate it */
578 /* Copy LEN characters at START from the Scheme string SRC to memory
579 at DST. START is an index into SRC; zero means the beginning of
580 the string. DST has already been allocated by the caller.
582 If START + LEN is off the end of SRC, silently truncate the source
583 region to fit the string. If truncation occurs, the corresponding
584 area of DST is left unchanged. */
586 gh_get_substr (SCM src
, char *dst
, long start
, size_t len
)
588 size_t src_len
, effective_length
;
589 SCM_ASSERT (SCM_STRINGP (src
), src
, SCM_ARG3
, "gh_get_substr");
591 src_len
= SCM_STRING_LENGTH (src
);
592 effective_length
= (len
< src_len
) ? len
: src_len
;
593 memcpy (dst
+ start
, SCM_STRING_CHARS (src
), effective_length
* sizeof (char));
594 /* FIXME: must signal an error if len > src_len */
595 scm_remember_upto_here_1 (src
);
599 /* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
600 pointer to a string with the symbol characters "identifier",
601 followed by a null byte. If lenp is non-null, set *lenp to the
604 This function uses malloc to obtain storage for the copy; the
605 caller is responsible for freeing it. If out of memory, NULL is
608 gh_symbol2newstr (SCM sym
, size_t *lenp
)
613 SCM_ASSERT (SCM_SYMBOLP (sym
), sym
, SCM_ARG3
, "gh_scm2newsymbol");
615 len
= SCM_SYMBOL_LENGTH (sym
);
617 ret_str
= (char *) malloc ((len
+ 1) * sizeof (char));
620 /* so we copy sym to ret_str, which is what we will allocate */
621 memcpy (ret_str
, SCM_SYMBOL_CHARS (sym
), len
);
622 scm_remember_upto_here_1 (sym
);
623 /* now make sure we null-terminate it */
635 /* create a new vector of the given length, all initialized to the
638 gh_make_vector (SCM len
, SCM fill
)
640 return scm_make_vector (len
, fill
);
643 /* set the given element of the given vector to the given value */
645 gh_vector_set_x (SCM vec
, SCM pos
, SCM val
)
647 return scm_vector_set_x (vec
, pos
, val
);
650 /* retrieve the given element of the given vector */
652 gh_vector_ref (SCM vec
, SCM pos
)
654 return scm_vector_ref (vec
, pos
);
657 /* returns the length of the given vector */
659 gh_vector_length (SCM v
)
661 return (unsigned long) SCM_VECTOR_LENGTH (v
);
665 /* uniform vector support */
667 /* returns the length as a C unsigned long integer */
669 gh_uniform_vector_length (SCM v
)
671 return (unsigned long) SCM_UVECTOR_LENGTH (v
);
674 /* gets the given element from a uniform vector; ilist is a list (or
675 possibly a single integer) of indices, and its length is the
676 dimension of the uniform vector */
678 gh_uniform_vector_ref (SCM v
, SCM ilist
)
680 return scm_uniform_vector_ref (v
, ilist
);
683 /* sets an individual element in a uniform vector */
685 /* gh_list_to_uniform_array ( */
688 /* Data lookups between C and Scheme
690 Look up a symbol with a given name, and return the object to which
691 it is bound. gh_lookup examines the Guile top level, and
692 gh_module_lookup checks the module namespace specified by the
695 The return value is the Scheme object to which SNAME is bound, or
696 SCM_UNDEFINED if SNAME is not bound in the given context.
700 gh_lookup (const char *sname
)
702 return gh_module_lookup (scm_current_module (), sname
);
707 gh_module_lookup (SCM module
, const char *sname
)
708 #define FUNC_NAME "gh_module_lookup"
712 SCM_VALIDATE_MODULE (SCM_ARG1
, module
);
714 sym
= gh_symbol2scm (sname
);
715 var
= scm_sym2var (sym
, scm_module_lookup_closure (module
), SCM_BOOL_F
);
716 if (var
!= SCM_BOOL_F
)
717 return SCM_VARIABLE_REF (var
);
719 return SCM_UNDEFINED
;