implemented several missing gh_ functions, mostly related to lists and pairs
[bpt/guile.git] / libguile / gh_data.c
CommitLineData
1e598865 1/* Copyright (C) 1995,1996,1997 Free Software Foundation, Inc.
ee2a8b9b
JB
2
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2, or (at your option)
6 * any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this software; see the file COPYING. If not, write to
82892bed
JB
15 * the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
16 * Boston, MA 02111-1307 USA
ee2a8b9b
JB
17 *
18 * As a special exception, the Free Software Foundation gives permission
19 * for additional uses of the text contained in its release of GUILE.
20 *
21 * The exception is that, if you link the GUILE library with other files
22 * to produce an executable, this does not by itself cause the
23 * resulting executable to be covered by the GNU General Public License.
24 * Your use of that executable is in no way restricted on account of
25 * linking the GUILE library code into it.
26 *
27 * This exception does not however invalidate any other reasons why
28 * the executable file might be covered by the GNU General Public License.
29 *
30 * This exception applies only to the code released by the
31 * Free Software Foundation under the name GUILE. If you copy
32 * code from other Free Software Foundation releases into a copy of
33 * GUILE, as the General Public License permits, the exception does
34 * not apply to the code that you add in this way. To avoid misleading
35 * anyone as to the status of such modified files, you must delete
36 * this exception notice from them.
37 *
38 * If you write modifications of your own for GUILE, it is your choice
39 * whether to permit this exception to apply to your modifications.
82892bed 40 * If you do not wish that, delete this exception notice. */
ee2a8b9b
JB
41\f
42
43/* data initialization and C<->Scheme data conversion */
44
45#include <stdio.h>
46
47#include <gh.h>
48
49/* data conversion C->scheme */
50SCM
dbb3005d
MG
51gh_int2scmb (int x) /* this is being phased out */
52{
53 return (x ? SCM_BOOL_T : SCM_BOOL_F);
54}
55SCM
56gh_bool2scm (int x)
ee2a8b9b
JB
57{
58 return (x ? SCM_BOOL_T : SCM_BOOL_F);
59}
60SCM
61gh_int2scm (int x)
62{
63 return scm_long2num ((long) x);
64}
65SCM
66gh_ulong2scm (unsigned long x)
67{
68 return scm_ulong2num (x);
69}
70SCM
71gh_long2scm (long x)
72{
73 return scm_long2num (x);
74}
75SCM
76gh_double2scm (double x)
77{
78 return scm_makdbl (x, 0.0);
79}
80SCM
81gh_char2scm (char c)
82{
83 return SCM_MAKICHR (c);
84}
85SCM
86gh_str2scm (char *s, int len)
87{
88 return scm_makfromstr (s, len, 0);
89}
90SCM
91gh_str02scm (char *s)
92{
93 return scm_makfrom0str (s);
94}
95/* Copy LEN characters at SRC into the *existing* Scheme string DST,
96 starting at START. START is an index into DST; zero means the
97 beginning of the string.
98
99 If START + LEN is off the end of DST, signal an out-of-range
100 error. */
101void
102gh_set_substr (char *src, SCM dst, int start, int len)
103{
104 char *dst_ptr, dst_len, effective_length;
105
106 SCM_ASSERT (SCM_NIMP (dst) && SCM_STRINGP (dst), dst, SCM_ARG3,
107 "gh_set_substr");
108 scm_protect_object (dst);
109 dst_ptr = SCM_CHARS (dst);
110 dst_len = SCM_LENGTH (dst);
111 effective_length = (len < dst_len) ? len : dst_len;
112 memcpy (dst_ptr + start, src, effective_length);
113 /* FIXME: must signal an error if len > dst_len */
114 scm_unprotect_object (dst);
115}
116
117/* Return the symbol named SYMBOL_STR. */
118SCM
119gh_symbol2scm (char *symbol_str)
120{
121 return SCM_CAR (scm_intern (symbol_str, strlen (symbol_str)));
122}
123
124
125/* data conversion scheme->C */
126int
127gh_scm2bool (SCM obj)
128{
129 return ((obj) == SCM_BOOL_F) ? 0 : 1;
130}
131unsigned long
132gh_scm2ulong (SCM obj)
133{
134 return scm_num2ulong (obj, (char *) SCM_ARG1, "gh_scm2ulong");
135}
136long
137gh_scm2long (SCM obj)
138{
139 return scm_num2long (obj, (char *) SCM_ARG1, "gh_scm2long");
140}
141int
142gh_scm2int (SCM obj)
143{
144 /* NOTE: possible loss of precision here */
145 return (int) scm_num2long (obj, (char *) SCM_ARG1, "gh_scm2int");
146}
147double
148gh_scm2double (SCM obj)
149{
150 return scm_num2dbl (obj, "gh_scm2double");
151}
152char
153gh_scm2char (SCM obj)
154{
155 return SCM_ICHR (obj);
156}
157
158/* string conversions between C and Scheme */
159
160/* gh_scm2newstr() -- Given a Scheme string STR, return a pointer to a
161 new copy of its contents, followed by a null byte. If lenp is
162 non-null, set *lenp to the string's length.
163
164 This function uses malloc to obtain storage for the copy; the
165 caller is responsible for freeing it.
166
167 Note that Scheme strings may contain arbitrary data, including null
168 characters. This means that null termination is not a reliable way
169 to determine the length of the returned value. However, the
170 function always copies the complete contents of STR, and sets
171 *LEN_P to the true length of the string (when LEN_P is non-null). */
172char *
173gh_scm2newstr (SCM str, int *lenp)
174{
175 char *ret_str;
176 int len;
177
178 SCM_ASSERT (SCM_NIMP (str) && SCM_STRINGP (str), str, SCM_ARG3,
179 "gh_scm2newstr");
180
181 /* protect str from GC while we copy off its data */
182 scm_protect_object (str);
183
184 len = SCM_LENGTH (str);
185
9b1b00fe
JB
186 ret_str = (char *) scm_must_malloc ((len + 1) * sizeof (char),
187 "gh_scm2newstr");
ee2a8b9b
JB
188 /* so we copy tmp_str to ret_str, which is what we will allocate */
189 memcpy (ret_str, SCM_CHARS (str), len);
190 /* now make sure we null-terminate it */
191 ret_str[len] = '\0';
192
193 scm_unprotect_object (str);
194
195 if (lenp != NULL)
196 {
197 *lenp = len;
198 }
199
200 return ret_str;
201}
202
203
204/* Copy LEN characters at START from the Scheme string SRC to memory
205 at DST. START is an index into SRC; zero means the beginning of
206 the string. DST has already been allocated by the caller.
207
208 If START + LEN is off the end of SRC, silently truncate the source
209 region to fit the string. If truncation occurs, the corresponding
210 area of DST is left unchanged. */
211void
212gh_get_substr (SCM src, char *dst, int start, int len)
213{
214 int src_len, effective_length;
215 SCM_ASSERT (SCM_NIMP (src) && SCM_STRINGP (src), src, SCM_ARG3,
216 "gh_get_substr");
217
218 scm_protect_object (src);
219 src_len = SCM_LENGTH (src);
220 effective_length = (len < src_len) ? len : src_len;
221 memcpy (dst + start, SCM_CHARS (src), effective_length * sizeof (char));
222 /* FIXME: must signal an error if len > src_len */
223 scm_unprotect_object (src);
224}
225
226
227/* gh_scm2newsymbol() -- Given a Scheme symbol 'identifier, return a
228 pointer to a string with the symbol characters "identifier",
229 followed by a null byte. If lenp is non-null, set *lenp to the
230 string's length.
231
232 This function uses malloc to obtain storage for the copy; the
233 caller is responsible for freeing it. */
234char *
235gh_symbol2newstr (SCM sym, int *lenp)
236{
237 char *ret_str;
238 int len;
239
240 SCM_ASSERT (SCM_NIMP (sym) && SCM_SYMBOLP (sym), sym, SCM_ARG3,
241 "gh_scm2newsymbol");
242
243 /* protect str from GC while we copy off its data */
244 scm_protect_object (sym);
245
246 len = SCM_LENGTH (sym);
247
9b1b00fe
JB
248 ret_str = (char *) scm_must_malloc ((len + 1) * sizeof (char),
249 "gh_symbol2newstr");
ee2a8b9b
JB
250 /* so we copy tmp_str to ret_str, which is what we will allocate */
251 memcpy (ret_str, SCM_CHARS (sym), len);
252 /* now make sure we null-terminate it */
253 ret_str[len] = '\0';
254
255 scm_unprotect_object (sym);
256
257 if (lenp != NULL)
258 {
259 *lenp = len;
260 }
261
262 return ret_str;
263}
264
265
266/* create a new vector of the given length, all initialized to the
267 given value */
e5eece74
MG
268SCM
269gh_make_vector (SCM len, SCM fill)
ee2a8b9b 270{
e5eece74
MG
271 /* scm_make_vector() takes a third boolean argument which should be
272 set to SCM_BOOL_T when you are dealing with multi-dimensional
273 arrays; gh_make_vector() does not do multi-dimensional arrays */
274 return scm_make_vector(len, fill, SCM_BOOL_F);
ee2a8b9b
JB
275}
276
277/* set the given element of the given vector to the given value */
278SCM
e5eece74 279gh_vector_set (SCM vec, SCM pos, SCM val)
ee2a8b9b
JB
280{
281 return scm_vector_set_x (vec, pos, val);
282}
283
284/* retrieve the given element of the given vector */
285SCM
e5eece74 286gh_vector_ref (SCM vec, SCM pos)
ee2a8b9b
JB
287{
288 return scm_vector_ref (vec, pos);
289}
290
291/* returns the length of the given vector */
292unsigned long
293gh_vector_length (SCM v)
294{
295 return gh_scm2ulong (scm_vector_length (v));
296}
35379308
JB
297
298/* Data lookups between C and Scheme
299
300 Look up a symbol with a given name, and return the object to which
301 it is bound. gh_lookup examines the Guile top level, and
302 gh_module_lookup checks the module namespace specified by the
303 `vec' argument.
304
305 The return value is the Scheme object to which SNAME is bound, or
306 SCM_UNDEFINED if SNAME is not bound in the given context. [FIXME:
307 should this be SCM_UNSPECIFIED? Can a symbol ever legitimately be
308 bound to SCM_UNDEFINED or SCM_UNSPECIFIED? What is the difference?
309 -twp] */
310
311SCM
312gh_lookup (char *sname)
313{
314 return gh_module_lookup (SCM_BOOL_F, sname);
315}
316
317SCM
318gh_module_lookup (SCM vec, char *sname)
319{
320 SCM sym = gh_symbol2scm (sname);
321 if ((scm_symbol_bound_p (vec, sym)) == SCM_BOOL_T)
322 return scm_symbol_binding (vec, sym);
323 else
324 return SCM_UNDEFINED;
325}