b4a7063cfdb8ccdcc990661e8b5cc494390b0ac9
1 /* classes: src_files */
3 /* Copyright (C) 1994,1996,1997,1999,2000,2001 Free Software Foundation, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "libguile/_scm.h"
28 #include "libguile/chars.h"
29 #include "libguile/strings.h"
31 #include "libguile/validate.h"
32 #include "libguile/strop.h"
33 #include "libguile/read.h" /*For SCM_CASE_INSENSITIVE_P*/
42 xSCM_DEFINE (scm_i_index, "i-index", 2, 2, 0,
43 (SCM str, SCM chr, SCM frm, SCM to),
44 "@deftypefn {Internal C Function} {static int} scm_i_index (SCM *@var{str},\n"
45 "SCM @var{chr}, int @var{direction}, SCM @var{sub_start}, SCM @var{sub_end}, char *@var{why})
46 "This is a workhorse function that performs either an @code{index} or\n"
47 "@code{rindex} function, depending on the value of @var{direction}."
49 /* implements index if direction > 0 otherwise rindex. */
51 scm_i_index (SCM str
, SCM chr
, int direction
, SCM sub_start
,
52 SCM sub_end
, const char *why
)
60 SCM_ASSERT (scm_is_string (str
), str
, SCM_ARG1
, why
);
61 SCM_ASSERT (SCM_CHARP (chr
), chr
, SCM_ARG2
, why
);
63 if (scm_is_false (sub_start
))
66 lower
= scm_to_signed_integer (sub_start
, 0, scm_i_string_length(str
));
68 if (scm_is_false (sub_end
))
69 upper
= scm_i_string_length (str
);
71 upper
= scm_to_signed_integer (sub_end
, lower
, scm_i_string_length(str
));
77 p
= (unsigned char *) scm_i_string_chars (str
) + lower
;
80 for (x
= lower
; x
< upper
; ++x
, ++p
)
86 p
= upper
- 1 + (unsigned char *)scm_i_string_chars (str
);
88 for (x
= upper
- 1; x
>= lower
; --x
, --p
)
94 scm_remember_upto_here_1 (str
);
98 SCM_DEFINE (scm_string_index
, "string-index", 2, 2, 0,
99 (SCM str
, SCM chr
, SCM frm
, SCM to
),
100 "Return the index of the first occurrence of @var{chr} in\n"
101 "@var{str}. The optional integer arguments @var{frm} and\n"
102 "@var{to} limit the search to a portion of the string. This\n"
103 "procedure essentially implements the @code{index} or\n"
104 "@code{strchr} functions from the C library.\n"
107 "(string-index \"weiner\" #\\e)\n"
109 "(string-index \"weiner\" #\\e 2)\n"
111 "(string-index \"weiner\" #\\e 2 4)\n"
114 #define FUNC_NAME s_scm_string_index
118 if (SCM_UNBNDP (frm
))
122 pos
= scm_i_index (str
, chr
, 1, frm
, to
, FUNC_NAME
);
125 : scm_from_long (pos
));
129 SCM_DEFINE (scm_string_rindex
, "string-rindex", 2, 2, 0,
130 (SCM str
, SCM chr
, SCM frm
, SCM to
),
131 "Like @code{string-index}, but search from the right of the\n"
132 "string rather than from the left. This procedure essentially\n"
133 "implements the @code{rindex} or @code{strrchr} functions from\n"
137 "(string-rindex \"weiner\" #\\e)\n"
139 "(string-rindex \"weiner\" #\\e 2 4)\n"
141 "(string-rindex \"weiner\" #\\e 2 5)\n"
144 #define FUNC_NAME s_scm_string_rindex
148 if (SCM_UNBNDP (frm
))
152 pos
= scm_i_index (str
, chr
, -1, frm
, to
, FUNC_NAME
);
155 : scm_from_long (pos
));
159 SCM_DEFINE (scm_substring_move_x
, "substring-move!", 5, 0, 0,
160 (SCM str1
, SCM start1
, SCM end1
, SCM str2
, SCM start2
),
161 "Copy the substring of @var{str1} bounded by @var{start1} and @var{end1}\n"
162 "into @var{str2} beginning at position @var{start2}.\n"
163 "@var{str1} and @var{str2} can be the same string.")
164 #define FUNC_NAME s_scm_substring_move_x
166 unsigned long s1
, s2
, e
, len
;
170 SCM_VALIDATE_STRING (1, str1
);
171 SCM_VALIDATE_STRING (4, str2
);
172 s1
= scm_to_unsigned_integer (start1
, 0, scm_i_string_length(str1
));
173 e
= scm_to_unsigned_integer (end1
, s1
, scm_i_string_length(str1
));
175 s2
= scm_to_unsigned_integer (start2
, 0, scm_i_string_length(str2
)-len
);
177 src
= scm_i_string_chars (str2
);
178 dst
= scm_i_string_writable_chars (str1
);
179 SCM_SYSCALL (memmove (dst
+s2
, src
+s1
, len
));
180 scm_i_string_stop_writing ();
182 scm_remember_upto_here_2 (str1
, str2
);
183 return SCM_UNSPECIFIED
;
188 SCM_DEFINE (scm_substring_fill_x
, "substring-fill!", 4, 0, 0,
189 (SCM str
, SCM start
, SCM end
, SCM fill
),
190 "Change every character in @var{str} between @var{start} and\n"
191 "@var{end} to @var{fill}.\n"
194 "(define y \"abcdefg\")\n"
195 "(substring-fill! y 1 3 #\\r)\n"
197 "@result{} \"arrdefg\"\n"
199 #define FUNC_NAME s_scm_substring_fill_x
205 SCM_VALIDATE_STRING (1, str
);
206 i
= scm_to_unsigned_integer (start
, 0, scm_i_string_length (str
));
207 e
= scm_to_unsigned_integer (end
, i
, scm_i_string_length (str
));
208 SCM_VALIDATE_CHAR_COPY (4, fill
, c
);
209 dst
= scm_i_string_writable_chars (str
);
212 scm_i_string_stop_writing ();
213 scm_remember_upto_here (str
);
214 return SCM_UNSPECIFIED
;
219 SCM_DEFINE (scm_string_null_p
, "string-null?", 1, 0, 0,
221 "Return @code{#t} if @var{str}'s length is zero, and\n"
222 "@code{#f} otherwise.\n"
224 "(string-null? \"\") @result{} #t\n"
225 "y @result{} \"foo\"\n"
226 "(string-null? y) @result{} #f\n"
228 #define FUNC_NAME s_scm_string_null_p
230 SCM_VALIDATE_STRING (1, str
);
231 return scm_from_bool (scm_i_string_length (str
) == 0);
236 SCM_DEFINE (scm_string_to_list
, "string->list", 1, 0, 0,
238 "Return a newly allocated list of the characters that make up\n"
239 "the given string @var{str}. @code{string->list} and\n"
240 "@code{list->string} are inverses as far as @samp{equal?} is\n"
242 #define FUNC_NAME s_scm_string_to_list
246 const unsigned char *src
;
247 SCM_VALIDATE_STRING (1, str
);
248 src
= scm_i_string_chars (str
);
249 for (i
= scm_i_string_length (str
)-1;i
>= 0;i
--)
250 res
= scm_cons (SCM_MAKE_CHAR (src
[i
]), res
);
251 scm_remember_upto_here_1 (src
);
257 /* Helper function for the string copy and string conversion functions.
258 * No argument checking is performed. */
260 string_copy (SCM str
)
262 const char* chars
= scm_i_string_chars (str
);
263 size_t length
= scm_i_string_length (str
);
265 SCM new_string
= scm_i_make_string (length
, &dst
);
266 memcpy (dst
, chars
, length
);
267 scm_remember_upto_here_1 (str
);
272 SCM_DEFINE (scm_string_copy
, "string-copy", 1, 0, 0,
274 "Return a newly allocated copy of the given @var{string}.")
275 #define FUNC_NAME s_scm_string_copy
277 SCM_VALIDATE_STRING (1, str
);
279 return string_copy (str
);
284 SCM_DEFINE (scm_string_fill_x
, "string-fill!", 2, 0, 0,
286 "Store @var{char} in every element of the given @var{string} and\n"
287 "return an unspecified value.")
288 #define FUNC_NAME s_scm_string_fill_x
292 SCM_VALIDATE_STRING (1, str
);
293 SCM_VALIDATE_CHAR_COPY (2, chr
, c
);
294 dst
= scm_i_string_writable_chars (str
);
295 for (k
= scm_i_string_length (str
)-1;k
>= 0;k
--)
297 scm_i_string_stop_writing ();
298 scm_remember_upto_here_1 (str
);
299 return SCM_UNSPECIFIED
;
304 /* Helper function for the string uppercase conversion functions.
305 * No argument checking is performed. */
307 string_upcase_x (SCM v
)
312 len
= scm_i_string_length (v
);
313 dst
= scm_i_string_writable_chars (v
);
314 for (k
= 0; k
< len
; ++k
)
315 dst
[k
] = scm_c_upcase (dst
[k
]);
316 scm_i_string_stop_writing ();
321 SCM_DEFINE (scm_string_upcase_x
, "string-upcase!", 1, 0, 0,
323 "Destructively upcase every character in @var{str} and return\n"
326 "y @result{} \"arrdefg\"\n"
327 "(string-upcase! y) @result{} \"ARRDEFG\"\n"
328 "y @result{} \"ARRDEFG\"\n"
330 #define FUNC_NAME s_scm_string_upcase_x
332 SCM_VALIDATE_STRING (1, str
);
334 return string_upcase_x (str
);
339 SCM_DEFINE (scm_string_upcase
, "string-upcase", 1, 0, 0,
341 "Return a freshly allocated string containing the characters of\n"
342 "@var{str} in upper case.")
343 #define FUNC_NAME s_scm_string_upcase
345 SCM_VALIDATE_STRING (1, str
);
347 return string_upcase_x (string_copy (str
));
352 /* Helper function for the string lowercase conversion functions.
353 * No argument checking is performed. */
355 string_downcase_x (SCM v
)
360 len
= scm_i_string_length (v
);
361 dst
= scm_i_string_writable_chars (v
);
362 for (k
= 0; k
< len
; ++k
)
363 dst
[k
] = scm_c_downcase (dst
[k
]);
364 scm_i_string_stop_writing ();
370 SCM_DEFINE (scm_string_downcase_x
, "string-downcase!", 1, 0, 0,
372 "Destructively downcase every character in @var{str} and return\n"
375 "y @result{} \"ARRDEFG\"\n"
376 "(string-downcase! y) @result{} \"arrdefg\"\n"
377 "y @result{} \"arrdefg\"\n"
379 #define FUNC_NAME s_scm_string_downcase_x
381 SCM_VALIDATE_STRING (1, str
);
383 return string_downcase_x (str
);
388 SCM_DEFINE (scm_string_downcase
, "string-downcase", 1, 0, 0,
390 "Return a freshly allocation string containing the characters in\n"
391 "@var{str} in lower case.")
392 #define FUNC_NAME s_scm_string_downcase
394 SCM_VALIDATE_STRING (1, str
);
396 return string_downcase_x (string_copy (str
));
401 /* Helper function for the string capitalization functions.
402 * No argument checking is performed. */
404 string_capitalize_x (SCM str
)
410 len
= scm_i_string_length (str
);
411 sz
= scm_i_string_writable_chars (str
);
412 for (i
= 0; i
< len
; i
++)
414 if (scm_is_true (scm_char_alphabetic_p (SCM_MAKE_CHAR (sz
[i
]))))
418 sz
[i
] = scm_c_upcase (sz
[i
]);
423 sz
[i
] = scm_c_downcase (sz
[i
]);
429 scm_i_string_stop_writing ();
434 SCM_DEFINE (scm_string_capitalize_x
, "string-capitalize!", 1, 0, 0,
436 "Upcase the first character of every word in @var{str}\n"
437 "destructively and return @var{str}.\n"
440 "y @result{} \"hello world\"\n"
441 "(string-capitalize! y) @result{} \"Hello World\"\n"
442 "y @result{} \"Hello World\"\n"
444 #define FUNC_NAME s_scm_string_capitalize_x
446 SCM_VALIDATE_STRING (1, str
);
448 return string_capitalize_x (str
);
453 SCM_DEFINE (scm_string_capitalize
, "string-capitalize", 1, 0, 0,
455 "Return a freshly allocated string with the characters in\n"
456 "@var{str}, where the first character of every word is\n"
458 #define FUNC_NAME s_scm_string_capitalize
460 SCM_VALIDATE_STRING (1, str
);
462 return string_capitalize_x (string_copy (str
));
467 SCM_DEFINE (scm_string_split
, "string-split", 2, 0, 0,
469 "Split the string @var{str} into the a list of the substrings delimited\n"
470 "by appearances of the character @var{chr}. Note that an empty substring\n"
471 "between separator characters will result in an empty string in the\n"
475 "(string-split \"root:x:0:0:root:/root:/bin/bash\" #\\:)\n"
477 "(\"root\" \"x\" \"0\" \"0\" \"root\" \"/root\" \"/bin/bash\")\n"
479 "(string-split \"::\" #\\:)\n"
483 "(string-split \"\" #\\:)\n"
487 #define FUNC_NAME s_scm_string_split
494 SCM_VALIDATE_STRING (1, str
);
495 SCM_VALIDATE_CHAR (2, chr
);
497 idx
= scm_i_string_length (str
);
498 p
= scm_i_string_chars (str
);
503 while (idx
> 0 && p
[idx
- 1] != ch
)
507 res
= scm_cons (scm_c_substring (str
, idx
, last_idx
), res
);
508 p
= scm_i_string_chars (str
);
512 scm_remember_upto_here_1 (str
);
518 SCM_DEFINE (scm_string_ci_to_symbol
, "string-ci->symbol", 1, 0, 0,
520 "Return the symbol whose name is @var{str}. @var{str} is\n"
521 "converted to lowercase before the conversion is done, if Guile\n"
522 "is currently reading symbols case-insensitively.")
523 #define FUNC_NAME s_scm_string_ci_to_symbol
525 return scm_string_to_symbol (SCM_CASE_INSENSITIVE_P
526 ? scm_string_downcase(str
)
534 #include "libguile/strop.x"