(ipv6_net_to_num, scm_from_ipv6): Renamed
[bpt/guile.git] / libguile / strings.c
CommitLineData
be54b15d 1/* Copyright (C) 1995,1996,1998,2000,2001 Free Software Foundation, Inc.
0f2d19dd 2 *
73be1d9e
MV
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.
0f2d19dd 7 *
73be1d9e
MV
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.
0f2d19dd 12 *
73be1d9e
MV
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
16 */
1bbd0b84 17
1bbd0b84 18
0f2d19dd
JB
19\f
20
faf2c9d7
MD
21#include <string.h>
22
a0599745
MD
23#include "libguile/_scm.h"
24#include "libguile/chars.h"
7c33806a 25#include "libguile/root.h"
a0599745 26#include "libguile/strings.h"
1afff620 27#include "libguile/deprecation.h"
a0599745 28#include "libguile/validate.h"
1afff620 29
0f2d19dd
JB
30\f
31
32/* {Strings}
33 */
34
3b3b36dd 35SCM_DEFINE (scm_string_p, "string?", 1, 0, 0,
0d26a824 36 (SCM obj),
bb2c02f2 37 "Return @code{#t} if @var{obj} is a string, else @code{#f}.")
1bbd0b84 38#define FUNC_NAME s_scm_string_p
0f2d19dd 39{
7888309b 40 return scm_from_bool (SCM_STRINGP (obj));
0f2d19dd 41}
1bbd0b84 42#undef FUNC_NAME
0f2d19dd 43
e53cc817 44
bd9e24b3 45SCM_REGISTER_PROC (s_scm_list_to_string, "list->string", 1, 0, 0, scm_string);
1bbd0b84 46
3b3b36dd 47SCM_DEFINE (scm_string, "string", 0, 0, 1,
6fa73e72 48 (SCM chrs),
8f85c0c6 49 "@deffnx {Scheme Procedure} list->string chrs\n"
1e6808ea 50 "Return a newly allocated string composed of the arguments,\n"
0d26a824 51 "@var{chrs}.")
1bbd0b84 52#define FUNC_NAME s_scm_string
0f2d19dd 53{
bd9e24b3
GH
54 SCM result;
55
0f2d19dd 56 {
c014a02e 57 long i = scm_ilength (chrs);
bd9e24b3 58
4d6aae71 59 SCM_ASSERT (i >= 0, chrs, SCM_ARG1, FUNC_NAME);
be54b15d 60 result = scm_allocate_string (i);
0f2d19dd 61 }
bd9e24b3
GH
62
63 {
322ac0c5 64 unsigned char *data = SCM_STRING_UCHARS (result);
bd9e24b3 65
36284627 66 while (!SCM_NULLP (chrs))
bd9e24b3
GH
67 {
68 SCM elt = SCM_CAR (chrs);
69
7866a09b
GB
70 SCM_VALIDATE_CHAR (SCM_ARGn, elt);
71 *data++ = SCM_CHAR (elt);
bd9e24b3
GH
72 chrs = SCM_CDR (chrs);
73 }
74 }
75 return result;
0f2d19dd 76}
1bbd0b84 77#undef FUNC_NAME
0f2d19dd 78
0f2d19dd
JB
79
80/* converts C scm_array of strings to SCM scm_list of strings. */
81/* If argc < 0, a null terminated scm_array is assumed. */
0f2d19dd 82SCM
1bbd0b84 83scm_makfromstrs (int argc, char **argv)
0f2d19dd
JB
84{
85 int i = argc;
86 SCM lst = SCM_EOL;
87 if (0 > i)
88 for (i = 0; argv[i]; i++);
89 while (i--)
36284627 90 lst = scm_cons (scm_mem2string (argv[i], strlen (argv[i])), lst);
0f2d19dd
JB
91 return lst;
92}
93
94
ee149d03
JB
95/* This function must only be applied to memory obtained via malloc,
96 since the GC is going to apply `free' to it when the string is
97 dropped.
98
99 Also, s[len] must be `\0', since we promise that strings are
100 null-terminated. Perhaps we could handle non-null-terminated
101 strings by claiming they're shared substrings of a string we just
102 made up. */
0f2d19dd 103SCM
1be6b49c 104scm_take_str (char *s, size_t len)
cb0d8be2 105#define FUNC_NAME "scm_take_str"
0f2d19dd
JB
106{
107 SCM answer;
cb0d8be2
DH
108
109 SCM_ASSERT_RANGE (2, scm_ulong2num (len), len <= SCM_STRING_MAX_LENGTH);
110
228a24ef 111 answer = scm_cell (SCM_MAKE_STRING_TAG (len), (scm_t_bits) s);
4c9419ac 112 scm_gc_register_collectable_memory (s, len+1, "string");
cb0d8be2 113
0f2d19dd
JB
114 return answer;
115}
cb0d8be2
DH
116#undef FUNC_NAME
117
0f2d19dd 118
ee149d03
JB
119/* `s' must be a malloc'd string. See scm_take_str. */
120SCM
121scm_take0str (char *s)
122{
123 return scm_take_str (s, strlen (s));
124}
125
36284627
DH
126
127SCM
128scm_mem2string (const char *src, size_t len)
0f2d19dd 129{
be54b15d 130 SCM s = scm_allocate_string (len);
86c991c2 131 char *dst = SCM_STRING_CHARS (s);
b9d4df2c 132 memcpy (dst, src, len);
0f2d19dd
JB
133 return s;
134}
135
b00418df
DH
136
137SCM
138scm_str2string (const char *src)
139{
140 return scm_mem2string (src, strlen (src));
141}
142
143
0f2d19dd 144SCM
1bbd0b84 145scm_makfrom0str (const char *src)
0f2d19dd
JB
146{
147 if (!src) return SCM_BOOL_F;
36284627 148 return scm_mem2string (src, strlen (src));
0f2d19dd
JB
149}
150
1cc91f1b 151
0f2d19dd 152SCM
1bbd0b84 153scm_makfrom0str_opt (const char *src)
0f2d19dd
JB
154{
155 return scm_makfrom0str (src);
156}
157
158
be54b15d 159SCM
1be6b49c 160scm_allocate_string (size_t len)
be54b15d
DH
161#define FUNC_NAME "scm_allocate_string"
162{
163 char *mem;
164 SCM s;
165
166 SCM_ASSERT_RANGE (1, scm_long2num (len), len <= SCM_STRING_MAX_LENGTH);
167
4c9419ac 168 mem = (char *) scm_gc_malloc (len + 1, "string");
be54b15d
DH
169 mem[len] = 0;
170
228a24ef 171 s = scm_cell (SCM_MAKE_STRING_TAG (len), (scm_t_bits) mem);
be54b15d
DH
172
173 return s;
174}
175#undef FUNC_NAME
176
177
3b3b36dd 178SCM_DEFINE (scm_make_string, "make-string", 1, 1, 0,
6fa73e72 179 (SCM k, SCM chr),
0d26a824
MG
180 "Return a newly allocated string of\n"
181 "length @var{k}. If @var{chr} is given, then all elements of\n"
182 "the string are initialized to @var{chr}, otherwise the contents\n"
9401323e 183 "of the @var{string} are unspecified.")
1bbd0b84 184#define FUNC_NAME s_scm_make_string
0f2d19dd 185{
cb0d8be2 186 if (SCM_INUMP (k))
0f2d19dd 187 {
c014a02e 188 long int i = SCM_INUM (k);
cb0d8be2
DH
189 SCM res;
190
191 SCM_ASSERT_RANGE (1, k, i >= 0);
192
be54b15d 193 res = scm_allocate_string (i);
cb0d8be2
DH
194 if (!SCM_UNBNDP (chr))
195 {
196 unsigned char *dst;
197
198 SCM_VALIDATE_CHAR (2, chr);
199
200 dst = SCM_STRING_UCHARS (res);
201 memset (dst, SCM_CHAR (chr), i);
202 }
203
204 return res;
0f2d19dd 205 }
cb0d8be2
DH
206 else if (SCM_BIGP (k))
207 SCM_OUT_OF_RANGE (1, k);
208 else
209 SCM_WRONG_TYPE_ARG (1, k);
0f2d19dd 210}
1bbd0b84 211#undef FUNC_NAME
0f2d19dd 212
cb0d8be2 213
3b3b36dd 214SCM_DEFINE (scm_string_length, "string-length", 1, 0, 0,
0d26a824
MG
215 (SCM string),
216 "Return the number of characters in @var{string}.")
1bbd0b84 217#define FUNC_NAME s_scm_string_length
0f2d19dd 218{
d1ca2c64 219 SCM_VALIDATE_STRING (1, string);
93ccaef0 220 return SCM_I_MAKINUM (SCM_STRING_LENGTH (string));
0f2d19dd 221}
1bbd0b84 222#undef FUNC_NAME
0f2d19dd 223
bd9e24b3 224SCM_DEFINE (scm_string_ref, "string-ref", 2, 0, 0,
6fa73e72 225 (SCM str, SCM k),
0d26a824
MG
226 "Return character @var{k} of @var{str} using zero-origin\n"
227 "indexing. @var{k} must be a valid index of @var{str}.")
1bbd0b84 228#define FUNC_NAME s_scm_string_ref
0f2d19dd 229{
c014a02e 230 long idx;
bd9e24b3 231
d1ca2c64 232 SCM_VALIDATE_STRING (1, str);
bd9e24b3 233 SCM_VALIDATE_INUM_COPY (2, k, idx);
d1ca2c64 234 SCM_ASSERT_RANGE (2, k, idx >= 0 && idx < SCM_STRING_LENGTH (str));
34f0f2b8 235 return SCM_MAKE_CHAR (SCM_STRING_UCHARS (str)[idx]);
0f2d19dd 236}
1bbd0b84 237#undef FUNC_NAME
0f2d19dd 238
f0942910 239
3b3b36dd 240SCM_DEFINE (scm_string_set_x, "string-set!", 3, 0, 0,
6fa73e72 241 (SCM str, SCM k, SCM chr),
0d26a824
MG
242 "Store @var{chr} in element @var{k} of @var{str} and return\n"
243 "an unspecified value. @var{k} must be a valid index of\n"
244 "@var{str}.")
1bbd0b84 245#define FUNC_NAME s_scm_string_set_x
0f2d19dd 246{
f0942910 247 SCM_VALIDATE_STRING (1, str);
34d19ef6
HWN
248 SCM_VALIDATE_INUM_RANGE (2, k,0, SCM_STRING_LENGTH(str));
249 SCM_VALIDATE_CHAR (3, chr);
322ac0c5 250 SCM_STRING_UCHARS (str)[SCM_INUM (k)] = SCM_CHAR (chr);
0f2d19dd
JB
251 return SCM_UNSPECIFIED;
252}
1bbd0b84 253#undef FUNC_NAME
0f2d19dd
JB
254
255
3b3b36dd 256SCM_DEFINE (scm_substring, "substring", 2, 1, 0,
0d26a824
MG
257 (SCM str, SCM start, SCM end),
258 "Return a newly allocated string formed from the characters\n"
259 "of @var{str} beginning with index @var{start} (inclusive) and\n"
260 "ending with index @var{end} (exclusive).\n"
261 "@var{str} must be a string, @var{start} and @var{end} must be\n"
262 "exact integers satisfying:\n\n"
263 "0 <= @var{start} <= @var{end} <= (string-length @var{str}).")
1bbd0b84 264#define FUNC_NAME s_scm_substring
0f2d19dd 265{
c014a02e
ML
266 long int from;
267 long int to;
36284627 268 SCM substr;
685c0d71 269
d1ca2c64 270 SCM_VALIDATE_STRING (1, str);
685c0d71 271 SCM_VALIDATE_INUM (2, start);
d1ca2c64 272 SCM_VALIDATE_INUM_DEF (3, end, SCM_STRING_LENGTH (str));
685c0d71
DH
273
274 from = SCM_INUM (start);
d1ca2c64 275 SCM_ASSERT_RANGE (2, start, 0 <= from && from <= SCM_STRING_LENGTH (str));
685c0d71 276 to = SCM_INUM (end);
d1ca2c64 277 SCM_ASSERT_RANGE (3, end, from <= to && to <= SCM_STRING_LENGTH (str));
685c0d71 278
36284627
DH
279 substr = scm_mem2string (&SCM_STRING_CHARS (str)[from], to - from);
280 scm_remember_upto_here_1 (str);
281 return substr;
0f2d19dd 282}
1bbd0b84 283#undef FUNC_NAME
0f2d19dd 284
685c0d71 285
3b3b36dd 286SCM_DEFINE (scm_string_append, "string-append", 0, 0, 1,
6fa73e72 287 (SCM args),
0d26a824
MG
288 "Return a newly allocated string whose characters form the\n"
289 "concatenation of the given strings, @var{args}.")
1bbd0b84 290#define FUNC_NAME s_scm_string_append
0f2d19dd
JB
291{
292 SCM res;
1be6b49c 293 size_t i = 0;
0f2d19dd 294 register SCM l, s;
a65b9c80 295 register unsigned char *data;
af45e3b0
DH
296
297 SCM_VALIDATE_REST_ARGUMENT (args);
298 for (l = args; !SCM_NULLP (l); l = SCM_CDR (l)) {
0f2d19dd 299 s = SCM_CAR (l);
34d19ef6 300 SCM_VALIDATE_STRING (SCM_ARGn, s);
d1ca2c64 301 i += SCM_STRING_LENGTH (s);
0f2d19dd 302 }
be54b15d 303 res = scm_allocate_string (i);
322ac0c5 304 data = SCM_STRING_UCHARS (res);
36284627 305 for (l = args; !SCM_NULLP (l);l = SCM_CDR (l)) {
0f2d19dd 306 s = SCM_CAR (l);
34f0f2b8 307 for (i = 0;i<SCM_STRING_LENGTH (s);i++) *data++ = SCM_STRING_UCHARS (s)[i];
0f2d19dd
JB
308 }
309 return res;
310}
1bbd0b84 311#undef FUNC_NAME
0f2d19dd 312
24933780 313
4d4528e7
SJ
314/* Converts the given Scheme string OBJ into a C string, containing a copy
315 of OBJ's content with a trailing null byte. If LENP is non-NULL, set
316 *LENP to the string's length.
317
318 When STR is non-NULL it receives the copy and is returned by the function,
319 otherwise new memory is allocated and the caller is responsible for
320 freeing it via free(). If out of memory, NULL is returned.
321
322 Note that Scheme strings may contain arbitrary data, including null
323 characters. This means that null termination is not a reliable way to
324 determine the length of the returned value. However, the function always
24933780
DH
325 copies the complete contents of OBJ, and sets *LENP to the length of the
326 scheme string (if LENP is non-null). */
af68e5e5 327#define FUNC_NAME "scm_c_string2str"
4d4528e7
SJ
328char *
329scm_c_string2str (SCM obj, char *str, size_t *lenp)
330{
331 size_t len;
332
af68e5e5 333 SCM_ASSERT (SCM_STRINGP (obj), obj, SCM_ARG1, FUNC_NAME);
4d4528e7
SJ
334 len = SCM_STRING_LENGTH (obj);
335
4d4528e7 336 if (str == NULL)
24933780
DH
337 {
338 /* FIXME: Should we use exported wrappers for malloc (and free), which
339 * allow windows DLLs to call the correct freeing function? */
67329a9e 340 str = (char *) scm_malloc ((len + 1) * sizeof (char));
24933780
DH
341 if (str == NULL)
342 return NULL;
343 }
4d4528e7
SJ
344
345 memcpy (str, SCM_STRING_CHARS (obj), len);
4d4528e7
SJ
346 scm_remember_upto_here_1 (obj);
347 str[len] = '\0';
348
349 if (lenp != NULL)
350 *lenp = len;
24933780 351
4d4528e7
SJ
352 return str;
353}
af68e5e5
SJ
354#undef FUNC_NAME
355
356
357/* Copy LEN characters at START from the Scheme string OBJ to memory
358 at STR. START is an index into OBJ; zero means the beginning of
359 the string. STR has already been allocated by the caller.
360
361 If START + LEN is off the end of OBJ, silently truncate the source
362 region to fit the string. If truncation occurs, the corresponding
363 area of STR is left unchanged. */
364#define FUNC_NAME "scm_c_substring2str"
365char *
366scm_c_substring2str (SCM obj, char *str, size_t start, size_t len)
367{
368 size_t src_length, effective_length;
369
370 SCM_ASSERT (SCM_STRINGP (obj), obj, SCM_ARG2, FUNC_NAME);
371 src_length = SCM_STRING_LENGTH (obj);
372 effective_length = (len + start <= src_length) ? len : src_length - start;
373 memcpy (str, SCM_STRING_CHARS (obj) + start, effective_length);
374 scm_remember_upto_here_1 (obj);
375 return str;
376}
377#undef FUNC_NAME
e53cc817 378
24933780 379
0f2d19dd
JB
380void
381scm_init_strings ()
0f2d19dd 382{
7c33806a
DH
383 scm_nullstr = scm_allocate_string (0);
384
a0599745 385#include "libguile/strings.x"
0f2d19dd
JB
386}
387
89e00824
ML
388
389/*
390 Local Variables:
391 c-file-style: "gnu"
392 End:
393*/