1 /* Copyright (C) 1995,1996,1998,2000,2001 Free Software Foundation, Inc.
3 * This library is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 2.1 of the License, or (at your option) any later version.
8 * This library 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 GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with this library; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "libguile/_scm.h"
24 #include "libguile/chars.h"
25 #include "libguile/root.h"
26 #include "libguile/strings.h"
27 #include "libguile/deprecation.h"
28 #include "libguile/validate.h"
29 #include "libguile/dynwind.h"
36 SCM_DEFINE (scm_string_p
, "string?", 1, 0, 0,
38 "Return @code{#t} if @var{obj} is a string, else @code{#f}.")
39 #define FUNC_NAME s_scm_string_p
41 return scm_from_bool (SCM_I_STRINGP (obj
));
46 SCM_REGISTER_PROC (s_scm_list_to_string
, "list->string", 1, 0, 0, scm_string
);
48 SCM_DEFINE (scm_string
, "string", 0, 0, 1,
50 "@deffnx {Scheme Procedure} list->string chrs\n"
51 "Return a newly allocated string composed of the arguments,\n"
53 #define FUNC_NAME s_scm_string
58 long i
= scm_ilength (chrs
);
60 SCM_ASSERT (i
>= 0, chrs
, SCM_ARG1
, FUNC_NAME
);
61 result
= scm_allocate_string (i
);
65 unsigned char *data
= SCM_I_STRING_UCHARS (result
);
67 while (!SCM_NULLP (chrs
))
69 SCM elt
= SCM_CAR (chrs
);
71 SCM_VALIDATE_CHAR (SCM_ARGn
, elt
);
72 *data
++ = SCM_CHAR (elt
);
73 chrs
= SCM_CDR (chrs
);
81 /* converts C scm_array of strings to SCM scm_list of strings. */
82 /* If argc < 0, a null terminated scm_array is assumed. */
84 scm_makfromstrs (int argc
, char **argv
)
89 for (i
= 0; argv
[i
]; i
++);
91 lst
= scm_cons (scm_mem2string (argv
[i
], strlen (argv
[i
])), lst
);
96 /* This function must only be applied to memory obtained via malloc,
97 since the GC is going to apply `free' to it when the string is
100 Also, s[len] must be `\0', since we promise that strings are
101 null-terminated. Perhaps we could handle non-null-terminated
102 strings by claiming they're shared substrings of a string we just
105 scm_take_str (char *s
, size_t len
)
106 #define FUNC_NAME "scm_take_str"
110 SCM_ASSERT_RANGE (2, scm_from_ulong (len
), len
<= SCM_STRING_MAX_LENGTH
);
112 answer
= scm_cell (SCM_I_MAKE_STRING_TAG (len
), (scm_t_bits
) s
);
113 scm_gc_register_collectable_memory (s
, len
+1, "string");
120 /* `s' must be a malloc'd string. See scm_take_str. */
122 scm_take0str (char *s
)
124 return scm_take_locale_string (s
);
129 scm_mem2string (const char *src
, size_t len
)
131 return scm_from_locale_stringn (src
, len
);
136 scm_str2string (const char *src
)
138 return scm_from_locale_string (src
);
143 scm_makfrom0str (const char *src
)
145 if (!src
) return SCM_BOOL_F
;
146 return scm_from_locale_string (src
);
151 scm_makfrom0str_opt (const char *src
)
153 return scm_makfrom0str (src
);
158 scm_allocate_string (size_t len
)
159 #define FUNC_NAME "scm_allocate_string"
164 SCM_ASSERT_RANGE (1, scm_from_size_t (len
), len
<= SCM_STRING_MAX_LENGTH
);
166 mem
= (char *) scm_gc_malloc (len
+ 1, "string");
169 s
= scm_cell (SCM_I_MAKE_STRING_TAG (len
), (scm_t_bits
) mem
);
176 SCM_DEFINE (scm_make_string
, "make-string", 1, 1, 0,
178 "Return a newly allocated string of\n"
179 "length @var{k}. If @var{chr} is given, then all elements of\n"
180 "the string are initialized to @var{chr}, otherwise the contents\n"
181 "of the @var{string} are unspecified.")
182 #define FUNC_NAME s_scm_make_string
184 size_t i
= scm_to_unsigned_integer (k
, 0, SCM_STRING_MAX_LENGTH
);
185 SCM res
= scm_allocate_string (i
);
187 if (!SCM_UNBNDP (chr
))
191 SCM_VALIDATE_CHAR (2, chr
);
193 dst
= SCM_I_STRING_UCHARS (res
);
194 memset (dst
, SCM_CHAR (chr
), i
);
202 SCM_DEFINE (scm_string_length
, "string-length", 1, 0, 0,
204 "Return the number of characters in @var{string}.")
205 #define FUNC_NAME s_scm_string_length
207 SCM_VALIDATE_STRING (1, string
);
208 return scm_from_size_t (SCM_I_STRING_LENGTH (string
));
212 SCM_DEFINE (scm_string_ref
, "string-ref", 2, 0, 0,
214 "Return character @var{k} of @var{str} using zero-origin\n"
215 "indexing. @var{k} must be a valid index of @var{str}.")
216 #define FUNC_NAME s_scm_string_ref
220 SCM_VALIDATE_STRING (1, str
);
221 idx
= scm_to_unsigned_integer (k
, 0, SCM_I_STRING_LENGTH(str
)-1);
222 return SCM_MAKE_CHAR (SCM_I_STRING_UCHARS (str
)[idx
]);
227 SCM_DEFINE (scm_string_set_x
, "string-set!", 3, 0, 0,
228 (SCM str
, SCM k
, SCM chr
),
229 "Store @var{chr} in element @var{k} of @var{str} and return\n"
230 "an unspecified value. @var{k} must be a valid index of\n"
232 #define FUNC_NAME s_scm_string_set_x
236 SCM_VALIDATE_STRING (1, str
);
237 idx
= scm_to_unsigned_integer (k
, 0, SCM_I_STRING_LENGTH(str
)-1);
238 SCM_VALIDATE_CHAR (3, chr
);
239 SCM_I_STRING_UCHARS (str
)[idx
] = SCM_CHAR (chr
);
240 return SCM_UNSPECIFIED
;
245 SCM_DEFINE (scm_substring
, "substring", 2, 1, 0,
246 (SCM str
, SCM start
, SCM end
),
247 "Return a newly allocated string formed from the characters\n"
248 "of @var{str} beginning with index @var{start} (inclusive) and\n"
249 "ending with index @var{end} (exclusive).\n"
250 "@var{str} must be a string, @var{start} and @var{end} must be\n"
251 "exact integers satisfying:\n\n"
252 "0 <= @var{start} <= @var{end} <= (string-length @var{str}).")
253 #define FUNC_NAME s_scm_substring
255 unsigned long int from
;
256 unsigned long int to
;
259 SCM_VALIDATE_STRING (1, str
);
260 from
= scm_to_unsigned_integer (start
, 0, SCM_I_STRING_LENGTH(str
));
261 if (SCM_UNBNDP (end
))
262 to
= SCM_I_STRING_LENGTH(str
);
264 to
= scm_to_unsigned_integer (end
, from
, SCM_I_STRING_LENGTH(str
));
265 substr
= scm_allocate_string (to
- from
);
266 memcpy (SCM_I_STRING_CHARS (substr
), SCM_I_STRING_CHARS (str
) + from
,
268 scm_remember_upto_here_1 (str
);
274 SCM_DEFINE (scm_string_append
, "string-append", 0, 0, 1,
276 "Return a newly allocated string whose characters form the\n"
277 "concatenation of the given strings, @var{args}.")
278 #define FUNC_NAME s_scm_string_append
285 SCM_VALIDATE_REST_ARGUMENT (args
);
286 for (l
= args
; !SCM_NULLP (l
); l
= SCM_CDR (l
))
289 SCM_VALIDATE_STRING (SCM_ARGn
, s
);
290 i
+= SCM_I_STRING_LENGTH (s
);
292 res
= scm_allocate_string (i
);
293 data
= SCM_I_STRING_CHARS (res
);
294 for (l
= args
; !SCM_NULLP (l
); l
= SCM_CDR (l
))
297 memcpy (data
, SCM_I_STRING_CHARS (s
), SCM_I_STRING_LENGTH (s
));
298 data
+= SCM_I_STRING_LENGTH (s
);
299 scm_remember_upto_here_1 (s
);
306 scm_is_string (SCM obj
)
308 return SCM_I_STRINGP (obj
);
312 scm_from_locale_stringn (const char *str
, size_t len
)
317 if (len
== (size_t)-1)
319 res
= scm_allocate_string (len
);
320 dst
= SCM_I_STRING_CHARS (res
);
321 memcpy (dst
, str
, len
);
326 scm_from_locale_string (const char *str
)
328 return scm_from_locale_stringn (str
, -1);
332 scm_take_locale_stringn (char *str
, size_t len
)
334 if (len
== (size_t)-1)
335 return scm_take_locale_string (str
);
338 /* STR might not be zero terminated and we are not allowed to
339 look at str[len], so we have to make a new one...
341 SCM res
= scm_from_locale_stringn (str
, len
);
348 scm_take_locale_string (char *str
)
350 size_t len
= strlen (str
);
353 if (len
> SCM_STRING_MAX_LENGTH
)
356 scm_out_of_range (NULL
, scm_from_size_t (len
));
359 res
= scm_cell (SCM_I_MAKE_STRING_TAG (len
), (scm_t_bits
) str
);
360 scm_gc_register_collectable_memory (str
, len
+1, "string");
366 scm_to_locale_stringn (SCM str
, size_t *lenp
)
371 if (!SCM_I_STRINGP (str
))
372 scm_wrong_type_arg_msg (NULL
, 0, str
, "string");
373 len
= SCM_I_STRING_LENGTH (str
);
374 res
= scm_malloc (len
+ ((lenp
==NULL
)? 1 : 0));
375 memcpy (res
, SCM_I_STRING_CHARS (str
), len
);
379 if (strlen (res
) != len
)
382 scm_misc_error (NULL
,
383 "string contains #\\nul character: ~S",
390 scm_remember_upto_here_1 (str
);
395 scm_to_locale_string (SCM str
)
397 return scm_to_locale_stringn (str
, NULL
);
401 scm_to_locale_stringbuf (SCM str
, char *buf
, size_t max_len
)
405 if (!SCM_I_STRINGP (str
))
406 scm_wrong_type_arg_msg (NULL
, 0, str
, "string");
407 len
= SCM_I_STRING_LENGTH (str
);
408 memcpy (buf
, SCM_I_STRING_CHARS (str
), (len
> max_len
)? max_len
: len
);
409 scm_remember_upto_here_1 (str
);
413 /* Return a newly allocated array of char pointers to each of the strings
414 in args, with a terminating NULL pointer. */
417 scm_i_allocate_string_pointers (SCM list
)
420 int len
= scm_ilength (list
);
424 scm_wrong_type_arg_msg (NULL
, 0, list
, "proper list");
428 result
= (char **) scm_malloc ((len
+ 1) * sizeof (char *));
430 scm_frame_unwind_handler (free
, result
, 0);
432 /* The list might be have been modified in another thread, so
433 we check LIST before each access.
435 for (i
= 0; i
< len
&& SCM_CONSP (list
); i
++)
437 result
[i
] = scm_to_locale_string (SCM_CAR (list
));
438 list
= SCM_CDR (list
);
446 scm_i_free_string_pointers (char **pointers
)
450 for (i
= 0; pointers
[i
]; i
++)
458 scm_nullstr
= scm_allocate_string (0);
460 #include "libguile/strings.x"