summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorBarry Warsaw <barry@python.org>2002-08-06 16:58:21 (GMT)
committerBarry Warsaw <barry@python.org>2002-08-06 16:58:21 (GMT)
commit817918cc3c10d0ed6b14e0e3f2bc0c5227c508cd (patch)
tree5dcdd3861db33fde0a76f275c09d40cba9c6fa22 /Objects
parentb57089cdf8b63b38ca736785c9fcc38a9fce89da (diff)
downloadcpython-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.c25
-rw-r--r--Objects/unicodeobject.c40
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;
+ }
}
}