diff options
author | Barry Warsaw <barry@python.org> | 2002-08-06 16:58:21 (GMT) |
---|---|---|
committer | Barry Warsaw <barry@python.org> | 2002-08-06 16:58:21 (GMT) |
commit | 817918cc3c10d0ed6b14e0e3f2bc0c5227c508cd (patch) | |
tree | 5dcdd3861db33fde0a76f275c09d40cba9c6fa22 /Objects | |
parent | b57089cdf8b63b38ca736785c9fcc38a9fce89da (diff) | |
download | cpython-817918cc3c10d0ed6b14e0e3f2bc0c5227c508cd.zip cpython-817918cc3c10d0ed6b14e0e3f2bc0c5227c508cd.tar.gz cpython-817918cc3c10d0ed6b14e0e3f2bc0c5227c508cd.tar.bz2 |
Committing patch #591250 which provides "str1 in str2" when str1 is a
string of longer than 1 character.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/stringobject.c | 25 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 40 |
2 files changed, 39 insertions, 26 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c index 3c1b303..1d5277c 100644 --- a/Objects/stringobject.c +++ b/Objects/stringobject.c @@ -803,24 +803,31 @@ string_slice(register PyStringObject *a, register int i, register int j) static int string_contains(PyObject *a, PyObject *el) { - register char *s, *end; - register char c; + const char *lhs, *rhs, *end; + int size; #ifdef Py_USING_UNICODE if (PyUnicode_Check(el)) return PyUnicode_Contains(a, el); #endif - if (!PyString_Check(el) || PyString_Size(el) != 1) { + if (!PyString_Check(el)) { PyErr_SetString(PyExc_TypeError, - "'in <string>' requires character as left operand"); + "'in <string>' requires string as left operand"); return -1; } - c = PyString_AsString(el)[0]; - s = PyString_AsString(a); - end = s + PyString_Size(a); - while (s < end) { - if (c == *s++) + size = PyString_Size(el); + rhs = PyString_AS_STRING(el); + lhs = PyString_AS_STRING(a); + + /* optimize for a single character */ + if (size == 1) + return memchr(lhs, *rhs, PyString_Size(a)) != NULL; + + end = lhs + (PyString_Size(a) - size); + while (lhs <= end) { + if (memcmp(lhs++, rhs, size) == 0) return 1; } + return 0; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 6ca709b..a577bfd 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -3732,15 +3732,14 @@ int PyUnicode_Contains(PyObject *container, PyObject *element) { PyUnicodeObject *u = NULL, *v = NULL; - int result; - register const Py_UNICODE *p, *e; - register Py_UNICODE ch; + int result, size; + register const Py_UNICODE *lhs, *end, *rhs; /* Coerce the two arguments */ v = (PyUnicodeObject *)PyUnicode_FromObject(element); if (v == NULL) { PyErr_SetString(PyExc_TypeError, - "'in <string>' requires character as left operand"); + "'in <string>' requires string as left operand"); goto onError; } u = (PyUnicodeObject *)PyUnicode_FromObject(container); @@ -3749,20 +3748,27 @@ int PyUnicode_Contains(PyObject *container, goto onError; } - /* Check v in u */ - if (PyUnicode_GET_SIZE(v) != 1) { - PyErr_SetString(PyExc_TypeError, - "'in <string>' requires character as left operand"); - goto onError; - } - ch = *PyUnicode_AS_UNICODE(v); - p = PyUnicode_AS_UNICODE(u); - e = p + PyUnicode_GET_SIZE(u); + size = PyUnicode_GET_SIZE(v); + rhs = PyUnicode_AS_UNICODE(v); + lhs = PyUnicode_AS_UNICODE(u); + result = 0; - while (p < e) { - if (*p++ == ch) { - result = 1; - break; + if (size == 1) { + end = lhs + PyUnicode_GET_SIZE(u); + while (lhs < end) { + if (*lhs++ == *rhs) { + result = 1; + break; + } + } + } + else { + end = lhs + (PyUnicode_GET_SIZE(u) - size); + while (lhs <= end) { + if (memcmp(lhs++, rhs, size) == 0) { + result = 1; + break; + } } } |