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
, int 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
, int start
, int len
)
101 unsigned long dst_len
;
102 unsigned long 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 && (unsigned) len
<= dst_len
,
109 dst
, SCM_ARG4
, "gh_set_substr");
111 effective_length
= ((unsigned) 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
, int 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_long2big (d
[i
]));
137 gh_doubles2scm (const double *d
, int 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
, int len
, int type
)
158 SCM_SET_UVECTOR_BASE (ans
, m
);
159 SCM_SET_UVECTOR_LENGTH (ans
, len
, type
);
165 gh_chars2byvect (const char *d
, int 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
, int 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
, int 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
, int 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
, int 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
, int 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 /* NOTE: possible loss of precision here */
233 return (int) scm_num2long (obj
, SCM_ARG1
, "gh_scm2int");
236 gh_scm2double (SCM obj
)
238 return scm_num2dbl (obj
, "gh_scm2double");
241 gh_scm2char (SCM obj
)
242 #define FUNC_NAME "gh_scm2char"
244 SCM_VALIDATE_CHAR (SCM_ARG1
, obj
);
245 return SCM_CHAR (obj
);
249 /* Convert a vector, weak vector, string, substring or uniform vector
250 into an array of chars. If result array in arg 2 is NULL, malloc a
251 new one. If out of memory, return NULL. */
253 gh_scm2chars (SCM obj
, char *m
)
259 scm_wrong_type_arg (0, 0, obj
);
260 switch (SCM_TYP7 (obj
))
264 n
= SCM_VECTOR_LENGTH (obj
);
265 for (i
= 0; i
< n
; ++i
)
267 val
= SCM_VELTS (obj
)[i
];
271 if (v
< -128 || v
> 255)
272 scm_out_of_range (0, obj
);
275 scm_wrong_type_arg (0, 0, obj
);
278 m
= (char *) malloc (n
* sizeof (char));
281 for (i
= 0; i
< n
; ++i
)
282 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
286 n
= SCM_UVECTOR_LENGTH (obj
);
288 m
= (char *) malloc (n
* sizeof (char));
291 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (char));
295 case scm_tc7_substring
:
296 n
= SCM_STRING_LENGTH (obj
);
298 m
= (char *) malloc (n
* sizeof (char));
301 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (char));
304 scm_wrong_type_arg (0, 0, obj
);
309 /* Convert a vector, weak vector or uniform vector into an array of
310 shorts. If result array in arg 2 is NULL, malloc a new one. If
311 out of memory, return NULL. */
313 gh_scm2shorts (SCM obj
, short *m
)
319 scm_wrong_type_arg (0, 0, obj
);
320 switch (SCM_TYP7 (obj
))
324 n
= SCM_VECTOR_LENGTH (obj
);
325 for (i
= 0; i
< n
; ++i
)
327 val
= SCM_VELTS (obj
)[i
];
331 if (v
< -32768 || v
> 65535)
332 scm_out_of_range (0, obj
);
335 scm_wrong_type_arg (0, 0, obj
);
338 m
= (short *) malloc (n
* sizeof (short));
341 for (i
= 0; i
< n
; ++i
)
342 m
[i
] = SCM_INUM (SCM_VELTS (obj
)[i
]);
346 n
= SCM_UVECTOR_LENGTH (obj
);
348 m
= (short *) malloc (n
* sizeof (short));
351 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (short));
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
);
370 switch (SCM_TYP7 (obj
))
374 n
= SCM_VECTOR_LENGTH (obj
);
375 for (i
= 0; i
< n
; ++i
)
377 val
= SCM_VELTS (obj
)[i
];
378 if (!SCM_INUMP (val
) && !SCM_BIGP (val
))
379 scm_wrong_type_arg (0, 0, obj
);
382 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
)
390 : scm_num2long (val
, 0, NULL
);
396 n
= SCM_UVECTOR_LENGTH (obj
);
398 m
= (long *) malloc (n
* sizeof (long));
401 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (long));
405 scm_wrong_type_arg (0, 0, obj
);
410 /* Convert a vector, weak vector or uniform vector into an array of
411 floats. If result array in arg 2 is NULL, malloc a new one. If
412 out of memory, return NULL. */
414 gh_scm2floats (SCM obj
, float *m
)
419 scm_wrong_type_arg (0, 0, obj
);
420 switch (SCM_TYP7 (obj
))
424 n
= SCM_VECTOR_LENGTH (obj
);
425 for (i
= 0; i
< n
; ++i
)
427 val
= SCM_VELTS (obj
)[i
];
429 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
430 scm_wrong_type_arg (0, 0, val
);
433 m
= (float *) malloc (n
* sizeof (float));
436 for (i
= 0; i
< n
; ++i
)
438 val
= SCM_VELTS (obj
)[i
];
440 m
[i
] = SCM_INUM (val
);
441 else if (SCM_BIGP (val
))
442 m
[i
] = scm_num2long (val
, 0, NULL
);
444 m
[i
] = SCM_REAL_VALUE (val
);
449 n
= SCM_UVECTOR_LENGTH (obj
);
451 m
= (float *) malloc (n
* sizeof (float));
454 memcpy (m
, (float *) SCM_VELTS (obj
), n
* sizeof (float));
458 n
= SCM_UVECTOR_LENGTH (obj
);
460 m
= (float*) malloc (n
* sizeof (float));
463 for (i
= 0; i
< n
; ++i
)
464 m
[i
] = ((double *) SCM_VELTS (obj
))[i
];
468 scm_wrong_type_arg (0, 0, obj
);
473 /* Convert a vector, weak vector or uniform vector into an array of
474 doubles. If result array in arg 2 is NULL, malloc a new one. If
475 out of memory, return NULL. */
477 gh_scm2doubles (SCM obj
, double *m
)
482 scm_wrong_type_arg (0, 0, obj
);
483 switch (SCM_TYP7 (obj
))
487 n
= SCM_VECTOR_LENGTH (obj
);
488 for (i
= 0; i
< n
; ++i
)
490 val
= SCM_VELTS (obj
)[i
];
492 && !(SCM_BIGP (val
) || SCM_REALP (val
)))
493 scm_wrong_type_arg (0, 0, val
);
496 m
= (double *) malloc (n
* sizeof (double));
499 for (i
= 0; i
< n
; ++i
)
501 val
= SCM_VELTS (obj
)[i
];
503 m
[i
] = SCM_INUM (val
);
504 else if (SCM_BIGP (val
))
505 m
[i
] = scm_num2long (val
, 0, NULL
);
507 m
[i
] = SCM_REAL_VALUE (val
);
512 n
= SCM_UVECTOR_LENGTH (obj
);
514 m
= (double *) malloc (n
* sizeof (double));
517 for (i
= 0; i
< n
; ++i
)
518 m
[i
] = ((float *) SCM_VELTS (obj
))[i
];
522 n
= SCM_UVECTOR_LENGTH (obj
);
524 m
= (double*) malloc (n
* sizeof (double));
527 memcpy (m
, SCM_VELTS (obj
), n
* sizeof (double));
531 scm_wrong_type_arg (0, 0, obj
);
536 /* string conversions between C and Scheme */
538 /* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
539 new copy of its contents, followed by a null byte. If lenp is
540 non-null, set *lenp to the string's length.
542 This function uses malloc to obtain storage for the copy; the
543 caller is responsible for freeing it. If out of memory, NULL is
546 Note that Scheme strings may contain arbitrary data, including null
547 characters. This means that null termination is not a reliable way
548 to determine the length of the returned value. However, the
549 function always copies the complete contents of STR, and sets
550 *LEN_P to the true length of the string (when LEN_P is non-null). */
552 gh_scm2newstr (SCM str
, int *lenp
)
557 SCM_ASSERT (SCM_STRINGP (str
), str
, SCM_ARG3
, "gh_scm2newstr");
559 len
= SCM_STRING_LENGTH (str
);
561 ret_str
= (char *) malloc ((len
+ 1) * sizeof (char));
564 /* so we copy tmp_str to ret_str, which is what we will allocate */
565 memcpy (ret_str
, SCM_STRING_CHARS (str
), len
);
566 scm_remember_upto_here_1 (str
);
567 /* now make sure we null-terminate it */
579 /* Copy LEN characters at START from the Scheme string SRC to memory
580 at DST. START is an index into SRC; zero means the beginning of
581 the string. DST has already been allocated by the caller.
583 If START + LEN is off the end of SRC, silently truncate the source
584 region to fit the string. If truncation occurs, the corresponding
585 area of DST is left unchanged. */
587 gh_get_substr (SCM src
, char *dst
, int start
, int len
)
589 int src_len
, effective_length
;
590 SCM_ASSERT (SCM_STRINGP (src
), src
, SCM_ARG3
, "gh_get_substr");
592 src_len
= SCM_STRING_LENGTH (src
);
593 effective_length
= (len
< src_len
) ? len
: src_len
;
594 memcpy (dst
+ start
, SCM_STRING_CHARS (src
), effective_length
* sizeof (char));
595 /* FIXME: must signal an error if len > src_len */
596 scm_remember_upto_here_1 (src
);
600 /* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
601 pointer to a string with the symbol characters "identifier",
602 followed by a null byte. If lenp is non-null, set *lenp to the
605 This function uses malloc to obtain storage for the copy; the
606 caller is responsible for freeing it. If out of memory, NULL is
609 gh_symbol2newstr (SCM sym
, int *lenp
)
614 SCM_ASSERT (SCM_SYMBOLP (sym
), sym
, SCM_ARG3
, "gh_scm2newsymbol");
616 len
= SCM_SYMBOL_LENGTH (sym
);
618 ret_str
= (char *) malloc ((len
+ 1) * sizeof (char));
621 /* so we copy sym to ret_str, which is what we will allocate */
622 memcpy (ret_str
, SCM_SYMBOL_CHARS (sym
), len
);
623 scm_remember_upto_here_1 (sym
);
624 /* now make sure we null-terminate it */
636 /* create a new vector of the given length, all initialized to the
639 gh_make_vector (SCM len
, SCM fill
)
641 return scm_make_vector (len
, fill
);
644 /* set the given element of the given vector to the given value */
646 gh_vector_set_x (SCM vec
, SCM pos
, SCM val
)
648 return scm_vector_set_x (vec
, pos
, val
);
651 /* retrieve the given element of the given vector */
653 gh_vector_ref (SCM vec
, SCM pos
)
655 return scm_vector_ref (vec
, pos
);
658 /* returns the length of the given vector */
660 gh_vector_length (SCM v
)
662 return gh_scm2ulong (scm_vector_length (v
));
666 /* uniform vector support */
668 /* returns the length as a C unsigned long integer */
670 gh_uniform_vector_length (SCM v
)
672 return gh_scm2ulong (scm_uniform_vector_length (v
));
675 /* gets the given element from a uniform vector; ilist is a list (or
676 possibly a single integer) of indices, and its length is the
677 dimension of the uniform vector */
679 gh_uniform_vector_ref (SCM v
, SCM ilist
)
681 return scm_uniform_vector_ref (v
, ilist
);
684 /* sets an individual element in a uniform vector */
686 /* gh_list_to_uniform_array ( */
689 /* Data lookups between C and Scheme
691 Look up a symbol with a given name, and return the object to which
692 it is bound. gh_lookup examines the Guile top level, and
693 gh_module_lookup checks the module namespace specified by the
696 The return value is the Scheme object to which SNAME is bound, or
697 SCM_UNDEFINED if SNAME is not bound in the given context.
701 gh_lookup (const char *sname
)
703 return gh_module_lookup (SCM_BOOL_F
, sname
);
707 gh_module_lookup (SCM vec
, const char *sname
)
709 SCM sym
= gh_symbol2scm (sname
);
710 if (SCM_EQ_P (scm_symbol_bound_p (vec
, sym
), SCM_BOOL_T
))
711 return scm_symbol_binding (vec
, sym
);
713 return SCM_UNDEFINED
;