1 /* classes: src_files */
3 /* Copyright (C) 1994,1996,1997,1999,2000,2001 Free Software Foundation, Inc.
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2, or (at your option)
10 This program 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
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this software; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 As a special exception, the Free Software Foundation gives permission
21 for additional uses of the text contained in its release of GUILE.
23 The exception is that, if you link the GUILE library with other files
24 to produce an executable, this does not by itself cause the
25 resulting executable to be covered by the GNU General Public License.
26 Your use of that executable is in no way restricted on account of
27 linking the GUILE library code into it.
29 This exception does not however invalidate any other reasons why
30 the executable file might be covered by the GNU General Public License.
32 This exception applies only to the code released by the
33 Free Software Foundation under the name GUILE. If you copy
34 code from other Free Software Foundation releases into a copy of
35 GUILE, as the General Public License permits, the exception does
36 not apply to the code that you add in this way. To avoid misleading
37 anyone as to the status of such modified files, you must delete
38 this exception notice from them.
40 If you write modifications of your own for GUILE, it is your choice
41 whether to permit this exception to apply to your modifications.
42 If you do not wish that, delete this exception notice. */
51 #include "libguile/_scm.h"
52 #include "libguile/chars.h"
53 #include "libguile/strings.h"
55 #include "libguile/validate.h"
56 #include "libguile/strop.h"
57 #include "libguile/read.h" /*For SCM_CASE_INSENSITIVE_P*/
66 xSCM_DEFINE (scm_i_index, "i-index", 2, 2, 0,
67 (SCM str, SCM chr, SCM frm, SCM to),
68 "@deftypefn {Internal C Function} {static int} scm_i_index (SCM *@var{str},\n"
69 "SCM @var{chr}, int @var{direction}, SCM @var{sub_start}, SCM @var{sub_end}, char *@var{why})
70 "This is a workhorse function that performs either an @code{index} or\n"
71 "@code{rindex} function, depending on the value of @var{direction}."
73 /* implements index if direction > 0 otherwise rindex. */
75 scm_i_index (SCM
*str
, SCM chr
, int direction
, SCM sub_start
,
76 SCM sub_end
, const char *why
)
84 SCM_ASSERT (SCM_STRINGP (*str
), *str
, SCM_ARG1
, why
);
85 SCM_ASSERT (SCM_CHARP (chr
), chr
, SCM_ARG2
, why
);
87 if (SCM_FALSEP (sub_start
))
88 sub_start
= SCM_MAKINUM (0);
90 SCM_ASSERT (SCM_INUMP (sub_start
), sub_start
, SCM_ARG3
, why
);
91 lower
= SCM_INUM (sub_start
);
92 if (lower
< 0 || lower
> SCM_STRING_LENGTH (*str
))
93 scm_out_of_range (why
, sub_start
);
95 if (SCM_FALSEP (sub_end
))
96 sub_end
= SCM_MAKINUM (SCM_STRING_LENGTH (*str
));
98 SCM_ASSERT (SCM_INUMP (sub_end
), sub_end
, SCM_ARG4
, why
);
99 upper
= SCM_INUM (sub_end
);
100 if (upper
< SCM_INUM (sub_start
) || upper
> SCM_STRING_LENGTH (*str
))
101 scm_out_of_range (why
, sub_end
);
105 p
= SCM_STRING_UCHARS (*str
) + lower
;
108 for (x
= SCM_INUM (sub_start
); x
< upper
; ++x
, ++p
)
114 p
= upper
- 1 + SCM_STRING_UCHARS (*str
);
116 for (x
= upper
- 1; x
>= lower
; --x
, --p
)
124 SCM_DEFINE (scm_string_index
, "string-index", 2, 2, 0,
125 (SCM str
, SCM chr
, SCM frm
, SCM to
),
126 "Return the index of the first occurrence of @var{chr} in\n"
127 "@var{str}. The optional integer arguments @var{frm} and\n"
128 "@var{to} limit the search to a portion of the string. This\n"
129 "procedure essentially implements the @code{index} or\n"
130 "@code{strchr} functions from the C library.\n"
133 "(string-index \"weiner\" #\\e)\n"
135 "(string-index \"weiner\" #\\e 2)\n"
137 "(string-index \"weiner\" #\\e 2 4)\n"
140 #define FUNC_NAME s_scm_string_index
144 if (SCM_UNBNDP (frm
))
148 pos
= scm_i_index (&str
, chr
, 1, frm
, to
, FUNC_NAME
);
151 : SCM_MAKINUM (pos
));
155 SCM_DEFINE (scm_string_rindex
, "string-rindex", 2, 2, 0,
156 (SCM str
, SCM chr
, SCM frm
, SCM to
),
157 "Like @code{string-index}, but search from the right of the\n"
158 "string rather than from the left. This procedure essentially\n"
159 "implements the @code{rindex} or @code{strrchr} functions from\n"
163 "(string-rindex \"weiner\" #\\e)\n"
165 "(string-rindex \"weiner\" #\\e 2 4)\n"
167 "(string-rindex \"weiner\" #\\e 2 5)\n"
170 #define FUNC_NAME s_scm_string_rindex
174 if (SCM_UNBNDP (frm
))
178 pos
= scm_i_index (&str
, chr
, -1, frm
, to
, FUNC_NAME
);
181 : SCM_MAKINUM (pos
));
185 SCM_DEFINE (scm_substring_move_x
, "substring-move!", 5, 0, 0,
186 (SCM str1
, SCM start1
, SCM end1
, SCM str2
, SCM start2
),
187 "Copy the substring of @var{str1} bounded by @var{start1} and @var{end1}\n"
188 "into @var{str2} beginning at position @var{start2}.\n"
189 "@var{str1} and @var{str2} can be the same string.")
190 #define FUNC_NAME s_scm_substring_move_x
194 SCM_VALIDATE_STRING (1, str1
);
195 SCM_VALIDATE_INUM_COPY (2, start1
, s1
);
196 SCM_VALIDATE_INUM_COPY (3, end1
, e
);
197 SCM_VALIDATE_STRING (4, str2
);
198 SCM_VALIDATE_INUM_COPY (5, start2
, s2
);
200 SCM_ASSERT_RANGE (3, end1
, len
>= 0);
201 SCM_ASSERT_RANGE (2, start1
, s1
<= SCM_STRING_LENGTH (str1
) && s1
>= 0);
202 SCM_ASSERT_RANGE (5, start2
, s2
<= SCM_STRING_LENGTH (str2
) && s2
>= 0);
203 SCM_ASSERT_RANGE (3, end1
, e
<= SCM_STRING_LENGTH (str1
) && e
>= 0);
204 SCM_ASSERT_RANGE (5, start2
, len
+s2
<= SCM_STRING_LENGTH (str2
));
206 SCM_SYSCALL(memmove((void *)(&(SCM_STRING_CHARS(str2
)[s2
])),
207 (void *)(&(SCM_STRING_CHARS(str1
)[s1
])),
210 return scm_return_first(SCM_UNSPECIFIED
, str1
, str2
);
215 SCM_DEFINE (scm_substring_fill_x
, "substring-fill!", 4, 0, 0,
216 (SCM str
, SCM start
, SCM end
, SCM fill
),
217 "Change every character in @var{str} between @var{start} and\n"
218 "@var{end} to @var{fill}.\n"
221 "(define y \"abcdefg\")\n"
222 "(substring-fill! y 1 3 #\\r)\n"
224 "@result{} \"arrdefg\"\n"
226 #define FUNC_NAME s_scm_substring_fill_x
230 SCM_VALIDATE_STRING (1, str
);
231 SCM_VALIDATE_INUM_COPY (2, start
, i
);
232 SCM_VALIDATE_INUM_COPY (3, end
, e
);
233 SCM_VALIDATE_CHAR_COPY (4, fill
, c
);
234 SCM_ASSERT_RANGE (2, start
, i
<= SCM_STRING_LENGTH (str
) && i
>= 0);
235 SCM_ASSERT_RANGE (3, end
, e
<= SCM_STRING_LENGTH (str
) && e
>= 0);
236 while (i
<e
) SCM_STRING_CHARS (str
)[i
++] = c
;
237 return SCM_UNSPECIFIED
;
242 SCM_DEFINE (scm_string_null_p
, "string-null?", 1, 0, 0,
244 "Return @code{#t} if @var{str}'s length is zero, and\n"
245 "@code{#f} otherwise.\n"
247 "(string-null? \"\") @result{} #t\n"
248 "y @result{} \"foo\"\n"
249 "(string-null? y) @result{} #f\n"
251 #define FUNC_NAME s_scm_string_null_p
253 SCM_VALIDATE_STRING (1, str
);
254 return SCM_BOOL (SCM_STRING_LENGTH (str
) == 0);
259 SCM_DEFINE (scm_string_to_list
, "string->list", 1, 0, 0,
261 "Return a newly allocated list of the characters that make up\n"
262 "the given string @var{str}. @code{string->list} and\n"
263 "@code{list->string} are inverses as far as @samp{equal?} is\n"
265 #define FUNC_NAME s_scm_string_to_list
270 SCM_VALIDATE_STRING (1, str
);
271 src
= SCM_STRING_UCHARS (str
);
272 for (i
= SCM_STRING_LENGTH (str
)-1;i
>= 0;i
--) res
= scm_cons (SCM_MAKE_CHAR (src
[i
]), res
);
278 /* Helper function for the string copy and string conversion functions.
279 * No argument checking is performed. */
281 string_copy (SCM str
)
283 const char* chars
= SCM_STRING_CHARS (str
);
284 size_t length
= SCM_STRING_LENGTH (str
);
285 SCM new_string
= scm_mem2string (chars
, length
);
286 scm_remember_upto_here_1 (str
);
291 SCM_DEFINE (scm_string_copy
, "string-copy", 1, 0, 0,
293 "Return a newly allocated copy of the given @var{string}.")
294 #define FUNC_NAME s_scm_string_copy
296 SCM_VALIDATE_STRING (1, str
);
298 return string_copy (str
);
303 SCM_DEFINE (scm_string_fill_x
, "string-fill!", 2, 0, 0,
305 "Store @var{char} in every element of the given @var{string} and\n"
306 "return an unspecified value.")
307 #define FUNC_NAME s_scm_string_fill_x
309 register char *dst
, c
;
311 SCM_VALIDATE_STRING_COPY (1, str
, dst
);
312 SCM_VALIDATE_CHAR_COPY (2, chr
, c
);
313 for (k
= SCM_STRING_LENGTH (str
)-1;k
>= 0;k
--) dst
[k
] = c
;
314 return SCM_UNSPECIFIED
;
319 /* Helper function for the string uppercase conversion functions.
320 * No argument checking is performed. */
322 string_upcase_x (SCM v
)
326 for (k
= 0; k
< SCM_STRING_LENGTH (v
); ++k
)
327 SCM_STRING_UCHARS (v
) [k
] = scm_upcase (SCM_STRING_UCHARS (v
) [k
]);
333 SCM_DEFINE (scm_string_upcase_x
, "string-upcase!", 1, 0, 0,
335 "Destructively upcase every character in @var{str} and return\n"
338 "y @result{} \"arrdefg\"\n"
339 "(string-upcase! y) @result{} \"ARRDEFG\"\n"
340 "y @result{} \"ARRDEFG\"\n"
342 #define FUNC_NAME s_scm_string_upcase_x
344 SCM_VALIDATE_STRING (1, str
);
346 return string_upcase_x (str
);
351 SCM_DEFINE (scm_string_upcase
, "string-upcase", 1, 0, 0,
353 "Return a freshly allocated string containing the characters of\n"
354 "@var{str} in upper case.")
355 #define FUNC_NAME s_scm_string_upcase
357 SCM_VALIDATE_STRING (1, str
);
359 return string_upcase_x (string_copy (str
));
364 /* Helper function for the string lowercase conversion functions.
365 * No argument checking is performed. */
367 string_downcase_x (SCM v
)
371 for (k
= 0; k
< SCM_STRING_LENGTH (v
); ++k
)
372 SCM_STRING_UCHARS (v
) [k
] = scm_downcase (SCM_STRING_UCHARS (v
) [k
]);
378 SCM_DEFINE (scm_string_downcase_x
, "string-downcase!", 1, 0, 0,
380 "Destructively downcase every character in @var{str} and return\n"
383 "y @result{} \"ARRDEFG\"\n"
384 "(string-downcase! y) @result{} \"arrdefg\"\n"
385 "y @result{} \"arrdefg\"\n"
387 #define FUNC_NAME s_scm_string_downcase_x
389 SCM_VALIDATE_STRING (1, str
);
391 return string_downcase_x (str
);
396 SCM_DEFINE (scm_string_downcase
, "string-downcase", 1, 0, 0,
398 "Return a freshly allocation string containing the characters in\n"
399 "@var{str} in lower case.")
400 #define FUNC_NAME s_scm_string_downcase
402 SCM_VALIDATE_STRING (1, str
);
404 return string_downcase_x (string_copy (str
));
409 /* Helper function for the string capitalization functions.
410 * No argument checking is performed. */
412 string_capitalize_x (SCM str
)
418 len
= SCM_STRING_LENGTH(str
);
419 sz
= SCM_STRING_UCHARS (str
);
420 for(i
=0; i
<len
; i
++) {
421 if (!SCM_FALSEP (scm_char_alphabetic_p (SCM_MAKE_CHAR (sz
[i
])))) {
423 sz
[i
] = scm_upcase(sz
[i
]);
426 sz
[i
] = scm_downcase(sz
[i
]);
435 SCM_DEFINE (scm_string_capitalize_x
, "string-capitalize!", 1, 0, 0,
437 "Upcase the first character of every word in @var{str}\n"
438 "destructively and return @var{str}.\n"
441 "y @result{} \"hello world\"\n"
442 "(string-capitalize! y) @result{} \"Hello World\"\n"
443 "y @result{} \"Hello World\"\n"
445 #define FUNC_NAME s_scm_string_capitalize_x
447 SCM_VALIDATE_STRING (1, str
);
449 return string_capitalize_x (str
);
454 SCM_DEFINE (scm_string_capitalize
, "string-capitalize", 1, 0, 0,
456 "Return a freshly allocated string with the characters in\n"
457 "@var{str}, where the first character of every word is\n"
459 #define FUNC_NAME s_scm_string_capitalize
461 SCM_VALIDATE_STRING (1, str
);
463 return string_capitalize_x (string_copy (str
));
468 SCM_DEFINE (scm_string_split
, "string-split", 2, 0, 0,
470 "Split the string @var{str} into the a list of the substrings delimited\n"
471 "by appearances of the character @var{chr}. Note that an empty substring\n"
472 "between separator characters will result in an empty string in the\n"
476 "(string-split \"root:x:0:0:root:/root:/bin/bash\" #\\:)\n"
478 "(\"root\" \"x\" \"0\" \"0\" \"root\" \"/root\" \"/bin/bash\")\n"
480 "(string-split \"::\" #\\:)\n"
484 "(string-split \"\" #\\:)\n"
488 #define FUNC_NAME s_scm_string_split
495 SCM_VALIDATE_STRING (1, str
);
496 SCM_VALIDATE_CHAR (2, chr
);
498 idx
= SCM_STRING_LENGTH (str
);
499 p
= SCM_STRING_CHARS (str
);
504 while (idx
> 0 && p
[idx
- 1] != ch
)
508 res
= scm_cons (scm_mem2string (p
+ idx
, last_idx
- idx
), res
);
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"