symbian-qemu-0.9.1-12/python-2.6.1/Modules/stropmodule.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /* strop module */
       
     2 
       
     3 #define PY_SSIZE_T_CLEAN
       
     4 #include "Python.h"
       
     5 #include <ctype.h>
       
     6 
       
     7 PyDoc_STRVAR(strop_module__doc__,
       
     8 "Common string manipulations, optimized for speed.\n"
       
     9 "\n"
       
    10 "Always use \"import string\" rather than referencing\n"
       
    11 "this module directly.");
       
    12 
       
    13 /* XXX This file assumes that the <ctype.h> is*() functions
       
    14    XXX are defined for all 8-bit characters! */
       
    15 
       
    16 #define WARN if (PyErr_Warn(PyExc_DeprecationWarning, \
       
    17 		       "strop functions are obsolete; use string methods")) \
       
    18 	     return NULL
       
    19 
       
    20 /* The lstrip(), rstrip() and strip() functions are implemented
       
    21    in do_strip(), which uses an additional parameter to indicate what
       
    22    type of strip should occur. */
       
    23 
       
    24 #define LEFTSTRIP 0
       
    25 #define RIGHTSTRIP 1
       
    26 #define BOTHSTRIP 2
       
    27 
       
    28 
       
    29 static PyObject *
       
    30 split_whitespace(char *s, Py_ssize_t len, Py_ssize_t maxsplit)
       
    31 {
       
    32 	Py_ssize_t i = 0, j;
       
    33 	int err;
       
    34 	Py_ssize_t countsplit = 0;
       
    35 	PyObject* item;
       
    36 	PyObject *list = PyList_New(0);
       
    37 
       
    38 	if (list == NULL)
       
    39 		return NULL;
       
    40 
       
    41 	while (i < len) {
       
    42 		while (i < len && isspace(Py_CHARMASK(s[i]))) {
       
    43 			i = i+1;
       
    44 		}
       
    45 		j = i;
       
    46 		while (i < len && !isspace(Py_CHARMASK(s[i]))) {
       
    47 			i = i+1;
       
    48 		}
       
    49 		if (j < i) {
       
    50 			item = PyString_FromStringAndSize(s+j, i-j);
       
    51 			if (item == NULL)
       
    52 				goto finally;
       
    53 
       
    54 			err = PyList_Append(list, item);
       
    55 			Py_DECREF(item);
       
    56 			if (err < 0)
       
    57 				goto finally;
       
    58 
       
    59 			countsplit++;
       
    60 			while (i < len && isspace(Py_CHARMASK(s[i]))) {
       
    61 				i = i+1;
       
    62 			}
       
    63 			if (maxsplit && (countsplit >= maxsplit) && i < len) {
       
    64 				item = PyString_FromStringAndSize(
       
    65                                         s+i, len - i);
       
    66 				if (item == NULL)
       
    67 					goto finally;
       
    68 
       
    69 				err = PyList_Append(list, item);
       
    70 				Py_DECREF(item);
       
    71 				if (err < 0)
       
    72 					goto finally;
       
    73 
       
    74 				i = len;
       
    75 			}
       
    76 		}
       
    77 	}
       
    78 	return list;
       
    79   finally:
       
    80 	Py_DECREF(list);
       
    81 	return NULL;
       
    82 }
       
    83 
       
    84 
       
    85 PyDoc_STRVAR(splitfields__doc__,
       
    86 "split(s [,sep [,maxsplit]]) -> list of strings\n"
       
    87 "splitfields(s [,sep [,maxsplit]]) -> list of strings\n"
       
    88 "\n"
       
    89 "Return a list of the words in the string s, using sep as the\n"
       
    90 "delimiter string.  If maxsplit is nonzero, splits into at most\n"
       
    91 "maxsplit words.  If sep is not specified, any whitespace string\n"
       
    92 "is a separator.  Maxsplit defaults to 0.\n"
       
    93 "\n"
       
    94 "(split and splitfields are synonymous)");
       
    95 
       
    96 static PyObject *
       
    97 strop_splitfields(PyObject *self, PyObject *args)
       
    98 {
       
    99 	Py_ssize_t len, n, i, j, err;
       
   100 	Py_ssize_t splitcount, maxsplit;
       
   101 	char *s, *sub;
       
   102 	PyObject *list, *item;
       
   103 
       
   104 	WARN;
       
   105 	sub = NULL;
       
   106 	n = 0;
       
   107 	splitcount = 0;
       
   108 	maxsplit = 0;
       
   109 	if (!PyArg_ParseTuple(args, "t#|z#n:split", &s, &len, &sub, &n, &maxsplit))
       
   110 		return NULL;
       
   111 	if (sub == NULL)
       
   112 		return split_whitespace(s, len, maxsplit);
       
   113 	if (n == 0) {
       
   114 		PyErr_SetString(PyExc_ValueError, "empty separator");
       
   115 		return NULL;
       
   116 	}
       
   117 
       
   118 	list = PyList_New(0);
       
   119 	if (list == NULL)
       
   120 		return NULL;
       
   121 
       
   122 	i = j = 0;
       
   123 	while (i+n <= len) {
       
   124 		if (s[i] == sub[0] && (n == 1 || memcmp(s+i, sub, n) == 0)) {
       
   125 			item = PyString_FromStringAndSize(s+j, i-j);
       
   126 			if (item == NULL)
       
   127 				goto fail;
       
   128 			err = PyList_Append(list, item);
       
   129 			Py_DECREF(item);
       
   130 			if (err < 0)
       
   131 				goto fail;
       
   132 			i = j = i + n;
       
   133 			splitcount++;
       
   134 			if (maxsplit && (splitcount >= maxsplit))
       
   135 				break;
       
   136 		}
       
   137 		else
       
   138 			i++;
       
   139 	}
       
   140 	item = PyString_FromStringAndSize(s+j, len-j);
       
   141 	if (item == NULL)
       
   142 		goto fail;
       
   143 	err = PyList_Append(list, item);
       
   144 	Py_DECREF(item);
       
   145 	if (err < 0)
       
   146 		goto fail;
       
   147 
       
   148 	return list;
       
   149 
       
   150  fail:
       
   151 	Py_DECREF(list);
       
   152 	return NULL;
       
   153 }
       
   154 
       
   155 
       
   156 PyDoc_STRVAR(joinfields__doc__,
       
   157 "join(list [,sep]) -> string\n"
       
   158 "joinfields(list [,sep]) -> string\n"
       
   159 "\n"
       
   160 "Return a string composed of the words in list, with\n"
       
   161 "intervening occurrences of sep.  Sep defaults to a single\n"
       
   162 "space.\n"
       
   163 "\n"
       
   164 "(join and joinfields are synonymous)");
       
   165 
       
   166 static PyObject *
       
   167 strop_joinfields(PyObject *self, PyObject *args)
       
   168 {
       
   169 	PyObject *seq;
       
   170 	char *sep = NULL;
       
   171 	Py_ssize_t seqlen, seplen = 0;
       
   172 	Py_ssize_t i, reslen = 0, slen = 0, sz = 100;
       
   173 	PyObject *res = NULL;
       
   174 	char* p = NULL;
       
   175 	ssizeargfunc getitemfunc;
       
   176 
       
   177 	WARN;
       
   178 	if (!PyArg_ParseTuple(args, "O|t#:join", &seq, &sep, &seplen))
       
   179 		return NULL;
       
   180 	if (sep == NULL) {
       
   181 		sep = " ";
       
   182 		seplen = 1;
       
   183 	}
       
   184 
       
   185 	seqlen = PySequence_Size(seq);
       
   186 	if (seqlen < 0 && PyErr_Occurred())
       
   187 		return NULL;
       
   188 
       
   189 	if (seqlen == 1) {
       
   190 		/* Optimization if there's only one item */
       
   191 		PyObject *item = PySequence_GetItem(seq, 0);
       
   192 		if (item && !PyString_Check(item)) {
       
   193 			PyErr_SetString(PyExc_TypeError,
       
   194 				 "first argument must be sequence of strings");
       
   195 			Py_DECREF(item);
       
   196 			return NULL;
       
   197 		}
       
   198 		return item;
       
   199 	}
       
   200 
       
   201 	if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))
       
   202 		return NULL;
       
   203 	p = PyString_AsString(res);
       
   204 
       
   205 	/* optimize for lists, since it's the most common case.  all others
       
   206 	 * (tuples and arbitrary sequences) just use the sequence abstract
       
   207 	 * interface.
       
   208 	 */
       
   209 	if (PyList_Check(seq)) {
       
   210 		for (i = 0; i < seqlen; i++) {
       
   211 			PyObject *item = PyList_GET_ITEM(seq, i);
       
   212 			if (!PyString_Check(item)) {
       
   213 				PyErr_SetString(PyExc_TypeError,
       
   214 				"first argument must be sequence of strings");
       
   215 				Py_DECREF(res);
       
   216 				return NULL;
       
   217 			}
       
   218 			slen = PyString_GET_SIZE(item);
       
   219 			if (slen > PY_SSIZE_T_MAX - reslen ||
       
   220 			    seplen > PY_SSIZE_T_MAX - reslen - seplen) {
       
   221 				PyErr_SetString(PyExc_OverflowError,
       
   222 						"input too long");
       
   223 				Py_DECREF(res);
       
   224 				return NULL;
       
   225 			}
       
   226 			while (reslen + slen + seplen >= sz) {
       
   227 				if (_PyString_Resize(&res, sz * 2) < 0)
       
   228 					return NULL;
       
   229 				sz *= 2;
       
   230 				p = PyString_AsString(res) + reslen;
       
   231 			}
       
   232 			if (i > 0) {
       
   233 				memcpy(p, sep, seplen);
       
   234 				p += seplen;
       
   235 				reslen += seplen;
       
   236 			}
       
   237 			memcpy(p, PyString_AS_STRING(item), slen);
       
   238 			p += slen;
       
   239 			reslen += slen;
       
   240 		}
       
   241 		_PyString_Resize(&res, reslen);
       
   242 		return res;
       
   243 	}
       
   244 
       
   245 	if (seq->ob_type->tp_as_sequence == NULL ||
       
   246 		 (getitemfunc = seq->ob_type->tp_as_sequence->sq_item) == NULL)
       
   247 	{
       
   248 		PyErr_SetString(PyExc_TypeError,
       
   249 				"first argument must be a sequence");
       
   250 		return NULL;
       
   251 	}
       
   252 	/* This is now type safe */
       
   253 	for (i = 0; i < seqlen; i++) {
       
   254 		PyObject *item = getitemfunc(seq, i);
       
   255 		if (!item || !PyString_Check(item)) {
       
   256 			PyErr_SetString(PyExc_TypeError,
       
   257 				 "first argument must be sequence of strings");
       
   258 			Py_DECREF(res);
       
   259 			Py_XDECREF(item);
       
   260 			return NULL;
       
   261 		}
       
   262 		slen = PyString_GET_SIZE(item);
       
   263 		if (slen > PY_SSIZE_T_MAX - reslen ||
       
   264 		    seplen > PY_SSIZE_T_MAX - reslen - seplen) {
       
   265 			PyErr_SetString(PyExc_OverflowError,
       
   266 					"input too long");
       
   267 			Py_DECREF(res);
       
   268 			Py_XDECREF(item);
       
   269 			return NULL;
       
   270 		}
       
   271 		while (reslen + slen + seplen >= sz) {
       
   272 			if (_PyString_Resize(&res, sz * 2) < 0) {
       
   273 				Py_DECREF(item);
       
   274 				return NULL;
       
   275 			}
       
   276 			sz *= 2;
       
   277 			p = PyString_AsString(res) + reslen;
       
   278 		}
       
   279 		if (i > 0) {
       
   280 			memcpy(p, sep, seplen);
       
   281 			p += seplen;
       
   282 			reslen += seplen;
       
   283 		}
       
   284 		memcpy(p, PyString_AS_STRING(item), slen);
       
   285 		p += slen;
       
   286 		reslen += slen;
       
   287 		Py_DECREF(item);
       
   288 	}
       
   289 	_PyString_Resize(&res, reslen);
       
   290 	return res;
       
   291 }
       
   292 
       
   293 
       
   294 PyDoc_STRVAR(find__doc__,
       
   295 "find(s, sub [,start [,end]]) -> in\n"
       
   296 "\n"
       
   297 "Return the lowest index in s where substring sub is found,\n"
       
   298 "such that sub is contained within s[start,end].  Optional\n"
       
   299 "arguments start and end are interpreted as in slice notation.\n"
       
   300 "\n"
       
   301 "Return -1 on failure.");
       
   302 
       
   303 static PyObject *
       
   304 strop_find(PyObject *self, PyObject *args)
       
   305 {
       
   306 	char *s, *sub;
       
   307 	Py_ssize_t len, n, i = 0, last = PY_SSIZE_T_MAX;
       
   308 
       
   309 	WARN;
       
   310 	if (!PyArg_ParseTuple(args, "t#t#|nn:find", &s, &len, &sub, &n, &i, &last))
       
   311 		return NULL;
       
   312 
       
   313 	if (last > len)
       
   314 		last = len;
       
   315 	if (last < 0)
       
   316 		last += len;
       
   317 	if (last < 0)
       
   318 		last = 0;
       
   319 	if (i < 0)
       
   320 		i += len;
       
   321 	if (i < 0)
       
   322 		i = 0;
       
   323 
       
   324 	if (n == 0 && i <= last)
       
   325 		return PyInt_FromLong((long)i);
       
   326 
       
   327 	last -= n;
       
   328 	for (; i <= last; ++i)
       
   329 		if (s[i] == sub[0] &&
       
   330 		    (n == 1 || memcmp(&s[i+1], &sub[1], n-1) == 0))
       
   331 			return PyInt_FromLong((long)i);
       
   332 
       
   333 	return PyInt_FromLong(-1L);
       
   334 }
       
   335 
       
   336 
       
   337 PyDoc_STRVAR(rfind__doc__,
       
   338 "rfind(s, sub [,start [,end]]) -> int\n"
       
   339 "\n"
       
   340 "Return the highest index in s where substring sub is found,\n"
       
   341 "such that sub is contained within s[start,end].  Optional\n"
       
   342 "arguments start and end are interpreted as in slice notation.\n"
       
   343 "\n"
       
   344 "Return -1 on failure.");
       
   345 
       
   346 static PyObject *
       
   347 strop_rfind(PyObject *self, PyObject *args)
       
   348 {
       
   349 	char *s, *sub;
       
   350 	Py_ssize_t len, n, j;
       
   351 	Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;
       
   352 
       
   353 	WARN;
       
   354 	if (!PyArg_ParseTuple(args, "t#t#|nn:rfind", &s, &len, &sub, &n, &i, &last))
       
   355 		return NULL;
       
   356 
       
   357 	if (last > len)
       
   358 		last = len;
       
   359 	if (last < 0)
       
   360 		last += len;
       
   361 	if (last < 0)
       
   362 		last = 0;
       
   363 	if (i < 0)
       
   364 		i += len;
       
   365 	if (i < 0)
       
   366 		i = 0;
       
   367 
       
   368 	if (n == 0 && i <= last)
       
   369 		return PyInt_FromLong((long)last);
       
   370 
       
   371 	for (j = last-n; j >= i; --j)
       
   372 		if (s[j] == sub[0] &&
       
   373 		    (n == 1 || memcmp(&s[j+1], &sub[1], n-1) == 0))
       
   374 			return PyInt_FromLong((long)j);
       
   375 
       
   376 	return PyInt_FromLong(-1L);
       
   377 }
       
   378 
       
   379 
       
   380 static PyObject *
       
   381 do_strip(PyObject *args, int striptype)
       
   382 {
       
   383 	char *s;
       
   384 	Py_ssize_t len, i, j;
       
   385 
       
   386 
       
   387 	if (PyString_AsStringAndSize(args, &s, &len))
       
   388 		return NULL;
       
   389 
       
   390 	i = 0;
       
   391 	if (striptype != RIGHTSTRIP) {
       
   392 		while (i < len && isspace(Py_CHARMASK(s[i]))) {
       
   393 			i++;
       
   394 		}
       
   395 	}
       
   396 
       
   397 	j = len;
       
   398 	if (striptype != LEFTSTRIP) {
       
   399 		do {
       
   400 			j--;
       
   401 		} while (j >= i && isspace(Py_CHARMASK(s[j])));
       
   402 		j++;
       
   403 	}
       
   404 
       
   405 	if (i == 0 && j == len) {
       
   406 		Py_INCREF(args);
       
   407 		return args;
       
   408 	}
       
   409 	else
       
   410 		return PyString_FromStringAndSize(s+i, j-i);
       
   411 }
       
   412 
       
   413 
       
   414 PyDoc_STRVAR(strip__doc__,
       
   415 "strip(s) -> string\n"
       
   416 "\n"
       
   417 "Return a copy of the string s with leading and trailing\n"
       
   418 "whitespace removed.");
       
   419 
       
   420 static PyObject *
       
   421 strop_strip(PyObject *self, PyObject *args)
       
   422 {
       
   423 	WARN;
       
   424 	return do_strip(args, BOTHSTRIP);
       
   425 }
       
   426 
       
   427 
       
   428 PyDoc_STRVAR(lstrip__doc__,
       
   429 "lstrip(s) -> string\n"
       
   430 "\n"
       
   431 "Return a copy of the string s with leading whitespace removed.");
       
   432 
       
   433 static PyObject *
       
   434 strop_lstrip(PyObject *self, PyObject *args)
       
   435 {
       
   436 	WARN;
       
   437 	return do_strip(args, LEFTSTRIP);
       
   438 }
       
   439 
       
   440 
       
   441 PyDoc_STRVAR(rstrip__doc__,
       
   442 "rstrip(s) -> string\n"
       
   443 "\n"
       
   444 "Return a copy of the string s with trailing whitespace removed.");
       
   445 
       
   446 static PyObject *
       
   447 strop_rstrip(PyObject *self, PyObject *args)
       
   448 {
       
   449 	WARN;
       
   450 	return do_strip(args, RIGHTSTRIP);
       
   451 }
       
   452 
       
   453 
       
   454 PyDoc_STRVAR(lower__doc__,
       
   455 "lower(s) -> string\n"
       
   456 "\n"
       
   457 "Return a copy of the string s converted to lowercase.");
       
   458 
       
   459 static PyObject *
       
   460 strop_lower(PyObject *self, PyObject *args)
       
   461 {
       
   462 	char *s, *s_new;
       
   463 	Py_ssize_t i, n;
       
   464 	PyObject *newstr;
       
   465 	int changed;
       
   466 
       
   467 	WARN;
       
   468 	if (PyString_AsStringAndSize(args, &s, &n))
       
   469 		return NULL;
       
   470 	newstr = PyString_FromStringAndSize(NULL, n);
       
   471 	if (newstr == NULL)
       
   472 		return NULL;
       
   473 	s_new = PyString_AsString(newstr);
       
   474 	changed = 0;
       
   475 	for (i = 0; i < n; i++) {
       
   476 		int c = Py_CHARMASK(*s++);
       
   477 		if (isupper(c)) {
       
   478 			changed = 1;
       
   479 			*s_new = tolower(c);
       
   480 		} else
       
   481 			*s_new = c;
       
   482 		s_new++;
       
   483 	}
       
   484 	if (!changed) {
       
   485 		Py_DECREF(newstr);
       
   486 		Py_INCREF(args);
       
   487 		return args;
       
   488 	}
       
   489 	return newstr;
       
   490 }
       
   491 
       
   492 
       
   493 PyDoc_STRVAR(upper__doc__,
       
   494 "upper(s) -> string\n"
       
   495 "\n"
       
   496 "Return a copy of the string s converted to uppercase.");
       
   497 
       
   498 static PyObject *
       
   499 strop_upper(PyObject *self, PyObject *args)
       
   500 {
       
   501 	char *s, *s_new;
       
   502 	Py_ssize_t i, n;
       
   503 	PyObject *newstr;
       
   504 	int changed;
       
   505 
       
   506 	WARN;
       
   507 	if (PyString_AsStringAndSize(args, &s, &n))
       
   508 		return NULL;
       
   509 	newstr = PyString_FromStringAndSize(NULL, n);
       
   510 	if (newstr == NULL)
       
   511 		return NULL;
       
   512 	s_new = PyString_AsString(newstr);
       
   513 	changed = 0;
       
   514 	for (i = 0; i < n; i++) {
       
   515 		int c = Py_CHARMASK(*s++);
       
   516 		if (islower(c)) {
       
   517 			changed = 1;
       
   518 			*s_new = toupper(c);
       
   519 		} else
       
   520 			*s_new = c;
       
   521 		s_new++;
       
   522 	}
       
   523 	if (!changed) {
       
   524 		Py_DECREF(newstr);
       
   525 		Py_INCREF(args);
       
   526 		return args;
       
   527 	}
       
   528 	return newstr;
       
   529 }
       
   530 
       
   531 
       
   532 PyDoc_STRVAR(capitalize__doc__,
       
   533 "capitalize(s) -> string\n"
       
   534 "\n"
       
   535 "Return a copy of the string s with only its first character\n"
       
   536 "capitalized.");
       
   537 
       
   538 static PyObject *
       
   539 strop_capitalize(PyObject *self, PyObject *args)
       
   540 {
       
   541 	char *s, *s_new;
       
   542 	Py_ssize_t i, n;
       
   543 	PyObject *newstr;
       
   544 	int changed;
       
   545 
       
   546 	WARN;
       
   547 	if (PyString_AsStringAndSize(args, &s, &n))
       
   548 		return NULL;
       
   549 	newstr = PyString_FromStringAndSize(NULL, n);
       
   550 	if (newstr == NULL)
       
   551 		return NULL;
       
   552 	s_new = PyString_AsString(newstr);
       
   553 	changed = 0;
       
   554 	if (0 < n) {
       
   555 		int c = Py_CHARMASK(*s++);
       
   556 		if (islower(c)) {
       
   557 			changed = 1;
       
   558 			*s_new = toupper(c);
       
   559 		} else
       
   560 			*s_new = c;
       
   561 		s_new++;
       
   562 	}
       
   563 	for (i = 1; i < n; i++) {
       
   564 		int c = Py_CHARMASK(*s++);
       
   565 		if (isupper(c)) {
       
   566 			changed = 1;
       
   567 			*s_new = tolower(c);
       
   568 		} else
       
   569 			*s_new = c;
       
   570 		s_new++;
       
   571 	}
       
   572 	if (!changed) {
       
   573 		Py_DECREF(newstr);
       
   574 		Py_INCREF(args);
       
   575 		return args;
       
   576 	}
       
   577 	return newstr;
       
   578 }
       
   579 
       
   580 
       
   581 PyDoc_STRVAR(expandtabs__doc__,
       
   582 "expandtabs(string, [tabsize]) -> string\n"
       
   583 "\n"
       
   584 "Expand tabs in a string, i.e. replace them by one or more spaces,\n"
       
   585 "depending on the current column and the given tab size (default 8).\n"
       
   586 "The column number is reset to zero after each newline occurring in the\n"
       
   587 "string.  This doesn't understand other non-printing characters.");
       
   588 
       
   589 static PyObject *
       
   590 strop_expandtabs(PyObject *self, PyObject *args)
       
   591 {
       
   592 	/* Original by Fredrik Lundh */
       
   593 	char* e;
       
   594 	char* p;
       
   595 	char* q;
       
   596 	Py_ssize_t i, j, old_j;
       
   597 	PyObject* out;
       
   598 	char* string;
       
   599 	Py_ssize_t stringlen;
       
   600 	int tabsize = 8;
       
   601 
       
   602 	WARN;
       
   603 	/* Get arguments */
       
   604 	if (!PyArg_ParseTuple(args, "s#|i:expandtabs", &string, &stringlen, &tabsize))
       
   605 		return NULL;
       
   606 	if (tabsize < 1) {
       
   607 		PyErr_SetString(PyExc_ValueError,
       
   608 				"tabsize must be at least 1");
       
   609 		return NULL;
       
   610 	}
       
   611 
       
   612 	/* First pass: determine size of output string */
       
   613 	i = j = old_j = 0; /* j: current column; i: total of previous lines */
       
   614 	e = string + stringlen;
       
   615 	for (p = string; p < e; p++) {
       
   616 		if (*p == '\t') {
       
   617 			j += tabsize - (j%tabsize);
       
   618 			if (old_j > j) {
       
   619 				PyErr_SetString(PyExc_OverflowError,
       
   620 						"new string is too long");
       
   621 				return NULL;
       
   622 			}
       
   623 			old_j = j;
       
   624 		} else {
       
   625 			j++;
       
   626 			if (*p == '\n') {
       
   627 				i += j;
       
   628 				j = 0;
       
   629 			}
       
   630 		}
       
   631 	}
       
   632 
       
   633 	if ((i + j) < 0) {
       
   634 		PyErr_SetString(PyExc_OverflowError, "new string is too long");
       
   635 		return NULL;
       
   636 	}
       
   637 
       
   638 	/* Second pass: create output string and fill it */
       
   639 	out = PyString_FromStringAndSize(NULL, i+j);
       
   640 	if (out == NULL)
       
   641 		return NULL;
       
   642 
       
   643 	i = 0;
       
   644 	q = PyString_AS_STRING(out);
       
   645 
       
   646 	for (p = string; p < e; p++) {
       
   647 		if (*p == '\t') {
       
   648 			j = tabsize - (i%tabsize);
       
   649 			i += j;
       
   650 			while (j-- > 0)
       
   651 				*q++ = ' ';
       
   652 		} else {
       
   653 			*q++ = *p;
       
   654 			i++;
       
   655 			if (*p == '\n')
       
   656 				i = 0;
       
   657 		}
       
   658 	}
       
   659 
       
   660 	return out;
       
   661 }
       
   662 
       
   663 
       
   664 PyDoc_STRVAR(count__doc__,
       
   665 "count(s, sub[, start[, end]]) -> int\n"
       
   666 "\n"
       
   667 "Return the number of occurrences of substring sub in string\n"
       
   668 "s[start:end].  Optional arguments start and end are\n"
       
   669 "interpreted as in slice notation.");
       
   670 
       
   671 static PyObject *
       
   672 strop_count(PyObject *self, PyObject *args)
       
   673 {
       
   674 	char *s, *sub;
       
   675 	Py_ssize_t len, n;
       
   676 	Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;
       
   677 	Py_ssize_t m, r;
       
   678 
       
   679 	WARN;
       
   680 	if (!PyArg_ParseTuple(args, "t#t#|nn:count", &s, &len, &sub, &n, &i, &last))
       
   681 		return NULL;
       
   682 	if (last > len)
       
   683 		last = len;
       
   684 	if (last < 0)
       
   685 		last += len;
       
   686 	if (last < 0)
       
   687 		last = 0;
       
   688 	if (i < 0)
       
   689 		i += len;
       
   690 	if (i < 0)
       
   691 		i = 0;
       
   692 	m = last + 1 - n;
       
   693 	if (n == 0)
       
   694 		return PyInt_FromLong((long) (m-i));
       
   695 
       
   696 	r = 0;
       
   697 	while (i < m) {
       
   698 		if (!memcmp(s+i, sub, n)) {
       
   699 			r++;
       
   700 			i += n;
       
   701 		} else {
       
   702 			i++;
       
   703 		}
       
   704 	}
       
   705 	return PyInt_FromLong((long) r);
       
   706 }
       
   707 
       
   708 
       
   709 PyDoc_STRVAR(swapcase__doc__,
       
   710 "swapcase(s) -> string\n"
       
   711 "\n"
       
   712 "Return a copy of the string s with upper case characters\n"
       
   713 "converted to lowercase and vice versa.");
       
   714 
       
   715 static PyObject *
       
   716 strop_swapcase(PyObject *self, PyObject *args)
       
   717 {
       
   718 	char *s, *s_new;
       
   719 	Py_ssize_t i, n;
       
   720 	PyObject *newstr;
       
   721 	int changed;
       
   722 
       
   723 	WARN;
       
   724 	if (PyString_AsStringAndSize(args, &s, &n))
       
   725 		return NULL;
       
   726 	newstr = PyString_FromStringAndSize(NULL, n);
       
   727 	if (newstr == NULL)
       
   728 		return NULL;
       
   729 	s_new = PyString_AsString(newstr);
       
   730 	changed = 0;
       
   731 	for (i = 0; i < n; i++) {
       
   732 		int c = Py_CHARMASK(*s++);
       
   733 		if (islower(c)) {
       
   734 			changed = 1;
       
   735 			*s_new = toupper(c);
       
   736 		}
       
   737 		else if (isupper(c)) {
       
   738 			changed = 1;
       
   739 			*s_new = tolower(c);
       
   740 		}
       
   741 		else
       
   742 			*s_new = c;
       
   743 		s_new++;
       
   744 	}
       
   745 	if (!changed) {
       
   746 		Py_DECREF(newstr);
       
   747 		Py_INCREF(args);
       
   748 		return args;
       
   749 	}
       
   750 	return newstr;
       
   751 }
       
   752 
       
   753 
       
   754 PyDoc_STRVAR(atoi__doc__,
       
   755 "atoi(s [,base]) -> int\n"
       
   756 "\n"
       
   757 "Return the integer represented by the string s in the given\n"
       
   758 "base, which defaults to 10.  The string s must consist of one\n"
       
   759 "or more digits, possibly preceded by a sign.  If base is 0, it\n"
       
   760 "is chosen from the leading characters of s, 0 for octal, 0x or\n"
       
   761 "0X for hexadecimal.  If base is 16, a preceding 0x or 0X is\n"
       
   762 "accepted.");
       
   763 
       
   764 static PyObject *
       
   765 strop_atoi(PyObject *self, PyObject *args)
       
   766 {
       
   767 	char *s, *end;
       
   768 	int base = 10;
       
   769 	long x;
       
   770 	char buffer[256]; /* For errors */
       
   771 
       
   772 	WARN;
       
   773 	if (!PyArg_ParseTuple(args, "s|i:atoi", &s, &base))
       
   774 		return NULL;
       
   775 
       
   776 	if ((base != 0 && base < 2) || base > 36) {
       
   777 		PyErr_SetString(PyExc_ValueError, "invalid base for atoi()");
       
   778 		return NULL;
       
   779 	}
       
   780 
       
   781 	while (*s && isspace(Py_CHARMASK(*s)))
       
   782 		s++;
       
   783 	errno = 0;
       
   784 	if (base == 0 && s[0] == '0')
       
   785 		x = (long) PyOS_strtoul(s, &end, base);
       
   786 	else
       
   787 		x = PyOS_strtol(s, &end, base);
       
   788 	if (end == s || !isalnum(Py_CHARMASK(end[-1])))
       
   789 		goto bad;
       
   790 	while (*end && isspace(Py_CHARMASK(*end)))
       
   791 		end++;
       
   792 	if (*end != '\0') {
       
   793   bad:
       
   794 		PyOS_snprintf(buffer, sizeof(buffer),
       
   795 			      "invalid literal for atoi(): %.200s", s);
       
   796 		PyErr_SetString(PyExc_ValueError, buffer);
       
   797 		return NULL;
       
   798 	}
       
   799 	else if (errno != 0) {
       
   800 		PyOS_snprintf(buffer, sizeof(buffer), 
       
   801 			      "atoi() literal too large: %.200s", s);
       
   802 		PyErr_SetString(PyExc_ValueError, buffer);
       
   803 		return NULL;
       
   804 	}
       
   805 	return PyInt_FromLong(x);
       
   806 }
       
   807 
       
   808 
       
   809 PyDoc_STRVAR(atol__doc__,
       
   810 "atol(s [,base]) -> long\n"
       
   811 "\n"
       
   812 "Return the long integer represented by the string s in the\n"
       
   813 "given base, which defaults to 10.  The string s must consist\n"
       
   814 "of one or more digits, possibly preceded by a sign.  If base\n"
       
   815 "is 0, it is chosen from the leading characters of s, 0 for\n"
       
   816 "octal, 0x or 0X for hexadecimal.  If base is 16, a preceding\n"
       
   817 "0x or 0X is accepted.  A trailing L or l is not accepted,\n"
       
   818 "unless base is 0.");
       
   819 
       
   820 static PyObject *
       
   821 strop_atol(PyObject *self, PyObject *args)
       
   822 {
       
   823 	char *s, *end;
       
   824 	int base = 10;
       
   825 	PyObject *x;
       
   826 	char buffer[256]; /* For errors */
       
   827 
       
   828 	WARN;
       
   829 	if (!PyArg_ParseTuple(args, "s|i:atol", &s, &base))
       
   830 		return NULL;
       
   831 
       
   832 	if ((base != 0 && base < 2) || base > 36) {
       
   833 		PyErr_SetString(PyExc_ValueError, "invalid base for atol()");
       
   834 		return NULL;
       
   835 	}
       
   836 
       
   837 	while (*s && isspace(Py_CHARMASK(*s)))
       
   838 		s++;
       
   839 	if (s[0] == '\0') {
       
   840 		PyErr_SetString(PyExc_ValueError, "empty string for atol()");
       
   841 		return NULL;
       
   842 	}
       
   843 	x = PyLong_FromString(s, &end, base);
       
   844 	if (x == NULL)
       
   845 		return NULL;
       
   846 	if (base == 0 && (*end == 'l' || *end == 'L'))
       
   847 		end++;
       
   848 	while (*end && isspace(Py_CHARMASK(*end)))
       
   849 		end++;
       
   850 	if (*end != '\0') {
       
   851 		PyOS_snprintf(buffer, sizeof(buffer),
       
   852 			      "invalid literal for atol(): %.200s", s);
       
   853 		PyErr_SetString(PyExc_ValueError, buffer);
       
   854 		Py_DECREF(x);
       
   855 		return NULL;
       
   856 	}
       
   857 	return x;
       
   858 }
       
   859 
       
   860 
       
   861 PyDoc_STRVAR(atof__doc__,
       
   862 "atof(s) -> float\n"
       
   863 "\n"
       
   864 "Return the floating point number represented by the string s.");
       
   865 
       
   866 static PyObject *
       
   867 strop_atof(PyObject *self, PyObject *args)
       
   868 {
       
   869 	char *s, *end;
       
   870 	double x;
       
   871 	char buffer[256]; /* For errors */
       
   872 
       
   873 	WARN;
       
   874 	if (!PyArg_ParseTuple(args, "s:atof", &s))
       
   875 		return NULL;
       
   876 	while (*s && isspace(Py_CHARMASK(*s)))
       
   877 		s++;
       
   878 	if (s[0] == '\0') {
       
   879 		PyErr_SetString(PyExc_ValueError, "empty string for atof()");
       
   880 		return NULL;
       
   881 	}
       
   882 	errno = 0;
       
   883 	PyFPE_START_PROTECT("strop_atof", return 0)
       
   884 	x = PyOS_ascii_strtod(s, &end);
       
   885 	PyFPE_END_PROTECT(x)
       
   886 	while (*end && isspace(Py_CHARMASK(*end)))
       
   887 		end++;
       
   888 	if (*end != '\0') {
       
   889 		PyOS_snprintf(buffer, sizeof(buffer),
       
   890 			      "invalid literal for atof(): %.200s", s);
       
   891 		PyErr_SetString(PyExc_ValueError, buffer);
       
   892 		return NULL;
       
   893 	}
       
   894 	else if (errno != 0) {
       
   895 		PyOS_snprintf(buffer, sizeof(buffer), 
       
   896 			      "atof() literal too large: %.200s", s);
       
   897 		PyErr_SetString(PyExc_ValueError, buffer);
       
   898 		return NULL;
       
   899 	}
       
   900 	return PyFloat_FromDouble(x);
       
   901 }
       
   902 
       
   903 
       
   904 PyDoc_STRVAR(maketrans__doc__,
       
   905 "maketrans(frm, to) -> string\n"
       
   906 "\n"
       
   907 "Return a translation table (a string of 256 bytes long)\n"
       
   908 "suitable for use in string.translate.  The strings frm and to\n"
       
   909 "must be of the same length.");
       
   910 
       
   911 static PyObject *
       
   912 strop_maketrans(PyObject *self, PyObject *args)
       
   913 {
       
   914 	unsigned char *c, *from=NULL, *to=NULL;
       
   915 	Py_ssize_t i, fromlen=0, tolen=0;
       
   916 	PyObject *result;
       
   917 
       
   918 	if (!PyArg_ParseTuple(args, "t#t#:maketrans", &from, &fromlen, &to, &tolen))
       
   919 		return NULL;
       
   920 
       
   921 	if (fromlen != tolen) {
       
   922 		PyErr_SetString(PyExc_ValueError,
       
   923 				"maketrans arguments must have same length");
       
   924 		return NULL;
       
   925 	}
       
   926 
       
   927 	result = PyString_FromStringAndSize((char *)NULL, 256);
       
   928 	if (result == NULL)
       
   929 		return NULL;
       
   930 	c = (unsigned char *) PyString_AS_STRING((PyStringObject *)result);
       
   931 	for (i = 0; i < 256; i++)
       
   932 		c[i]=(unsigned char)i;
       
   933 	for (i = 0; i < fromlen; i++)
       
   934 		c[from[i]]=to[i];
       
   935 
       
   936 	return result;
       
   937 }
       
   938 
       
   939 
       
   940 PyDoc_STRVAR(translate__doc__,
       
   941 "translate(s,table [,deletechars]) -> string\n"
       
   942 "\n"
       
   943 "Return a copy of the string s, where all characters occurring\n"
       
   944 "in the optional argument deletechars are removed, and the\n"
       
   945 "remaining characters have been mapped through the given\n"
       
   946 "translation table, which must be a string of length 256.");
       
   947 
       
   948 static PyObject *
       
   949 strop_translate(PyObject *self, PyObject *args)
       
   950 {
       
   951 	register char *input, *table, *output;
       
   952 	Py_ssize_t i; 
       
   953 	int c, changed = 0;
       
   954 	PyObject *input_obj;
       
   955 	char *table1, *output_start, *del_table=NULL;
       
   956 	Py_ssize_t inlen, tablen, dellen = 0;
       
   957 	PyObject *result;
       
   958 	int trans_table[256];
       
   959 
       
   960 	WARN;
       
   961 	if (!PyArg_ParseTuple(args, "St#|t#:translate", &input_obj,
       
   962 			      &table1, &tablen, &del_table, &dellen))
       
   963 		return NULL;
       
   964 	if (tablen != 256) {
       
   965 		PyErr_SetString(PyExc_ValueError,
       
   966 			      "translation table must be 256 characters long");
       
   967 		return NULL;
       
   968 	}
       
   969 
       
   970 	table = table1;
       
   971 	inlen = PyString_GET_SIZE(input_obj);
       
   972 	result = PyString_FromStringAndSize((char *)NULL, inlen);
       
   973 	if (result == NULL)
       
   974 		return NULL;
       
   975 	output_start = output = PyString_AsString(result);
       
   976 	input = PyString_AsString(input_obj);
       
   977 
       
   978 	if (dellen == 0) {
       
   979 		/* If no deletions are required, use faster code */
       
   980 		for (i = inlen; --i >= 0; ) {
       
   981 			c = Py_CHARMASK(*input++);
       
   982 			if (Py_CHARMASK((*output++ = table[c])) != c)
       
   983 				changed = 1;
       
   984 		}
       
   985 		if (changed)
       
   986 			return result;
       
   987 		Py_DECREF(result);
       
   988 		Py_INCREF(input_obj);
       
   989 		return input_obj;
       
   990 	}
       
   991 
       
   992 	for (i = 0; i < 256; i++)
       
   993 		trans_table[i] = Py_CHARMASK(table[i]);
       
   994 
       
   995 	for (i = 0; i < dellen; i++)
       
   996 		trans_table[(int) Py_CHARMASK(del_table[i])] = -1;
       
   997 
       
   998 	for (i = inlen; --i >= 0; ) {
       
   999 		c = Py_CHARMASK(*input++);
       
  1000 		if (trans_table[c] != -1)
       
  1001 			if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
       
  1002 				continue;
       
  1003 		changed = 1;
       
  1004 	}
       
  1005 	if (!changed) {
       
  1006 		Py_DECREF(result);
       
  1007 		Py_INCREF(input_obj);
       
  1008 		return input_obj;
       
  1009 	}
       
  1010 	/* Fix the size of the resulting string */
       
  1011 	if (inlen > 0)
       
  1012 		_PyString_Resize(&result, output - output_start);
       
  1013 	return result;
       
  1014 }
       
  1015 
       
  1016 
       
  1017 /* What follows is used for implementing replace().  Perry Stoll. */
       
  1018 
       
  1019 /*
       
  1020   mymemfind
       
  1021 
       
  1022   strstr replacement for arbitrary blocks of memory.
       
  1023 
       
  1024   Locates the first occurrence in the memory pointed to by MEM of the
       
  1025   contents of memory pointed to by PAT.  Returns the index into MEM if
       
  1026   found, or -1 if not found.  If len of PAT is greater than length of
       
  1027   MEM, the function returns -1.
       
  1028 */
       
  1029 static Py_ssize_t 
       
  1030 mymemfind(const char *mem, Py_ssize_t len, const char *pat, Py_ssize_t pat_len)
       
  1031 {
       
  1032 	register Py_ssize_t ii;
       
  1033 
       
  1034 	/* pattern can not occur in the last pat_len-1 chars */
       
  1035 	len -= pat_len;
       
  1036 
       
  1037 	for (ii = 0; ii <= len; ii++) {
       
  1038 		if (mem[ii] == pat[0] &&
       
  1039 		    (pat_len == 1 ||
       
  1040 		     memcmp(&mem[ii+1], &pat[1], pat_len-1) == 0)) {
       
  1041 			return ii;
       
  1042 		}
       
  1043 	}
       
  1044 	return -1;
       
  1045 }
       
  1046 
       
  1047 /*
       
  1048   mymemcnt
       
  1049 
       
  1050    Return the number of distinct times PAT is found in MEM.
       
  1051    meaning mem=1111 and pat==11 returns 2.
       
  1052            mem=11111 and pat==11 also return 2.
       
  1053  */
       
  1054 static Py_ssize_t 
       
  1055 mymemcnt(const char *mem, Py_ssize_t len, const char *pat, Py_ssize_t pat_len)
       
  1056 {
       
  1057 	register Py_ssize_t offset = 0;
       
  1058 	Py_ssize_t nfound = 0;
       
  1059 
       
  1060 	while (len >= 0) {
       
  1061 		offset = mymemfind(mem, len, pat, pat_len);
       
  1062 		if (offset == -1)
       
  1063 			break;
       
  1064 		mem += offset + pat_len;
       
  1065 		len -= offset + pat_len;
       
  1066 		nfound++;
       
  1067 	}
       
  1068 	return nfound;
       
  1069 }
       
  1070 
       
  1071 /*
       
  1072    mymemreplace
       
  1073 
       
  1074    Return a string in which all occurrences of PAT in memory STR are
       
  1075    replaced with SUB.
       
  1076 
       
  1077    If length of PAT is less than length of STR or there are no occurrences
       
  1078    of PAT in STR, then the original string is returned. Otherwise, a new
       
  1079    string is allocated here and returned.
       
  1080 
       
  1081    on return, out_len is:
       
  1082        the length of output string, or
       
  1083        -1 if the input string is returned, or
       
  1084        unchanged if an error occurs (no memory).
       
  1085 
       
  1086    return value is:
       
  1087        the new string allocated locally, or
       
  1088        NULL if an error occurred.
       
  1089 */
       
  1090 static char *
       
  1091 mymemreplace(const char *str, Py_ssize_t len,		/* input string */
       
  1092              const char *pat, Py_ssize_t pat_len,	/* pattern string to find */
       
  1093              const char *sub, Py_ssize_t sub_len,	/* substitution string */
       
  1094              Py_ssize_t count,				/* number of replacements */
       
  1095 	     Py_ssize_t *out_len)
       
  1096 {
       
  1097 	char *out_s;
       
  1098 	char *new_s;
       
  1099 	Py_ssize_t nfound, offset, new_len;
       
  1100 
       
  1101 	if (len == 0 || pat_len > len)
       
  1102 		goto return_same;
       
  1103 
       
  1104 	/* find length of output string */
       
  1105 	nfound = mymemcnt(str, len, pat, pat_len);
       
  1106 	if (count < 0)
       
  1107 		count = PY_SSIZE_T_MAX;
       
  1108 	else if (nfound > count)
       
  1109 		nfound = count;
       
  1110 	if (nfound == 0)
       
  1111 		goto return_same;
       
  1112 
       
  1113 	new_len = len + nfound*(sub_len - pat_len);
       
  1114 	if (new_len == 0) {
       
  1115 		/* Have to allocate something for the caller to free(). */
       
  1116 		out_s = (char *)PyMem_MALLOC(1);
       
  1117 		if (out_s == NULL)
       
  1118 			return NULL;
       
  1119 		out_s[0] = '\0';
       
  1120 	}
       
  1121 	else {
       
  1122 		assert(new_len > 0);
       
  1123 		new_s = (char *)PyMem_MALLOC(new_len);
       
  1124 		if (new_s == NULL)
       
  1125 			return NULL;
       
  1126 		out_s = new_s;
       
  1127 
       
  1128 		for (; count > 0 && len > 0; --count) {
       
  1129 			/* find index of next instance of pattern */
       
  1130 			offset = mymemfind(str, len, pat, pat_len);
       
  1131 			if (offset == -1)
       
  1132 				break;
       
  1133 
       
  1134 			/* copy non matching part of input string */
       
  1135 			memcpy(new_s, str, offset);
       
  1136 			str += offset + pat_len;
       
  1137 			len -= offset + pat_len;
       
  1138 
       
  1139 			/* copy substitute into the output string */
       
  1140 			new_s += offset;
       
  1141 			memcpy(new_s, sub, sub_len);
       
  1142 			new_s += sub_len;
       
  1143 		}
       
  1144 		/* copy any remaining values into output string */
       
  1145 		if (len > 0)
       
  1146 			memcpy(new_s, str, len);
       
  1147 	}
       
  1148 	*out_len = new_len;
       
  1149 	return out_s;
       
  1150 
       
  1151   return_same:
       
  1152 	*out_len = -1;
       
  1153 	return (char *)str; /* cast away const */
       
  1154 }
       
  1155 
       
  1156 
       
  1157 PyDoc_STRVAR(replace__doc__,
       
  1158 "replace (str, old, new[, maxsplit]) -> string\n"
       
  1159 "\n"
       
  1160 "Return a copy of string str with all occurrences of substring\n"
       
  1161 "old replaced by new. If the optional argument maxsplit is\n"
       
  1162 "given, only the first maxsplit occurrences are replaced.");
       
  1163 
       
  1164 static PyObject *
       
  1165 strop_replace(PyObject *self, PyObject *args)
       
  1166 {
       
  1167 	char *str, *pat,*sub,*new_s;
       
  1168 	Py_ssize_t len,pat_len,sub_len,out_len;
       
  1169 	Py_ssize_t count = -1;
       
  1170 	PyObject *newstr;
       
  1171 
       
  1172 	WARN;
       
  1173 	if (!PyArg_ParseTuple(args, "t#t#t#|n:replace",
       
  1174 			      &str, &len, &pat, &pat_len, &sub, &sub_len,
       
  1175 			      &count))
       
  1176 		return NULL;
       
  1177 	if (pat_len <= 0) {
       
  1178 		PyErr_SetString(PyExc_ValueError, "empty pattern string");
       
  1179 		return NULL;
       
  1180 	}
       
  1181 	/* CAUTION:  strop treats a replace count of 0 as infinity, unlke
       
  1182 	 * current (2.1) string.py and string methods.  Preserve this for
       
  1183 	 * ... well, hard to say for what <wink>.
       
  1184 	 */
       
  1185 	if (count == 0)
       
  1186 		count = -1;
       
  1187 	new_s = mymemreplace(str,len,pat,pat_len,sub,sub_len,count,&out_len);
       
  1188 	if (new_s == NULL) {
       
  1189 		PyErr_NoMemory();
       
  1190 		return NULL;
       
  1191 	}
       
  1192 	if (out_len == -1) {
       
  1193 		/* we're returning another reference to the input string */
       
  1194 		newstr = PyTuple_GetItem(args, 0);
       
  1195 		Py_XINCREF(newstr);
       
  1196 	}
       
  1197 	else {
       
  1198 		newstr = PyString_FromStringAndSize(new_s, out_len);
       
  1199 		PyMem_FREE(new_s);
       
  1200 	}
       
  1201 	return newstr;
       
  1202 }
       
  1203 
       
  1204 
       
  1205 /* List of functions defined in the module */
       
  1206 
       
  1207 static PyMethodDef
       
  1208 strop_methods[] = {
       
  1209 	{"atof",	strop_atof,	   METH_VARARGS, atof__doc__},
       
  1210 	{"atoi",	strop_atoi,	   METH_VARARGS, atoi__doc__},
       
  1211 	{"atol",	strop_atol,	   METH_VARARGS, atol__doc__},
       
  1212 	{"capitalize",	strop_capitalize,  METH_O,       capitalize__doc__},
       
  1213 	{"count",	strop_count,	   METH_VARARGS, count__doc__},
       
  1214 	{"expandtabs",	strop_expandtabs,  METH_VARARGS, expandtabs__doc__},
       
  1215 	{"find",	strop_find,	   METH_VARARGS, find__doc__},
       
  1216 	{"join",	strop_joinfields,  METH_VARARGS, joinfields__doc__},
       
  1217 	{"joinfields",	strop_joinfields,  METH_VARARGS, joinfields__doc__},
       
  1218 	{"lstrip",	strop_lstrip,	   METH_O,       lstrip__doc__},
       
  1219 	{"lower",	strop_lower,	   METH_O,       lower__doc__},
       
  1220 	{"maketrans",	strop_maketrans,   METH_VARARGS, maketrans__doc__},
       
  1221 	{"replace",	strop_replace,	   METH_VARARGS, replace__doc__},
       
  1222 	{"rfind",	strop_rfind,	   METH_VARARGS, rfind__doc__},
       
  1223 	{"rstrip",	strop_rstrip,	   METH_O,       rstrip__doc__},
       
  1224 	{"split",	strop_splitfields, METH_VARARGS, splitfields__doc__},
       
  1225 	{"splitfields",	strop_splitfields, METH_VARARGS, splitfields__doc__},
       
  1226 	{"strip",	strop_strip,	   METH_O,       strip__doc__},
       
  1227 	{"swapcase",	strop_swapcase,    METH_O,       swapcase__doc__},
       
  1228 	{"translate",	strop_translate,   METH_VARARGS, translate__doc__},
       
  1229 	{"upper",	strop_upper,	   METH_O,       upper__doc__},
       
  1230 	{NULL,		NULL}	/* sentinel */
       
  1231 };
       
  1232 
       
  1233 
       
  1234 PyMODINIT_FUNC
       
  1235 initstrop(void)
       
  1236 {
       
  1237 	PyObject *m, *s;
       
  1238 	char buf[256];
       
  1239 	int c, n;
       
  1240 	m = Py_InitModule4("strop", strop_methods, strop_module__doc__,
       
  1241 			   (PyObject*)NULL, PYTHON_API_VERSION);
       
  1242 	if (m == NULL)
       
  1243 		return;
       
  1244 
       
  1245 	/* Create 'whitespace' object */
       
  1246 	n = 0;
       
  1247 	for (c = 0; c < 256; c++) {
       
  1248 		if (isspace(c))
       
  1249 			buf[n++] = c;
       
  1250 	}
       
  1251 	s = PyString_FromStringAndSize(buf, n);
       
  1252 	if (s)
       
  1253 		PyModule_AddObject(m, "whitespace", s);
       
  1254 
       
  1255 	/* Create 'lowercase' object */
       
  1256 	n = 0;
       
  1257 	for (c = 0; c < 256; c++) {
       
  1258 		if (islower(c))
       
  1259 			buf[n++] = c;
       
  1260 	}
       
  1261 	s = PyString_FromStringAndSize(buf, n);
       
  1262 	if (s)
       
  1263 		PyModule_AddObject(m, "lowercase", s);
       
  1264 
       
  1265 	/* Create 'uppercase' object */
       
  1266 	n = 0;
       
  1267 	for (c = 0; c < 256; c++) {
       
  1268 		if (isupper(c))
       
  1269 			buf[n++] = c;
       
  1270 	}
       
  1271 	s = PyString_FromStringAndSize(buf, n);
       
  1272 	if (s)
       
  1273 		PyModule_AddObject(m, "uppercase", s);
       
  1274 }