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_STRINGP (*str
), *str
, SCM_ARG1
, why
);
61 SCM_ASSERT (SCM_CHARP (chr
), chr
, SCM_ARG2
, why
);
63 if (scm_is_false (sub_start
))
64 sub_start
= SCM_I_MAKINUM (0);
66 SCM_ASSERT (SCM_INUMP (sub_start
), sub_start
, SCM_ARG3
, why
);
67 lower
= SCM_INUM (sub_start
);
68 if (lower
< 0 || lower
> SCM_STRING_LENGTH (*str
))
69 scm_out_of_range (why
, sub_start
);
71 if (scm_is_false (sub_end
))
72 sub_end
= SCM_I_MAKINUM (SCM_STRING_LENGTH (*str
));
74 SCM_ASSERT (SCM_INUMP (sub_end
), sub_end
, SCM_ARG4
, why
);
75 upper
= SCM_INUM (sub_end
);
76 if (upper
< SCM_INUM (sub_start
) || upper
> SCM_STRING_LENGTH (*str
))
77 scm_out_of_range (why
, sub_end
);
81 p
= SCM_STRING_UCHARS (*str
) + lower
;
84 for (x
= SCM_INUM (sub_start
); x
< upper
; ++x
, ++p
)
90 p
= upper
- 1 + SCM_STRING_UCHARS (*str
);
92 for (x
= upper
- 1; x
>= lower
; --x
, --p
)
100 SCM_DEFINE (scm_string_index
, "string-index", 2, 2, 0,
101 (SCM str
, SCM chr
, SCM frm
, SCM to
),
102 "Return the index of the first occurrence of @var{chr} in\n"
103 "@var{str}. The optional integer arguments @var{frm} and\n"
104 "@var{to} limit the search to a portion of the string. This\n"
105 "procedure essentially implements the @code{index} or\n"
106 "@code{strchr} functions from the C library.\n"
109 "(string-index \"weiner\" #\\e)\n"
111 "(string-index \"weiner\" #\\e 2)\n"
113 "(string-index \"weiner\" #\\e 2 4)\n"
116 #define FUNC_NAME s_scm_string_index
120 if (SCM_UNBNDP (frm
))
124 pos
= scm_i_index (&str
, chr
, 1, frm
, to
, FUNC_NAME
);
127 : SCM_I_MAKINUM (pos
));
131 SCM_DEFINE (scm_string_rindex
, "string-rindex", 2, 2, 0,
132 (SCM str
, SCM chr
, SCM frm
, SCM to
),
133 "Like @code{string-index}, but search from the right of the\n"
134 "string rather than from the left. This procedure essentially\n"
135 "implements the @code{rindex} or @code{strrchr} functions from\n"
139 "(string-rindex \"weiner\" #\\e)\n"
141 "(string-rindex \"weiner\" #\\e 2 4)\n"
143 "(string-rindex \"weiner\" #\\e 2 5)\n"
146 #define FUNC_NAME s_scm_string_rindex
150 if (SCM_UNBNDP (frm
))
154 pos
= scm_i_index (&str
, chr
, -1, frm
, to
, FUNC_NAME
);
157 : SCM_I_MAKINUM (pos
));
161 SCM_DEFINE (scm_substring_move_x
, "substring-move!", 5, 0, 0,
162 (SCM str1
, SCM start1
, SCM end1
, SCM str2
, SCM start2
),
163 "Copy the substring of @var{str1} bounded by @var{start1} and @var{end1}\n"
164 "into @var{str2} beginning at position @var{start2}.\n"
165 "@var{str1} and @var{str2} can be the same string.")
166 #define FUNC_NAME s_scm_substring_move_x
168 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_STRING_LENGTH(str1
));
173 e
= scm_to_unsigned_integer (end1
, s1
, SCM_STRING_LENGTH(str1
));
175 s2
= scm_to_unsigned_integer (start2
, 0, SCM_STRING_LENGTH(str2
)-len
);
177 SCM_SYSCALL(memmove((void *)(&(SCM_STRING_CHARS(str2
)[s2
])),
178 (void *)(&(SCM_STRING_CHARS(str1
)[s1
])),
181 return scm_return_first(SCM_UNSPECIFIED
, str1
, str2
);
186 SCM_DEFINE (scm_substring_fill_x
, "substring-fill!", 4, 0, 0,
187 (SCM str
, SCM start
, SCM end
, SCM fill
),
188 "Change every character in @var{str} between @var{start} and\n"
189 "@var{end} to @var{fill}.\n"
192 "(define y \"abcdefg\")\n"
193 "(substring-fill! y 1 3 #\\r)\n"
195 "@result{} \"arrdefg\"\n"
197 #define FUNC_NAME s_scm_substring_fill_x
201 SCM_VALIDATE_STRING (1, str
);
202 i
= scm_to_unsigned_integer (start
, 0, SCM_STRING_LENGTH (str
));
203 e
= scm_to_unsigned_integer (end
, i
, SCM_STRING_LENGTH (str
));
204 SCM_VALIDATE_CHAR_COPY (4, fill
, c
);
205 while (i
<e
) SCM_STRING_CHARS (str
)[i
++] = c
;
206 return SCM_UNSPECIFIED
;
211 SCM_DEFINE (scm_string_null_p
, "string-null?", 1, 0, 0,
213 "Return @code{#t} if @var{str}'s length is zero, and\n"
214 "@code{#f} otherwise.\n"
216 "(string-null? \"\") @result{} #t\n"
217 "y @result{} \"foo\"\n"
218 "(string-null? y) @result{} #f\n"
220 #define FUNC_NAME s_scm_string_null_p
222 SCM_VALIDATE_STRING (1, str
);
223 return scm_from_bool (SCM_STRING_LENGTH (str
) == 0);
228 SCM_DEFINE (scm_string_to_list
, "string->list", 1, 0, 0,
230 "Return a newly allocated list of the characters that make up\n"
231 "the given string @var{str}. @code{string->list} and\n"
232 "@code{list->string} are inverses as far as @samp{equal?} is\n"
234 #define FUNC_NAME s_scm_string_to_list
239 SCM_VALIDATE_STRING (1, str
);
240 src
= SCM_STRING_UCHARS (str
);
241 for (i
= SCM_STRING_LENGTH (str
)-1;i
>= 0;i
--) res
= scm_cons (SCM_MAKE_CHAR (src
[i
]), res
);
247 /* Helper function for the string copy and string conversion functions.
248 * No argument checking is performed. */
250 string_copy (SCM str
)
252 const char* chars
= SCM_STRING_CHARS (str
);
253 size_t length
= SCM_STRING_LENGTH (str
);
254 SCM new_string
= scm_mem2string (chars
, length
);
255 scm_remember_upto_here_1 (str
);
260 SCM_DEFINE (scm_string_copy
, "string-copy", 1, 0, 0,
262 "Return a newly allocated copy of the given @var{string}.")
263 #define FUNC_NAME s_scm_string_copy
265 SCM_VALIDATE_STRING (1, str
);
267 return string_copy (str
);
272 SCM_DEFINE (scm_string_fill_x
, "string-fill!", 2, 0, 0,
274 "Store @var{char} in every element of the given @var{string} and\n"
275 "return an unspecified value.")
276 #define FUNC_NAME s_scm_string_fill_x
278 register char *dst
, c
;
280 SCM_VALIDATE_STRING_COPY (1, str
, dst
);
281 SCM_VALIDATE_CHAR_COPY (2, chr
, c
);
282 for (k
= SCM_STRING_LENGTH (str
)-1;k
>= 0;k
--) dst
[k
] = c
;
283 return SCM_UNSPECIFIED
;
288 /* Helper function for the string uppercase conversion functions.
289 * No argument checking is performed. */
291 string_upcase_x (SCM v
)
295 for (k
= 0; k
< SCM_STRING_LENGTH (v
); ++k
)
296 SCM_STRING_UCHARS (v
) [k
] = scm_c_upcase (SCM_STRING_UCHARS (v
) [k
]);
302 SCM_DEFINE (scm_string_upcase_x
, "string-upcase!", 1, 0, 0,
304 "Destructively upcase every character in @var{str} and return\n"
307 "y @result{} \"arrdefg\"\n"
308 "(string-upcase! y) @result{} \"ARRDEFG\"\n"
309 "y @result{} \"ARRDEFG\"\n"
311 #define FUNC_NAME s_scm_string_upcase_x
313 SCM_VALIDATE_STRING (1, str
);
315 return string_upcase_x (str
);
320 SCM_DEFINE (scm_string_upcase
, "string-upcase", 1, 0, 0,
322 "Return a freshly allocated string containing the characters of\n"
323 "@var{str} in upper case.")
324 #define FUNC_NAME s_scm_string_upcase
326 SCM_VALIDATE_STRING (1, str
);
328 return string_upcase_x (string_copy (str
));
333 /* Helper function for the string lowercase conversion functions.
334 * No argument checking is performed. */
336 string_downcase_x (SCM v
)
340 for (k
= 0; k
< SCM_STRING_LENGTH (v
); ++k
)
341 SCM_STRING_UCHARS (v
) [k
] = scm_c_downcase (SCM_STRING_UCHARS (v
) [k
]);
347 SCM_DEFINE (scm_string_downcase_x
, "string-downcase!", 1, 0, 0,
349 "Destructively downcase every character in @var{str} and return\n"
352 "y @result{} \"ARRDEFG\"\n"
353 "(string-downcase! y) @result{} \"arrdefg\"\n"
354 "y @result{} \"arrdefg\"\n"
356 #define FUNC_NAME s_scm_string_downcase_x
358 SCM_VALIDATE_STRING (1, str
);
360 return string_downcase_x (str
);
365 SCM_DEFINE (scm_string_downcase
, "string-downcase", 1, 0, 0,
367 "Return a freshly allocation string containing the characters in\n"
368 "@var{str} in lower case.")
369 #define FUNC_NAME s_scm_string_downcase
371 SCM_VALIDATE_STRING (1, str
);
373 return string_downcase_x (string_copy (str
));
378 /* Helper function for the string capitalization functions.
379 * No argument checking is performed. */
381 string_capitalize_x (SCM str
)
387 len
= SCM_STRING_LENGTH(str
);
388 sz
= SCM_STRING_UCHARS (str
);
389 for(i
=0; i
<len
; i
++) {
390 if (scm_is_true (scm_char_alphabetic_p (SCM_MAKE_CHAR (sz
[i
])))) {
392 sz
[i
] = scm_c_upcase(sz
[i
]);
395 sz
[i
] = scm_c_downcase(sz
[i
]);
404 SCM_DEFINE (scm_string_capitalize_x
, "string-capitalize!", 1, 0, 0,
406 "Upcase the first character of every word in @var{str}\n"
407 "destructively and return @var{str}.\n"
410 "y @result{} \"hello world\"\n"
411 "(string-capitalize! y) @result{} \"Hello World\"\n"
412 "y @result{} \"Hello World\"\n"
414 #define FUNC_NAME s_scm_string_capitalize_x
416 SCM_VALIDATE_STRING (1, str
);
418 return string_capitalize_x (str
);
423 SCM_DEFINE (scm_string_capitalize
, "string-capitalize", 1, 0, 0,
425 "Return a freshly allocated string with the characters in\n"
426 "@var{str}, where the first character of every word is\n"
428 #define FUNC_NAME s_scm_string_capitalize
430 SCM_VALIDATE_STRING (1, str
);
432 return string_capitalize_x (string_copy (str
));
437 SCM_DEFINE (scm_string_split
, "string-split", 2, 0, 0,
439 "Split the string @var{str} into the a list of the substrings delimited\n"
440 "by appearances of the character @var{chr}. Note that an empty substring\n"
441 "between separator characters will result in an empty string in the\n"
445 "(string-split \"root:x:0:0:root:/root:/bin/bash\" #\\:)\n"
447 "(\"root\" \"x\" \"0\" \"0\" \"root\" \"/root\" \"/bin/bash\")\n"
449 "(string-split \"::\" #\\:)\n"
453 "(string-split \"\" #\\:)\n"
457 #define FUNC_NAME s_scm_string_split
464 SCM_VALIDATE_STRING (1, str
);
465 SCM_VALIDATE_CHAR (2, chr
);
467 idx
= SCM_STRING_LENGTH (str
);
468 p
= SCM_STRING_CHARS (str
);
473 while (idx
> 0 && p
[idx
- 1] != ch
)
477 res
= scm_cons (scm_mem2string (p
+ idx
, last_idx
- idx
), res
);
481 scm_remember_upto_here_1 (str
);
487 SCM_DEFINE (scm_string_ci_to_symbol
, "string-ci->symbol", 1, 0, 0,
489 "Return the symbol whose name is @var{str}. @var{str} is\n"
490 "converted to lowercase before the conversion is done, if Guile\n"
491 "is currently reading symbols case-insensitively.")
492 #define FUNC_NAME s_scm_string_ci_to_symbol
494 return scm_string_to_symbol (SCM_CASE_INSENSITIVE_P
495 ? scm_string_downcase(str
)
503 #include "libguile/strop.x"