From c8bc5377ac59c6e6af5c0e925fa0af7d9df7ebc0 Mon Sep 17 00:00:00 2001 From: Victor Stinner Date: Mon, 4 Nov 2013 11:08:10 +0100 Subject: [PATCH] Issue #16286: write a new subfunction bytes_compare_eq() * cleanup bytes_richcompare() * PyUnicode_RichCompare(): replace a test with a XOR --- Objects/bytesobject.c | 84 +++++++++++++++++++++++------------------ Objects/unicodeobject.c | 8 ++-- 2 files changed, 50 insertions(+), 42 deletions(-) diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 529c634708c..9aa3ee286b1 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -802,6 +802,23 @@ bytes_item(PyBytesObject *a, Py_ssize_t i) return PyLong_FromLong((unsigned char)a->ob_sval[i]); } +Py_LOCAL(int) +bytes_compare_eq(PyBytesObject *a, PyBytesObject *b) +{ + int cmp; + Py_ssize_t len; + + len = Py_SIZE(a); + if (Py_SIZE(b) != len) + return 0; + + if (a->ob_sval[0] != b->ob_sval[0]) + return 0; + + cmp = memcmp(a->ob_sval, b->ob_sval, len); + return (cmp == 0); +} + static PyObject* bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) { @@ -822,53 +839,46 @@ bytes_richcompare(PyBytesObject *a, PyBytesObject *b, int op) return NULL; } result = Py_NotImplemented; - goto out; } - if (a == b) { + else if (a == b) { switch (op) { case Py_EQ:case Py_LE:case Py_GE: result = Py_True; - goto out; + break; case Py_NE:case Py_LT:case Py_GT: result = Py_False; - goto out; + break; } } - if (op == Py_EQ) { - /* Supporting Py_NE here as well does not save - much time, since Py_NE is rarely used. */ - if (Py_SIZE(a) == Py_SIZE(b) - && (a->ob_sval[0] == b->ob_sval[0] - && memcmp(a->ob_sval, b->ob_sval, Py_SIZE(a)) == 0)) { - result = Py_True; - } else { - result = Py_False; + else if (op == Py_EQ || op == Py_NE) { + int eq = bytes_compare_eq(a, b); + eq ^= (op == Py_NE); + result = eq ? Py_True : Py_False; + } + else { + len_a = Py_SIZE(a); len_b = Py_SIZE(b); + 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); } - goto out; + 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_GT: c = c > 0; break; + case Py_GE: c = c >= 0; break; + default: + assert(op != Py_EQ && op != Py_NE); + Py_RETURN_NOTIMPLEMENTED; + } + result = c ? Py_True : Py_False; } - len_a = Py_SIZE(a); len_b = Py_SIZE(b); - 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: assert(0); break; /* unreachable */ - 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; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 01e5355449f..17ae481aec9 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -10526,7 +10526,7 @@ unicode_compare(PyObject *str1, PyObject *str2) #undef COMPARE } -static int +Py_LOCAL(int) unicode_compare_eq(PyObject *str1, PyObject *str2) { int kind; @@ -10630,10 +10630,8 @@ PyUnicode_RichCompare(PyObject *left, PyObject *right, int op) if (op == Py_EQ || op == Py_NE) { result = unicode_compare_eq(left, right); - if (op == Py_EQ) - v = TEST_COND(result); - else - v = TEST_COND(!result); + result ^= (op == Py_NE); + v = TEST_COND(result); } else { result = unicode_compare(left, right);