* Makefile.in: Rebuilt.
[bpt/guile.git] / libguile / strop.c
1 /* classes: src_files */
2
3 /* Copyright (C) 1994, 1996, 1997 Software Foundation, Inc.
4
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)
8 any later version.
9
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.
14
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
18 02111-1307 USA */
19
20 \f
21
22 #include <stdio.h>
23 #include "_scm.h"
24 #include "chars.h"
25
26 #include "strop.h"
27 \f
28
29
30 static int scm_i_index SCM_P ((SCM * str, SCM chr, int direction, SCM sub_start, SCM sub_end, int pos, int pos2, int pos3, int pos4, char * why));
31
32 /* implements index if direction > 0 otherwise rindex. */
33 static int
34 scm_i_index (str, chr, direction, sub_start, sub_end, pos, pos2, pos3, pos4,
35 why)
36 SCM * str;
37 SCM chr;
38 int direction;
39 SCM sub_start;
40 SCM sub_end;
41 int pos;
42 int pos2;
43 int pos3;
44 int pos4;
45 char * why;
46 {
47 unsigned char * p;
48 int x;
49 int lower;
50 int upper;
51 int ch;
52
53 SCM_ASSERT (SCM_NIMP (*str) && SCM_ROSTRINGP (*str), *str, pos, why);
54 SCM_ASSERT (SCM_ICHRP (chr), chr, pos2, why);
55
56 if (sub_start == SCM_BOOL_F)
57 sub_start = SCM_MAKINUM (0);
58
59 SCM_ASSERT (SCM_INUMP (sub_start), sub_start, pos3, why);
60 lower = SCM_INUM (sub_start);
61 if (lower < 0
62 || lower > SCM_ROLENGTH (*str))
63 scm_out_of_range (why, sub_start);
64
65 if (sub_end == SCM_BOOL_F)
66 sub_end = SCM_MAKINUM (SCM_ROLENGTH (*str));
67
68 SCM_ASSERT (SCM_INUMP (sub_end), sub_end, pos4, why);
69 upper = SCM_INUM (sub_end);
70 if (upper < SCM_INUM (sub_start)
71 || upper > SCM_ROLENGTH (*str))
72 scm_out_of_range (why, sub_end);
73
74 if (direction > 0)
75 {
76 p = (unsigned char *)SCM_ROCHARS (*str) + lower;
77 ch = SCM_ICHR (chr);
78
79 for (x = SCM_INUM (sub_start); x < upper; ++x, ++p)
80 if (*p == ch)
81 return x;
82 }
83 else
84 {
85 p = upper - 1 + (unsigned char *)SCM_ROCHARS (*str);
86 ch = SCM_ICHR (chr);
87 for (x = upper - 1; x >= lower; --x, --p)
88 if (*p == ch)
89 return x;
90 }
91
92 return -1;
93 }
94
95 SCM_PROC(s_string_index, "string-index", 2, 2, 0, scm_string_index);
96
97 SCM
98 scm_string_index (str, chr, frm, to)
99 SCM str;
100 SCM chr;
101 SCM frm;
102 SCM to;
103 {
104 int pos;
105
106 if (frm == SCM_UNDEFINED)
107 frm = SCM_BOOL_F;
108 if (to == SCM_UNDEFINED)
109 to = SCM_BOOL_F;
110 pos = scm_i_index (&str, chr, 1, frm, to, SCM_ARG1, SCM_ARG2, SCM_ARG3, SCM_ARG4, s_string_index);
111 return (pos < 0
112 ? SCM_BOOL_F
113 : SCM_MAKINUM (pos));
114 }
115
116 SCM_PROC(s_string_rindex, "string-rindex", 2, 2, 0, scm_string_rindex);
117
118 SCM
119 scm_string_rindex (str, chr, frm, to)
120 SCM str;
121 SCM chr;
122 SCM frm;
123 SCM to;
124 {
125 int pos;
126
127 if (frm == SCM_UNDEFINED)
128 frm = SCM_BOOL_F;
129 if (to == SCM_UNDEFINED)
130 to = SCM_BOOL_F;
131 pos = scm_i_index (&str, chr, -1, frm, to, SCM_ARG1, SCM_ARG2, SCM_ARG3, SCM_ARG4, s_string_rindex);
132 return (pos < 0
133 ? SCM_BOOL_F
134 : SCM_MAKINUM (pos));
135 }
136
137 SCM_PROC(s_substring_move_left_x, "substring-move-left!", 2, 0, 1, scm_substring_move_left_x);
138
139 SCM
140 scm_substring_move_left_x (str1, start1, args)
141 SCM str1;
142 SCM start1;
143 SCM args;
144 {
145 SCM end1, str2, start2;
146 long i, j, e;
147 SCM_ASSERT (3==scm_ilength (args), scm_makfrom0str (s_substring_move_left_x),
148 SCM_WNA, NULL);
149 end1 = SCM_CAR (args); args = SCM_CDR (args);
150 str2 = SCM_CAR (args); args = SCM_CDR (args);
151 start2 = SCM_CAR (args);
152 SCM_ASSERT (SCM_NIMP (str1) && SCM_STRINGP (str1), str1, SCM_ARG1, s_substring_move_left_x);
153 SCM_ASSERT (SCM_INUMP (start1), start1, SCM_ARG2, s_substring_move_left_x);
154 SCM_ASSERT (SCM_INUMP (end1), end1, SCM_ARG3, s_substring_move_left_x);
155 SCM_ASSERT (SCM_NIMP (str2) && SCM_STRINGP (str2), str2, SCM_ARG4, s_substring_move_left_x);
156 SCM_ASSERT (SCM_INUMP (start2), start2, SCM_ARG5, s_substring_move_left_x);
157 i = SCM_INUM (start1), j = SCM_INUM (start2), e = SCM_INUM (end1);
158 SCM_ASSERT (i <= SCM_LENGTH (str1) && i >= 0, start1, SCM_OUTOFRANGE, s_substring_move_left_x);
159 SCM_ASSERT (j <= SCM_LENGTH (str2) && j >= 0, start2, SCM_OUTOFRANGE, s_substring_move_left_x);
160 SCM_ASSERT (e <= SCM_LENGTH (str1) && e >= 0, end1, SCM_OUTOFRANGE, s_substring_move_left_x);
161 SCM_ASSERT (e-i+j <= SCM_LENGTH (str2), start2, SCM_OUTOFRANGE, s_substring_move_left_x);
162 while (i<e) SCM_CHARS (str2)[j++] = SCM_CHARS (str1)[i++];
163 return SCM_UNSPECIFIED;
164 }
165
166
167 SCM_PROC(s_substring_move_right_x, "substring-move-right!", 2, 0, 1, scm_substring_move_right_x);
168
169 SCM
170 scm_substring_move_right_x (str1, start1, args)
171 SCM str1;
172 SCM start1;
173 SCM args;
174 {
175 SCM end1, str2, start2;
176 long i, j, e;
177 SCM_ASSERT (3==scm_ilength (args),
178 scm_makfrom0str (s_substring_move_right_x), SCM_WNA, NULL);
179 end1 = SCM_CAR (args); args = SCM_CDR (args);
180 str2 = SCM_CAR (args); args = SCM_CDR (args);
181 start2 = SCM_CAR (args);
182 SCM_ASSERT (SCM_NIMP (str1) && SCM_STRINGP (str1), str1, SCM_ARG1, s_substring_move_right_x);
183 SCM_ASSERT (SCM_INUMP (start1), start1, SCM_ARG2, s_substring_move_right_x);
184 SCM_ASSERT (SCM_INUMP (end1), end1, SCM_ARG3, s_substring_move_right_x);
185 SCM_ASSERT (SCM_NIMP (str2) && SCM_STRINGP (str2), str2, SCM_ARG4, s_substring_move_right_x);
186 SCM_ASSERT (SCM_INUMP (start2), start2, SCM_ARG5, s_substring_move_right_x);
187 i = SCM_INUM (start1), j = SCM_INUM (start2), e = SCM_INUM (end1);
188 SCM_ASSERT (i <= SCM_LENGTH (str1) && i >= 0, start1, SCM_OUTOFRANGE, s_substring_move_right_x);
189 SCM_ASSERT (j <= SCM_LENGTH (str2) && j >= 0, start2, SCM_OUTOFRANGE, s_substring_move_right_x);
190 SCM_ASSERT (e <= SCM_LENGTH (str1) && e >= 0, end1, SCM_OUTOFRANGE, s_substring_move_right_x);
191 SCM_ASSERT ((j = e-i+j) <= SCM_LENGTH (str2), start2, SCM_OUTOFRANGE, s_substring_move_right_x);
192 while (i<e) SCM_CHARS (str2)[--j] = SCM_CHARS (str1)[--e];
193 return SCM_UNSPECIFIED;
194 }
195
196
197 SCM_PROC(s_substring_fill_x, "substring-fill!", 2, 0, 1, scm_substring_fill_x);
198
199 SCM
200 scm_substring_fill_x (str, start, args)
201 SCM str;
202 SCM start;
203 SCM args;
204 {
205 SCM end, fill;
206 long i, e;
207 char c;
208 SCM_ASSERT (2==scm_ilength (args), scm_makfrom0str (s_substring_fill_x),
209 SCM_WNA, NULL);
210 end = SCM_CAR (args); args = SCM_CDR (args);
211 fill = SCM_CAR (args);
212 SCM_ASSERT (SCM_NIMP (str) && SCM_STRINGP (str), str, SCM_ARG1, s_substring_fill_x);
213 SCM_ASSERT (SCM_INUMP (start), start, SCM_ARG2, s_substring_fill_x);
214 SCM_ASSERT (SCM_INUMP (end), end, SCM_ARG3, s_substring_fill_x);
215 SCM_ASSERT (SCM_ICHRP (fill), fill, SCM_ARG4, s_substring_fill_x);
216 i = SCM_INUM (start), e = SCM_INUM (end);c = SCM_ICHR (fill);
217 SCM_ASSERT (i <= SCM_LENGTH (str) && i >= 0, start, SCM_OUTOFRANGE, s_substring_fill_x);
218 SCM_ASSERT (e <= SCM_LENGTH (str) && e >= 0, end, SCM_OUTOFRANGE, s_substring_fill_x);
219 while (i<e) SCM_CHARS (str)[i++] = c;
220 return SCM_UNSPECIFIED;
221 }
222
223
224 SCM_PROC(s_string_null_p, "string-null?", 1, 0, 0, scm_string_null_p);
225
226 SCM
227 scm_string_null_p (str)
228 SCM str;
229 {
230 SCM_ASSERT (SCM_NIMP (str) && SCM_ROSTRINGP (str), str, SCM_ARG1, s_string_null_p);
231 return (SCM_ROLENGTH (str)
232 ? SCM_BOOL_F
233 : SCM_BOOL_T);
234 }
235
236
237 SCM_PROC(s_string_to_list, "string->list", 1, 0, 0, scm_string_to_list);
238
239 SCM
240 scm_string_to_list (str)
241 SCM str;
242 {
243 long i;
244 SCM res = SCM_EOL;
245 unsigned char *src;
246 SCM_ASSERT (SCM_NIMP (str) && SCM_ROSTRINGP (str), str, SCM_ARG1, s_string_to_list);
247 src = SCM_ROUCHARS (str);
248 for (i = SCM_ROLENGTH (str)-1;i >= 0;i--) res = scm_cons ((SCM)SCM_MAKICHR (src[i]), res);
249 return res;
250 }
251
252
253
254 SCM_PROC(s_string_copy, "string-copy", 1, 0, 0, scm_string_copy);
255
256 SCM
257 scm_string_copy (str)
258 SCM str;
259 {
260 SCM_ASSERT (SCM_NIMP (str) && (SCM_STRINGP (str) || SCM_SUBSTRP (str)),
261 str, SCM_ARG1, s_string_copy);
262 return scm_makfromstr (SCM_ROCHARS (str), (scm_sizet)SCM_ROLENGTH (str), 0);
263 }
264
265
266 SCM_PROC(s_string_fill_x, "string-fill!", 2, 0, 0, scm_string_fill_x);
267
268 SCM
269 scm_string_fill_x (str, chr)
270 SCM str;
271 SCM chr;
272 {
273 register char *dst, c;
274 register long k;
275 SCM_ASSERT (SCM_NIMP (str) && SCM_STRINGP (str), str, SCM_ARG1, s_string_fill_x);
276 SCM_ASSERT (SCM_ICHRP (chr), chr, SCM_ARG2, s_string_fill_x);
277 c = SCM_ICHR (chr);
278 dst = SCM_CHARS (str);
279 for (k = SCM_LENGTH (str)-1;k >= 0;k--) dst[k] = c;
280 return SCM_UNSPECIFIED;
281 }
282
283 SCM_PROC(s_string_upcase_x, "string-upcase!", 1, 0, 0, scm_string_upcase_x);
284
285 SCM
286 scm_string_upcase_x (v)
287 SCM v;
288 {
289 register long k;
290 register unsigned char *cs;
291 SCM_ASRTGO (SCM_NIMP (v), badarg1);
292 k = SCM_LENGTH (v);
293 switch SCM_TYP7
294 (v)
295 {
296 case scm_tc7_string:
297 cs = SCM_UCHARS (v);
298 while (k--)
299 cs[k] = scm_upcase(cs[k]);
300 break;
301 default:
302 badarg1:scm_wta (v, (char *) SCM_ARG1, s_string_upcase_x);
303 }
304 return v;
305 }
306
307 SCM_PROC(s_string_downcase_x, "string-downcase!", 1, 0, 0, scm_string_downcase_x);
308
309 SCM
310 scm_string_downcase_x (v)
311 SCM v;
312 {
313 register long k;
314 register unsigned char *cs;
315 SCM_ASRTGO (SCM_NIMP (v), badarg1);
316 k = SCM_LENGTH (v);
317 switch SCM_TYP7
318 (v)
319 {
320 case scm_tc7_string:
321 cs = SCM_UCHARS (v);
322 while (k--)
323 cs[k] = scm_downcase(cs[k]);
324 break;
325 default:
326 badarg1:scm_wta (v, (char *) SCM_ARG1, s_string_downcase_x);
327 }
328 return v;
329 }
330
331
332 void
333 scm_init_strop ()
334 {
335 #include "strop.x"
336 }
337