blob: ef943a431146ac6d26f08df3240e8f6a61430371 [file] [log] [blame]
Guido van Rossume270b431992-09-03 20:21:07 +00001/***********************************************************
Guido van Rossum524b5881995-01-04 19:10:35 +00002Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
3The Netherlands.
Guido van Rossume270b431992-09-03 20:21:07 +00004
5 All Rights Reserved
6
7Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
9provided that the above copyright notice appear in all copies and that
10both that copyright notice and this permission notice appear in
11supporting documentation, and that the names of Stichting Mathematisch
12Centrum or CWI not be used in advertising or publicity pertaining to
13distribution of the software without specific, written prior permission.
14
15STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO
16THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE
18FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
21OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22
23******************************************************************/
24
25/* strop module */
26
27#include "allobjects.h"
28#include "modsupport.h"
29
Guido van Rossumd05eb8b1993-07-08 11:12:36 +000030#include <ctype.h>
Guido van Rossume22e6441993-07-09 10:51:31 +000031/* XXX This file assumes that the <ctype.h> is*() functions
32 XXX are defined for all 8-bit characters! */
Guido van Rossumd05eb8b1993-07-08 11:12:36 +000033
Guido van Rossumb6775db1994-08-01 11:34:53 +000034#include <errno.h>
35
Guido van Rossum7999a5c1996-08-08 19:16:15 +000036/* The lstrip(), rstrip() and strip() functions are implemented
37 in do_strip(), which uses an additional parameter to indicate what
38 type of strip should occur. */
39
40#define LEFTSTRIP 0
41#define RIGHTSTRIP 1
42#define BOTHSTRIP 2
43
Guido van Rossume270b431992-09-03 20:21:07 +000044
45static object *
Guido van Rossum7999a5c1996-08-08 19:16:15 +000046split_whitespace(s, len, maxsplit)
Guido van Rossume270b431992-09-03 20:21:07 +000047 char *s;
Guido van Rossum009e79b1995-05-03 17:40:23 +000048 int len;
Guido van Rossum7999a5c1996-08-08 19:16:15 +000049 int maxsplit;
Guido van Rossum009e79b1995-05-03 17:40:23 +000050{
51 int i, j, err;
Guido van Rossum7999a5c1996-08-08 19:16:15 +000052 int countsplit;
Guido van Rossume270b431992-09-03 20:21:07 +000053 object *list, *item;
54
Guido van Rossume270b431992-09-03 20:21:07 +000055 list = newlistobject(0);
56 if (list == NULL)
57 return NULL;
58
59 i = 0;
Guido van Rossum7999a5c1996-08-08 19:16:15 +000060 countsplit = 0;
61
Guido van Rossume270b431992-09-03 20:21:07 +000062 while (i < len) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +000063 while (i < len && isspace(Py_CHARMASK(s[i]))) {
Guido van Rossume270b431992-09-03 20:21:07 +000064 i = i+1;
65 }
66 j = i;
Guido van Rossumee1813d1995-02-14 00:58:59 +000067 while (i < len && !isspace(Py_CHARMASK(s[i]))) {
Guido van Rossume270b431992-09-03 20:21:07 +000068 i = i+1;
69 }
70 if (j < i) {
71 item = newsizedstringobject(s+j, (int)(i-j));
Guido van Rossum572d2d91993-11-05 10:14:49 +000072 if (item == NULL) {
73 DECREF(list);
74 return NULL;
75 }
76 err = addlistitem(list, item);
77 DECREF(item);
78 if (err < 0) {
Guido van Rossume270b431992-09-03 20:21:07 +000079 DECREF(list);
80 return NULL;
81 }
Guido van Rossum7999a5c1996-08-08 19:16:15 +000082
83 countsplit++;
84 if (maxsplit && (countsplit >= maxsplit)) {
85 item = newsizedstringobject(s+i, (int)(len - i));
86 if (item == NULL) {
87 DECREF(list);
88 return NULL;
89 }
90 err = addlistitem(list, item);
91 DECREF(item);
92 if (err < 0) {
93 DECREF(list);
94 return NULL;
95 }
96 i = len;
97 }
98
Guido van Rossume270b431992-09-03 20:21:07 +000099 }
100 }
101
102 return list;
103}
104
105
106static object *
107strop_splitfields(self, args)
108 object *self; /* Not used */
109 object *args;
110{
Guido van Rossum572d2d91993-11-05 10:14:49 +0000111 int len, n, i, j, err;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000112 int splitcount, maxsplit;
Guido van Rossume270b431992-09-03 20:21:07 +0000113 char *s, *sub;
Guido van Rossume270b431992-09-03 20:21:07 +0000114 object *list, *item;
115
Guido van Rossum009e79b1995-05-03 17:40:23 +0000116 sub = NULL;
117 n = 0;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000118 splitcount = 0;
119 maxsplit = 0;
120 if (!newgetargs(args, "s#|z#i", &s, &len, &sub, &n, &maxsplit))
Guido van Rossume270b431992-09-03 20:21:07 +0000121 return NULL;
Guido van Rossum009e79b1995-05-03 17:40:23 +0000122 if (sub == NULL)
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000123 return split_whitespace(s, len, maxsplit);
Guido van Rossume270b431992-09-03 20:21:07 +0000124 if (n == 0) {
125 err_setstr(ValueError, "empty separator");
126 return NULL;
127 }
128
129 list = newlistobject(0);
130 if (list == NULL)
131 return NULL;
132
133 i = j = 0;
134 while (i+n <= len) {
135 if (s[i] == sub[0] && (n == 1 || strncmp(s+i, sub, n) == 0)) {
136 item = newsizedstringobject(s+j, (int)(i-j));
Guido van Rossum572d2d91993-11-05 10:14:49 +0000137 if (item == NULL)
138 goto fail;
139 err = addlistitem(list, item);
140 DECREF(item);
141 if (err < 0)
142 goto fail;
Guido van Rossume270b431992-09-03 20:21:07 +0000143 i = j = i + n;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000144 splitcount++;
145 if (maxsplit && (splitcount >= maxsplit))
146 break;
Guido van Rossume270b431992-09-03 20:21:07 +0000147 }
148 else
149 i++;
150 }
151 item = newsizedstringobject(s+j, (int)(len-j));
Guido van Rossum572d2d91993-11-05 10:14:49 +0000152 if (item == NULL)
153 goto fail;
154 err = addlistitem(list, item);
155 DECREF(item);
156 if (err < 0)
157 goto fail;
Guido van Rossume270b431992-09-03 20:21:07 +0000158
159 return list;
Guido van Rossum572d2d91993-11-05 10:14:49 +0000160
161 fail:
162 DECREF(list);
163 return NULL;
Guido van Rossume270b431992-09-03 20:21:07 +0000164}
165
166
167static object *
Guido van Rossumc89705d1992-11-26 08:54:07 +0000168strop_joinfields(self, args)
169 object *self; /* Not used */
170 object *args;
171{
172 object *seq, *item, *res;
173 object * (*getitem) FPROTO((object *, int));
174 char *sep, *p;
175 int seplen, seqlen, reslen, itemlen, i;
176
Guido van Rossum009e79b1995-05-03 17:40:23 +0000177 sep = NULL;
178 seplen = 0;
179 if (!newgetargs(args, "O|s#", &seq, &sep, &seplen))
Guido van Rossumc89705d1992-11-26 08:54:07 +0000180 return NULL;
Guido van Rossum009e79b1995-05-03 17:40:23 +0000181 if (sep == NULL) {
182 sep = " ";
183 seplen = 1;
184 }
Guido van Rossumc89705d1992-11-26 08:54:07 +0000185 if (is_listobject(seq)) {
186 getitem = getlistitem;
187 seqlen = getlistsize(seq);
188 }
189 else if (is_tupleobject(seq)) {
190 getitem = gettupleitem;
191 seqlen = gettuplesize(seq);
192 }
193 else {
194 err_setstr(TypeError, "first argument must be list/tuple");
195 return NULL;
196 }
197 reslen = 0;
198 for (i = 0; i < seqlen; i++) {
199 item = getitem(seq, i);
200 if (!is_stringobject(item)) {
201 err_setstr(TypeError,
202 "first argument must be list/tuple of strings");
203 return NULL;
204 }
205 if (i > 0)
206 reslen = reslen + seplen;
207 reslen = reslen + getstringsize(item);
208 }
209 if (seqlen == 1) {
210 /* Optimization if there's only one item */
211 item = getitem(seq, 0);
212 INCREF(item);
213 return item;
214 }
215 res = newsizedstringobject((char *)NULL, reslen);
216 if (res == NULL)
217 return NULL;
218 p = getstringvalue(res);
219 for (i = 0; i < seqlen; i++) {
220 item = getitem(seq, i);
221 if (i > 0) {
222 memcpy(p, sep, seplen);
223 p += seplen;
224 }
225 itemlen = getstringsize(item);
226 memcpy(p, getstringvalue(item), itemlen);
227 p += itemlen;
228 }
229 if (p != getstringvalue(res) + reslen) {
230 err_setstr(SystemError, "strop.joinfields: assertion failed");
231 return NULL;
232 }
233 return res;
234}
235
236
237static object *
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000238strop_find(self, args)
Guido van Rossume270b431992-09-03 20:21:07 +0000239 object *self; /* Not used */
240 object *args;
241{
242 char *s, *sub;
243 int len, n, i;
244
245 if (getargs(args, "(s#s#i)", &s, &len, &sub, &n, &i)) {
Guido van Rossumee9012f1993-10-26 15:23:55 +0000246 if (i < 0)
247 i += len;
Guido van Rossum602099a1994-09-14 13:32:22 +0000248 if (i < 0)
249 i = 0;
Guido van Rossume270b431992-09-03 20:21:07 +0000250 }
251 else {
252 err_clear();
253 if (!getargs(args, "(s#s#)", &s, &len, &sub, &n))
254 return NULL;
255 i = 0;
256 }
257
258 if (n == 0)
259 return newintobject((long)i);
260
261 len -= n;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000262 for (; i <= len; ++i)
263 if (s[i] == sub[0] &&
264 (n == 1 || strncmp(&s[i+1], &sub[1], n-1) == 0))
265 return newintobject((long)i);
266
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000267 return newintobject(-1L);
Guido van Rossumee9012f1993-10-26 15:23:55 +0000268}
269
270
271static object *
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000272strop_rfind(self, args)
Guido van Rossumee9012f1993-10-26 15:23:55 +0000273 object *self; /* Not used */
274 object *args;
275{
276 char *s, *sub;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000277 int len, n, i, j;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000278
279 if (getargs(args, "(s#s#i)", &s, &len, &sub, &n, &i)) {
280 if (i < 0)
281 i += len;
Guido van Rossum602099a1994-09-14 13:32:22 +0000282 if (i < 0)
283 i = 0;
Guido van Rossume270b431992-09-03 20:21:07 +0000284 }
Guido van Rossumee9012f1993-10-26 15:23:55 +0000285 else {
286 err_clear();
287 if (!getargs(args, "(s#s#)", &s, &len, &sub, &n))
288 return NULL;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000289 i = 0;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000290 }
291
292 if (n == 0)
Guido van Rossumc65a5251994-08-05 13:44:50 +0000293 return newintobject((long)len);
Guido van Rossumee9012f1993-10-26 15:23:55 +0000294
Guido van Rossumb6775db1994-08-01 11:34:53 +0000295 for (j = len-n; j >= i; --j)
296 if (s[j] == sub[0] &&
297 (n == 1 || strncmp(&s[j+1], &sub[1], n-1) == 0))
298 return newintobject((long)j);
Guido van Rossume270b431992-09-03 20:21:07 +0000299
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000300 return newintobject(-1L);
Guido van Rossume270b431992-09-03 20:21:07 +0000301}
302
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000303static object *
304do_strip(args, striptype)
305 object *args;
306 int striptype;
307{
308 char *s;
309 int len, i, j;
310
311
312 if (!getargs(args, "s#", &s, &len))
313 return NULL;
314
315 i = 0;
316 if (striptype != RIGHTSTRIP) {
317 while (i < len && isspace(Py_CHARMASK(s[i]))) {
318 i++;
319 }
320 }
321
322
323 j = len;
324 if (striptype != LEFTSTRIP) {
325 do {
326 j--;
327 } while (j >= i && isspace(Py_CHARMASK(s[j])));
328 j++;
329 }
330
331 if (i == 0 && j == len) {
332 INCREF(args);
333 return args;
334 }
335 else
336 return newsizedstringobject(s+i, j-i);
337}
338
Guido van Rossume270b431992-09-03 20:21:07 +0000339
340static object *
341strop_strip(self, args)
342 object *self; /* Not used */
343 object *args;
344{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000345 return do_strip(args, BOTHSTRIP);
346}
Guido van Rossume270b431992-09-03 20:21:07 +0000347
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000348static object *
349strop_lstrip(self, args)
350 object *self; /* Not used */
351 object *args;
352{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000353 return do_strip(args, LEFTSTRIP);
354}
Guido van Rossume270b431992-09-03 20:21:07 +0000355
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000356static object *
357strop_rstrip(self, args)
358 object *self; /* Not used */
359 object *args;
360{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000361 return do_strip(args, RIGHTSTRIP);
Guido van Rossume270b431992-09-03 20:21:07 +0000362}
363
364
Guido van Rossum5c850621992-09-11 23:55:51 +0000365static object *
366strop_lower(self, args)
367 object *self; /* Not used */
368 object *args;
369{
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000370 char *s, *s_new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000371 int i, n;
372 object *new;
373 int changed;
374
375 if (!getargs(args, "s#", &s, &n))
376 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000377 new = newsizedstringobject(NULL, n);
Guido van Rossum5c850621992-09-11 23:55:51 +0000378 if (new == NULL)
379 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000380 s_new = getstringvalue(new);
Guido van Rossum5c850621992-09-11 23:55:51 +0000381 changed = 0;
382 for (i = 0; i < n; i++) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000383 int c = Py_CHARMASK(*s++);
Guido van Rossum5c850621992-09-11 23:55:51 +0000384 if (isupper(c)) {
385 changed = 1;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000386 *s_new = tolower(c);
387 } else
388 *s_new = c;
389 s_new++;
Guido van Rossum5c850621992-09-11 23:55:51 +0000390 }
391 if (!changed) {
392 DECREF(new);
393 INCREF(args);
394 return args;
395 }
396 return new;
397}
398
399
400static object *
401strop_upper(self, args)
402 object *self; /* Not used */
403 object *args;
404{
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000405 char *s, *s_new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000406 int i, n;
407 object *new;
408 int changed;
409
410 if (!getargs(args, "s#", &s, &n))
411 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000412 new = newsizedstringobject(NULL, n);
Guido van Rossum5c850621992-09-11 23:55:51 +0000413 if (new == NULL)
414 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000415 s_new = getstringvalue(new);
Guido van Rossum5c850621992-09-11 23:55:51 +0000416 changed = 0;
417 for (i = 0; i < n; i++) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000418 int c = Py_CHARMASK(*s++);
Guido van Rossum5c850621992-09-11 23:55:51 +0000419 if (islower(c)) {
420 changed = 1;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000421 *s_new = toupper(c);
422 } else
423 *s_new = c;
424 s_new++;
Guido van Rossum5c850621992-09-11 23:55:51 +0000425 }
426 if (!changed) {
427 DECREF(new);
428 INCREF(args);
429 return args;
430 }
431 return new;
432}
433
434
435static object *
Guido van Rossum27457531996-06-12 04:24:52 +0000436strop_capitalize(self, args)
437 object *self; /* Not used */
438 object *args;
439{
440 char *s, *s_new;
441 int i, n;
442 object *new;
443 int changed;
444
445 if (!getargs(args, "s#", &s, &n))
446 return NULL;
447 new = newsizedstringobject(NULL, n);
448 if (new == NULL)
449 return NULL;
450 s_new = getstringvalue(new);
451 changed = 0;
Guido van Rossum529c9631996-06-17 16:59:33 +0000452 if (0 < n) {
Guido van Rossum27457531996-06-12 04:24:52 +0000453 int c = Py_CHARMASK(*s++);
454 if (islower(c)) {
455 changed = 1;
456 *s_new = toupper(c);
457 } else
458 *s_new = c;
459 s_new++;
460 }
461 for (i = 1; i < n; i++) {
462 int c = Py_CHARMASK(*s++);
463 if (isupper(c)) {
464 changed = 1;
465 *s_new = tolower(c);
466 } else
467 *s_new = c;
468 s_new++;
469 }
470 if (!changed) {
471 DECREF(new);
472 INCREF(args);
473 return args;
474 }
475 return new;
476}
477
478
479static object *
Guido van Rossum5c850621992-09-11 23:55:51 +0000480strop_swapcase(self, args)
481 object *self; /* Not used */
482 object *args;
483{
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000484 char *s, *s_new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000485 int i, n;
486 object *new;
487 int changed;
488
489 if (!getargs(args, "s#", &s, &n))
490 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000491 new = newsizedstringobject(NULL, n);
Guido van Rossum5c850621992-09-11 23:55:51 +0000492 if (new == NULL)
493 return NULL;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000494 s_new = getstringvalue(new);
Guido van Rossum5c850621992-09-11 23:55:51 +0000495 changed = 0;
496 for (i = 0; i < n; i++) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000497 int c = Py_CHARMASK(*s++);
Guido van Rossum5c850621992-09-11 23:55:51 +0000498 if (islower(c)) {
499 changed = 1;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000500 *s_new = toupper(c);
Guido van Rossum5c850621992-09-11 23:55:51 +0000501 }
502 else if (isupper(c)) {
503 changed = 1;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000504 *s_new = tolower(c);
Guido van Rossum5c850621992-09-11 23:55:51 +0000505 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000506 else
507 *s_new = c;
508 s_new++;
Guido van Rossum5c850621992-09-11 23:55:51 +0000509 }
510 if (!changed) {
511 DECREF(new);
512 INCREF(args);
513 return args;
514 }
515 return new;
516}
517
518
Guido van Rossumb6775db1994-08-01 11:34:53 +0000519static object *
520strop_atoi(self, args)
521 object *self; /* Not used */
522 object *args;
523{
524 extern long mystrtol PROTO((const char *, char **, int));
525 extern unsigned long mystrtoul PROTO((const char *, char **, int));
526 char *s, *end;
527 int base = 10;
528 long x;
529
530 if (args != NULL && is_tupleobject(args)) {
531 if (!getargs(args, "(si)", &s, &base))
532 return NULL;
533 if (base != 0 && base < 2 || base > 36) {
534 err_setstr(ValueError, "invalid base for atoi()");
535 return NULL;
536 }
537 }
538 else if (!getargs(args, "s", &s))
539 return NULL;
540 errno = 0;
541 if (base == 0 && s[0] == '0')
542 x = (long) mystrtoul(s, &end, base);
543 else
544 x = mystrtol(s, &end, base);
545 if (*end != '\0') {
546 err_setstr(ValueError, "invalid literal for atoi()");
547 return NULL;
548 }
549 else if (errno != 0) {
550 err_setstr(OverflowError, "atoi() literal too large");
551 return NULL;
552 }
553 return newintobject(x);
554}
555
556
557static object *
558strop_atol(self, args)
559 object *self; /* Not used */
560 object *args;
561{
562 char *s, *end;
563 int base = 10;
564 object *x;
565
566 if (args != NULL && is_tupleobject(args)) {
567 if (!getargs(args, "(si)", &s, &base))
568 return NULL;
569 if (base != 0 && base < 2 || base > 36) {
570 err_setstr(ValueError, "invalid base for atol()");
571 return NULL;
572 }
573 }
574 else if (!getargs(args, "s", &s))
575 return NULL;
576 x = long_escan(s, &end, base);
577 if (x == NULL)
578 return NULL;
579 if (base == 0 && (*end == 'l' || *end == 'L'))
580 end++;
581 if (*end != '\0') {
582 err_setstr(ValueError, "invalid literal for atol()");
583 DECREF(x);
584 return NULL;
585 }
586 return x;
587}
588
589
590static object *
591strop_atof(self, args)
592 object *self; /* Not used */
593 object *args;
594{
595 extern double strtod PROTO((const char *, char **));
596 char *s, *end;
597 double x;
598
599 if (!getargs(args, "s", &s))
600 return NULL;
601 errno = 0;
602 x = strtod(s, &end);
603 if (*end != '\0') {
604 err_setstr(ValueError, "invalid literal for atof()");
605 return NULL;
606 }
607 else if (errno != 0) {
608 err_setstr(OverflowError, "atof() literal too large");
609 return NULL;
610 }
611 return newfloatobject(x);
612}
613
614
Guido van Rossumed7253c1996-07-23 18:12:39 +0000615static PyObject *
616strop_maketrans(self, args)
617 PyObject *self; /* Not used */
618 PyObject *args;
619{
620 unsigned char c[256], *from=NULL, *to=NULL;
621 int i, fromlen=0, tolen=0;
622
623 if (PyTuple_Size(args)!=0) {
624 if (!PyArg_ParseTuple(args, "s#s#", &from, &fromlen,
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000625 &to, &tolen))
Guido van Rossumed7253c1996-07-23 18:12:39 +0000626 return NULL;
627 }
628
629 if (fromlen!=tolen) {
630 PyErr_SetString(ValueError,
631 "maketrans arguments must have same length");
632 return NULL;
633 }
634 for(i=0; i<256; i++)
635 c[i]=(unsigned char)i;
636 for(i=0; i<fromlen; i++) {
637 c[from[i]]=to[i];
638 }
639 return PyString_FromStringAndSize((char *)c, 256);
640}
641
642
Guido van Rossuma3127e81995-09-13 17:39:06 +0000643static object *
644strop_translate(self, args)
645 object *self;
646 object *args;
647{
Guido van Rossumed7253c1996-07-23 18:12:39 +0000648 char *input, *table, *output, *output_start, *delete=NULL;
649 int inlen, tablen, dellen;
650 PyObject *result;
651 int i, trans_table[256];
Guido van Rossuma3127e81995-09-13 17:39:06 +0000652
Guido van Rossumed7253c1996-07-23 18:12:39 +0000653 if (!PyArg_ParseTuple(args, "s#s#|s#", &input, &inlen,
654 &table, &tablen, &delete, &dellen))
Guido van Rossuma3127e81995-09-13 17:39:06 +0000655 return NULL;
656 if (tablen != 256) {
Guido van Rossumed7253c1996-07-23 18:12:39 +0000657 PyErr_SetString(ValueError,
Guido van Rossuma3127e81995-09-13 17:39:06 +0000658 "translation table must be 256 characters long");
659 return NULL;
660 }
Guido van Rossumed7253c1996-07-23 18:12:39 +0000661 for(i=0; i<256; i++)
662 trans_table[i]=Py_CHARMASK(table[i]);
663 if (delete!=NULL) {
664 for(i=0; i<dellen; i++)
665 trans_table[delete[i]]=-1;
666 }
667
668 result = PyString_FromStringAndSize((char *)NULL, inlen);
Guido van Rossuma3127e81995-09-13 17:39:06 +0000669 if (result == NULL)
670 return NULL;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000671 output_start = output = PyString_AsString(result);
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000672 if (delete!=NULL && dellen!=0) {
Guido van Rossumed7253c1996-07-23 18:12:39 +0000673 for (i = 0; i < inlen; i++) {
674 int c = Py_CHARMASK(*input++);
675 if (trans_table[c]!=-1)
676 *output++ = (char)trans_table[c];
677 }
678 /* Fix the size of the resulting string */
679 if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
680 return NULL;
681 } else {
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000682 /* If no deletions are required, use a faster loop */
Guido van Rossumed7253c1996-07-23 18:12:39 +0000683 for (i = 0; i < inlen; i++) {
684 int c = Py_CHARMASK(*input++);
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000685 *output++ = (char)trans_table[c];
686 }
Guido van Rossuma3127e81995-09-13 17:39:06 +0000687 }
688 return result;
689}
690
691
Guido van Rossume270b431992-09-03 20:21:07 +0000692/* List of functions defined in the module */
693
694static struct methodlist strop_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000695 {"atof", strop_atof},
696 {"atoi", strop_atoi},
697 {"atol", strop_atol},
Guido van Rossum27457531996-06-12 04:24:52 +0000698 {"capitalize", strop_capitalize},
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000699 {"find", strop_find},
Guido van Rossum009e79b1995-05-03 17:40:23 +0000700 {"join", strop_joinfields, 1},
701 {"joinfields", strop_joinfields, 1},
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000702 {"lstrip", strop_lstrip},
Guido van Rossum5c850621992-09-11 23:55:51 +0000703 {"lower", strop_lower},
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000704 {"rfind", strop_rfind},
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000705 {"rstrip", strop_rstrip},
Guido van Rossum009e79b1995-05-03 17:40:23 +0000706 {"split", strop_splitfields, 1},
707 {"splitfields", strop_splitfields, 1},
Guido van Rossume270b431992-09-03 20:21:07 +0000708 {"strip", strop_strip},
Guido van Rossum5c850621992-09-11 23:55:51 +0000709 {"swapcase", strop_swapcase},
Guido van Rossumed7253c1996-07-23 18:12:39 +0000710 {"maketrans", strop_maketrans, 1},
Guido van Rossuma3127e81995-09-13 17:39:06 +0000711 {"translate", strop_translate, 1},
Guido van Rossum5c850621992-09-11 23:55:51 +0000712 {"upper", strop_upper},
Guido van Rossume270b431992-09-03 20:21:07 +0000713 {NULL, NULL} /* sentinel */
714};
715
716
Guido van Rossume270b431992-09-03 20:21:07 +0000717void
718initstrop()
719{
Guido van Rossumd05eb8b1993-07-08 11:12:36 +0000720 object *m, *d, *s;
721 char buf[256];
722 int c, n;
723 m = initmodule("strop", strop_methods);
724 d = getmoduledict(m);
Guido van Rossume22e6441993-07-09 10:51:31 +0000725
726 /* Create 'whitespace' object */
Guido van Rossumd05eb8b1993-07-08 11:12:36 +0000727 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000728 for (c = 0; c < 256; c++) {
Guido van Rossumd05eb8b1993-07-08 11:12:36 +0000729 if (isspace(c))
730 buf[n++] = c;
731 }
Sjoerd Mullenderd96ec441993-09-14 08:37:39 +0000732 s = newsizedstringobject(buf, n);
Guido van Rossume22e6441993-07-09 10:51:31 +0000733 if (s) {
Guido van Rossume22e6441993-07-09 10:51:31 +0000734 dictinsert(d, "whitespace", s);
735 DECREF(s);
736 }
737 /* Create 'lowercase' object */
738 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000739 for (c = 0; c < 256; c++) {
Guido van Rossume22e6441993-07-09 10:51:31 +0000740 if (islower(c))
741 buf[n++] = c;
742 }
Guido van Rossumd05eb8b1993-07-08 11:12:36 +0000743 s = newsizedstringobject(buf, n);
Guido van Rossume22e6441993-07-09 10:51:31 +0000744 if (s) {
745 dictinsert(d, "lowercase", s);
746 DECREF(s);
747 }
748
749 /* Create 'uppercase' object */
750 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000751 for (c = 0; c < 256; c++) {
Guido van Rossume22e6441993-07-09 10:51:31 +0000752 if (isupper(c))
753 buf[n++] = c;
754 }
755 s = newsizedstringobject(buf, n);
756 if (s) {
757 dictinsert(d, "uppercase", s);
758 DECREF(s);
759 }
760
761 if (err_occurred())
762 fatal("can't initialize module strop");
Guido van Rossume270b431992-09-03 20:21:07 +0000763}