blob: d52ac7f239d3b1ab008a9188a620b4a6eaf5bcf7 [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++;
88 if (maxsplit && (countsplit >= maxsplit)) {
Barry Warsawf5256011996-12-09 18:35:56 +000089 item = PyString_FromStringAndSize(
90 s+i, (int)(len - i));
Barry Warsawe8fc29c1997-01-03 22:45:34 +000091 if (item == NULL)
92 goto finally;
93
Barry Warsawf5256011996-12-09 18:35:56 +000094 err = PyList_Append(list, item);
95 Py_DECREF(item);
Barry Warsawe8fc29c1997-01-03 22:45:34 +000096 if (err < 0)
97 goto finally;
98
Guido van Rossum7999a5c1996-08-08 19:16:15 +000099 i = len;
100 }
101
Guido van Rossume270b431992-09-03 20:21:07 +0000102 }
103 }
Guido van Rossume270b431992-09-03 20:21:07 +0000104 return list;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000105 finally:
106 Py_DECREF(list);
107 return NULL;
Guido van Rossume270b431992-09-03 20:21:07 +0000108}
109
110
Barry Warsawf5256011996-12-09 18:35:56 +0000111static PyObject *
Guido van Rossume270b431992-09-03 20:21:07 +0000112strop_splitfields(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000113 PyObject *self; /* Not used */
114 PyObject *args;
Guido van Rossume270b431992-09-03 20:21:07 +0000115{
Guido van Rossum572d2d91993-11-05 10:14:49 +0000116 int len, n, i, j, err;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000117 int splitcount, maxsplit;
Guido van Rossume270b431992-09-03 20:21:07 +0000118 char *s, *sub;
Barry Warsawf5256011996-12-09 18:35:56 +0000119 PyObject *list, *item;
Guido van Rossume270b431992-09-03 20:21:07 +0000120
Guido van Rossum009e79b1995-05-03 17:40:23 +0000121 sub = NULL;
122 n = 0;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000123 splitcount = 0;
124 maxsplit = 0;
Barry Warsawf5256011996-12-09 18:35:56 +0000125 if (!PyArg_ParseTuple(args, "s#|z#i", &s, &len, &sub, &n, &maxsplit))
Guido van Rossume270b431992-09-03 20:21:07 +0000126 return NULL;
Guido van Rossum009e79b1995-05-03 17:40:23 +0000127 if (sub == NULL)
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000128 return split_whitespace(s, len, maxsplit);
Guido van Rossume270b431992-09-03 20:21:07 +0000129 if (n == 0) {
Barry Warsawf5256011996-12-09 18:35:56 +0000130 PyErr_SetString(PyExc_ValueError, "empty separator");
Guido van Rossume270b431992-09-03 20:21:07 +0000131 return NULL;
132 }
133
Barry Warsawf5256011996-12-09 18:35:56 +0000134 list = PyList_New(0);
Guido van Rossume270b431992-09-03 20:21:07 +0000135 if (list == NULL)
136 return NULL;
137
138 i = j = 0;
139 while (i+n <= len) {
Guido van Rossuma0ca4c41996-10-04 13:39:37 +0000140 if (s[i] == sub[0] && (n == 1 || memcmp(s+i, sub, n) == 0)) {
Barry Warsawf5256011996-12-09 18:35:56 +0000141 item = PyString_FromStringAndSize(s+j, (int)(i-j));
Guido van Rossum572d2d91993-11-05 10:14:49 +0000142 if (item == NULL)
143 goto fail;
Barry Warsawf5256011996-12-09 18:35:56 +0000144 err = PyList_Append(list, item);
145 Py_DECREF(item);
Guido van Rossum572d2d91993-11-05 10:14:49 +0000146 if (err < 0)
147 goto fail;
Guido van Rossume270b431992-09-03 20:21:07 +0000148 i = j = i + n;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000149 splitcount++;
150 if (maxsplit && (splitcount >= maxsplit))
151 break;
Guido van Rossume270b431992-09-03 20:21:07 +0000152 }
153 else
154 i++;
155 }
Barry Warsawf5256011996-12-09 18:35:56 +0000156 item = PyString_FromStringAndSize(s+j, (int)(len-j));
Guido van Rossum572d2d91993-11-05 10:14:49 +0000157 if (item == NULL)
158 goto fail;
Barry Warsawf5256011996-12-09 18:35:56 +0000159 err = PyList_Append(list, item);
160 Py_DECREF(item);
Guido van Rossum572d2d91993-11-05 10:14:49 +0000161 if (err < 0)
162 goto fail;
Guido van Rossume270b431992-09-03 20:21:07 +0000163
164 return list;
Guido van Rossum572d2d91993-11-05 10:14:49 +0000165
166 fail:
Barry Warsawf5256011996-12-09 18:35:56 +0000167 Py_DECREF(list);
Guido van Rossum572d2d91993-11-05 10:14:49 +0000168 return NULL;
Guido van Rossume270b431992-09-03 20:21:07 +0000169}
170
171
Barry Warsawf5256011996-12-09 18:35:56 +0000172static PyObject *
Guido van Rossumc89705d1992-11-26 08:54:07 +0000173strop_joinfields(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000174 PyObject *self; /* Not used */
175 PyObject *args;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000176{
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000177 PyObject *seq;
178 char *sep = NULL;
179 int seqlen, seplen = 0;
180 int i, reslen = 0, slen = 0, sz = 100;
181 PyObject *res = NULL;
182 char* p = NULL;
183 intargfunc getitemfunc;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000184
Barry Warsawf5256011996-12-09 18:35:56 +0000185 if (!PyArg_ParseTuple(args, "O|s#", &seq, &sep, &seplen))
Guido van Rossumc89705d1992-11-26 08:54:07 +0000186 return NULL;
Guido van Rossum009e79b1995-05-03 17:40:23 +0000187 if (sep == NULL) {
188 sep = " ";
189 seplen = 1;
190 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000191
192 seqlen = PySequence_Length(seq);
193 if (seqlen < 0 && PyErr_Occurred())
194 return NULL;
195
196 if (seqlen == 1) {
197 /* Optimization if there's only one item */
198 PyObject *item = PySequence_GetItem(seq, 0);
199 if (item && !PyString_Check(item))
200 PyErr_SetString(PyExc_TypeError,
201 "first argument must be sequence of strings");
202 return item;
203 }
204
205 if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))
206 return NULL;
207 p = PyString_AsString(res);
208
209 /* optimize for lists, since it's the most common case. all others
210 * (tuples and arbitrary sequences) just use the sequence abstract
211 * interface.
Barry Warsaw04d2d151997-01-03 23:46:51 +0000212 */
213 if (PyList_Check(seq)) {
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000214 for (i = 0; i < seqlen; i++) {
215 PyObject *item = PyList_GET_ITEM(seq, i);
216 if (!PyString_Check(item)) {
217 PyErr_SetString(PyExc_TypeError,
218 "first argument must be sequence of strings");
219 Py_DECREF(res);
220 return NULL;
221 }
222 slen = PyString_GET_SIZE(item);
223 while (reslen + slen + seplen >= sz) {
224 if (_PyString_Resize(&res, sz * 2)) {
225 Py_DECREF(res);
226 return NULL;
227 }
228 sz *= 2;
229 p = PyString_AsString(res) + reslen;
230 }
231 if (i > 0) {
232 memcpy(p, sep, seplen);
233 p += seplen;
234 reslen += seplen;
235 }
236 memcpy(p, PyString_AS_STRING(item), slen);
237 p += slen;
238 reslen += slen;
239 }
240 if (_PyString_Resize(&res, reslen)) {
241 Py_DECREF(res);
242 res = NULL;
243 }
244 return res;
Barry Warsaw04d2d151997-01-03 23:46:51 +0000245 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000246 else if (!PySequence_Check(seq)) {
Barry Warsawf5256011996-12-09 18:35:56 +0000247 PyErr_SetString(PyExc_TypeError,
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000248 "first argument must be a sequence");
Guido van Rossumc89705d1992-11-26 08:54:07 +0000249 return NULL;
250 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000251 /* type safe */
252 getitemfunc = seq->ob_type->tp_as_sequence->sq_item;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000253 for (i = 0; i < seqlen; i++) {
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000254 PyObject *item = getitemfunc(seq, i);
255 if (!item || !PyString_Check(item)) {
Barry Warsawf5256011996-12-09 18:35:56 +0000256 PyErr_SetString(PyExc_TypeError,
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000257 "first argument must be sequence of strings");
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000258 Py_DECREF(res);
259 Py_XDECREF(item);
Guido van Rossumc89705d1992-11-26 08:54:07 +0000260 return NULL;
261 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000262 slen = PyString_GET_SIZE(item);
263 while (reslen + slen + seplen >= sz) {
264 if (_PyString_Resize(&res, sz * 2)) {
265 Py_DECREF(res);
266 Py_DECREF(item);
267 return NULL;
268 }
269 sz *= 2;
270 p = PyString_AsString(res) + reslen;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000271 }
Guido van Rossumc89705d1992-11-26 08:54:07 +0000272 if (i > 0) {
273 memcpy(p, sep, seplen);
274 p += seplen;
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000275 reslen += seplen;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000276 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000277 memcpy(p, PyString_AS_STRING(item), slen);
278 p += slen;
279 reslen += slen;
280 Py_DECREF(item);
Guido van Rossumc89705d1992-11-26 08:54:07 +0000281 }
Barry Warsawd4ff1b91997-01-06 22:48:32 +0000282 if (_PyString_Resize(&res, reslen)) {
283 Py_DECREF(res);
284 res = NULL;
Guido van Rossumc89705d1992-11-26 08:54:07 +0000285 }
286 return res;
287}
288
Barry Warsawf5256011996-12-09 18:35:56 +0000289static PyObject *
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000290strop_find(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000291 PyObject *self; /* Not used */
292 PyObject *args;
Guido van Rossume270b431992-09-03 20:21:07 +0000293{
294 char *s, *sub;
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000295 int len, n, i = 0, last = INT_MAX;
Guido van Rossume270b431992-09-03 20:21:07 +0000296
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000297 if (!PyArg_ParseTuple(args, "s#s#|ii", &s, &len, &sub, &n, &i, &last))
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000298 return NULL;
299
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000300 if (last > len)
301 last = len;
302 if (last < 0)
303 last += len;
304 if (last < 0)
305 last = 0;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000306 if (i < 0)
307 i += len;
308 if (i < 0)
Guido van Rossume270b431992-09-03 20:21:07 +0000309 i = 0;
Guido van Rossume270b431992-09-03 20:21:07 +0000310
311 if (n == 0)
Barry Warsawf5256011996-12-09 18:35:56 +0000312 return PyInt_FromLong((long)i);
Guido van Rossume270b431992-09-03 20:21:07 +0000313
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000314 last -= n;
315 for (; i <= last; ++i)
Guido van Rossumee9012f1993-10-26 15:23:55 +0000316 if (s[i] == sub[0] &&
Guido van Rossuma0ca4c41996-10-04 13:39:37 +0000317 (n == 1 || memcmp(&s[i+1], &sub[1], n-1) == 0))
Barry Warsawf5256011996-12-09 18:35:56 +0000318 return PyInt_FromLong((long)i);
Guido van Rossumee9012f1993-10-26 15:23:55 +0000319
Barry Warsawf5256011996-12-09 18:35:56 +0000320 return PyInt_FromLong(-1L);
Guido van Rossumee9012f1993-10-26 15:23:55 +0000321}
322
323
Barry Warsawf5256011996-12-09 18:35:56 +0000324static PyObject *
Guido van Rossum5806a4f1994-08-17 13:15:46 +0000325strop_rfind(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000326 PyObject *self; /* Not used */
327 PyObject *args;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000328{
329 char *s, *sub;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000330 int len, n, j;
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000331 int i = 0, last = INT_MAX;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000332
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000333 if (!PyArg_ParseTuple(args, "s#s#|ii", &s, &len, &sub, &n, &i, &last))
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000334 return NULL;
335
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000336 if (last > len)
337 last = len;
338 if (last < 0)
339 last += len;
340 if (last < 0)
341 last = 0;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000342 if (i < 0)
343 i += len;
344 if (i < 0)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000345 i = 0;
Guido van Rossumee9012f1993-10-26 15:23:55 +0000346
347 if (n == 0)
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000348 return PyInt_FromLong((long)last);
Guido van Rossumee9012f1993-10-26 15:23:55 +0000349
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000350 for (j = last-n; j >= i; --j)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000351 if (s[j] == sub[0] &&
Guido van Rossuma0ca4c41996-10-04 13:39:37 +0000352 (n == 1 || memcmp(&s[j+1], &sub[1], n-1) == 0))
Barry Warsawf5256011996-12-09 18:35:56 +0000353 return PyInt_FromLong((long)j);
Guido van Rossume270b431992-09-03 20:21:07 +0000354
Barry Warsawf5256011996-12-09 18:35:56 +0000355 return PyInt_FromLong(-1L);
Guido van Rossume270b431992-09-03 20:21:07 +0000356}
357
Barry Warsawf5256011996-12-09 18:35:56 +0000358static PyObject *
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000359do_strip(args, striptype)
Barry Warsawf5256011996-12-09 18:35:56 +0000360 PyObject *args;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000361 int striptype;
362{
363 char *s;
364 int len, i, j;
365
366
Barry Warsawf5256011996-12-09 18:35:56 +0000367 if (!PyArg_Parse(args, "s#", &s, &len))
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000368 return NULL;
369
370 i = 0;
371 if (striptype != RIGHTSTRIP) {
372 while (i < len && isspace(Py_CHARMASK(s[i]))) {
373 i++;
374 }
375 }
376
377
378 j = len;
379 if (striptype != LEFTSTRIP) {
380 do {
381 j--;
382 } while (j >= i && isspace(Py_CHARMASK(s[j])));
383 j++;
384 }
385
386 if (i == 0 && j == len) {
Barry Warsawf5256011996-12-09 18:35:56 +0000387 Py_INCREF(args);
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000388 return args;
389 }
390 else
Barry Warsawf5256011996-12-09 18:35:56 +0000391 return PyString_FromStringAndSize(s+i, j-i);
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000392}
393
Guido van Rossume270b431992-09-03 20:21:07 +0000394
Barry Warsawf5256011996-12-09 18:35:56 +0000395static PyObject *
Guido van Rossume270b431992-09-03 20:21:07 +0000396strop_strip(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000397 PyObject *self; /* Not used */
398 PyObject *args;
Guido van Rossume270b431992-09-03 20:21:07 +0000399{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000400 return do_strip(args, BOTHSTRIP);
401}
Guido van Rossume270b431992-09-03 20:21:07 +0000402
Barry Warsawf5256011996-12-09 18:35:56 +0000403static PyObject *
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000404strop_lstrip(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000405 PyObject *self; /* Not used */
406 PyObject *args;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000407{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000408 return do_strip(args, LEFTSTRIP);
409}
Guido van Rossume270b431992-09-03 20:21:07 +0000410
Barry Warsawf5256011996-12-09 18:35:56 +0000411static PyObject *
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000412strop_rstrip(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000413 PyObject *self; /* Not used */
414 PyObject *args;
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000415{
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000416 return do_strip(args, RIGHTSTRIP);
Guido van Rossume270b431992-09-03 20:21:07 +0000417}
418
419
Barry Warsawf5256011996-12-09 18:35:56 +0000420static PyObject *
Barry Warsaw04d2d151997-01-03 23:46:51 +0000421strop_lower(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000422 PyObject *self; /* Not used */
423 PyObject *args;
Guido van Rossum5c850621992-09-11 23:55:51 +0000424{
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000425 char *s, *s_new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000426 int i, n;
Barry Warsawf5256011996-12-09 18:35:56 +0000427 PyObject *new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000428 int changed;
429
Barry Warsawf5256011996-12-09 18:35:56 +0000430 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum5c850621992-09-11 23:55:51 +0000431 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000432 new = PyString_FromStringAndSize(NULL, n);
Guido van Rossum5c850621992-09-11 23:55:51 +0000433 if (new == NULL)
434 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000435 s_new = PyString_AsString(new);
Guido van Rossum5c850621992-09-11 23:55:51 +0000436 changed = 0;
437 for (i = 0; i < n; i++) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000438 int c = Py_CHARMASK(*s++);
Barry Warsaw04d2d151997-01-03 23:46:51 +0000439 if (isupper(c)) {
Guido van Rossum5c850621992-09-11 23:55:51 +0000440 changed = 1;
Barry Warsaw04d2d151997-01-03 23:46:51 +0000441 *s_new = tolower(c);
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000442 } else
443 *s_new = c;
444 s_new++;
Guido van Rossum5c850621992-09-11 23:55:51 +0000445 }
446 if (!changed) {
Barry Warsawf5256011996-12-09 18:35:56 +0000447 Py_DECREF(new);
448 Py_INCREF(args);
Guido van Rossum5c850621992-09-11 23:55:51 +0000449 return args;
450 }
451 return new;
452}
453
454
Barry Warsawf5256011996-12-09 18:35:56 +0000455static PyObject *
Guido van Rossum5c850621992-09-11 23:55:51 +0000456strop_upper(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000457 PyObject *self; /* Not used */
458 PyObject *args;
Guido van Rossum5c850621992-09-11 23:55:51 +0000459{
Barry Warsaw04d2d151997-01-03 23:46:51 +0000460 char *s, *s_new;
461 int i, n;
462 PyObject *new;
463 int changed;
464
465 if (!PyArg_Parse(args, "s#", &s, &n))
466 return NULL;
467 new = PyString_FromStringAndSize(NULL, n);
468 if (new == NULL)
469 return NULL;
470 s_new = PyString_AsString(new);
471 changed = 0;
472 for (i = 0; i < n; i++) {
473 int c = Py_CHARMASK(*s++);
474 if (islower(c)) {
475 changed = 1;
476 *s_new = toupper(c);
477 } else
478 *s_new = c;
479 s_new++;
480 }
481 if (!changed) {
482 Py_DECREF(new);
483 Py_INCREF(args);
484 return args;
485 }
486 return new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000487}
488
489
Barry Warsawf5256011996-12-09 18:35:56 +0000490static PyObject *
Guido van Rossum27457531996-06-12 04:24:52 +0000491strop_capitalize(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000492 PyObject *self; /* Not used */
493 PyObject *args;
Guido van Rossum27457531996-06-12 04:24:52 +0000494{
495 char *s, *s_new;
496 int i, n;
Barry Warsawf5256011996-12-09 18:35:56 +0000497 PyObject *new;
Guido van Rossum27457531996-06-12 04:24:52 +0000498 int changed;
499
Barry Warsawf5256011996-12-09 18:35:56 +0000500 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum27457531996-06-12 04:24:52 +0000501 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000502 new = PyString_FromStringAndSize(NULL, n);
Guido van Rossum27457531996-06-12 04:24:52 +0000503 if (new == NULL)
504 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000505 s_new = PyString_AsString(new);
Guido van Rossum27457531996-06-12 04:24:52 +0000506 changed = 0;
Guido van Rossum529c9631996-06-17 16:59:33 +0000507 if (0 < n) {
Guido van Rossum27457531996-06-12 04:24:52 +0000508 int c = Py_CHARMASK(*s++);
509 if (islower(c)) {
510 changed = 1;
511 *s_new = toupper(c);
512 } else
513 *s_new = c;
514 s_new++;
515 }
516 for (i = 1; i < n; i++) {
517 int c = Py_CHARMASK(*s++);
518 if (isupper(c)) {
519 changed = 1;
520 *s_new = tolower(c);
521 } else
522 *s_new = c;
523 s_new++;
524 }
525 if (!changed) {
Barry Warsawf5256011996-12-09 18:35:56 +0000526 Py_DECREF(new);
527 Py_INCREF(args);
Guido van Rossum27457531996-06-12 04:24:52 +0000528 return args;
529 }
530 return new;
531}
532
533
Barry Warsawf5256011996-12-09 18:35:56 +0000534static PyObject *
Guido van Rossum5c850621992-09-11 23:55:51 +0000535strop_swapcase(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000536 PyObject *self; /* Not used */
537 PyObject *args;
Guido van Rossum5c850621992-09-11 23:55:51 +0000538{
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000539 char *s, *s_new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000540 int i, n;
Barry Warsawf5256011996-12-09 18:35:56 +0000541 PyObject *new;
Guido van Rossum5c850621992-09-11 23:55:51 +0000542 int changed;
543
Barry Warsawf5256011996-12-09 18:35:56 +0000544 if (!PyArg_Parse(args, "s#", &s, &n))
Guido van Rossum5c850621992-09-11 23:55:51 +0000545 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000546 new = PyString_FromStringAndSize(NULL, n);
Guido van Rossum5c850621992-09-11 23:55:51 +0000547 if (new == NULL)
548 return NULL;
Barry Warsawf5256011996-12-09 18:35:56 +0000549 s_new = PyString_AsString(new);
Guido van Rossum5c850621992-09-11 23:55:51 +0000550 changed = 0;
551 for (i = 0; i < n; i++) {
Guido van Rossum7f7f2741995-02-10 17:01:56 +0000552 int c = Py_CHARMASK(*s++);
Guido van Rossum5c850621992-09-11 23:55:51 +0000553 if (islower(c)) {
554 changed = 1;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000555 *s_new = toupper(c);
Guido van Rossum5c850621992-09-11 23:55:51 +0000556 }
557 else if (isupper(c)) {
558 changed = 1;
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000559 *s_new = tolower(c);
Guido van Rossum5c850621992-09-11 23:55:51 +0000560 }
Sjoerd Mullender3bb8a051993-10-22 12:04:32 +0000561 else
562 *s_new = c;
563 s_new++;
Guido van Rossum5c850621992-09-11 23:55:51 +0000564 }
565 if (!changed) {
Barry Warsawf5256011996-12-09 18:35:56 +0000566 Py_DECREF(new);
567 Py_INCREF(args);
Guido van Rossum5c850621992-09-11 23:55:51 +0000568 return args;
569 }
570 return new;
571}
572
573
Barry Warsawf5256011996-12-09 18:35:56 +0000574static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000575strop_atoi(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000576 PyObject *self; /* Not used */
577 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000578{
Barry Warsawf5256011996-12-09 18:35:56 +0000579 extern long PyOS_strtol Py_PROTO((const char *, char **, int));
580 extern unsigned long
581 PyOS_strtoul Py_PROTO((const char *, char **, int));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000582 char *s, *end;
583 int base = 10;
584 long x;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000585 char buffer[256]; /* For errors */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000586
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000587 if (!PyArg_ParseTuple(args, "s|i", &s, &base))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000588 return NULL;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000589
590 if ((base != 0 && base < 2) || base > 36) {
591 PyErr_SetString(PyExc_ValueError, "invalid base for atoi()");
592 return NULL;
593 }
594
Guido van Rossumc35f9331996-09-11 23:30:42 +0000595 while (*s && isspace(Py_CHARMASK(*s)))
596 s++;
Guido van Rossum171191e1996-08-21 20:02:25 +0000597 if (s[0] == '\0') {
Barry Warsawf5256011996-12-09 18:35:56 +0000598 PyErr_SetString(PyExc_ValueError, "empty string for atoi()");
Guido van Rossum171191e1996-08-21 20:02:25 +0000599 return NULL;
600 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000601 errno = 0;
602 if (base == 0 && s[0] == '0')
Barry Warsawf5256011996-12-09 18:35:56 +0000603 x = (long) PyOS_strtoul(s, &end, base);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000604 else
Barry Warsawf5256011996-12-09 18:35:56 +0000605 x = PyOS_strtol(s, &end, base);
Guido van Rossumc35f9331996-09-11 23:30:42 +0000606 while (*end && isspace(Py_CHARMASK(*end)))
607 end++;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000608 if (*end != '\0') {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000609 sprintf(buffer, "invalid literal for atoi(): %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000610 PyErr_SetString(PyExc_ValueError, buffer);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000611 return NULL;
612 }
613 else if (errno != 0) {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000614 sprintf(buffer, "atoi() literal too large: %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000615 PyErr_SetString(PyExc_ValueError, buffer);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000616 return NULL;
617 }
Barry Warsawf5256011996-12-09 18:35:56 +0000618 return PyInt_FromLong(x);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000619}
620
621
Barry Warsawf5256011996-12-09 18:35:56 +0000622static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000623strop_atol(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000624 PyObject *self; /* Not used */
625 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000626{
627 char *s, *end;
628 int base = 10;
Barry Warsawf5256011996-12-09 18:35:56 +0000629 PyObject *x;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000630 char buffer[256]; /* For errors */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000631
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000632 if (!PyArg_ParseTuple(args, "s|i", &s, &base))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000633 return NULL;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000634
635 if ((base != 0 && base < 2) || base > 36) {
636 PyErr_SetString(PyExc_ValueError, "invalid base for atol()");
637 return NULL;
638 }
639
Guido van Rossumc35f9331996-09-11 23:30:42 +0000640 while (*s && isspace(Py_CHARMASK(*s)))
641 s++;
Guido van Rossum171191e1996-08-21 20:02:25 +0000642 if (s[0] == '\0') {
Barry Warsawf5256011996-12-09 18:35:56 +0000643 PyErr_SetString(PyExc_ValueError, "empty string for atol()");
Guido van Rossum171191e1996-08-21 20:02:25 +0000644 return NULL;
645 }
Barry Warsawf5256011996-12-09 18:35:56 +0000646 x = PyLong_FromString(s, &end, base);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000647 if (x == NULL)
648 return NULL;
649 if (base == 0 && (*end == 'l' || *end == 'L'))
650 end++;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000651 while (*end && isspace(Py_CHARMASK(*end)))
652 end++;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000653 if (*end != '\0') {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000654 sprintf(buffer, "invalid literal for atol(): %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000655 PyErr_SetString(PyExc_ValueError, buffer);
656 Py_DECREF(x);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000657 return NULL;
658 }
659 return x;
660}
661
662
Barry Warsawf5256011996-12-09 18:35:56 +0000663static PyObject *
Guido van Rossumb6775db1994-08-01 11:34:53 +0000664strop_atof(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000665 PyObject *self; /* Not used */
666 PyObject *args;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000667{
Barry Warsawf5256011996-12-09 18:35:56 +0000668 extern double strtod Py_PROTO((const char *, char **));
Guido van Rossumb6775db1994-08-01 11:34:53 +0000669 char *s, *end;
670 double x;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000671 char buffer[256]; /* For errors */
Guido van Rossumb6775db1994-08-01 11:34:53 +0000672
Barry Warsawf5256011996-12-09 18:35:56 +0000673 if (!PyArg_Parse(args, "s", &s))
Guido van Rossumb6775db1994-08-01 11:34:53 +0000674 return NULL;
Guido van Rossumc35f9331996-09-11 23:30:42 +0000675 while (*s && isspace(Py_CHARMASK(*s)))
676 s++;
Guido van Rossum171191e1996-08-21 20:02:25 +0000677 if (s[0] == '\0') {
Barry Warsawf5256011996-12-09 18:35:56 +0000678 PyErr_SetString(PyExc_ValueError, "empty string for atof()");
Guido van Rossum171191e1996-08-21 20:02:25 +0000679 return NULL;
680 }
Guido van Rossumb6775db1994-08-01 11:34:53 +0000681 errno = 0;
Guido van Rossum52fa3a61997-02-14 22:59:58 +0000682 PyFPE_START_PROTECT("strop_atof", return 0)
Guido van Rossumb6775db1994-08-01 11:34:53 +0000683 x = strtod(s, &end);
Guido van Rossum7b7c5781997-03-14 04:13:56 +0000684 PyFPE_END_PROTECT(x)
Guido van Rossumc35f9331996-09-11 23:30:42 +0000685 while (*end && isspace(Py_CHARMASK(*end)))
686 end++;
Guido van Rossumb6775db1994-08-01 11:34:53 +0000687 if (*end != '\0') {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000688 sprintf(buffer, "invalid literal for atof(): %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000689 PyErr_SetString(PyExc_ValueError, buffer);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000690 return NULL;
691 }
692 else if (errno != 0) {
Guido van Rossumc35f9331996-09-11 23:30:42 +0000693 sprintf(buffer, "atof() literal too large: %.200s", s);
Barry Warsawf5256011996-12-09 18:35:56 +0000694 PyErr_SetString(PyExc_ValueError, buffer);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000695 return NULL;
696 }
Barry Warsawf5256011996-12-09 18:35:56 +0000697 return PyFloat_FromDouble(x);
Guido van Rossumb6775db1994-08-01 11:34:53 +0000698}
699
700
Guido van Rossumed7253c1996-07-23 18:12:39 +0000701static PyObject *
702strop_maketrans(self, args)
703 PyObject *self; /* Not used */
704 PyObject *args;
705{
Guido van Rossume0548b81997-01-06 16:50:09 +0000706 unsigned char *c, *from=NULL, *to=NULL;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000707 int i, fromlen=0, tolen=0;
Guido van Rossume0548b81997-01-06 16:50:09 +0000708 PyObject *result;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000709
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000710 if (!PyArg_ParseTuple(args, "s#s#", &from, &fromlen, &to, &tolen))
711 return NULL;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000712
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000713 if (fromlen != tolen) {
Barry Warsawf5256011996-12-09 18:35:56 +0000714 PyErr_SetString(PyExc_ValueError,
Guido van Rossumed7253c1996-07-23 18:12:39 +0000715 "maketrans arguments must have same length");
716 return NULL;
717 }
Guido van Rossume0548b81997-01-06 16:50:09 +0000718
719 result = PyString_FromStringAndSize((char *)NULL, 256);
720 if (result == NULL)
721 return NULL;
722 c = (unsigned char *) PyString_AS_STRING((PyStringObject *)result);
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000723 for (i = 0; i < 256; i++)
Guido van Rossumed7253c1996-07-23 18:12:39 +0000724 c[i]=(unsigned char)i;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000725 for (i = 0; i < fromlen; i++)
Guido van Rossumed7253c1996-07-23 18:12:39 +0000726 c[from[i]]=to[i];
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000727
Guido van Rossume0548b81997-01-06 16:50:09 +0000728 return result;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000729}
730
731
Barry Warsawf5256011996-12-09 18:35:56 +0000732static PyObject *
Guido van Rossuma3127e81995-09-13 17:39:06 +0000733strop_translate(self, args)
Barry Warsawf5256011996-12-09 18:35:56 +0000734 PyObject *self;
735 PyObject *args;
Guido van Rossuma3127e81995-09-13 17:39:06 +0000736{
Guido van Rossume0548b81997-01-06 16:50:09 +0000737 register char *input, *table, *output;
738 register int i, c, changed = 0;
739 PyObject *input_obj;
740 char *table1, *output_start, *del_table=NULL;
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000741 int inlen, tablen, dellen = 0;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000742 PyObject *result;
Guido van Rossume0548b81997-01-06 16:50:09 +0000743 int trans_table[256];
Guido van Rossuma3127e81995-09-13 17:39:06 +0000744
Guido van Rossume0548b81997-01-06 16:50:09 +0000745 if (!PyArg_ParseTuple(args, "Ss#|s#", &input_obj,
746 &table1, &tablen, &del_table, &dellen))
Guido van Rossuma3127e81995-09-13 17:39:06 +0000747 return NULL;
748 if (tablen != 256) {
Barry Warsawf5256011996-12-09 18:35:56 +0000749 PyErr_SetString(PyExc_ValueError,
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000750 "translation table must be 256 characters long");
Guido van Rossuma3127e81995-09-13 17:39:06 +0000751 return NULL;
752 }
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000753
Guido van Rossume0548b81997-01-06 16:50:09 +0000754 table = table1;
755 inlen = PyString_Size(input_obj);
Guido van Rossumed7253c1996-07-23 18:12:39 +0000756 result = PyString_FromStringAndSize((char *)NULL, inlen);
Guido van Rossuma3127e81995-09-13 17:39:06 +0000757 if (result == NULL)
758 return NULL;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000759 output_start = output = PyString_AsString(result);
Guido van Rossume0548b81997-01-06 16:50:09 +0000760 input = PyString_AsString(input_obj);
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000761
Guido van Rossume0548b81997-01-06 16:50:09 +0000762 if (dellen == 0) {
763 /* If no deletions are required, use faster code */
764 for (i = inlen; --i >= 0; ) {
765 c = Py_CHARMASK(*input++);
766 if (Py_CHARMASK((*output++ = table[c])) != c)
767 changed = 1;
Guido van Rossumed7253c1996-07-23 18:12:39 +0000768 }
Guido van Rossume0548b81997-01-06 16:50:09 +0000769 if (changed)
770 return result;
771 Py_DECREF(result);
772 Py_INCREF(input_obj);
773 return input_obj;
Guido van Rossuma3127e81995-09-13 17:39:06 +0000774 }
Guido van Rossume0548b81997-01-06 16:50:09 +0000775
776 for (i = 0; i < 256; i++)
777 trans_table[i] = Py_CHARMASK(table[i]);
778
779 for (i = 0; i < dellen; i++)
Guido van Rossum1ed5e571997-04-29 21:34:16 +0000780 trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
Guido van Rossume0548b81997-01-06 16:50:09 +0000781
782 for (i = inlen; --i >= 0; ) {
783 c = Py_CHARMASK(*input++);
784 if (trans_table[c] != -1)
785 if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
786 continue;
787 changed = 1;
788 }
789 if (!changed) {
790 Py_DECREF(result);
791 Py_INCREF(input_obj);
792 return input_obj;
793 }
794 /* Fix the size of the resulting string */
795 if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
796 return NULL;
Guido van Rossuma3127e81995-09-13 17:39:06 +0000797 return result;
798}
799
800
Guido van Rossum101923b1997-04-02 06:11:18 +0000801/* What follows is used for implementing replace(). Perry Stoll. */
802
803/*
804 mymemfind
805
806 strstr replacement for arbitrary blocks of memory.
807
808 Locates the first occurance in the memory pointed to by MEM of the
809 contents of memory pointed to by PAT. Returns the index into MEM if
810 found, or -1 if not found. If len of PAT is greater than length of
811 MEM, the function returns -1.
812*/
813static int mymemfind(mem, len, pat, pat_len)
814 char *mem;
815 int len;
816 char *pat;
817 int pat_len;
818{
819 register int ii;
820
821 /* pattern can not occur in the last pat_len-1 chars */
822 len -= pat_len;
823
824 for (ii = 0; ii <= len; ii++) {
825 if (mem[ii] == pat[0] &&
826 (pat_len == 1 ||
827 memcmp(&mem[ii+1], &pat[1], pat_len-1) == 0)) {
828 return ii;
829 }
830 }
831 return -1;
832}
833
834/*
835 mymemcnt
836
837 Return the number of distinct times PAT is found in MEM.
838 meaning mem=1111 and pat==11 returns 2.
839 mem=11111 and pat==11 also return 2.
840 */
841static int mymemcnt(mem, len, pat, pat_len)
842 char *mem;
843 int len;
844 char *pat;
845 int pat_len;
846{
847 register int offset = 0;
848 int nfound = 0;
849
850 while (len >= 0) {
851 offset = mymemfind(mem, len, pat, pat_len);
852 if (offset == -1)
853 break;
854 mem += offset + pat_len;
855 len -= offset + pat_len;
856 nfound++;
857 }
858 return nfound;
859}
860
861/*
862 mymemreplace
863
864 Return a string in which all occurences of PAT in memory STR are
865 replaced with SUB.
866
867 If length of PAT is less than length of STR or there are no occurences
868 of PAT in STR, then the original string is returned. Otherwise, a new
869 string is allocated here and returned.
870
871 on return, out_len is:
872 the length of output string, or
873 -1 if the input string is returned, or
874 unchanged if an error occurs (no memory).
875
876 return value is:
877 the new string allocated locally, or
878 NULL if an error occurred.
879*/
880static char *mymemreplace(str, len, pat, pat_len, sub, sub_len, out_len)
881 char *str;
882 int len; /* input string */
883 char *pat;
884 int pat_len; /* pattern string to find */
885 char *sub;
886 int sub_len; /* substitution string */
887 int *out_len;
888
889{
890 char *out_s;
891 char *new_s;
892 int nfound, offset, new_len;
893
894 if (len == 0 || pat_len > len)
895 goto return_same;
896
897 /* find length of output string */
898 nfound = mymemcnt(str, len, pat, pat_len);
899 if (nfound == 0)
900 goto return_same;
901 new_len = len + nfound*(sub_len - pat_len);
902
903 new_s = (char *)malloc(new_len);
904 if (new_s == NULL) return NULL;
905
906 *out_len = new_len;
907 out_s = new_s;
908
909 while (len > 0) {
910 /* find index of next instance of pattern */
911 offset = mymemfind(str, len, pat, pat_len);
912 /* if not found, break out of loop */
913 if (offset == -1) break;
914
915 /* copy non matching part of input string */
916 memcpy(new_s, str, offset); /* copy part of str before pat */
917 str += offset + pat_len; /* move str past pattern */
918 len -= offset + pat_len; /* reduce length of str remaining */
919
920 /* copy substitute into the output string */
921 new_s += offset; /* move new_s to dest for sub string */
922 memcpy(new_s, sub, sub_len); /* copy substring into new_s */
923 new_s += sub_len; /* offset new_s past sub string */
924 }
925 /* copy any remaining values into output string */
926 if (len > 0)
927 memcpy(new_s, str, len);
928 return out_s;
929
930 return_same:
931 *out_len = -1;
932 return str;
933}
934
935
936static PyObject*
937strop_replace(self, args)
938 PyObject *self; /* Not used */
939 PyObject *args;
940{
941 char *str, *pat,*sub,*new_s;
942 int len,pat_len,sub_len,out_len;
943 PyObject *new;
944
945 if (!PyArg_ParseTuple(args, "s#s#s#",
946 &str, &len, &pat, &pat_len, &sub, &sub_len))
947 return NULL;
948 new_s = mymemreplace(str,len,pat,pat_len,sub,sub_len,&out_len);
949 if (new_s == NULL) {
950 PyErr_NoMemory();
951 return NULL;
952 }
953 if (out_len == -1) {
954 /* we're returning another reference to the input string */
955 new = PyTuple_GetItem(args, 0);
956 Py_XINCREF(new);
957 }
958 else {
959 new = PyString_FromStringAndSize(new_s, out_len);
960 free(new_s);
961 }
962 return new;
963}
964
965
Guido van Rossume270b431992-09-03 20:21:07 +0000966/* List of functions defined in the module */
967
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000968static PyMethodDef
969strop_methods[] = {
Guido van Rossumb6775db1994-08-01 11:34:53 +0000970 {"atof", strop_atof},
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000971 {"atoi", strop_atoi, 1},
972 {"atol", strop_atol, 1},
Guido van Rossum27457531996-06-12 04:24:52 +0000973 {"capitalize", strop_capitalize},
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000974 {"find", strop_find, 1},
Guido van Rossum009e79b1995-05-03 17:40:23 +0000975 {"join", strop_joinfields, 1},
976 {"joinfields", strop_joinfields, 1},
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000977 {"lstrip", strop_lstrip},
Guido van Rossum5c850621992-09-11 23:55:51 +0000978 {"lower", strop_lower},
Guido van Rossum101923b1997-04-02 06:11:18 +0000979 {"maketrans", strop_maketrans, 1},
980 {"replace", strop_replace, 1},
Barry Warsawe8fc29c1997-01-03 22:45:34 +0000981 {"rfind", strop_rfind, 1},
Guido van Rossum7999a5c1996-08-08 19:16:15 +0000982 {"rstrip", strop_rstrip},
Guido van Rossum009e79b1995-05-03 17:40:23 +0000983 {"split", strop_splitfields, 1},
984 {"splitfields", strop_splitfields, 1},
Guido van Rossume270b431992-09-03 20:21:07 +0000985 {"strip", strop_strip},
Guido van Rossum5c850621992-09-11 23:55:51 +0000986 {"swapcase", strop_swapcase},
Guido van Rossuma3127e81995-09-13 17:39:06 +0000987 {"translate", strop_translate, 1},
Guido van Rossum5c850621992-09-11 23:55:51 +0000988 {"upper", strop_upper},
Guido van Rossume270b431992-09-03 20:21:07 +0000989 {NULL, NULL} /* sentinel */
990};
991
992
Guido van Rossume270b431992-09-03 20:21:07 +0000993void
994initstrop()
995{
Barry Warsawf5256011996-12-09 18:35:56 +0000996 PyObject *m, *d, *s;
Guido van Rossumd05eb8b1993-07-08 11:12:36 +0000997 char buf[256];
998 int c, n;
Barry Warsawf5256011996-12-09 18:35:56 +0000999 m = Py_InitModule("strop", strop_methods);
1000 d = PyModule_GetDict(m);
Guido van Rossume22e6441993-07-09 10:51:31 +00001001
1002 /* Create 'whitespace' object */
Guido van Rossumd05eb8b1993-07-08 11:12:36 +00001003 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +00001004 for (c = 0; c < 256; c++) {
Guido van Rossumd05eb8b1993-07-08 11:12:36 +00001005 if (isspace(c))
1006 buf[n++] = c;
1007 }
Barry Warsawf5256011996-12-09 18:35:56 +00001008 s = PyString_FromStringAndSize(buf, n);
Guido van Rossume22e6441993-07-09 10:51:31 +00001009 if (s) {
Barry Warsawf5256011996-12-09 18:35:56 +00001010 PyDict_SetItemString(d, "whitespace", s);
1011 Py_DECREF(s);
Guido van Rossume22e6441993-07-09 10:51:31 +00001012 }
1013 /* Create 'lowercase' object */
1014 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +00001015 for (c = 0; c < 256; c++) {
Guido van Rossume22e6441993-07-09 10:51:31 +00001016 if (islower(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, "lowercase", s);
1022 Py_DECREF(s);
Guido van Rossume22e6441993-07-09 10:51:31 +00001023 }
1024
1025 /* Create 'uppercase' object */
1026 n = 0;
Guido van Rossum7f7f2741995-02-10 17:01:56 +00001027 for (c = 0; c < 256; c++) {
Guido van Rossume22e6441993-07-09 10:51:31 +00001028 if (isupper(c))
1029 buf[n++] = c;
1030 }
Barry Warsawf5256011996-12-09 18:35:56 +00001031 s = PyString_FromStringAndSize(buf, n);
Guido van Rossume22e6441993-07-09 10:51:31 +00001032 if (s) {
Barry Warsawf5256011996-12-09 18:35:56 +00001033 PyDict_SetItemString(d, "uppercase", s);
1034 Py_DECREF(s);
Guido van Rossume22e6441993-07-09 10:51:31 +00001035 }
1036
Barry Warsawf5256011996-12-09 18:35:56 +00001037 if (PyErr_Occurred())
1038 Py_FatalError("can't initialize module strop");
Guido van Rossume270b431992-09-03 20:21:07 +00001039}