env.use_utility_code(pyunicode_equals_utility_code)
self.special_bool_cmp_function = "__Pyx_PyUnicode_Equals"
return True
+ elif type1 is Builtin.bytes_type or type2 is Builtin.bytes_type:
+ env.use_utility_code(pybytes_equals_utility_code)
+ self.special_bool_cmp_function = "__Pyx_PyBytes_Equals"
+ return True
+ elif type1 is Builtin.str_type or type2 is Builtin.str_type:
+ env.use_utility_code(pystr_equals_utility_code)
+ self.special_bool_cmp_function = "__Pyx_PyString_Equals"
+ return True
return False
def generate_operation_code(self, code, result_code,
return -1;
return (equals == Py_EQ) ? (result == 0) : (result != 0);
}
- } else if ((s1 == Py_None) & (s2 == Py_None)) {
- return (equals == Py_EQ);
} else if ((s1 == Py_None) & PyUnicode_CheckExact(s2)) {
return (equals == Py_NE);
} else if ((s2 == Py_None) & PyUnicode_CheckExact(s1)) {
}
""")
+pybytes_equals_utility_code = UtilityCode(
+proto="""
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
+""",
+impl="""
+static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
+ if (s1 == s2) { /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
+ return (equals == Py_EQ);
+ } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
+ if (PyBytes_GET_SIZE(s1) != PyBytes_GET_SIZE(s2)) {
+ return (equals == Py_NE);
+ } else if (PyBytes_GET_SIZE(s1) == 1) {
+ if (equals == Py_EQ)
+ return (PyBytes_AS_STRING(s1)[0] == PyBytes_AS_STRING(s2)[0]);
+ else
+ return (PyBytes_AS_STRING(s1)[0] != PyBytes_AS_STRING(s2)[0]);
+ } else {
+ int result = memcmp(PyBytes_AS_STRING(s1), PyBytes_AS_STRING(s2), PyBytes_GET_SIZE(s1));
+ return (equals == Py_EQ) ? (result == 0) : (result != 0);
+ }
+ } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
+ return (equals == Py_NE);
+ } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
+ return (equals == Py_NE);
+ } else {
+ int result;
+ PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
+ if (!py_result)
+ return -1;
+ result = __Pyx_PyObject_IsTrue(py_result);
+ Py_DECREF(py_result);
+ return result;
+ }
+}
+""",
+requires=[Builtin.include_string_h_utility_code])
+
+pystr_equals_utility_code = UtilityCode(
+proto="""
+#if PY_MAJOR_VERSION >= 3
+#define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
+#else
+#define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
+#endif
+""",
+requires=[pybytes_equals_utility_code, pyunicode_equals_utility_code])
+
class PrimaryCmpNode(ExprNode, CmpNode):
# Non-cascaded comparison or first comparison of
# from intobject.c
division_overflow_test_code = UtilityCode(
proto="""
- #define UNARY_NEG_WOULD_OVERFLOW(x) \
- (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
+ #define UNARY_NEG_WOULD_OVERFLOW(x) \
+ (((x) < 0) & ((unsigned long)(x) == 0-(unsigned long)(x)))
""")
impl="""
static PyObject *%(binding_cfunc)s_NewEx(PyMethodDef *ml, PyObject *self, PyObject *module) {
- %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
+ %(binding_cfunc)s_object *op = PyObject_GC_New(%(binding_cfunc)s_object, %(binding_cfunc)s);
if (op == NULL)
return NULL;
- op->func.m_ml = ml;
- Py_XINCREF(self);
- op->func.m_self = self;
- Py_XINCREF(module);
- op->func.m_module = module;
- PyObject_GC_Track(op);
- return (PyObject *)op;
+ op->func.m_ml = ml;
+ Py_XINCREF(self);
+ op->func.m_self = self;
+ Py_XINCREF(module);
+ op->func.m_module = module;
+ PyObject_GC_Track(op);
+ return (PyObject *)op;
}
static void %(binding_cfunc)s_dealloc(%(binding_cfunc)s_object *m) {
- PyObject_GC_UnTrack(m);
- Py_XDECREF(m->func.m_self);
- Py_XDECREF(m->func.m_module);
+ PyObject_GC_UnTrack(m);
+ Py_XDECREF(m->func.m_self);
+ Py_XDECREF(m->func.m_module);
PyObject_GC_Del(m);
}
static PyObject *%(binding_cfunc)s_descr_get(PyObject *func, PyObject *obj, PyObject *type) {
- if (obj == Py_None)
- obj = NULL;
- return PyMethod_New(func, obj, type);
+ if (obj == Py_None)
+ obj = NULL;
+ return PyMethod_New(func, obj, type);
}
static int %(binding_cfunc)s_init(void) {