+++ /dev/null
-/* strop module */\r
-\r
-#define PY_SSIZE_T_CLEAN\r
-#include "Python.h"\r
-#include <ctype.h>\r
-\r
-PyDoc_STRVAR(strop_module__doc__,\r
-"Common string manipulations, optimized for speed.\n"\r
-"\n"\r
-"Always use \"import string\" rather than referencing\n"\r
-"this module directly.");\r
-\r
-/* XXX This file assumes that the <ctype.h> is*() functions\r
- XXX are defined for all 8-bit characters! */\r
-\r
-#define WARN if (PyErr_Warn(PyExc_DeprecationWarning, \\r
- "strop functions are obsolete; use string methods")) \\r
- return NULL\r
-\r
-/* The lstrip(), rstrip() and strip() functions are implemented\r
- in do_strip(), which uses an additional parameter to indicate what\r
- type of strip should occur. */\r
-\r
-#define LEFTSTRIP 0\r
-#define RIGHTSTRIP 1\r
-#define BOTHSTRIP 2\r
-\r
-\r
-static PyObject *\r
-split_whitespace(char *s, Py_ssize_t len, Py_ssize_t maxsplit)\r
-{\r
- Py_ssize_t i = 0, j;\r
- int err;\r
- Py_ssize_t countsplit = 0;\r
- PyObject* item;\r
- PyObject *list = PyList_New(0);\r
-\r
- if (list == NULL)\r
- return NULL;\r
-\r
- while (i < len) {\r
- while (i < len && isspace(Py_CHARMASK(s[i]))) {\r
- i = i+1;\r
- }\r
- j = i;\r
- while (i < len && !isspace(Py_CHARMASK(s[i]))) {\r
- i = i+1;\r
- }\r
- if (j < i) {\r
- item = PyString_FromStringAndSize(s+j, i-j);\r
- if (item == NULL)\r
- goto finally;\r
-\r
- err = PyList_Append(list, item);\r
- Py_DECREF(item);\r
- if (err < 0)\r
- goto finally;\r
-\r
- countsplit++;\r
- while (i < len && isspace(Py_CHARMASK(s[i]))) {\r
- i = i+1;\r
- }\r
- if (maxsplit && (countsplit >= maxsplit) && i < len) {\r
- item = PyString_FromStringAndSize(\r
- s+i, len - i);\r
- if (item == NULL)\r
- goto finally;\r
-\r
- err = PyList_Append(list, item);\r
- Py_DECREF(item);\r
- if (err < 0)\r
- goto finally;\r
-\r
- i = len;\r
- }\r
- }\r
- }\r
- return list;\r
- finally:\r
- Py_DECREF(list);\r
- return NULL;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(splitfields__doc__,\r
-"split(s [,sep [,maxsplit]]) -> list of strings\n"\r
-"splitfields(s [,sep [,maxsplit]]) -> list of strings\n"\r
-"\n"\r
-"Return a list of the words in the string s, using sep as the\n"\r
-"delimiter string. If maxsplit is nonzero, splits into at most\n"\r
-"maxsplit words. If sep is not specified, any whitespace string\n"\r
-"is a separator. Maxsplit defaults to 0.\n"\r
-"\n"\r
-"(split and splitfields are synonymous)");\r
-\r
-static PyObject *\r
-strop_splitfields(PyObject *self, PyObject *args)\r
-{\r
- Py_ssize_t len, n, i, j, err;\r
- Py_ssize_t splitcount, maxsplit;\r
- char *s, *sub;\r
- PyObject *list, *item;\r
-\r
- WARN;\r
- sub = NULL;\r
- n = 0;\r
- splitcount = 0;\r
- maxsplit = 0;\r
- if (!PyArg_ParseTuple(args, "t#|z#n:split", &s, &len, &sub, &n, &maxsplit))\r
- return NULL;\r
- if (sub == NULL)\r
- return split_whitespace(s, len, maxsplit);\r
- if (n == 0) {\r
- PyErr_SetString(PyExc_ValueError, "empty separator");\r
- return NULL;\r
- }\r
-\r
- list = PyList_New(0);\r
- if (list == NULL)\r
- return NULL;\r
-\r
- i = j = 0;\r
- while (i+n <= len) {\r
- if (s[i] == sub[0] && (n == 1 || memcmp(s+i, sub, n) == 0)) {\r
- item = PyString_FromStringAndSize(s+j, i-j);\r
- if (item == NULL)\r
- goto fail;\r
- err = PyList_Append(list, item);\r
- Py_DECREF(item);\r
- if (err < 0)\r
- goto fail;\r
- i = j = i + n;\r
- splitcount++;\r
- if (maxsplit && (splitcount >= maxsplit))\r
- break;\r
- }\r
- else\r
- i++;\r
- }\r
- item = PyString_FromStringAndSize(s+j, len-j);\r
- if (item == NULL)\r
- goto fail;\r
- err = PyList_Append(list, item);\r
- Py_DECREF(item);\r
- if (err < 0)\r
- goto fail;\r
-\r
- return list;\r
-\r
- fail:\r
- Py_DECREF(list);\r
- return NULL;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(joinfields__doc__,\r
-"join(list [,sep]) -> string\n"\r
-"joinfields(list [,sep]) -> string\n"\r
-"\n"\r
-"Return a string composed of the words in list, with\n"\r
-"intervening occurrences of sep. Sep defaults to a single\n"\r
-"space.\n"\r
-"\n"\r
-"(join and joinfields are synonymous)");\r
-\r
-static PyObject *\r
-strop_joinfields(PyObject *self, PyObject *args)\r
-{\r
- PyObject *seq;\r
- char *sep = NULL;\r
- Py_ssize_t seqlen, seplen = 0;\r
- Py_ssize_t i, reslen = 0, slen = 0, sz = 100;\r
- PyObject *res = NULL;\r
- char* p = NULL;\r
- ssizeargfunc getitemfunc;\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "O|t#:join", &seq, &sep, &seplen))\r
- return NULL;\r
- if (sep == NULL) {\r
- sep = " ";\r
- seplen = 1;\r
- }\r
-\r
- seqlen = PySequence_Size(seq);\r
- if (seqlen < 0 && PyErr_Occurred())\r
- return NULL;\r
-\r
- if (seqlen == 1) {\r
- /* Optimization if there's only one item */\r
- PyObject *item = PySequence_GetItem(seq, 0);\r
- if (item && !PyString_Check(item)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "first argument must be sequence of strings");\r
- Py_DECREF(item);\r
- return NULL;\r
- }\r
- return item;\r
- }\r
-\r
- if (!(res = PyString_FromStringAndSize((char*)NULL, sz)))\r
- return NULL;\r
- p = PyString_AsString(res);\r
-\r
- /* optimize for lists, since it's the most common case. all others\r
- * (tuples and arbitrary sequences) just use the sequence abstract\r
- * interface.\r
- */\r
- if (PyList_Check(seq)) {\r
- for (i = 0; i < seqlen; i++) {\r
- PyObject *item = PyList_GET_ITEM(seq, i);\r
- if (!PyString_Check(item)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "first argument must be sequence of strings");\r
- Py_DECREF(res);\r
- return NULL;\r
- }\r
- slen = PyString_GET_SIZE(item);\r
- if (slen > PY_SSIZE_T_MAX - reslen ||\r
- seplen > PY_SSIZE_T_MAX - reslen - seplen) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "input too long");\r
- Py_DECREF(res);\r
- return NULL;\r
- }\r
- while (reslen + slen + seplen >= sz) {\r
- if (_PyString_Resize(&res, sz * 2) < 0)\r
- return NULL;\r
- sz *= 2;\r
- p = PyString_AsString(res) + reslen;\r
- }\r
- if (i > 0) {\r
- memcpy(p, sep, seplen);\r
- p += seplen;\r
- reslen += seplen;\r
- }\r
- memcpy(p, PyString_AS_STRING(item), slen);\r
- p += slen;\r
- reslen += slen;\r
- }\r
- _PyString_Resize(&res, reslen);\r
- return res;\r
- }\r
-\r
- if (seq->ob_type->tp_as_sequence == NULL ||\r
- (getitemfunc = seq->ob_type->tp_as_sequence->sq_item) == NULL)\r
- {\r
- PyErr_SetString(PyExc_TypeError,\r
- "first argument must be a sequence");\r
- return NULL;\r
- }\r
- /* This is now type safe */\r
- for (i = 0; i < seqlen; i++) {\r
- PyObject *item = getitemfunc(seq, i);\r
- if (!item || !PyString_Check(item)) {\r
- PyErr_SetString(PyExc_TypeError,\r
- "first argument must be sequence of strings");\r
- Py_DECREF(res);\r
- Py_XDECREF(item);\r
- return NULL;\r
- }\r
- slen = PyString_GET_SIZE(item);\r
- if (slen > PY_SSIZE_T_MAX - reslen ||\r
- seplen > PY_SSIZE_T_MAX - reslen - seplen) {\r
- PyErr_SetString(PyExc_OverflowError,\r
- "input too long");\r
- Py_DECREF(res);\r
- Py_XDECREF(item);\r
- return NULL;\r
- }\r
- while (reslen + slen + seplen >= sz) {\r
- if (_PyString_Resize(&res, sz * 2) < 0) {\r
- Py_DECREF(item);\r
- return NULL;\r
- }\r
- sz *= 2;\r
- p = PyString_AsString(res) + reslen;\r
- }\r
- if (i > 0) {\r
- memcpy(p, sep, seplen);\r
- p += seplen;\r
- reslen += seplen;\r
- }\r
- memcpy(p, PyString_AS_STRING(item), slen);\r
- p += slen;\r
- reslen += slen;\r
- Py_DECREF(item);\r
- }\r
- _PyString_Resize(&res, reslen);\r
- return res;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(find__doc__,\r
-"find(s, sub [,start [,end]]) -> in\n"\r
-"\n"\r
-"Return the lowest index in s where substring sub is found,\n"\r
-"such that sub is contained within s[start,end]. Optional\n"\r
-"arguments start and end are interpreted as in slice notation.\n"\r
-"\n"\r
-"Return -1 on failure.");\r
-\r
-static PyObject *\r
-strop_find(PyObject *self, PyObject *args)\r
-{\r
- char *s, *sub;\r
- Py_ssize_t len, n, i = 0, last = PY_SSIZE_T_MAX;\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "t#t#|nn:find", &s, &len, &sub, &n, &i, &last))\r
- return NULL;\r
-\r
- if (last > len)\r
- last = len;\r
- if (last < 0)\r
- last += len;\r
- if (last < 0)\r
- last = 0;\r
- if (i < 0)\r
- i += len;\r
- if (i < 0)\r
- i = 0;\r
-\r
- if (n == 0 && i <= last)\r
- return PyInt_FromLong((long)i);\r
-\r
- last -= n;\r
- for (; i <= last; ++i)\r
- if (s[i] == sub[0] &&\r
- (n == 1 || memcmp(&s[i+1], &sub[1], n-1) == 0))\r
- return PyInt_FromLong((long)i);\r
-\r
- return PyInt_FromLong(-1L);\r
-}\r
-\r
-\r
-PyDoc_STRVAR(rfind__doc__,\r
-"rfind(s, sub [,start [,end]]) -> int\n"\r
-"\n"\r
-"Return the highest index in s where substring sub is found,\n"\r
-"such that sub is contained within s[start,end]. Optional\n"\r
-"arguments start and end are interpreted as in slice notation.\n"\r
-"\n"\r
-"Return -1 on failure.");\r
-\r
-static PyObject *\r
-strop_rfind(PyObject *self, PyObject *args)\r
-{\r
- char *s, *sub;\r
- Py_ssize_t len, n, j;\r
- Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "t#t#|nn:rfind", &s, &len, &sub, &n, &i, &last))\r
- return NULL;\r
-\r
- if (last > len)\r
- last = len;\r
- if (last < 0)\r
- last += len;\r
- if (last < 0)\r
- last = 0;\r
- if (i < 0)\r
- i += len;\r
- if (i < 0)\r
- i = 0;\r
-\r
- if (n == 0 && i <= last)\r
- return PyInt_FromLong((long)last);\r
-\r
- for (j = last-n; j >= i; --j)\r
- if (s[j] == sub[0] &&\r
- (n == 1 || memcmp(&s[j+1], &sub[1], n-1) == 0))\r
- return PyInt_FromLong((long)j);\r
-\r
- return PyInt_FromLong(-1L);\r
-}\r
-\r
-\r
-static PyObject *\r
-do_strip(PyObject *args, int striptype)\r
-{\r
- char *s;\r
- Py_ssize_t len, i, j;\r
-\r
-\r
- if (PyString_AsStringAndSize(args, &s, &len))\r
- return NULL;\r
-\r
- i = 0;\r
- if (striptype != RIGHTSTRIP) {\r
- while (i < len && isspace(Py_CHARMASK(s[i]))) {\r
- i++;\r
- }\r
- }\r
-\r
- j = len;\r
- if (striptype != LEFTSTRIP) {\r
- do {\r
- j--;\r
- } while (j >= i && isspace(Py_CHARMASK(s[j])));\r
- j++;\r
- }\r
-\r
- if (i == 0 && j == len) {\r
- Py_INCREF(args);\r
- return args;\r
- }\r
- else\r
- return PyString_FromStringAndSize(s+i, j-i);\r
-}\r
-\r
-\r
-PyDoc_STRVAR(strip__doc__,\r
-"strip(s) -> string\n"\r
-"\n"\r
-"Return a copy of the string s with leading and trailing\n"\r
-"whitespace removed.");\r
-\r
-static PyObject *\r
-strop_strip(PyObject *self, PyObject *args)\r
-{\r
- WARN;\r
- return do_strip(args, BOTHSTRIP);\r
-}\r
-\r
-\r
-PyDoc_STRVAR(lstrip__doc__,\r
-"lstrip(s) -> string\n"\r
-"\n"\r
-"Return a copy of the string s with leading whitespace removed.");\r
-\r
-static PyObject *\r
-strop_lstrip(PyObject *self, PyObject *args)\r
-{\r
- WARN;\r
- return do_strip(args, LEFTSTRIP);\r
-}\r
-\r
-\r
-PyDoc_STRVAR(rstrip__doc__,\r
-"rstrip(s) -> string\n"\r
-"\n"\r
-"Return a copy of the string s with trailing whitespace removed.");\r
-\r
-static PyObject *\r
-strop_rstrip(PyObject *self, PyObject *args)\r
-{\r
- WARN;\r
- return do_strip(args, RIGHTSTRIP);\r
-}\r
-\r
-\r
-PyDoc_STRVAR(lower__doc__,\r
-"lower(s) -> string\n"\r
-"\n"\r
-"Return a copy of the string s converted to lowercase.");\r
-\r
-static PyObject *\r
-strop_lower(PyObject *self, PyObject *args)\r
-{\r
- char *s, *s_new;\r
- Py_ssize_t i, n;\r
- PyObject *newstr;\r
- int changed;\r
-\r
- WARN;\r
- if (PyString_AsStringAndSize(args, &s, &n))\r
- return NULL;\r
- newstr = PyString_FromStringAndSize(NULL, n);\r
- if (newstr == NULL)\r
- return NULL;\r
- s_new = PyString_AsString(newstr);\r
- changed = 0;\r
- for (i = 0; i < n; i++) {\r
- int c = Py_CHARMASK(*s++);\r
- if (isupper(c)) {\r
- changed = 1;\r
- *s_new = tolower(c);\r
- } else\r
- *s_new = c;\r
- s_new++;\r
- }\r
- if (!changed) {\r
- Py_DECREF(newstr);\r
- Py_INCREF(args);\r
- return args;\r
- }\r
- return newstr;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(upper__doc__,\r
-"upper(s) -> string\n"\r
-"\n"\r
-"Return a copy of the string s converted to uppercase.");\r
-\r
-static PyObject *\r
-strop_upper(PyObject *self, PyObject *args)\r
-{\r
- char *s, *s_new;\r
- Py_ssize_t i, n;\r
- PyObject *newstr;\r
- int changed;\r
-\r
- WARN;\r
- if (PyString_AsStringAndSize(args, &s, &n))\r
- return NULL;\r
- newstr = PyString_FromStringAndSize(NULL, n);\r
- if (newstr == NULL)\r
- return NULL;\r
- s_new = PyString_AsString(newstr);\r
- changed = 0;\r
- for (i = 0; i < n; i++) {\r
- int c = Py_CHARMASK(*s++);\r
- if (islower(c)) {\r
- changed = 1;\r
- *s_new = toupper(c);\r
- } else\r
- *s_new = c;\r
- s_new++;\r
- }\r
- if (!changed) {\r
- Py_DECREF(newstr);\r
- Py_INCREF(args);\r
- return args;\r
- }\r
- return newstr;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(capitalize__doc__,\r
-"capitalize(s) -> string\n"\r
-"\n"\r
-"Return a copy of the string s with only its first character\n"\r
-"capitalized.");\r
-\r
-static PyObject *\r
-strop_capitalize(PyObject *self, PyObject *args)\r
-{\r
- char *s, *s_new;\r
- Py_ssize_t i, n;\r
- PyObject *newstr;\r
- int changed;\r
-\r
- WARN;\r
- if (PyString_AsStringAndSize(args, &s, &n))\r
- return NULL;\r
- newstr = PyString_FromStringAndSize(NULL, n);\r
- if (newstr == NULL)\r
- return NULL;\r
- s_new = PyString_AsString(newstr);\r
- changed = 0;\r
- if (0 < n) {\r
- int c = Py_CHARMASK(*s++);\r
- if (islower(c)) {\r
- changed = 1;\r
- *s_new = toupper(c);\r
- } else\r
- *s_new = c;\r
- s_new++;\r
- }\r
- for (i = 1; i < n; i++) {\r
- int c = Py_CHARMASK(*s++);\r
- if (isupper(c)) {\r
- changed = 1;\r
- *s_new = tolower(c);\r
- } else\r
- *s_new = c;\r
- s_new++;\r
- }\r
- if (!changed) {\r
- Py_DECREF(newstr);\r
- Py_INCREF(args);\r
- return args;\r
- }\r
- return newstr;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(expandtabs__doc__,\r
-"expandtabs(string, [tabsize]) -> string\n"\r
-"\n"\r
-"Expand tabs in a string, i.e. replace them by one or more spaces,\n"\r
-"depending on the current column and the given tab size (default 8).\n"\r
-"The column number is reset to zero after each newline occurring in the\n"\r
-"string. This doesn't understand other non-printing characters.");\r
-\r
-static PyObject *\r
-strop_expandtabs(PyObject *self, PyObject *args)\r
-{\r
- /* Original by Fredrik Lundh */\r
- char* e;\r
- char* p;\r
- char* q;\r
- Py_ssize_t i, j;\r
- PyObject* out;\r
- char* string;\r
- Py_ssize_t stringlen;\r
- int tabsize = 8;\r
-\r
- WARN;\r
- /* Get arguments */\r
- if (!PyArg_ParseTuple(args, "s#|i:expandtabs", &string, &stringlen, &tabsize))\r
- return NULL;\r
- if (tabsize < 1) {\r
- PyErr_SetString(PyExc_ValueError,\r
- "tabsize must be at least 1");\r
- return NULL;\r
- }\r
-\r
- /* First pass: determine size of output string */\r
- i = j = 0; /* j: current column; i: total of previous lines */\r
- e = string + stringlen;\r
- for (p = string; p < e; p++) {\r
- if (*p == '\t') {\r
- Py_ssize_t incr = tabsize - (j%tabsize);\r
- if (j > PY_SSIZE_T_MAX - incr)\r
- goto overflow;\r
- j += incr;\r
- } else {\r
- if (j > PY_SSIZE_T_MAX - 1)\r
- goto overflow;\r
- j++;\r
- if (*p == '\n') {\r
- if (i > PY_SSIZE_T_MAX - j)\r
- goto overflow;\r
- i += j;\r
- j = 0;\r
- }\r
- }\r
- }\r
-\r
- if (i > PY_SSIZE_T_MAX - j)\r
- goto overflow;\r
-\r
- /* Second pass: create output string and fill it */\r
- out = PyString_FromStringAndSize(NULL, i+j);\r
- if (out == NULL)\r
- return NULL;\r
-\r
- i = 0;\r
- q = PyString_AS_STRING(out);\r
-\r
- for (p = string; p < e; p++) {\r
- if (*p == '\t') {\r
- j = tabsize - (i%tabsize);\r
- i += j;\r
- while (j-- > 0)\r
- *q++ = ' ';\r
- } else {\r
- *q++ = *p;\r
- i++;\r
- if (*p == '\n')\r
- i = 0;\r
- }\r
- }\r
-\r
- return out;\r
- overflow:\r
- PyErr_SetString(PyExc_OverflowError, "result is too long");\r
- return NULL;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(count__doc__,\r
-"count(s, sub[, start[, end]]) -> int\n"\r
-"\n"\r
-"Return the number of occurrences of substring sub in string\n"\r
-"s[start:end]. Optional arguments start and end are\n"\r
-"interpreted as in slice notation.");\r
-\r
-static PyObject *\r
-strop_count(PyObject *self, PyObject *args)\r
-{\r
- char *s, *sub;\r
- Py_ssize_t len, n;\r
- Py_ssize_t i = 0, last = PY_SSIZE_T_MAX;\r
- Py_ssize_t m, r;\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "t#t#|nn:count", &s, &len, &sub, &n, &i, &last))\r
- return NULL;\r
- if (last > len)\r
- last = len;\r
- if (last < 0)\r
- last += len;\r
- if (last < 0)\r
- last = 0;\r
- if (i < 0)\r
- i += len;\r
- if (i < 0)\r
- i = 0;\r
- m = last + 1 - n;\r
- if (n == 0)\r
- return PyInt_FromLong((long) (m-i));\r
-\r
- r = 0;\r
- while (i < m) {\r
- if (!memcmp(s+i, sub, n)) {\r
- r++;\r
- i += n;\r
- } else {\r
- i++;\r
- }\r
- }\r
- return PyInt_FromLong((long) r);\r
-}\r
-\r
-\r
-PyDoc_STRVAR(swapcase__doc__,\r
-"swapcase(s) -> string\n"\r
-"\n"\r
-"Return a copy of the string s with upper case characters\n"\r
-"converted to lowercase and vice versa.");\r
-\r
-static PyObject *\r
-strop_swapcase(PyObject *self, PyObject *args)\r
-{\r
- char *s, *s_new;\r
- Py_ssize_t i, n;\r
- PyObject *newstr;\r
- int changed;\r
-\r
- WARN;\r
- if (PyString_AsStringAndSize(args, &s, &n))\r
- return NULL;\r
- newstr = PyString_FromStringAndSize(NULL, n);\r
- if (newstr == NULL)\r
- return NULL;\r
- s_new = PyString_AsString(newstr);\r
- changed = 0;\r
- for (i = 0; i < n; i++) {\r
- int c = Py_CHARMASK(*s++);\r
- if (islower(c)) {\r
- changed = 1;\r
- *s_new = toupper(c);\r
- }\r
- else if (isupper(c)) {\r
- changed = 1;\r
- *s_new = tolower(c);\r
- }\r
- else\r
- *s_new = c;\r
- s_new++;\r
- }\r
- if (!changed) {\r
- Py_DECREF(newstr);\r
- Py_INCREF(args);\r
- return args;\r
- }\r
- return newstr;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(atoi__doc__,\r
-"atoi(s [,base]) -> int\n"\r
-"\n"\r
-"Return the integer represented by the string s in the given\n"\r
-"base, which defaults to 10. The string s must consist of one\n"\r
-"or more digits, possibly preceded by a sign. If base is 0, it\n"\r
-"is chosen from the leading characters of s, 0 for octal, 0x or\n"\r
-"0X for hexadecimal. If base is 16, a preceding 0x or 0X is\n"\r
-"accepted.");\r
-\r
-static PyObject *\r
-strop_atoi(PyObject *self, PyObject *args)\r
-{\r
- char *s, *end;\r
- int base = 10;\r
- long x;\r
- char buffer[256]; /* For errors */\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "s|i:atoi", &s, &base))\r
- return NULL;\r
-\r
- if ((base != 0 && base < 2) || base > 36) {\r
- PyErr_SetString(PyExc_ValueError, "invalid base for atoi()");\r
- return NULL;\r
- }\r
-\r
- while (*s && isspace(Py_CHARMASK(*s)))\r
- s++;\r
- errno = 0;\r
- if (base == 0 && s[0] == '0')\r
- x = (long) PyOS_strtoul(s, &end, base);\r
- else\r
- x = PyOS_strtol(s, &end, base);\r
- if (end == s || !isalnum(Py_CHARMASK(end[-1])))\r
- goto bad;\r
- while (*end && isspace(Py_CHARMASK(*end)))\r
- end++;\r
- if (*end != '\0') {\r
- bad:\r
- PyOS_snprintf(buffer, sizeof(buffer),\r
- "invalid literal for atoi(): %.200s", s);\r
- PyErr_SetString(PyExc_ValueError, buffer);\r
- return NULL;\r
- }\r
- else if (errno != 0) {\r
- PyOS_snprintf(buffer, sizeof(buffer),\r
- "atoi() literal too large: %.200s", s);\r
- PyErr_SetString(PyExc_ValueError, buffer);\r
- return NULL;\r
- }\r
- return PyInt_FromLong(x);\r
-}\r
-\r
-\r
-PyDoc_STRVAR(atol__doc__,\r
-"atol(s [,base]) -> long\n"\r
-"\n"\r
-"Return the long integer represented by the string s in the\n"\r
-"given base, which defaults to 10. The string s must consist\n"\r
-"of one or more digits, possibly preceded by a sign. If base\n"\r
-"is 0, it is chosen from the leading characters of s, 0 for\n"\r
-"octal, 0x or 0X for hexadecimal. If base is 16, a preceding\n"\r
-"0x or 0X is accepted. A trailing L or l is not accepted,\n"\r
-"unless base is 0.");\r
-\r
-static PyObject *\r
-strop_atol(PyObject *self, PyObject *args)\r
-{\r
- char *s, *end;\r
- int base = 10;\r
- PyObject *x;\r
- char buffer[256]; /* For errors */\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "s|i:atol", &s, &base))\r
- return NULL;\r
-\r
- if ((base != 0 && base < 2) || base > 36) {\r
- PyErr_SetString(PyExc_ValueError, "invalid base for atol()");\r
- return NULL;\r
- }\r
-\r
- while (*s && isspace(Py_CHARMASK(*s)))\r
- s++;\r
- if (s[0] == '\0') {\r
- PyErr_SetString(PyExc_ValueError, "empty string for atol()");\r
- return NULL;\r
- }\r
- x = PyLong_FromString(s, &end, base);\r
- if (x == NULL)\r
- return NULL;\r
- if (base == 0 && (*end == 'l' || *end == 'L'))\r
- end++;\r
- while (*end && isspace(Py_CHARMASK(*end)))\r
- end++;\r
- if (*end != '\0') {\r
- PyOS_snprintf(buffer, sizeof(buffer),\r
- "invalid literal for atol(): %.200s", s);\r
- PyErr_SetString(PyExc_ValueError, buffer);\r
- Py_DECREF(x);\r
- return NULL;\r
- }\r
- return x;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(atof__doc__,\r
-"atof(s) -> float\n"\r
-"\n"\r
-"Return the floating point number represented by the string s.");\r
-\r
-static PyObject *\r
-strop_atof(PyObject *self, PyObject *args)\r
-{\r
- char *s, *end;\r
- double x;\r
- char buffer[256]; /* For errors */\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "s:atof", &s))\r
- return NULL;\r
- while (*s && isspace(Py_CHARMASK(*s)))\r
- s++;\r
- if (s[0] == '\0') {\r
- PyErr_SetString(PyExc_ValueError, "empty string for atof()");\r
- return NULL;\r
- }\r
-\r
- PyFPE_START_PROTECT("strop_atof", return 0)\r
- x = PyOS_string_to_double(s, &end, PyExc_OverflowError);\r
- PyFPE_END_PROTECT(x)\r
- if (x == -1 && PyErr_Occurred())\r
- return NULL;\r
- while (*end && isspace(Py_CHARMASK(*end)))\r
- end++;\r
- if (*end != '\0') {\r
- PyOS_snprintf(buffer, sizeof(buffer),\r
- "invalid literal for atof(): %.200s", s);\r
- PyErr_SetString(PyExc_ValueError, buffer);\r
- return NULL;\r
- }\r
- return PyFloat_FromDouble(x);\r
-}\r
-\r
-\r
-PyDoc_STRVAR(maketrans__doc__,\r
-"maketrans(frm, to) -> string\n"\r
-"\n"\r
-"Return a translation table (a string of 256 bytes long)\n"\r
-"suitable for use in string.translate. The strings frm and to\n"\r
-"must be of the same length.");\r
-\r
-static PyObject *\r
-strop_maketrans(PyObject *self, PyObject *args)\r
-{\r
- unsigned char *c, *from=NULL, *to=NULL;\r
- Py_ssize_t i, fromlen=0, tolen=0;\r
- PyObject *result;\r
-\r
- if (!PyArg_ParseTuple(args, "t#t#:maketrans", &from, &fromlen, &to, &tolen))\r
- return NULL;\r
-\r
- if (fromlen != tolen) {\r
- PyErr_SetString(PyExc_ValueError,\r
- "maketrans arguments must have same length");\r
- return NULL;\r
- }\r
-\r
- result = PyString_FromStringAndSize((char *)NULL, 256);\r
- if (result == NULL)\r
- return NULL;\r
- c = (unsigned char *) PyString_AS_STRING((PyStringObject *)result);\r
- for (i = 0; i < 256; i++)\r
- c[i]=(unsigned char)i;\r
- for (i = 0; i < fromlen; i++)\r
- c[from[i]]=to[i];\r
-\r
- return result;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(translate__doc__,\r
-"translate(s,table [,deletechars]) -> string\n"\r
-"\n"\r
-"Return a copy of the string s, where all characters occurring\n"\r
-"in the optional argument deletechars are removed, and the\n"\r
-"remaining characters have been mapped through the given\n"\r
-"translation table, which must be a string of length 256.");\r
-\r
-static PyObject *\r
-strop_translate(PyObject *self, PyObject *args)\r
-{\r
- register char *input, *table, *output;\r
- Py_ssize_t i;\r
- int c, changed = 0;\r
- PyObject *input_obj;\r
- char *table1, *output_start, *del_table=NULL;\r
- Py_ssize_t inlen, tablen, dellen = 0;\r
- PyObject *result;\r
- int trans_table[256];\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "St#|t#:translate", &input_obj,\r
- &table1, &tablen, &del_table, &dellen))\r
- return NULL;\r
- if (tablen != 256) {\r
- PyErr_SetString(PyExc_ValueError,\r
- "translation table must be 256 characters long");\r
- return NULL;\r
- }\r
-\r
- table = table1;\r
- inlen = PyString_GET_SIZE(input_obj);\r
- result = PyString_FromStringAndSize((char *)NULL, inlen);\r
- if (result == NULL)\r
- return NULL;\r
- output_start = output = PyString_AsString(result);\r
- input = PyString_AsString(input_obj);\r
-\r
- if (dellen == 0) {\r
- /* If no deletions are required, use faster code */\r
- for (i = inlen; --i >= 0; ) {\r
- c = Py_CHARMASK(*input++);\r
- if (Py_CHARMASK((*output++ = table[c])) != c)\r
- changed = 1;\r
- }\r
- if (changed)\r
- return result;\r
- Py_DECREF(result);\r
- Py_INCREF(input_obj);\r
- return input_obj;\r
- }\r
-\r
- for (i = 0; i < 256; i++)\r
- trans_table[i] = Py_CHARMASK(table[i]);\r
-\r
- for (i = 0; i < dellen; i++)\r
- trans_table[(int) Py_CHARMASK(del_table[i])] = -1;\r
-\r
- for (i = inlen; --i >= 0; ) {\r
- c = Py_CHARMASK(*input++);\r
- if (trans_table[c] != -1)\r
- if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)\r
- continue;\r
- changed = 1;\r
- }\r
- if (!changed) {\r
- Py_DECREF(result);\r
- Py_INCREF(input_obj);\r
- return input_obj;\r
- }\r
- /* Fix the size of the resulting string */\r
- if (inlen > 0)\r
- _PyString_Resize(&result, output - output_start);\r
- return result;\r
-}\r
-\r
-\r
-/* What follows is used for implementing replace(). Perry Stoll. */\r
-\r
-/*\r
- mymemfind\r
-\r
- strstr replacement for arbitrary blocks of memory.\r
-\r
- Locates the first occurrence in the memory pointed to by MEM of the\r
- contents of memory pointed to by PAT. Returns the index into MEM if\r
- found, or -1 if not found. If len of PAT is greater than length of\r
- MEM, the function returns -1.\r
-*/\r
-static Py_ssize_t\r
-mymemfind(const char *mem, Py_ssize_t len, const char *pat, Py_ssize_t pat_len)\r
-{\r
- register Py_ssize_t ii;\r
-\r
- /* pattern can not occur in the last pat_len-1 chars */\r
- len -= pat_len;\r
-\r
- for (ii = 0; ii <= len; ii++) {\r
- if (mem[ii] == pat[0] &&\r
- (pat_len == 1 ||\r
- memcmp(&mem[ii+1], &pat[1], pat_len-1) == 0)) {\r
- return ii;\r
- }\r
- }\r
- return -1;\r
-}\r
-\r
-/*\r
- mymemcnt\r
-\r
- Return the number of distinct times PAT is found in MEM.\r
- meaning mem=1111 and pat==11 returns 2.\r
- mem=11111 and pat==11 also return 2.\r
- */\r
-static Py_ssize_t\r
-mymemcnt(const char *mem, Py_ssize_t len, const char *pat, Py_ssize_t pat_len)\r
-{\r
- register Py_ssize_t offset = 0;\r
- Py_ssize_t nfound = 0;\r
-\r
- while (len >= 0) {\r
- offset = mymemfind(mem, len, pat, pat_len);\r
- if (offset == -1)\r
- break;\r
- mem += offset + pat_len;\r
- len -= offset + pat_len;\r
- nfound++;\r
- }\r
- return nfound;\r
-}\r
-\r
-/*\r
- mymemreplace\r
-\r
- Return a string in which all occurrences of PAT in memory STR are\r
- replaced with SUB.\r
-\r
- If length of PAT is less than length of STR or there are no occurrences\r
- of PAT in STR, then the original string is returned. Otherwise, a new\r
- string is allocated here and returned.\r
-\r
- on return, out_len is:\r
- the length of output string, or\r
- -1 if the input string is returned, or\r
- unchanged if an error occurs (no memory).\r
-\r
- return value is:\r
- the new string allocated locally, or\r
- NULL if an error occurred.\r
-*/\r
-static char *\r
-mymemreplace(const char *str, Py_ssize_t len, /* input string */\r
- const char *pat, Py_ssize_t pat_len, /* pattern string to find */\r
- const char *sub, Py_ssize_t sub_len, /* substitution string */\r
- Py_ssize_t count, /* number of replacements */\r
- Py_ssize_t *out_len)\r
-{\r
- char *out_s;\r
- char *new_s;\r
- Py_ssize_t nfound, offset, new_len;\r
-\r
- if (len == 0 || pat_len > len)\r
- goto return_same;\r
-\r
- /* find length of output string */\r
- nfound = mymemcnt(str, len, pat, pat_len);\r
- if (count < 0)\r
- count = PY_SSIZE_T_MAX;\r
- else if (nfound > count)\r
- nfound = count;\r
- if (nfound == 0)\r
- goto return_same;\r
-\r
- new_len = len + nfound*(sub_len - pat_len);\r
- if (new_len == 0) {\r
- /* Have to allocate something for the caller to free(). */\r
- out_s = (char *)PyMem_MALLOC(1);\r
- if (out_s == NULL)\r
- return NULL;\r
- out_s[0] = '\0';\r
- }\r
- else {\r
- assert(new_len > 0);\r
- new_s = (char *)PyMem_MALLOC(new_len);\r
- if (new_s == NULL)\r
- return NULL;\r
- out_s = new_s;\r
-\r
- for (; count > 0 && len > 0; --count) {\r
- /* find index of next instance of pattern */\r
- offset = mymemfind(str, len, pat, pat_len);\r
- if (offset == -1)\r
- break;\r
-\r
- /* copy non matching part of input string */\r
- memcpy(new_s, str, offset);\r
- str += offset + pat_len;\r
- len -= offset + pat_len;\r
-\r
- /* copy substitute into the output string */\r
- new_s += offset;\r
- memcpy(new_s, sub, sub_len);\r
- new_s += sub_len;\r
- }\r
- /* copy any remaining values into output string */\r
- if (len > 0)\r
- memcpy(new_s, str, len);\r
- }\r
- *out_len = new_len;\r
- return out_s;\r
-\r
- return_same:\r
- *out_len = -1;\r
- return (char *)str; /* cast away const */\r
-}\r
-\r
-\r
-PyDoc_STRVAR(replace__doc__,\r
-"replace (str, old, new[, maxsplit]) -> string\n"\r
-"\n"\r
-"Return a copy of string str with all occurrences of substring\n"\r
-"old replaced by new. If the optional argument maxsplit is\n"\r
-"given, only the first maxsplit occurrences are replaced.");\r
-\r
-static PyObject *\r
-strop_replace(PyObject *self, PyObject *args)\r
-{\r
- char *str, *pat,*sub,*new_s;\r
- Py_ssize_t len,pat_len,sub_len,out_len;\r
- Py_ssize_t count = -1;\r
- PyObject *newstr;\r
-\r
- WARN;\r
- if (!PyArg_ParseTuple(args, "t#t#t#|n:replace",\r
- &str, &len, &pat, &pat_len, &sub, &sub_len,\r
- &count))\r
- return NULL;\r
- if (pat_len <= 0) {\r
- PyErr_SetString(PyExc_ValueError, "empty pattern string");\r
- return NULL;\r
- }\r
- /* CAUTION: strop treats a replace count of 0 as infinity, unlke\r
- * current (2.1) string.py and string methods. Preserve this for\r
- * ... well, hard to say for what <wink>.\r
- */\r
- if (count == 0)\r
- count = -1;\r
- new_s = mymemreplace(str,len,pat,pat_len,sub,sub_len,count,&out_len);\r
- if (new_s == NULL) {\r
- PyErr_NoMemory();\r
- return NULL;\r
- }\r
- if (out_len == -1) {\r
- /* we're returning another reference to the input string */\r
- newstr = PyTuple_GetItem(args, 0);\r
- Py_XINCREF(newstr);\r
- }\r
- else {\r
- newstr = PyString_FromStringAndSize(new_s, out_len);\r
- PyMem_FREE(new_s);\r
- }\r
- return newstr;\r
-}\r
-\r
-\r
-/* List of functions defined in the module */\r
-\r
-static PyMethodDef\r
-strop_methods[] = {\r
- {"atof", strop_atof, METH_VARARGS, atof__doc__},\r
- {"atoi", strop_atoi, METH_VARARGS, atoi__doc__},\r
- {"atol", strop_atol, METH_VARARGS, atol__doc__},\r
- {"capitalize", strop_capitalize, METH_O, capitalize__doc__},\r
- {"count", strop_count, METH_VARARGS, count__doc__},\r
- {"expandtabs", strop_expandtabs, METH_VARARGS, expandtabs__doc__},\r
- {"find", strop_find, METH_VARARGS, find__doc__},\r
- {"join", strop_joinfields, METH_VARARGS, joinfields__doc__},\r
- {"joinfields", strop_joinfields, METH_VARARGS, joinfields__doc__},\r
- {"lstrip", strop_lstrip, METH_O, lstrip__doc__},\r
- {"lower", strop_lower, METH_O, lower__doc__},\r
- {"maketrans", strop_maketrans, METH_VARARGS, maketrans__doc__},\r
- {"replace", strop_replace, METH_VARARGS, replace__doc__},\r
- {"rfind", strop_rfind, METH_VARARGS, rfind__doc__},\r
- {"rstrip", strop_rstrip, METH_O, rstrip__doc__},\r
- {"split", strop_splitfields, METH_VARARGS, splitfields__doc__},\r
- {"splitfields", strop_splitfields, METH_VARARGS, splitfields__doc__},\r
- {"strip", strop_strip, METH_O, strip__doc__},\r
- {"swapcase", strop_swapcase, METH_O, swapcase__doc__},\r
- {"translate", strop_translate, METH_VARARGS, translate__doc__},\r
- {"upper", strop_upper, METH_O, upper__doc__},\r
- {NULL, NULL} /* sentinel */\r
-};\r
-\r
-\r
-PyMODINIT_FUNC\r
-initstrop(void)\r
-{\r
- PyObject *m, *s;\r
- char buf[256];\r
- int c, n;\r
- m = Py_InitModule4("strop", strop_methods, strop_module__doc__,\r
- (PyObject*)NULL, PYTHON_API_VERSION);\r
- if (m == NULL)\r
- return;\r
-\r
- /* Create 'whitespace' object */\r
- n = 0;\r
- for (c = 0; c < 256; c++) {\r
- if (isspace(c))\r
- buf[n++] = c;\r
- }\r
- s = PyString_FromStringAndSize(buf, n);\r
- if (s)\r
- PyModule_AddObject(m, "whitespace", s);\r
-\r
- /* Create 'lowercase' object */\r
- n = 0;\r
- for (c = 0; c < 256; c++) {\r
- if (islower(c))\r
- buf[n++] = c;\r
- }\r
- s = PyString_FromStringAndSize(buf, n);\r
- if (s)\r
- PyModule_AddObject(m, "lowercase", s);\r
-\r
- /* Create 'uppercase' object */\r
- n = 0;\r
- for (c = 0; c < 256; c++) {\r
- if (isupper(c))\r
- buf[n++] = c;\r
- }\r
- s = PyString_FromStringAndSize(buf, n);\r
- if (s)\r
- PyModule_AddObject(m, "uppercase", s);\r
-}\r