📄 stringobject.c
字号:
const static char split__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.split([sep [,maxsplit]]) -> list of strings\n\
\n\
Return a list of the words in the string S, using sep as the\n\
delimiter string. If maxsplit is given, at most maxsplit\n\
splits are done. If sep is not specified or is None, any\n\
whitespace string is a separator.";
#endif
static PyObject *
string_split(PyStringObject *self, PyObject *args)
{
int len = PyString_GET_SIZE(self), n, i, j, err;
int maxsplit = -1;
const char *s = PyString_AS_STRING(self), *sub;
PyObject *list, *item, *subobj = Py_None;
if (!PyArg_ParseTuple(args, "|Oi:split", &subobj, &maxsplit))
return NULL;
if (maxsplit < 0)
maxsplit = INT_MAX;
if (subobj == Py_None)
return split_whitespace(s, len, maxsplit);
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
n = PyString_GET_SIZE(subobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(subobj))
return PyUnicode_Split((PyObject *)self, subobj, maxsplit);
#endif
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
return NULL;
if (n == 0) {
PyErr_SetString(PyExc_ValueError, "empty separator");
return NULL;
}
list = PyList_New(0);
if (list == NULL)
return NULL;
i = j = 0;
while (i+n <= len) {
if (s[i] == sub[0] && memcmp(s+i, sub, n) == 0) {
if (maxsplit-- <= 0)
break;
item = PyString_FromStringAndSize(s+j, (int)(i-j));
if (item == NULL)
goto fail;
err = PyList_Append(list, item);
Py_DECREF(item);
if (err < 0)
goto fail;
i = j = i + n;
}
else
i++;
}
item = PyString_FromStringAndSize(s+j, (int)(len-j));
if (item == NULL)
goto fail;
err = PyList_Append(list, item);
Py_DECREF(item);
if (err < 0)
goto fail;
return list;
fail:
Py_DECREF(list);
return NULL;
}
const static char join__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.join(sequence) -> string\n\
\n\
Return a string which is the concatenation of the strings in the\n\
sequence. The separator between elements is S.";
#endif
static PyObject *
string_join(PyStringObject *self, PyObject *orig)
{
char *sep = PyString_AS_STRING(self);
const int seplen = PyString_GET_SIZE(self);
PyObject *res = NULL;
char *p;
int seqlen = 0;
size_t sz = 0;
int i;
PyObject *seq, *item;
seq = PySequence_Fast(orig, "");
if (seq == NULL) {
if (PyErr_ExceptionMatches(PyExc_TypeError))
PyErr_Format(PyExc_TypeError,
"sequence expected, %.80s found",
orig->ob_type->tp_name);
return NULL;
}
seqlen = PySequence_Size(seq);
if (seqlen == 0) {
Py_DECREF(seq);
return PyString_FromString("");
}
if (seqlen == 1) {
item = PySequence_Fast_GET_ITEM(seq, 0);
if (!PyString_Check(item) && !PyUnicode_Check(item)) {
PyErr_Format(PyExc_TypeError,
"sequence item 0: expected string,"
" %.80s found",
item->ob_type->tp_name);
Py_DECREF(seq);
return NULL;
}
Py_INCREF(item);
Py_DECREF(seq);
return item;
}
/* There are at least two things to join. Do a pre-pass to figure out
* the total amount of space we'll need (sz), see whether any argument
* is absurd, and defer to the Unicode join if appropriate.
*/
for (i = 0; i < seqlen; i++) {
const size_t old_sz = sz;
item = PySequence_Fast_GET_ITEM(seq, i);
if (!PyString_Check(item)){
#ifdef Py_USING_UNICODE
if (PyUnicode_Check(item)) {
/* Defer to Unicode join.
* CAUTION: There's no gurantee that the
* original sequence can be iterated over
* again, so we must pass seq here.
*/
PyObject *result;
result = PyUnicode_Join((PyObject *)self, seq);
Py_DECREF(seq);
return result;
}
#endif
PyErr_Format(PyExc_TypeError,
"sequence item %i: expected string,"
" %.80s found",
i, item->ob_type->tp_name);
Py_DECREF(seq);
return NULL;
}
sz += PyString_GET_SIZE(item);
if (i != 0)
sz += seplen;
if (sz < old_sz || sz > INT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"join() is too long for a Python string");
Py_DECREF(seq);
return NULL;
}
}
/* Allocate result space. */
res = PyString_FromStringAndSize((char*)NULL, (int)sz);
if (res == NULL) {
Py_DECREF(seq);
return NULL;
}
/* Catenate everything. */
p = PyString_AS_STRING(res);
for (i = 0; i < seqlen; ++i) {
size_t n;
item = PySequence_Fast_GET_ITEM(seq, i);
n = PyString_GET_SIZE(item);
memcpy(p, PyString_AS_STRING(item), n);
p += n;
if (i < seqlen - 1) {
memcpy(p, sep, seplen);
p += seplen;
}
}
Py_DECREF(seq);
return res;
}
DL_EXPORT(PyObject *)
_PyString_Join(PyObject *sep, PyObject *x)
{
assert(sep != NULL && PyString_Check(sep));
assert(x != NULL);
return string_join((PyStringObject *)sep, x);
}
static long
string_find_internal(PyStringObject *self, PyObject *args, int dir)
{
const char *s = PyString_AS_STRING(self), *sub;
int len = PyString_GET_SIZE(self);
int n, i = 0, last = INT_MAX;
PyObject *subobj;
if (!PyArg_ParseTuple(args, "O|O&O&:find/rfind/index/rindex",
&subobj, _PyEval_SliceIndex, &i, _PyEval_SliceIndex, &last))
return -2;
if (PyString_Check(subobj)) {
sub = PyString_AS_STRING(subobj);
n = PyString_GET_SIZE(subobj);
}
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(subobj))
return PyUnicode_Find((PyObject *)self, subobj, i, last, dir);
#endif
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
return -2;
if (last > len)
last = len;
if (last < 0)
last += len;
if (last < 0)
last = 0;
if (i < 0)
i += len;
if (i < 0)
i = 0;
if (dir > 0) {
if (n == 0 && i <= last)
return (long)i;
last -= n;
for (; i <= last; ++i)
if (s[i] == sub[0] && memcmp(&s[i], sub, n) == 0)
return (long)i;
}
else {
int j;
if (n == 0 && i <= last)
return (long)last;
for (j = last-n; j >= i; --j)
if (s[j] == sub[0] && memcmp(&s[j], sub, n) == 0)
return (long)j;
}
return -1;
}
const static char find__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.find(sub [,start [,end]]) -> int\n\
\n\
Return the lowest index in S where substring sub is found,\n\
such that sub is contained within s[start,end]. Optional\n\
arguments start and end are interpreted as in slice notation.\n\
\n\
Return -1 on failure.";
#endif
static PyObject *
string_find(PyStringObject *self, PyObject *args)
{
long result = string_find_internal(self, args, +1);
if (result == -2)
return NULL;
return PyInt_FromLong(result);
}
const static char index__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.index(sub [,start [,end]]) -> int\n\
\n\
Like S.find() but raise ValueError when the substring is not found.";
#endif
static PyObject *
string_index(PyStringObject *self, PyObject *args)
{
long result = string_find_internal(self, args, +1);
if (result == -2)
return NULL;
if (result == -1) {
PyErr_SetString(PyExc_ValueError,
"substring not found in string.index");
return NULL;
}
return PyInt_FromLong(result);
}
const static char rfind__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.rfind(sub [,start [,end]]) -> int\n\
\n\
Return the highest index in S where substring sub is found,\n\
such that sub is contained within s[start,end]. Optional\n\
arguments start and end are interpreted as in slice notation.\n\
\n\
Return -1 on failure.";
#endif
static PyObject *
string_rfind(PyStringObject *self, PyObject *args)
{
long result = string_find_internal(self, args, -1);
if (result == -2)
return NULL;
return PyInt_FromLong(result);
}
const static char rindex__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.rindex(sub [,start [,end]]) -> int\n\
\n\
Like S.rfind() but raise ValueError when the substring is not found.";
#endif
static PyObject *
string_rindex(PyStringObject *self, PyObject *args)
{
long result = string_find_internal(self, args, -1);
if (result == -2)
return NULL;
if (result == -1) {
PyErr_SetString(PyExc_ValueError,
"substring not found in string.rindex");
return NULL;
}
return PyInt_FromLong(result);
}
static PyObject *
do_xstrip(PyStringObject *self, int striptype, PyObject *sepobj)
{
char *s = PyString_AS_STRING(self);
int len = PyString_GET_SIZE(self);
char *sep = PyString_AS_STRING(sepobj);
int seplen = PyString_GET_SIZE(sepobj);
int i, j;
i = 0;
if (striptype != RIGHTSTRIP) {
while (i < len && memchr(sep, Py_CHARMASK(s[i]), seplen)) {
i++;
}
}
j = len;
if (striptype != LEFTSTRIP) {
do {
j--;
} while (j >= i && memchr(sep, Py_CHARMASK(s[j]), seplen));
j++;
}
if (i == 0 && j == len && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*)self;
}
else
return PyString_FromStringAndSize(s+i, j-i);
}
static PyObject *
do_strip(PyStringObject *self, int striptype)
{
char *s = PyString_AS_STRING(self);
int len = PyString_GET_SIZE(self), i, j;
i = 0;
if (striptype != RIGHTSTRIP) {
while (i < len && isspace(Py_CHARMASK(s[i]))) {
i++;
}
}
j = len;
if (striptype != LEFTSTRIP) {
do {
j--;
} while (j >= i && isspace(Py_CHARMASK(s[j])));
j++;
}
if (i == 0 && j == len && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*)self;
}
else
return PyString_FromStringAndSize(s+i, j-i);
}
static PyObject *
do_argstrip(PyStringObject *self, int striptype, PyObject *args)
{
PyObject *sep = NULL;
if (!PyArg_ParseTuple(args, (char *)stripformat[striptype], &sep))
return NULL;
if (sep != NULL && sep != Py_None) {
if (PyString_Check(sep))
return do_xstrip(self, striptype, sep);
#ifdef Py_USING_UNICODE
else if (PyUnicode_Check(sep)) {
PyObject *uniself = PyUnicode_FromObject((PyObject *)self);
PyObject *res;
if (uniself==NULL)
return NULL;
res = _PyUnicode_XStrip((PyUnicodeObject *)uniself,
striptype, sep);
Py_DECREF(uniself);
return res;
}
#endif
else {
PyErr_Format(PyExc_TypeError,
#ifdef Py_USING_UNICODE
"%s arg must be None, str or unicode",
#else
"%s arg must be None or str",
#endif
STRIPNAME(striptype));
return NULL;
}
/* return do_xstrip(self, striptype, sep); // Unreachable code */
}
return do_strip(self, striptype);
}
const static char strip__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.strip([sep]) -> string or unicode\n\
\n\
Return a copy of the string S with leading and trailing\n\
whitespace removed.\n\
If sep is given and not None, remove characters in sep instead.\n\
If sep is unicode, S will be converted to unicode before stripping";
#endif
static PyObject *
string_strip(PyStringObject *self, PyObject *args)
{
if (PyTuple_GET_SIZE(args) == 0)
return do_strip(self, BOTHSTRIP); /* Common case */
else
return do_argstrip(self, BOTHSTRIP, args);
}
const static char lstrip__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.lstrip([sep]) -> string or unicode\n\
\n\
Return a copy of the string S with leading whitespace removed.\n\
If sep is given and not None, remove characters in sep instead.\n\
If sep is unicode, S will be converted to unicode before stripping";
#endif
static PyObject *
string_lstrip(PyStringObject *self, PyObject *args)
{
if (PyTuple_GET_SIZE(args) == 0)
return do_strip(self, LEFTSTRIP); /* Common case */
else
return do_argstrip(self, LEFTSTRIP, args);
}
const static char rstrip__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.rstrip([sep]) -> string or unicode\n\
\n\
Return a copy of the string S with trailing whitespace removed.\n\
If sep is given and not None, remove characters in sep instead.\n\
If sep is unicode, S will be converted to unicode before stripping";
#endif
static PyObject *
string_rstrip(PyStringObject *self, PyObject *args)
{
if (PyTuple_GET_SIZE(args) == 0)
return do_strip(self, RIGHTSTRIP); /* Common case */
else
return do_argstrip(self, RIGHTSTRIP, args);
}
const static char lower__doc__[] =
#ifdef SYMBIAN
"";
#else
"S.lower() -> string\n\
\n\
Return a copy of the string S converted to lowercase.";
#endif
static PyObject *
string_lower(PyStringObject *self)
{
char *s = PyString_AS_STRING(self), *s_new;
int i, n = PyString_GET_SIZE(self);
PyObject *new;
new = PyString_FromStringAndSize(NULL, n);
if (new == NULL)
return NULL;
s_new = PyString_AsString(new);
for (i = 0; i < n; i++) {
int c = Py_CHARMASK(*s++);
if (isupper(c)) {
*s_new = tolower(c);
} else
*s_new = c;
s_new++;
}
return new;
}
const static char upper__doc__[] =
#ifdef SYMBIAN
"";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -