blob: 6de624e7094f69151e35d315e628b09e7beaa495 [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
Guido van Rossumd266eb41996-10-25 14:44:06 +00007Permission to use, copy, modify, and distribute this software and its
8documentation for any purpose and without fee is hereby granted,
Guido van Rossume270b431992-09-03 20:21:07 +00009provided that the above copyright notice appear in all copies and that
Guido van Rossumd266eb41996-10-25 14:44:06 +000010both that copyright notice and this permission notice appear in
Guido van Rossume270b431992-09-03 20:21:07 +000011supporting documentation, and that the names of Stichting Mathematisch
Guido van Rossumd266eb41996-10-25 14:44:06 +000012Centrum or CWI or Corporation for National Research Initiatives or
13CNRI not be used in advertising or publicity pertaining to
14distribution of the software without specific, written prior
15permission.
Guido van Rossume270b431992-09-03 20:21:07 +000016
Guido van Rossumd266eb41996-10-25 14:44:06 +000017While CWI is the initial source for this software, a modified version
18is made available by the Corporation for National Research Initiatives
19(CNRI) at the Internet address ftp://ftp.python.org.
20
21STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
22REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
23MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
24CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
25DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
26PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
27TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
28PERFORMANCE OF THIS SOFTWARE.
Guido van Rossume270b431992-09-03 20:21:07 +000029
30******************************************************************/
31
32/* strop module */
33
Barry Warsawf5256011996-12-09 18:35:56 +000034#include "Python.h"
Guido van Rossume270b431992-09-03 20:21:07 +000035
Guido van Rossum7b7c5781997-03-14 04:13:56 +000036#ifdef HAVE_LIMITS_H
37#include <limits.h>
38#else
39#define INT_MAX 2147483647
40#endif
41
Guido van Rossumd05eb8b1993-07-08 11:12:36 +000042#include <ctype.h>
Guido van Rossume22e6441993-07-09 10:51:31 +000043/* XXX This file assumes that the <ctype.h> is*() functions
44 XXX are defined for all 8-bit characters! */
Guido van Rossumd05eb8b1993-07-08 11:12:36 +000045
Guido van Rossum7999a5c1996-08-08 19:16:15 +000046/* The lstrip(), rstrip() and strip() functions are implemented
47 in do_strip(), which uses an additional parameter to indicate what
48 type of strip should occur. */
49
50#define LEFTSTRIP 0
51#define RIGHTSTRIP 1
52#define BOTHSTRIP 2
53
Guido van Rossume270b431992-09-03 20:21:07 +000054
Barry Warsawf5256011996-12-09 18:35:56 +000055static PyObject *
Guido van Rossum7999a5c1996-08-08 19:16:15 +000056split_whitespace(s, len, maxsplit)
Guido van Rossume270b431992-09-03 20:21:07 +000057 char *s;
Guido van Rossum009e79b1995-05-03 17:40:23 +000058 int len;
Guido van Rossum7999a5c1996-08-08 19:16:15 +000059 int maxsplit;
Guido van Rossum009e79b1995-05-03 17:40:23 +000060{
Barry Warsawe8fc29c1997-01-03 22:45:34 +000061 int i = 0, j, err;
62 int countsplit = 0;
63 PyObject* item;
64 PyObject *list = PyList_New(0);
Guido van Rossume270b431992-09-03 20:21:07 +000065
Guido van Rossume270b431992-09-03 20:21:07 +000066 if (list == NULL)
67 return NULL;
68
Guido van Rossume270b431992-09-03 20:21:07 +000069 while (i < len) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +000070 while (i < len && isspace(Py_CHARMASK(s[i]))) {
Guido van Rossume270b431992-09-03 20:21:07 +000071 i = i+1;
72 }
73 j = i;
Guido van Rossumee1813d1995-02-14 00:58:59 +000074 while (i < len && !isspace(Py_CHARMASK(s[i]))) {
Guido van Rossume270b431992-09-03 20:21:07 +000075 i = i+1;
76 }
77 if (j < i) {
Barry Warsawf5256011996-12-09 18:35:56 +000078 item = PyString_FromStringAndSize(s+j, (int)(i-j));
Barry Warsawe8fc29c1997-01-03 22:45:34 +000079 if (item == NULL)
80 goto finally;
81
Barry Warsawf5256011996-12-09 18:35:56 +000082 err = PyList_Append(list, item);
83 Py_DECREF(item);
Barry Warsawe8fc29c1997-01-03 22:45:34 +000084 if (err < 0)
85 goto finally;
Guido van Rossum7999a5c1996-08-08 19:16:15 +000086
87 countsplit++;
Barry Warsaw93be92d1997-12-02 00:29:30 +000088 while (i < len && isspace(Py_CHARMASK(s[i]))) {
89 i = i+1;
90 }
91 if (maxsplit && (countsplit >= maxsplit) && i < len) {
Barry Warsawf5256011996-12-09 18:35:56 +000092 item = PyString_FromStringAndSize(
93 s+i, (int)(len - i));
Barry Warsawe8fc29c1997-01-03 22:45:34 +000094 if (item == NULL)
95 goto finally;
96
Barry Warsawf5256011996-12-09 18:35:56 +000097 err = PyList_Append(list, item);
98 Py_DECREF(item);
Barry Warsawe8fc29c1997-01-03 22:45:34 +000099 if (err < 0)
100 goto finally;
101
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000102 i = len;
103 }
104
Guido van Rossume270b431992-09-03 20:21:07 +0000105 }
106 }
Guido van Rossume270b431992-09-03 20:21:07 +0000107 return list;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000108 finally:
109 Py_DECREF(list);
110 return NULL;
Guido van Rossume270b431992-09-03 20:21:07 +0000111}
112
113
Barry Warsawf5256011996-12-09 18:35:56 +0000114static PyObject *
Guido van Rossume270b431992-09-03 20:21:07 +0000115strop_splitfields(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000116 PyObject *self; /* Not used */
117 PyObject *args;
Guido van Rossume270b431992-09-03 20:21:07 +0000118{
Guido van Rossum572d2d91993-11-05 10:14:49 +0000119 int len, n, i, j, err;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000120 int splitcount, maxsplit;
Guido van Rossume270b431992-09-03 20:21:07 +0000121 char *s, *sub;
Barry Warsawf5256011996-12-09 18:35:56 +0000122 PyObject *list, *item;
Guido van Rossume270b431992-09-03 20:21:07 +0000123
Guido van Rossum009e79b1995-05-03 17:40:23 +0000124 sub = NULL;
125 n = 0;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000126 splitcount = 0;
127 maxsplit = 0;
Barry Warsawf5256011996-12-09 18:35:56 +0000128 if (!PyArg_ParseTuple(args, "s#|z#i", &s, &len, &sub, &n, &maxsplit))
Guido van Rossume270b431992-09-03 20:21:07 +0000129 return NULL;
Guido van Rossum009e79b1995-05-03 17:40:23 +0000130 if (sub == NULL)
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000131 return split_whitespace(s, len, maxsplit);
Guido van Rossume270b431992-09-03 20:21:07 +0000132 if (n == 0) {
Barry Warsawf5256011996-12-09 18:35:56 +0000133 PyErr_SetString(PyExc_ValueError, "empty separator");
Guido van Rossume270b431992-09-03 20:21:07 +0000134 return NULL;
135 }
136
Barry Warsawf5256011996-12-09 18:35:56 +0000137 list = PyList_New(0);
Guido van Rossume270b431992-09-03 20:21:07 +0000138 if (list == NULL)
139 return NULL;
140
141 i = j = 0;
142 while (i+n <= len) {
Guido van Rossuma0ca4c41996-10-04 13:39:37 +0000143 if (s[i] == sub[0] && (n == 1 || memcmp(s+i, sub, n) == 0)) {
Barry Warsawf5256011996-12-09 18:35:56 +0000144 item = PyString_FromStringAndSize(s+j, (int)(i-j));
Guido van Rossum572d2d91993-11-05 10:14:49 +0000145 if (item == NULL)
146 goto fail;
Barry Warsawf5256011996-12-09 18:35:56 +0000147 err = PyList_Append(list, item);
148 Py_DECREF(item);
Guido van Rossum572d2d91993-11-05 10:14:49 +0000149 if (err < 0)
150 goto fail;
Guido van Rossume270b431992-09-03 20:21:07 +0000151 i = j = i + n;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000152 splitcount++;
153 if (maxsplit && (splitcount >= maxsplit))
154 break;
Guido van Rossume270b431992-09-03 20:21:07 +0000155 }
156 else
157 i++;
158 }
Barry Warsawf5256011996-12-09 18:35:56 +0000159 item = PyString_FromStringAndSize(s+j, (int)(len-j));
Guido van Rossum572d2d91993-11-05 10:14:49 +0000160 if (item == NULL)
161 goto fail;
Barry Warsawf5256011996-12-09 18:35:56 +0000162 err = PyList_Append(list, item);
163 Py_DECREF(item);
Guido van Rossum572d2d91993-11-05 10:14:49 +0000164 if (err < 0)
165 goto fail;
Guido van Rossume270b431992-09-03 20:21:07 +0000166
167 return list;
Guido van Rossum572d2d91993-11-05 10:14:49 +0000168
169 fail:
Barry Warsawf5256011996-12-09 18:35:56 +0000170 Py_DECREF(list);
Guido van Rossum572d2d91993-11-05 10:14:49 +0000171 return NULL;
Guido van Rossume270b431992-09-03 20:21:07 +0000172}
173
174
Barry Warsawf5256011996-12-09 18:35:56 +0000175static PyObject *
Guido van Rossumc89705d1992-11-26 08:54:07 +0000176strop_joinfields(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000177 PyObject *self; /* Not used */
178 PyObject *args;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000179{
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000180 PyObject *seq;
181 char *sep = NULL;
182 int seqlen, seplen = 0;
183 int i, reslen = 0, slen = 0, sz = 100;
184 PyObject *res = NULL;
185 char* p = NULL;
186 intargfunc getitemfunc;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000187
Barry Warsawf5256011996-12-09 18:35:56 +0000188 if (!PyArg_ParseTuple(args, "O|s#", &seq, &sep, &seplen))
Guido van Rossumc89705d1992-11-26 08:54:07 +0000189 return NULL;
Guido van Rossum009e79b1995-05-03 17:40:23 +0000190 if (sep == NULL) {
191 sep = " ";
192 seplen = 1;
193 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000194
195 seqlen = PySequence_Length(seq);
196 if (seqlen < 0 && PyErr_Occurred())
197 return NULL;
198
199 if (seqlen == 1) {
200 /* Optimization if there's only one item */
201 PyObject *item = PySequence_GetItem(seq, 0);
202 if (item && !PyString_Check(item))
203 PyErr_SetString(PyExc_TypeError,
204 "first argument must be sequence of strings");
205 return item;
206 }
207
208 if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))
209 return NULL;
210 p = PyString_AsString(res);
211
212 /* optimize for lists, since it's the most common case. all others
213 * (tuples and arbitrary sequences) just use the sequence abstract
214 * interface.
Barry Warsaw04d2d151997-01-03 23:46:51 +0000215 */
216 if (PyList_Check(seq)) {
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000217 for (i = 0; i < seqlen; i++) {
218 PyObject *item = PyList_GET_ITEM(seq, i);
219 if (!PyString_Check(item)) {
220 PyErr_SetString(PyExc_TypeError,
221 "first argument must be sequence of strings");
222 Py_DECREF(res);
223 return NULL;
224 }
225 slen = PyString_GET_SIZE(item);
226 while (reslen + slen + seplen >= sz) {
227 if (_PyString_Resize(&res, sz * 2)) {
228 Py_DECREF(res);
229 return NULL;
230 }
231 sz *= 2;
232 p = PyString_AsString(res) + reslen;
233 }
234 if (i > 0) {
235 memcpy(p, sep, seplen);
236 p += seplen;
237 reslen += seplen;
238 }
239 memcpy(p, PyString_AS_STRING(item), slen);
240 p += slen;
241 reslen += slen;
242 }
243 if (_PyString_Resize(&res, reslen)) {
244 Py_DECREF(res);
245 res = NULL;
246 }
247 return res;
Barry Warsaw04d2d151997-01-03 23:46:51 +0000248 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000249 else if (!PySequence_Check(seq)) {
Barry Warsawf5256011996-12-09 18:35:56 +0000250 PyErr_SetString(PyExc_TypeError,
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000251 "first argument must be a sequence");
Guido van Rossumc89705d1992-11-26 08:54:07 +0000252 return NULL;
253 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000254 /* type safe */
255 getitemfunc = seq->ob_type->tp_as_sequence->sq_item;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000256 for (i = 0; i < seqlen; i++) {
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000257 PyObject *item = getitemfunc(seq, i);
258 if (!item || !PyString_Check(item)) {
Barry Warsawf5256011996-12-09 18:35:56 +0000259 PyErr_SetString(PyExc_TypeError,
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000260 "first argument must be sequence of strings");
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000261 Py_DECREF(res);
262 Py_XDECREF(item);
Guido van Rossumc89705d1992-11-26 08:54:07 +0000263 return NULL;
264 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000265 slen = PyString_GET_SIZE(item);
266 while (reslen + slen + seplen >= sz) {
267 if (_PyString_Resize(&res, sz * 2)) {
268 Py_DECREF(res);
269 Py_DECREF(item);
270 return NULL;
271 }
272 sz *= 2;
273 p = PyString_AsString(res) + reslen;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000274 }
Guido van Rossumc89705d1992-11-26 08:54:07 +0000275 if (i > 0) {
276 memcpy(p, sep, seplen);
277 p += seplen;
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000278 reslen += seplen;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000279 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000280 memcpy(p, PyString_AS_STRING(item), slen);
281 p += slen;
282 reslen += slen;
283 Py_DECREF(item);
Guido van Rossumc89705d1992-11-26 08:54:07 +0000284 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000285 if (_PyString_Resize(&res, reslen)) {
286 Py_DECREF(res);
287 res = NULL;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000288 }
289 return res;
290}
291
Barry Warsawf5256011996-12-09 18:35:56 +0000292static PyObject *
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000293strop_find(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000294 PyObject *self; /* Not used */
295 PyObject *args;
Guido van Rossume270b431992-09-03 20:21:07 +0000296{
297 char *s, *sub;
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000298 int len, n, i = 0, last = INT_MAX;
Guido van Rossume270b431992-09-03 20:21:07 +0000299
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000300 if (!PyArg_ParseTuple(args, "s#s#|ii", &s, &len, &sub, &n, &i, &last))
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000301 return NULL;
302
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000303 if (last > len)
304 last = len;
305 if (last < 0)
306 last += len;
307 if (last < 0)
308 last = 0;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000309 if (i < 0)
310 i += len;
311 if (i < 0)
Guido van Rossume270b431992-09-03 20:21:07 +0000312 i = 0;
Guido van Rossume270b431992-09-03 20:21:07 +0000313
314 if (n == 0)
Barry Warsawf5256011996-12-09 18:35:56 +0000315 return PyInt_FromLong((long)i);
Guido van Rossume270b431992-09-03 20:21:07 +0000316
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000317 last -= n;
318 for (; i <= last; ++i)
Guido van Rossumee9012f1993-10-26 15:23:55 +0000319 if (s[i] == sub[0] &&
Guido van Rossuma0ca4c41996-10-04 13:39:37 +0000320 (n == 1 || memcmp(&s[i+1], &sub[1], n-1) == 0))
Barry Warsawf5256011996-12-09 18:35:56 +0000321 return PyInt_FromLong((long)i);
Guido van Rossumee9012f1993-10-26 15:23:55 +0000322
Barry Warsawf5256011996-12-09 18:35:56 +0000323 return PyInt_FromLong(-1L);
Guido van Rossumee9012f1993-10-26 15:23:55 +0000324}
325
326
Barry Warsawf5256011996-12-09 18:35:56 +0000327static PyObject *
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000328strop_rfind(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000329 PyObject *self; /* Not used */
330 PyObject *args;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000331{
332 char *s, *sub;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000333 int len, n, j;
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000334 int i = 0, last = INT_MAX;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000335
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000336 if (!PyArg_ParseTuple(args, "s#s#|ii", &s, &len, &sub, &n, &i, &last))
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000337 return NULL;
338
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000339 if (last > len)
340 last = len;
341 if (last < 0)
342 last += len;
343 if (last < 0)
344 last = 0;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000345 if (i < 0)
346 i += len;
347 if (i < 0)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000348 i = 0;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000349
350 if (n == 0)
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000351 return PyInt_FromLong((long)last);
Guido van Rossumee9012f1993-10-26 15:23:55 +0000352
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000353 for (j = last-n; j >= i; --j)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000354 if (s[j] == sub[0] &&
Guido van Rossuma0ca4c41996-10-04 13:39:37 +0000355 (n == 1 || memcmp(&s[j+1], &sub[1], n-1) == 0))
Barry Warsawf5256011996-12-09 18:35:56 +0000356 return PyInt_FromLong((long)j);
Guido van Rossume270b431992-09-03 20:21:07 +0000357
Barry Warsawf5256011996-12-09 18:35:56 +0000358 return PyInt_FromLong(-1L);
Guido van Rossume270b431992-09-03 20:21:07 +0000359}
360
Barry Warsawf5256011996-12-09 18:35:56 +0000361static PyObject *
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000362do_strip(args, striptype)
Barry Warsawf5256011996-12-09 18:35:56 +0000363 PyObject *args;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000364 int striptype;
365{
366 char *s;
367 int len, i, j;
368
369
Barry Warsawf5256011996-12-09 18:35:56 +0000370 if (!PyArg_Parse(args, "s#", &s, &len))
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000371 return NULL;
372
373 i = 0;
374 if (striptype != RIGHTSTRIP) {
375 while (i < len && isspace(Py_CHARMASK(s[i]))) {
376 i++;
377 }
378 }
379
380
381 j = len;
382 if (striptype != LEFTSTRIP) {
383 do {
384 j--;
385 } while (j >= i && isspace(Py_CHARMASK(s[j])));
386 j++;
387 }
388
389 if (i == 0 && j == len) {
Barry Warsawf5256011996-12-09 18:35:56 +0000390 Py_INCREF(args);
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000391 return args;
392 }
393 else
Barry Warsawf5256011996-12-09 18:35:56 +0000394 return PyString_FromStringAndSize(s+i, j-i);
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000395}
396
Guido van Rossume270b431992-09-03 20:21:07 +0000397
Barry Warsawf5256011996-12-09 18:35:56 +0000398static PyObject *
Guido van Rossume270b431992-09-03 20:21:07 +0000399strop_strip(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000400 PyObject *self; /* Not used */
401 PyObject *args;
Guido van Rossume270b431992-09-03 20:21:07 +0000402{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000403 return do_strip(args, BOTHSTRIP);
404}
Guido van Rossume270b431992-09-03 20:21:07 +0000405
Barry Warsawf5256011996-12-09 18:35:56 +0000406static PyObject *
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000407strop_lstrip(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000408 PyObject *self; /* Not used */
409 PyObject *args;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000410{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000411 return do_strip(args, LEFTSTRIP);
412}
Guido van Rossume270b431992-09-03 20:21:07 +0000413
Barry Warsawf5256011996-12-09 18:35:56 +0000414static PyObject *
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000415strop_rstrip(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000416 PyObject *self; /* Not used */
417 PyObject *args;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000418{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000419 return do_strip(args, RIGHTSTRIP);
Guido van Rossume270b431992-09-03 20:21:07 +0000420}
421
422
Barry Warsawf5256011996-12-09 18:35:56 +0000423static PyObject *
Barry Warsaw04d2d151997-01-03 23:46:51 +0000424strop_lower(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000425 PyObject *self; /* Not used */
426 PyObject *args;
Guido van Rossum5c850621992-09-11 23:55:51 +0000427{
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000428 char *s, *s_new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000429 int i, n;
Barry Warsawf5256011996-12-09 18:35:56 +0000430 PyObject *new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000431 int changed;
432
Barry Warsawf5256011996-12-09 18:35:56 +0000433 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum5c850621992-09-11 23:55:51 +0000434 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000435 new = PyString_FromStringAndSize(NULL, n);
Guido van Rossum5c850621992-09-11 23:55:51 +0000436 if (new == NULL)
437 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000438 s_new = PyString_AsString(new);
Guido van Rossum5c850621992-09-11 23:55:51 +0000439 changed = 0;
440 for (i = 0; i < n; i++) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000441 int c = Py_CHARMASK(*s++);
Barry Warsaw04d2d151997-01-03 23:46:51 +0000442 if (isupper(c)) {
Guido van Rossum5c850621992-09-11 23:55:51 +0000443 changed = 1;
Barry Warsaw04d2d151997-01-03 23:46:51 +0000444 *s_new = tolower(c);
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000445 } else
446 *s_new = c;
447 s_new++;
Guido van Rossum5c850621992-09-11 23:55:51 +0000448 }
449 if (!changed) {
Barry Warsawf5256011996-12-09 18:35:56 +0000450 Py_DECREF(new);
451 Py_INCREF(args);
Guido van Rossum5c850621992-09-11 23:55:51 +0000452 return args;
453 }
454 return new;
455}
456
457
Barry Warsawf5256011996-12-09 18:35:56 +0000458static PyObject *
Guido van Rossum5c850621992-09-11 23:55:51 +0000459strop_upper(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000460 PyObject *self; /* Not used */
461 PyObject *args;
Guido van Rossum5c850621992-09-11 23:55:51 +0000462{
Barry Warsaw04d2d151997-01-03 23:46:51 +0000463 char *s, *s_new;
464 int i, n;
465 PyObject *new;
466 int changed;
467
468 if (!PyArg_Parse(args, "s#", &s, &n))
469 return NULL;
470 new = PyString_FromStringAndSize(NULL, n);
471 if (new == NULL)
472 return NULL;
473 s_new = PyString_AsString(new);
474 changed = 0;
475 for (i = 0; i < n; i++) {
476 int c = Py_CHARMASK(*s++);
477 if (islower(c)) {
478 changed = 1;
479 *s_new = toupper(c);
480 } else
481 *s_new = c;
482 s_new++;
483 }
484 if (!changed) {
485 Py_DECREF(new);
486 Py_INCREF(args);
487 return args;
488 }
489 return new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000490}
491
492
Barry Warsawf5256011996-12-09 18:35:56 +0000493static PyObject *
Guido van Rossum27457531996-06-12 04:24:52 +0000494strop_capitalize(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000495 PyObject *self; /* Not used */
496 PyObject *args;
Guido van Rossum27457531996-06-12 04:24:52 +0000497{
498 char *s, *s_new;
499 int i, n;
Barry Warsawf5256011996-12-09 18:35:56 +0000500 PyObject *new;
Guido van Rossum27457531996-06-12 04:24:52 +0000501 int changed;
502
Barry Warsawf5256011996-12-09 18:35:56 +0000503 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum27457531996-06-12 04:24:52 +0000504 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000505 new = PyString_FromStringAndSize(NULL, n);
Guido van Rossum27457531996-06-12 04:24:52 +0000506 if (new == NULL)
507 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000508 s_new = PyString_AsString(new);
Guido van Rossum27457531996-06-12 04:24:52 +0000509 changed = 0;
Guido van Rossum529c9631996-06-17 16:59:33 +0000510 if (0 < n) {
Guido van Rossum27457531996-06-12 04:24:52 +0000511 int c = Py_CHARMASK(*s++);
512 if (islower(c)) {
513 changed = 1;
514 *s_new = toupper(c);
515 } else
516 *s_new = c;
517 s_new++;
518 }
519 for (i = 1; i < n; i++) {
520 int c = Py_CHARMASK(*s++);
521 if (isupper(c)) {
522 changed = 1;
523 *s_new = tolower(c);
524 } else
525 *s_new = c;
526 s_new++;
527 }
528 if (!changed) {
Barry Warsawf5256011996-12-09 18:35:56 +0000529 Py_DECREF(new);
530 Py_INCREF(args);
Guido van Rossum27457531996-06-12 04:24:52 +0000531 return args;
532 }
533 return new;
534}
535
536
Barry Warsawf5256011996-12-09 18:35:56 +0000537static PyObject *
Guido van Rossum5c850621992-09-11 23:55:51 +0000538strop_swapcase(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000539 PyObject *self; /* Not used */
540 PyObject *args;
Guido van Rossum5c850621992-09-11 23:55:51 +0000541{
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000542 char *s, *s_new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000543 int i, n;
Barry Warsawf5256011996-12-09 18:35:56 +0000544 PyObject *new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000545 int changed;
546
Barry Warsawf5256011996-12-09 18:35:56 +0000547 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum5c850621992-09-11 23:55:51 +0000548 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000549 new = PyString_FromStringAndSize(NULL, n);
Guido van Rossum5c850621992-09-11 23:55:51 +0000550 if (new == NULL)
551 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000552 s_new = PyString_AsString(new);
Guido van Rossum5c850621992-09-11 23:55:51 +0000553 changed = 0;
554 for (i = 0; i < n; i++) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000555 int c = Py_CHARMASK(*s++);
Guido van Rossum5c850621992-09-11 23:55:51 +0000556 if (islower(c)) {
557 changed = 1;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000558 *s_new = toupper(c);
Guido van Rossum5c850621992-09-11 23:55:51 +0000559 }
560 else if (isupper(c)) {
561 changed = 1;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000562 *s_new = tolower(c);
Guido van Rossum5c850621992-09-11 23:55:51 +0000563 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000564 else
565 *s_new = c;
566 s_new++;
Guido van Rossum5c850621992-09-11 23:55:51 +0000567 }
568 if (!changed) {
Barry Warsawf5256011996-12-09 18:35:56 +0000569 Py_DECREF(new);
570 Py_INCREF(args);
Guido van Rossum5c850621992-09-11 23:55:51 +0000571 return args;
572 }
573 return new;
574}
575
576
Barry Warsawf5256011996-12-09 18:35:56 +0000577static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000578strop_atoi(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000579 PyObject *self; /* Not used */
580 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000581{
Barry Warsawf5256011996-12-09 18:35:56 +0000582 extern long PyOS_strtol Py_PROTO((const char *, char **, int));
583 extern unsigned long
584 PyOS_strtoul Py_PROTO((const char *, char **, int));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000585 char *s, *end;
586 int base = 10;
587 long x;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000588 char buffer[256]; /* For errors */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000589
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000590 if (!PyArg_ParseTuple(args, "s|i", &s, &base))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000591 return NULL;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000592
593 if ((base != 0 && base < 2) || base > 36) {
594 PyErr_SetString(PyExc_ValueError, "invalid base for atoi()");
595 return NULL;
596 }
597
Guido van Rossumc35f9331996-09-11 23:30:42 +0000598 while (*s && isspace(Py_CHARMASK(*s)))
599 s++;
Guido van Rossum171191e1996-08-21 20:02:25 +0000600 if (s[0] == '\0') {
Barry Warsawf5256011996-12-09 18:35:56 +0000601 PyErr_SetString(PyExc_ValueError, "empty string for atoi()");
Guido van Rossum171191e1996-08-21 20:02:25 +0000602 return NULL;
603 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000604 errno = 0;
605 if (base == 0 && s[0] == '0')
Barry Warsawf5256011996-12-09 18:35:56 +0000606 x = (long) PyOS_strtoul(s, &end, base);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000607 else
Barry Warsawf5256011996-12-09 18:35:56 +0000608 x = PyOS_strtol(s, &end, base);
Guido van Rossumc35f9331996-09-11 23:30:42 +0000609 while (*end && isspace(Py_CHARMASK(*end)))
610 end++;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000611 if (*end != '\0') {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000612 sprintf(buffer, "invalid literal for atoi(): %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000613 PyErr_SetString(PyExc_ValueError, buffer);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000614 return NULL;
615 }
616 else if (errno != 0) {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000617 sprintf(buffer, "atoi() literal too large: %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000618 PyErr_SetString(PyExc_ValueError, buffer);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000619 return NULL;
620 }
Barry Warsawf5256011996-12-09 18:35:56 +0000621 return PyInt_FromLong(x);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000622}
623
624
Barry Warsawf5256011996-12-09 18:35:56 +0000625static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000626strop_atol(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000627 PyObject *self; /* Not used */
628 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000629{
630 char *s, *end;
631 int base = 10;
Barry Warsawf5256011996-12-09 18:35:56 +0000632 PyObject *x;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000633 char buffer[256]; /* For errors */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000634
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000635 if (!PyArg_ParseTuple(args, "s|i", &s, &base))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000636 return NULL;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000637
638 if ((base != 0 && base < 2) || base > 36) {
639 PyErr_SetString(PyExc_ValueError, "invalid base for atol()");
640 return NULL;
641 }
642
Guido van Rossumc35f9331996-09-11 23:30:42 +0000643 while (*s && isspace(Py_CHARMASK(*s)))
644 s++;
Guido van Rossum171191e1996-08-21 20:02:25 +0000645 if (s[0] == '\0') {
Barry Warsawf5256011996-12-09 18:35:56 +0000646 PyErr_SetString(PyExc_ValueError, "empty string for atol()");
Guido van Rossum171191e1996-08-21 20:02:25 +0000647 return NULL;
648 }
Barry Warsawf5256011996-12-09 18:35:56 +0000649 x = PyLong_FromString(s, &end, base);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000650 if (x == NULL)
651 return NULL;
652 if (base == 0 && (*end == 'l' || *end == 'L'))
653 end++;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000654 while (*end && isspace(Py_CHARMASK(*end)))
655 end++;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000656 if (*end != '\0') {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000657 sprintf(buffer, "invalid literal for atol(): %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000658 PyErr_SetString(PyExc_ValueError, buffer);
659 Py_DECREF(x);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000660 return NULL;
661 }
662 return x;
663}
664
665
Barry Warsawf5256011996-12-09 18:35:56 +0000666static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000667strop_atof(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000668 PyObject *self; /* Not used */
669 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000670{
Barry Warsawf5256011996-12-09 18:35:56 +0000671 extern double strtod Py_PROTO((const char *, char **));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000672 char *s, *end;
673 double x;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000674 char buffer[256]; /* For errors */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000675
Barry Warsawf5256011996-12-09 18:35:56 +0000676 if (!PyArg_Parse(args, "s", &s))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000677 return NULL;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000678 while (*s && isspace(Py_CHARMASK(*s)))
679 s++;
Guido van Rossum171191e1996-08-21 20:02:25 +0000680 if (s[0] == '\0') {
Barry Warsawf5256011996-12-09 18:35:56 +0000681 PyErr_SetString(PyExc_ValueError, "empty string for atof()");
Guido van Rossum171191e1996-08-21 20:02:25 +0000682 return NULL;
683 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000684 errno = 0;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000685 PyFPE_START_PROTECT("strop_atof", return 0)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000686 x = strtod(s, &end);
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000687 PyFPE_END_PROTECT(x)
Guido van Rossumc35f9331996-09-11 23:30:42 +0000688 while (*end && isspace(Py_CHARMASK(*end)))
689 end++;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000690 if (*end != '\0') {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000691 sprintf(buffer, "invalid literal for atof(): %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000692 PyErr_SetString(PyExc_ValueError, buffer);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000693 return NULL;
694 }
695 else if (errno != 0) {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000696 sprintf(buffer, "atof() literal too large: %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000697 PyErr_SetString(PyExc_ValueError, buffer);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000698 return NULL;
699 }
Barry Warsawf5256011996-12-09 18:35:56 +0000700 return PyFloat_FromDouble(x);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000701}
702
703
Guido van Rossumed7253c1996-07-23 18:12:39 +0000704static PyObject *
705strop_maketrans(self, args)
706 PyObject *self; /* Not used */
707 PyObject *args;
708{
Guido van Rossume0548b81997-01-06 16:50:09 +0000709 unsigned char *c, *from=NULL, *to=NULL;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000710 int i, fromlen=0, tolen=0;
Guido van Rossume0548b81997-01-06 16:50:09 +0000711 PyObject *result;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000712
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000713 if (!PyArg_ParseTuple(args, "s#s#", &from, &fromlen, &to, &tolen))
714 return NULL;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000715
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000716 if (fromlen != tolen) {
Barry Warsawf5256011996-12-09 18:35:56 +0000717 PyErr_SetString(PyExc_ValueError,
Guido van Rossumed7253c1996-07-23 18:12:39 +0000718 "maketrans arguments must have same length");
719 return NULL;
720 }
Guido van Rossume0548b81997-01-06 16:50:09 +0000721
722 result = PyString_FromStringAndSize((char *)NULL, 256);
723 if (result == NULL)
724 return NULL;
725 c = (unsigned char *) PyString_AS_STRING((PyStringObject *)result);
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000726 for (i = 0; i < 256; i++)
Guido van Rossumed7253c1996-07-23 18:12:39 +0000727 c[i]=(unsigned char)i;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000728 for (i = 0; i < fromlen; i++)
Guido van Rossumed7253c1996-07-23 18:12:39 +0000729 c[from[i]]=to[i];
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000730
Guido van Rossume0548b81997-01-06 16:50:09 +0000731 return result;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000732}
733
734
Barry Warsawf5256011996-12-09 18:35:56 +0000735static PyObject *
Guido van Rossuma3127e81995-09-13 17:39:06 +0000736strop_translate(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000737 PyObject *self;
738 PyObject *args;
Guido van Rossuma3127e81995-09-13 17:39:06 +0000739{
Guido van Rossume0548b81997-01-06 16:50:09 +0000740 register char *input, *table, *output;
741 register int i, c, changed = 0;
742 PyObject *input_obj;
743 char *table1, *output_start, *del_table=NULL;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000744 int inlen, tablen, dellen = 0;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000745 PyObject *result;
Guido van Rossume0548b81997-01-06 16:50:09 +0000746 int trans_table[256];
Guido van Rossuma3127e81995-09-13 17:39:06 +0000747
Guido van Rossume0548b81997-01-06 16:50:09 +0000748 if (!PyArg_ParseTuple(args, "Ss#|s#", &input_obj,
749 &table1, &tablen, &del_table, &dellen))
Guido van Rossuma3127e81995-09-13 17:39:06 +0000750 return NULL;
751 if (tablen != 256) {
Barry Warsawf5256011996-12-09 18:35:56 +0000752 PyErr_SetString(PyExc_ValueError,
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000753 "translation table must be 256 characters long");
Guido van Rossuma3127e81995-09-13 17:39:06 +0000754 return NULL;
755 }
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000756
Guido van Rossume0548b81997-01-06 16:50:09 +0000757 table = table1;
758 inlen = PyString_Size(input_obj);
Guido van Rossumed7253c1996-07-23 18:12:39 +0000759 result = PyString_FromStringAndSize((char *)NULL, inlen);
Guido van Rossuma3127e81995-09-13 17:39:06 +0000760 if (result == NULL)
761 return NULL;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000762 output_start = output = PyString_AsString(result);
Guido van Rossume0548b81997-01-06 16:50:09 +0000763 input = PyString_AsString(input_obj);
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000764
Guido van Rossume0548b81997-01-06 16:50:09 +0000765 if (dellen == 0) {
766 /* If no deletions are required, use faster code */
767 for (i = inlen; --i >= 0; ) {
768 c = Py_CHARMASK(*input++);
769 if (Py_CHARMASK((*output++ = table[c])) != c)
770 changed = 1;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000771 }
Guido van Rossume0548b81997-01-06 16:50:09 +0000772 if (changed)
773 return result;
774 Py_DECREF(result);
775 Py_INCREF(input_obj);
776 return input_obj;
Guido van Rossuma3127e81995-09-13 17:39:06 +0000777 }
Guido van Rossume0548b81997-01-06 16:50:09 +0000778
779 for (i = 0; i < 256; i++)
780 trans_table[i] = Py_CHARMASK(table[i]);
781
782 for (i = 0; i < dellen; i++)
Guido van Rossum1ed5e571997-04-29 21:34:16 +0000783 trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
Guido van Rossume0548b81997-01-06 16:50:09 +0000784
785 for (i = inlen; --i >= 0; ) {
786 c = Py_CHARMASK(*input++);
787 if (trans_table[c] != -1)
788 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
789 continue;
790 changed = 1;
791 }
792 if (!changed) {
793 Py_DECREF(result);
794 Py_INCREF(input_obj);
795 return input_obj;
796 }
797 /* Fix the size of the resulting string */
798 if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
799 return NULL;
Guido van Rossuma3127e81995-09-13 17:39:06 +0000800 return result;
801}
802
803
Guido van Rossum101923b1997-04-02 06:11:18 +0000804/* What follows is used for implementing replace(). Perry Stoll. */
805
806/*
807 mymemfind
808
809 strstr replacement for arbitrary blocks of memory.
810
811 Locates the first occurance in the memory pointed to by MEM of the
812 contents of memory pointed to by PAT. Returns the index into MEM if
813 found, or -1 if not found. If len of PAT is greater than length of
814 MEM, the function returns -1.
815*/
816static int mymemfind(mem, len, pat, pat_len)
817 char *mem;
818 int len;
819 char *pat;
820 int pat_len;
821{
822 register int ii;
823
824 /* pattern can not occur in the last pat_len-1 chars */
825 len -= pat_len;
826
827 for (ii = 0; ii <= len; ii++) {
828 if (mem[ii] == pat[0] &&
829 (pat_len == 1 ||
830 memcmp(&mem[ii+1], &pat[1], pat_len-1) == 0)) {
831 return ii;
832 }
833 }
834 return -1;
835}
836
837/*
838 mymemcnt
839
840 Return the number of distinct times PAT is found in MEM.
841 meaning mem=1111 and pat==11 returns 2.
842 mem=11111 and pat==11 also return 2.
843 */
844static int mymemcnt(mem, len, pat, pat_len)
845 char *mem;
846 int len;
847 char *pat;
848 int pat_len;
849{
850 register int offset = 0;
851 int nfound = 0;
852
853 while (len >= 0) {
854 offset = mymemfind(mem, len, pat, pat_len);
855 if (offset == -1)
856 break;
857 mem += offset + pat_len;
858 len -= offset + pat_len;
859 nfound++;
860 }
861 return nfound;
862}
863
864/*
865 mymemreplace
866
867 Return a string in which all occurences of PAT in memory STR are
868 replaced with SUB.
869
870 If length of PAT is less than length of STR or there are no occurences
871 of PAT in STR, then the original string is returned. Otherwise, a new
872 string is allocated here and returned.
873
874 on return, out_len is:
875 the length of output string, or
876 -1 if the input string is returned, or
877 unchanged if an error occurs (no memory).
878
879 return value is:
880 the new string allocated locally, or
881 NULL if an error occurred.
882*/
Barry Warsawf577c081997-11-29 00:10:07 +0000883static char *mymemreplace(str, len, pat, pat_len, sub, sub_len, count, out_len)
Guido van Rossum101923b1997-04-02 06:11:18 +0000884 char *str;
885 int len; /* input string */
886 char *pat;
887 int pat_len; /* pattern string to find */
888 char *sub;
889 int sub_len; /* substitution string */
Barry Warsawf577c081997-11-29 00:10:07 +0000890 int count; /* number of replacements, 0 == all */
Guido van Rossum101923b1997-04-02 06:11:18 +0000891 int *out_len;
892
893{
894 char *out_s;
895 char *new_s;
896 int nfound, offset, new_len;
897
898 if (len == 0 || pat_len > len)
899 goto return_same;
900
901 /* find length of output string */
902 nfound = mymemcnt(str, len, pat, pat_len);
Barry Warsawf577c081997-11-29 00:10:07 +0000903 if (count > 0)
904 nfound = nfound > count ? count : nfound;
Guido van Rossum101923b1997-04-02 06:11:18 +0000905 if (nfound == 0)
906 goto return_same;
907 new_len = len + nfound*(sub_len - pat_len);
908
909 new_s = (char *)malloc(new_len);
910 if (new_s == NULL) return NULL;
911
912 *out_len = new_len;
913 out_s = new_s;
914
915 while (len > 0) {
916 /* find index of next instance of pattern */
917 offset = mymemfind(str, len, pat, pat_len);
918 /* if not found, break out of loop */
919 if (offset == -1) break;
920
921 /* copy non matching part of input string */
922 memcpy(new_s, str, offset); /* copy part of str before pat */
923 str += offset + pat_len; /* move str past pattern */
924 len -= offset + pat_len; /* reduce length of str remaining */
925
926 /* copy substitute into the output string */
927 new_s += offset; /* move new_s to dest for sub string */
928 memcpy(new_s, sub, sub_len); /* copy substring into new_s */
929 new_s += sub_len; /* offset new_s past sub string */
Barry Warsawf577c081997-11-29 00:10:07 +0000930
931 /* break when we've done count replacements */
932 if (--count == 0) break;
Guido van Rossum101923b1997-04-02 06:11:18 +0000933 }
934 /* copy any remaining values into output string */
935 if (len > 0)
936 memcpy(new_s, str, len);
937 return out_s;
938
939 return_same:
940 *out_len = -1;
941 return str;
942}
943
944
945static PyObject*
946strop_replace(self, args)
947 PyObject *self; /* Not used */
948 PyObject *args;
949{
950 char *str, *pat,*sub,*new_s;
951 int len,pat_len,sub_len,out_len;
Barry Warsawf577c081997-11-29 00:10:07 +0000952 int count = 0;
Guido van Rossum101923b1997-04-02 06:11:18 +0000953 PyObject *new;
954
Barry Warsawf577c081997-11-29 00:10:07 +0000955 if (!PyArg_ParseTuple(args, "s#s#s#|i",
956 &str, &len, &pat, &pat_len, &sub, &sub_len,
957 &count))
Guido van Rossum101923b1997-04-02 06:11:18 +0000958 return NULL;
Barry Warsawf577c081997-11-29 00:10:07 +0000959 new_s = mymemreplace(str,len,pat,pat_len,sub,sub_len,count,&out_len);
Guido van Rossum101923b1997-04-02 06:11:18 +0000960 if (new_s == NULL) {
961 PyErr_NoMemory();
962 return NULL;
963 }
964 if (out_len == -1) {
965 /* we're returning another reference to the input string */
966 new = PyTuple_GetItem(args, 0);
967 Py_XINCREF(new);
968 }
969 else {
970 new = PyString_FromStringAndSize(new_s, out_len);
971 free(new_s);
972 }
973 return new;
974}
975
976
Guido van Rossume270b431992-09-03 20:21:07 +0000977/* List of functions defined in the module */
978
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000979static PyMethodDef
980strop_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000981 {"atof", strop_atof},
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000982 {"atoi", strop_atoi, 1},
983 {"atol", strop_atol, 1},
Guido van Rossum27457531996-06-12 04:24:52 +0000984 {"capitalize", strop_capitalize},
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000985 {"find", strop_find, 1},
Guido van Rossum009e79b1995-05-03 17:40:23 +0000986 {"join", strop_joinfields, 1},
987 {"joinfields", strop_joinfields, 1},
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000988 {"lstrip", strop_lstrip},
Guido van Rossum5c850621992-09-11 23:55:51 +0000989 {"lower", strop_lower},
Guido van Rossum101923b1997-04-02 06:11:18 +0000990 {"maketrans", strop_maketrans, 1},
991 {"replace", strop_replace, 1},
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000992 {"rfind", strop_rfind, 1},
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000993 {"rstrip", strop_rstrip},
Guido van Rossum009e79b1995-05-03 17:40:23 +0000994 {"split", strop_splitfields, 1},
995 {"splitfields", strop_splitfields, 1},
Guido van Rossume270b431992-09-03 20:21:07 +0000996 {"strip", strop_strip},
Guido van Rossum5c850621992-09-11 23:55:51 +0000997 {"swapcase", strop_swapcase},
Guido van Rossuma3127e81995-09-13 17:39:06 +0000998 {"translate", strop_translate, 1},
Guido van Rossum5c850621992-09-11 23:55:51 +0000999 {"upper", strop_upper},
Guido van Rossume270b431992-09-03 20:21:07 +00001000 {NULL, NULL} /* sentinel */
1001};
1002
1003
Guido van Rossume270b431992-09-03 20:21:07 +00001004void
1005initstrop()
1006{
Barry Warsawf5256011996-12-09 18:35:56 +00001007 PyObject *m, *d, *s;
Guido van Rossumd05eb8b1993-07-08 11:12:36 +00001008 char buf[256];
1009 int c, n;
Barry Warsawf5256011996-12-09 18:35:56 +00001010 m = Py_InitModule("strop", strop_methods);
1011 d = PyModule_GetDict(m);
Guido van Rossume22e6441993-07-09 10:51:31 +00001012
1013 /* Create 'whitespace' object */
Guido van Rossumd05eb8b1993-07-08 11:12:36 +00001014 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +00001015 for (c = 0; c < 256; c++) {
Guido van Rossumd05eb8b1993-07-08 11:12:36 +00001016 if (isspace(c))
1017 buf[n++] = c;
1018 }
Barry Warsawf5256011996-12-09 18:35:56 +00001019 s = PyString_FromStringAndSize(buf, n);
Guido van Rossume22e6441993-07-09 10:51:31 +00001020 if (s) {
Barry Warsawf5256011996-12-09 18:35:56 +00001021 PyDict_SetItemString(d, "whitespace", s);
1022 Py_DECREF(s);
Guido van Rossume22e6441993-07-09 10:51:31 +00001023 }
1024 /* Create 'lowercase' object */
1025 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +00001026 for (c = 0; c < 256; c++) {
Guido van Rossume22e6441993-07-09 10:51:31 +00001027 if (islower(c))
1028 buf[n++] = c;
1029 }
Barry Warsawf5256011996-12-09 18:35:56 +00001030 s = PyString_FromStringAndSize(buf, n);
Guido van Rossume22e6441993-07-09 10:51:31 +00001031 if (s) {
Barry Warsawf5256011996-12-09 18:35:56 +00001032 PyDict_SetItemString(d, "lowercase", s);
1033 Py_DECREF(s);
Guido van Rossume22e6441993-07-09 10:51:31 +00001034 }
1035
1036 /* Create 'uppercase' object */
1037 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +00001038 for (c = 0; c < 256; c++) {
Guido van Rossume22e6441993-07-09 10:51:31 +00001039 if (isupper(c))
1040 buf[n++] = c;
1041 }
Barry Warsawf5256011996-12-09 18:35:56 +00001042 s = PyString_FromStringAndSize(buf, n);
Guido van Rossume22e6441993-07-09 10:51:31 +00001043 if (s) {
Barry Warsawf5256011996-12-09 18:35:56 +00001044 PyDict_SetItemString(d, "uppercase", s);
1045 Py_DECREF(s);
Guido van Rossume22e6441993-07-09 10:51:31 +00001046 }
1047
Barry Warsawf5256011996-12-09 18:35:56 +00001048 if (PyErr_Occurred())
1049 Py_FatalError("can't initialize module strop");
Guido van Rossume270b431992-09-03 20:21:07 +00001050}