Index: Objects/stringobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/stringobject.c,v retrieving revision 2.116 diff -u -r2.116 stringobject.c --- Objects/stringobject.c 2001/05/15 11:58:06 2.116 +++ Objects/stringobject.c 2001/05/21 15:29:50 @@ -630,20 +630,81 @@ return v; } -static int -string_compare(PyStringObject *a, PyStringObject *b) +static PyObject* +string_richcompare(PyStringObject *a, PyStringObject *b, int op) { - int len_a = a->ob_size, len_b = b->ob_size; - int min_len = (len_a < len_b) ? len_a : len_b; - int cmp; - if (min_len > 0) { - cmp = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); - if (cmp == 0) - cmp = memcmp(a->ob_sval, b->ob_sval, min_len); - if (cmp != 0) - return cmp; + int c; + int len_a, len_b; + int min_len; + PyObject *result; + + /* One of the objects is a string object. Make sure the + other one is one, too. */ + if (a->ob_type != b->ob_type) { + result = Py_NotImplemented; + goto out; + } + if (a == b) { + switch (op) { + case Py_EQ:case Py_LE:case Py_GE: + result = Py_True; + goto out; + case Py_NE:case Py_LT:case Py_GT: + result = Py_False; + goto out; + } + } + if (op == Py_EQ) { + /* Supporting Py_NE here as well does not save + much time, since Py_NE is rarely used. */ + if (a->ob_size == b->ob_size + && (a->ob_sval[0] == b->ob_sval[0] + && memcmp(a->ob_sval, b->ob_sval, + a->ob_size) == 0)) { + result = Py_True; + } else { + result = Py_False; + } + goto out; } - return (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; + len_a = a->ob_size; len_b = b->ob_size; + min_len = (len_a < len_b) ? len_a : len_b; + if (min_len > 0) { + c = Py_CHARMASK(*a->ob_sval) - Py_CHARMASK(*b->ob_sval); + if (c==0) + c = memcmp(a->ob_sval, b->ob_sval, min_len); + }else + c = 0; + if (c == 0) + c = (len_a < len_b) ? -1 : (len_a > len_b) ? 1 : 0; + switch (op) { + case Py_LT: c = c < 0; break; + case Py_LE: c = c <= 0; break; + case Py_EQ: c = c == 0; break; /* not needed here */ + case Py_NE: c = c != 0; break; + case Py_GT: c = c > 0; break; + case Py_GE: c = c >= 0; break; + default: + result = Py_NotImplemented; + goto out; + } + result = c ? Py_True : Py_False; + out: + Py_INCREF(result); + return result; +} + +int +_PyString_Eq(PyObject *o1, PyObject *o2) +{ + PyStringObject *a, *b; + a = (PyStringObject*)o1; + b = (PyStringObject*)o2; + if (a->ob_size != b->ob_size) + return 0; + if (*a->ob_sval != *b->ob_sval) + return 0; + return memcmp(a->ob_sval, b->ob_sval, a->ob_size) == 0; } static long @@ -2466,7 +2527,7 @@ (printfunc)string_print, /*tp_print*/ (getattrfunc)string_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ - (cmpfunc)string_compare, /*tp_compare*/ + 0, /*tp_compare*/ (reprfunc)string_repr, /*tp_repr*/ 0, /*tp_as_number*/ &string_as_sequence, /*tp_as_sequence*/ @@ -2479,6 +2540,12 @@ &string_as_buffer, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ 0, /*tp_doc*/ + 0, /*tp_traverse*/ + 0, /*tp_clear*/ + (richcmpfunc)string_richcompare, /*tp_richcompare*/ + 0, /*tp_weaklistoffset*/ + 0, /*tp_iter*/ + 0, /*tp_iternext*/ }; void Index: Objects/dictobject.c =================================================================== RCS file: /cvsroot/python/python/dist/src/Objects/dictobject.c,v retrieving revision 2.90 diff -u -r2.90 dictobject.c --- Objects/dictobject.c 2001/05/19 07:04:38 2.90 +++ Objects/dictobject.c 2001/05/21 15:29:51 @@ -265,7 +265,7 @@ * this assumption allows testing for errors during PyObject_Compare() to * be dropped; string-string comparisons never raise exceptions. This also * means we don't need to go through PyObject_Compare(); we can always use - * the tp_compare slot of the string type object directly. + * _PyString_Eq directly. * * This really only becomes meaningful if proper error handling in lookdict() * is too expensive. @@ -279,7 +279,6 @@ register unsigned int mask = mp->ma_size-1; dictentry *ep0 = mp->ma_table; register dictentry *ep; - cmpfunc compare = PyString_Type.tp_compare; /* make sure this function doesn't have to handle non-string keys */ if (!PyString_Check(key)) { @@ -299,7 +298,7 @@ freeslot = ep; else { if (ep->me_hash == hash - && compare(ep->me_key, key) == 0) { + && _PyString_Eq(ep->me_key, key)) { return ep; } freeslot = NULL; @@ -318,7 +317,7 @@ if (ep->me_key == key || (ep->me_hash == hash && ep->me_key != dummy - && compare(ep->me_key, key) == 0)) + && _PyString_Eq(ep->me_key, key))) return ep; else if (ep->me_key == dummy && freeslot == NULL) freeslot = ep; Index: Include/stringobject.h =================================================================== RCS file: /cvsroot/python/python/dist/src/Include/stringobject.h,v retrieving revision 2.26 diff -u -r2.26 stringobject.h --- Include/stringobject.h 2001/05/15 11:58:05 2.26 +++ Include/stringobject.h 2001/05/21 15:29:51 @@ -58,6 +58,7 @@ extern DL_IMPORT(void) PyString_Concat(PyObject **, PyObject *); extern DL_IMPORT(void) PyString_ConcatAndDel(PyObject **, PyObject *); extern DL_IMPORT(int) _PyString_Resize(PyObject **, int); +extern DL_IMPORT(int) _PyString_Eq(PyObject *, PyObject*); extern DL_IMPORT(PyObject *) PyString_Format(PyObject *, PyObject *); extern DL_IMPORT(PyObject *) _PyString_FormatLong(PyObject*, int, int, int, char**, int*);