Home | History | Annotate | Download | only in Utility
      1 
      2 //////////////////// IncludeStringH.proto ////////////////////
      3 
      4 #include <string.h>
      5 
      6 //////////////////// IncludeCppStringH.proto ////////////////////
      7 
      8 #include <string>
      9 
     10 //////////////////// InitStrings.proto ////////////////////
     11 
     12 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t); /*proto*/
     13 
     14 //////////////////// InitStrings ////////////////////
     15 
     16 static int __Pyx_InitStrings(__Pyx_StringTabEntry *t) {
     17     while (t->p) {
     18         #if PY_MAJOR_VERSION < 3
     19         if (t->is_unicode) {
     20             *t->p = PyUnicode_DecodeUTF8(t->s, t->n - 1, NULL);
     21         } else if (t->intern) {
     22             *t->p = PyString_InternFromString(t->s);
     23         } else {
     24             *t->p = PyString_FromStringAndSize(t->s, t->n - 1);
     25         }
     26         #else  /* Python 3+ has unicode identifiers */
     27         if (t->is_unicode | t->is_str) {
     28             if (t->intern) {
     29                 *t->p = PyUnicode_InternFromString(t->s);
     30             } else if (t->encoding) {
     31                 *t->p = PyUnicode_Decode(t->s, t->n - 1, t->encoding, NULL);
     32             } else {
     33                 *t->p = PyUnicode_FromStringAndSize(t->s, t->n - 1);
     34             }
     35         } else {
     36             *t->p = PyBytes_FromStringAndSize(t->s, t->n - 1);
     37         }
     38         #endif
     39         if (!*t->p)
     40             return -1;
     41         ++t;
     42     }
     43     return 0;
     44 }
     45 
     46 //////////////////// BytesContains.proto ////////////////////
     47 
     48 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character); /*proto*/
     49 
     50 //////////////////// BytesContains ////////////////////
     51 
     52 static CYTHON_INLINE int __Pyx_BytesContains(PyObject* bytes, char character) {
     53     const Py_ssize_t length = PyBytes_GET_SIZE(bytes);
     54     char* char_start = PyBytes_AS_STRING(bytes);
     55     char* pos;
     56     for (pos=char_start; pos < char_start+length; pos++) {
     57         if (character == pos[0]) return 1;
     58     }
     59     return 0;
     60 }
     61 
     62 
     63 //////////////////// PyUCS4InUnicode.proto ////////////////////
     64 
     65 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character); /*proto*/
     66 static CYTHON_INLINE int __Pyx_PyUnicodeBufferContainsUCS4(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character); /*proto*/
     67 
     68 //////////////////// PyUCS4InUnicode ////////////////////
     69 
     70 static CYTHON_INLINE int __Pyx_UnicodeContainsUCS4(PyObject* unicode, Py_UCS4 character) {
     71 #if CYTHON_PEP393_ENABLED
     72     const int kind = PyUnicode_KIND(unicode);
     73     if (likely(kind != PyUnicode_WCHAR_KIND)) {
     74         Py_ssize_t i;
     75         const void* udata = PyUnicode_DATA(unicode);
     76         const Py_ssize_t length = PyUnicode_GET_LENGTH(unicode);
     77         for (i=0; i < length; i++) {
     78             if (unlikely(character == PyUnicode_READ(kind, udata, i))) return 1;
     79         }
     80         return 0;
     81     }
     82 #endif
     83     return __Pyx_PyUnicodeBufferContainsUCS4(
     84         PyUnicode_AS_UNICODE(unicode),
     85         PyUnicode_GET_SIZE(unicode),
     86         character);
     87 }
     88 
     89 static CYTHON_INLINE int __Pyx_PyUnicodeBufferContainsUCS4(Py_UNICODE* buffer, Py_ssize_t length, Py_UCS4 character) {
     90     Py_UNICODE uchar;
     91     Py_UNICODE* pos;
     92     #if Py_UNICODE_SIZE == 2
     93     if (character > 65535) {
     94         /* handle surrogate pairs for Py_UNICODE buffers in 16bit Unicode builds */
     95         Py_UNICODE high_val, low_val;
     96         high_val = (Py_UNICODE) (0xD800 | (((character - 0x10000) >> 10) & ((1<<10)-1)));
     97         low_val  = (Py_UNICODE) (0xDC00 | ( (character - 0x10000)        & ((1<<10)-1)));
     98         for (pos=buffer; pos < buffer+length-1; pos++) {
     99             if (unlikely(high_val == pos[0]) & unlikely(low_val == pos[1])) return 1;
    100         }
    101         return 0;
    102     }
    103     #endif
    104     uchar = (Py_UNICODE) character;
    105     for (pos=buffer; pos < buffer+length; pos++) {
    106         if (unlikely(uchar == pos[0])) return 1;
    107     }
    108     return 0;
    109 }
    110 
    111 
    112 //////////////////// PyUnicodeContains.proto ////////////////////
    113 
    114 static CYTHON_INLINE int __Pyx_PyUnicode_Contains(PyObject* substring, PyObject* text, int eq) {
    115     int result = PyUnicode_Contains(text, substring);
    116     return unlikely(result < 0) ? result : (result == (eq == Py_EQ));
    117 }
    118 
    119 
    120 //////////////////// StrEquals.proto ////////////////////
    121 //@requires: BytesEquals
    122 //@requires: UnicodeEquals
    123 
    124 #if PY_MAJOR_VERSION >= 3
    125 #define __Pyx_PyString_Equals __Pyx_PyUnicode_Equals
    126 #else
    127 #define __Pyx_PyString_Equals __Pyx_PyBytes_Equals
    128 #endif
    129 
    130 
    131 //////////////////// UnicodeEquals.proto ////////////////////
    132 
    133 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
    134 
    135 //////////////////// UnicodeEquals ////////////////////
    136 //@requires: BytesEquals
    137 
    138 static CYTHON_INLINE int __Pyx_PyUnicode_Equals(PyObject* s1, PyObject* s2, int equals) {
    139 #if CYTHON_COMPILING_IN_PYPY
    140     return PyObject_RichCompareBool(s1, s2, equals);
    141 #else
    142 #if PY_MAJOR_VERSION < 3
    143     PyObject* owned_ref = NULL;
    144 #endif
    145     int s1_is_unicode, s2_is_unicode;
    146     if (s1 == s2) {
    147         /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
    148         goto return_eq;
    149     }
    150     s1_is_unicode = PyUnicode_CheckExact(s1);
    151     s2_is_unicode = PyUnicode_CheckExact(s2);
    152 #if PY_MAJOR_VERSION < 3
    153     if ((s1_is_unicode & (!s2_is_unicode)) && PyString_CheckExact(s2)) {
    154         owned_ref = PyUnicode_FromObject(s2);
    155         if (unlikely(!owned_ref))
    156             return -1;
    157         s2 = owned_ref;
    158         s2_is_unicode = 1;
    159     } else if ((s2_is_unicode & (!s1_is_unicode)) && PyString_CheckExact(s1)) {
    160         owned_ref = PyUnicode_FromObject(s1);
    161         if (unlikely(!owned_ref))
    162             return -1;
    163         s1 = owned_ref;
    164         s1_is_unicode = 1;
    165     } else if (((!s2_is_unicode) & (!s1_is_unicode))) {
    166         return __Pyx_PyBytes_Equals(s1, s2, equals);
    167     }
    168 #endif
    169     if (s1_is_unicode & s2_is_unicode) {
    170         Py_ssize_t length;
    171         int kind;
    172         void *data1, *data2;
    173         #if CYTHON_PEP393_ENABLED
    174         if (unlikely(PyUnicode_READY(s1) < 0) || unlikely(PyUnicode_READY(s2) < 0))
    175             return -1;
    176         #endif
    177         length = __Pyx_PyUnicode_GET_LENGTH(s1);
    178         if (length != __Pyx_PyUnicode_GET_LENGTH(s2)) {
    179             goto return_ne;
    180         }
    181         // len(s1) == len(s2) >= 1  (empty string is interned, and "s1 is not s2")
    182         kind = __Pyx_PyUnicode_KIND(s1);
    183         if (kind != __Pyx_PyUnicode_KIND(s2)) {
    184             goto return_ne;
    185         }
    186         data1 = __Pyx_PyUnicode_DATA(s1);
    187         data2 = __Pyx_PyUnicode_DATA(s2);
    188         if (__Pyx_PyUnicode_READ(kind, data1, 0) != __Pyx_PyUnicode_READ(kind, data2, 0)) {
    189             goto return_ne;
    190         } else if (length == 1) {
    191             goto return_eq;
    192         } else {
    193             int result = memcmp(data1, data2, (size_t)(length * kind));
    194             #if PY_MAJOR_VERSION < 3
    195             Py_XDECREF(owned_ref);
    196             #endif
    197             return (equals == Py_EQ) ? (result == 0) : (result != 0);
    198         }
    199     } else if ((s1 == Py_None) & s2_is_unicode) {
    200         goto return_ne;
    201     } else if ((s2 == Py_None) & s1_is_unicode) {
    202         goto return_ne;
    203     } else {
    204         int result;
    205         PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
    206         if (!py_result)
    207             return -1;
    208         result = __Pyx_PyObject_IsTrue(py_result);
    209         Py_DECREF(py_result);
    210         return result;
    211     }
    212 return_eq:
    213     #if PY_MAJOR_VERSION < 3
    214     Py_XDECREF(owned_ref);
    215     #endif
    216     return (equals == Py_EQ);
    217 return_ne:
    218     #if PY_MAJOR_VERSION < 3
    219     Py_XDECREF(owned_ref);
    220     #endif
    221     return (equals == Py_NE);
    222 #endif
    223 }
    224 
    225 
    226 //////////////////// BytesEquals.proto ////////////////////
    227 
    228 static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals); /*proto*/
    229 
    230 //////////////////// BytesEquals ////////////////////
    231 //@requires: IncludeStringH
    232 
    233 static CYTHON_INLINE int __Pyx_PyBytes_Equals(PyObject* s1, PyObject* s2, int equals) {
    234 #if CYTHON_COMPILING_IN_PYPY
    235     return PyObject_RichCompareBool(s1, s2, equals);
    236 #else
    237     if (s1 == s2) {
    238         /* as done by PyObject_RichCompareBool(); also catches the (interned) empty string */
    239         return (equals == Py_EQ);
    240     } else if (PyBytes_CheckExact(s1) & PyBytes_CheckExact(s2)) {
    241         const char *ps1, *ps2;
    242         Py_ssize_t length = PyBytes_GET_SIZE(s1);
    243         if (length != PyBytes_GET_SIZE(s2))
    244             return (equals == Py_NE);
    245         // len(s1) == len(s2) >= 1  (empty string is interned, and "s1 is not s2")
    246         ps1 = PyBytes_AS_STRING(s1);
    247         ps2 = PyBytes_AS_STRING(s2);
    248         if (ps1[0] != ps2[0]) {
    249             return (equals == Py_NE);
    250         } else if (length == 1) {
    251             return (equals == Py_EQ);
    252         } else {
    253             int result = memcmp(ps1, ps2, (size_t)length);
    254             return (equals == Py_EQ) ? (result == 0) : (result != 0);
    255         }
    256     } else if ((s1 == Py_None) & PyBytes_CheckExact(s2)) {
    257         return (equals == Py_NE);
    258     } else if ((s2 == Py_None) & PyBytes_CheckExact(s1)) {
    259         return (equals == Py_NE);
    260     } else {
    261         int result;
    262         PyObject* py_result = PyObject_RichCompare(s1, s2, equals);
    263         if (!py_result)
    264             return -1;
    265         result = __Pyx_PyObject_IsTrue(py_result);
    266         Py_DECREF(py_result);
    267         return result;
    268     }
    269 #endif
    270 }
    271 
    272 //////////////////// GetItemIntByteArray.proto ////////////////////
    273 
    274 #define __Pyx_GetItemInt_ByteArray(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
    275     (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
    276     __Pyx_GetItemInt_ByteArray_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
    277     (PyErr_SetString(PyExc_IndexError, "bytearray index out of range"), -1))
    278 
    279 static CYTHON_INLINE int __Pyx_GetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i,
    280                                                          int wraparound, int boundscheck);
    281 
    282 //////////////////// GetItemIntByteArray ////////////////////
    283 
    284 static CYTHON_INLINE int __Pyx_GetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i,
    285                                                          int wraparound, int boundscheck) {
    286     Py_ssize_t length;
    287     if (wraparound | boundscheck) {
    288         length = PyByteArray_GET_SIZE(string);
    289         if (wraparound & unlikely(i < 0)) i += length;
    290         if ((!boundscheck) || likely((0 <= i) & (i < length))) {
    291             return (unsigned char) (PyByteArray_AS_STRING(string)[i]);
    292         } else {
    293             PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
    294             return -1;
    295         }
    296     } else {
    297         return (unsigned char) (PyByteArray_AS_STRING(string)[i]);
    298     }
    299 }
    300 
    301 
    302 //////////////////// SetItemIntByteArray.proto ////////////////////
    303 
    304 #define __Pyx_SetItemInt_ByteArray(o, i, v, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
    305     (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
    306     __Pyx_SetItemInt_ByteArray_Fast(o, (Py_ssize_t)i, v, wraparound, boundscheck) : \
    307     (PyErr_SetString(PyExc_IndexError, "bytearray index out of range"), -1))
    308 
    309 static CYTHON_INLINE int __Pyx_SetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, unsigned char v,
    310                                                          int wraparound, int boundscheck);
    311 
    312 //////////////////// SetItemIntByteArray ////////////////////
    313 
    314 static CYTHON_INLINE int __Pyx_SetItemInt_ByteArray_Fast(PyObject* string, Py_ssize_t i, unsigned char v,
    315                                                          int wraparound, int boundscheck) {
    316     Py_ssize_t length;
    317     if (wraparound | boundscheck) {
    318         length = PyByteArray_GET_SIZE(string);
    319         if (wraparound & unlikely(i < 0)) i += length;
    320         if ((!boundscheck) || likely((0 <= i) & (i < length))) {
    321             PyByteArray_AS_STRING(string)[i] = (char) v;
    322             return 0;
    323         } else {
    324             PyErr_SetString(PyExc_IndexError, "bytearray index out of range");
    325             return -1;
    326         }
    327     } else {
    328         PyByteArray_AS_STRING(string)[i] = (char) v;
    329         return 0;
    330     }
    331 }
    332 
    333 
    334 //////////////////// GetItemIntUnicode.proto ////////////////////
    335 
    336 #define __Pyx_GetItemInt_Unicode(o, i, type, is_signed, to_py_func, is_list, wraparound, boundscheck) \
    337     (__Pyx_fits_Py_ssize_t(i, type, is_signed) ? \
    338     __Pyx_GetItemInt_Unicode_Fast(o, (Py_ssize_t)i, wraparound, boundscheck) : \
    339     (PyErr_SetString(PyExc_IndexError, "string index out of range"), (Py_UCS4)-1))
    340 
    341 static CYTHON_INLINE Py_UCS4 __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i,
    342                                                            int wraparound, int boundscheck);
    343 
    344 //////////////////// GetItemIntUnicode ////////////////////
    345 
    346 static CYTHON_INLINE Py_UCS4 __Pyx_GetItemInt_Unicode_Fast(PyObject* ustring, Py_ssize_t i,
    347                                                            int wraparound, int boundscheck) {
    348     Py_ssize_t length;
    349 #if CYTHON_PEP393_ENABLED
    350     if (unlikely(__Pyx_PyUnicode_READY(ustring) < 0)) return (Py_UCS4)-1;
    351 #endif
    352     if (wraparound | boundscheck) {
    353         length = __Pyx_PyUnicode_GET_LENGTH(ustring);
    354         if (wraparound & unlikely(i < 0)) i += length;
    355         if ((!boundscheck) || likely((0 <= i) & (i < length))) {
    356             return __Pyx_PyUnicode_READ_CHAR(ustring, i);
    357         } else {
    358             PyErr_SetString(PyExc_IndexError, "string index out of range");
    359             return (Py_UCS4)-1;
    360         }
    361     } else {
    362         return __Pyx_PyUnicode_READ_CHAR(ustring, i);
    363     }
    364 }
    365 
    366 
    367 /////////////// decode_cpp_string.proto ///////////////
    368 //@requires: IncludeCppStringH
    369 //@requires: decode_c_bytes
    370 
    371 static CYTHON_INLINE PyObject* __Pyx_decode_cpp_string(
    372          std::string cppstring, Py_ssize_t start, Py_ssize_t stop,
    373          const char* encoding, const char* errors,
    374          PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
    375     return __Pyx_decode_c_bytes(
    376         cppstring.data(), cppstring.size(), start, stop, encoding, errors, decode_func);
    377 }
    378 
    379 /////////////// decode_c_string.proto ///////////////
    380 
    381 static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
    382          const char* cstring, Py_ssize_t start, Py_ssize_t stop,
    383          const char* encoding, const char* errors,
    384          PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
    385 
    386 /////////////// decode_c_string ///////////////
    387 //@requires: IncludeStringH
    388 
    389 /* duplicate code to avoid calling strlen() if start >= 0 and stop >= 0 */
    390 
    391 static CYTHON_INLINE PyObject* __Pyx_decode_c_string(
    392          const char* cstring, Py_ssize_t start, Py_ssize_t stop,
    393          const char* encoding, const char* errors,
    394          PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
    395     Py_ssize_t length;
    396     if (unlikely((start < 0) | (stop < 0))) {
    397         length = strlen(cstring);
    398         if (start < 0) {
    399             start += length;
    400             if (start < 0)
    401                 start = 0;
    402         }
    403         if (stop < 0)
    404             stop += length;
    405     }
    406     length = stop - start;
    407     if (unlikely(length <= 0))
    408         return PyUnicode_FromUnicode(NULL, 0);
    409     cstring += start;
    410     if (decode_func) {
    411         return decode_func(cstring, length, errors);
    412     } else {
    413         return PyUnicode_Decode(cstring, length, encoding, errors);
    414     }
    415 }
    416 
    417 /////////////// decode_c_bytes.proto ///////////////
    418 
    419 static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
    420          const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
    421          const char* encoding, const char* errors,
    422          PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors));
    423 
    424 /////////////// decode_c_bytes ///////////////
    425 
    426 static CYTHON_INLINE PyObject* __Pyx_decode_c_bytes(
    427          const char* cstring, Py_ssize_t length, Py_ssize_t start, Py_ssize_t stop,
    428          const char* encoding, const char* errors,
    429          PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
    430     if (unlikely((start < 0) | (stop < 0))) {
    431         if (start < 0) {
    432             start += length;
    433             if (start < 0)
    434                 start = 0;
    435         }
    436         if (stop < 0)
    437             stop += length;
    438     }
    439     if (stop > length)
    440         stop = length;
    441     length = stop - start;
    442     if (unlikely(length <= 0))
    443         return PyUnicode_FromUnicode(NULL, 0);
    444     cstring += start;
    445     if (decode_func) {
    446         return decode_func(cstring, length, errors);
    447     } else {
    448         return PyUnicode_Decode(cstring, length, encoding, errors);
    449     }
    450 }
    451 
    452 /////////////// decode_bytes.proto ///////////////
    453 //@requires: decode_c_bytes
    454 
    455 static CYTHON_INLINE PyObject* __Pyx_decode_bytes(
    456          PyObject* string, Py_ssize_t start, Py_ssize_t stop,
    457          const char* encoding, const char* errors,
    458          PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
    459     return __Pyx_decode_c_bytes(
    460         PyBytes_AS_STRING(string), PyBytes_GET_SIZE(string),
    461         start, stop, encoding, errors, decode_func);
    462 }
    463 
    464 /////////////// decode_bytearray.proto ///////////////
    465 //@requires: decode_c_bytes
    466 
    467 static CYTHON_INLINE PyObject* __Pyx_decode_bytearray(
    468          PyObject* string, Py_ssize_t start, Py_ssize_t stop,
    469          const char* encoding, const char* errors,
    470          PyObject* (*decode_func)(const char *s, Py_ssize_t size, const char *errors)) {
    471     return __Pyx_decode_c_bytes(
    472         PyByteArray_AS_STRING(string), PyByteArray_GET_SIZE(string),
    473         start, stop, encoding, errors, decode_func);
    474 }
    475 
    476 /////////////// PyUnicode_Substring.proto ///////////////
    477 
    478 static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
    479             PyObject* text, Py_ssize_t start, Py_ssize_t stop);
    480 
    481 /////////////// PyUnicode_Substring ///////////////
    482 
    483 static CYTHON_INLINE PyObject* __Pyx_PyUnicode_Substring(
    484             PyObject* text, Py_ssize_t start, Py_ssize_t stop) {
    485     Py_ssize_t length;
    486 #if CYTHON_PEP393_ENABLED
    487     if (unlikely(PyUnicode_READY(text) == -1)) return NULL;
    488     length = PyUnicode_GET_LENGTH(text);
    489 #else
    490     length = PyUnicode_GET_SIZE(text);
    491 #endif
    492     if (start < 0) {
    493         start += length;
    494         if (start < 0)
    495             start = 0;
    496     }
    497     if (stop < 0)
    498         stop += length;
    499     else if (stop > length)
    500         stop = length;
    501     length = stop - start;
    502     if (length <= 0)
    503         return PyUnicode_FromUnicode(NULL, 0);
    504 #if CYTHON_PEP393_ENABLED
    505     return PyUnicode_FromKindAndData(PyUnicode_KIND(text),
    506         PyUnicode_1BYTE_DATA(text) + start*PyUnicode_KIND(text), stop-start);
    507 #else
    508     return PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(text)+start, stop-start);
    509 #endif
    510 }
    511 
    512 
    513 /////////////// py_unicode_istitle.proto ///////////////
    514 
    515 // Py_UNICODE_ISTITLE() doesn't match unicode.istitle() as the latter
    516 // additionally allows character that comply with Py_UNICODE_ISUPPER()
    517 
    518 #if PY_VERSION_HEX < 0x030200A2
    519 static CYTHON_INLINE int __Pyx_Py_UNICODE_ISTITLE(Py_UNICODE uchar)
    520 #else
    521 static CYTHON_INLINE int __Pyx_Py_UNICODE_ISTITLE(Py_UCS4 uchar)
    522 #endif
    523 {
    524     return Py_UNICODE_ISTITLE(uchar) || Py_UNICODE_ISUPPER(uchar);
    525 }
    526 
    527 
    528 /////////////// unicode_tailmatch.proto ///////////////
    529 
    530 // Python's unicode.startswith() and unicode.endswith() support a
    531 // tuple of prefixes/suffixes, whereas it's much more common to
    532 // test for a single unicode string.
    533 
    534 static int __Pyx_PyUnicode_Tailmatch(PyObject* s, PyObject* substr,
    535                                      Py_ssize_t start, Py_ssize_t end, int direction) {
    536     if (unlikely(PyTuple_Check(substr))) {
    537         Py_ssize_t i, count = PyTuple_GET_SIZE(substr);
    538         for (i = 0; i < count; i++) {
    539             int result;
    540 #if CYTHON_COMPILING_IN_CPYTHON
    541             result = PyUnicode_Tailmatch(s, PyTuple_GET_ITEM(substr, i),
    542                                          start, end, direction);
    543 #else
    544             PyObject* sub = PySequence_GetItem(substr, i);
    545             if (unlikely(!sub)) return -1;
    546             result = PyUnicode_Tailmatch(s, sub, start, end, direction);
    547             Py_DECREF(sub);
    548 #endif
    549             if (result) {
    550                 return result;
    551             }
    552         }
    553         return 0;
    554     }
    555     return PyUnicode_Tailmatch(s, substr, start, end, direction);
    556 }
    557 
    558 
    559 /////////////// bytes_tailmatch.proto ///////////////
    560 
    561 static int __Pyx_PyBytes_SingleTailmatch(PyObject* self, PyObject* arg, Py_ssize_t start,
    562                                          Py_ssize_t end, int direction)
    563 {
    564     const char* self_ptr = PyBytes_AS_STRING(self);
    565     Py_ssize_t self_len = PyBytes_GET_SIZE(self);
    566     const char* sub_ptr;
    567     Py_ssize_t sub_len;
    568     int retval;
    569 
    570 #if PY_VERSION_HEX >= 0x02060000
    571     Py_buffer view;
    572     view.obj = NULL;
    573 #endif
    574 
    575     if ( PyBytes_Check(arg) ) {
    576         sub_ptr = PyBytes_AS_STRING(arg);
    577         sub_len = PyBytes_GET_SIZE(arg);
    578     }
    579 #if PY_MAJOR_VERSION < 3
    580     // Python 2.x allows mixing unicode and str
    581     else if ( PyUnicode_Check(arg) ) {
    582         return PyUnicode_Tailmatch(self, arg, start, end, direction);
    583     }
    584 #endif
    585     else {
    586 #if PY_VERSION_HEX < 0x02060000
    587         if (unlikely(PyObject_AsCharBuffer(arg, &sub_ptr, &sub_len)))
    588             return -1;
    589 #else
    590         if (unlikely(PyObject_GetBuffer(self, &view, PyBUF_SIMPLE) == -1))
    591             return -1;
    592         sub_ptr = (const char*) view.buf;
    593         sub_len = view.len;
    594 #endif
    595     }
    596 
    597     if (end > self_len)
    598         end = self_len;
    599     else if (end < 0)
    600         end += self_len;
    601     if (end < 0)
    602         end = 0;
    603     if (start < 0)
    604         start += self_len;
    605     if (start < 0)
    606         start = 0;
    607 
    608     if (direction > 0) {
    609         /* endswith */
    610         if (end-sub_len > start)
    611             start = end - sub_len;
    612     }
    613 
    614     if (start + sub_len <= end)
    615         retval = !memcmp(self_ptr+start, sub_ptr, (size_t)sub_len);
    616     else
    617         retval = 0;
    618 
    619 #if PY_VERSION_HEX >= 0x02060000
    620     if (view.obj)
    621         PyBuffer_Release(&view);
    622 #endif
    623 
    624     return retval;
    625 }
    626 
    627 static int __Pyx_PyBytes_Tailmatch(PyObject* self, PyObject* substr, Py_ssize_t start,
    628                                    Py_ssize_t end, int direction)
    629 {
    630     if (unlikely(PyTuple_Check(substr))) {
    631         Py_ssize_t i, count = PyTuple_GET_SIZE(substr);
    632         for (i = 0; i < count; i++) {
    633             int result;
    634 #if CYTHON_COMPILING_IN_CPYTHON
    635             result = __Pyx_PyBytes_SingleTailmatch(self, PyTuple_GET_ITEM(substr, i),
    636                                                    start, end, direction);
    637 #else
    638             PyObject* sub = PySequence_GetItem(substr, i);
    639             if (unlikely(!sub)) return -1;
    640             result = __Pyx_PyBytes_SingleTailmatch(self, sub, start, end, direction);
    641             Py_DECREF(sub);
    642 #endif
    643             if (result) {
    644                 return result;
    645             }
    646         }
    647         return 0;
    648     }
    649 
    650     return __Pyx_PyBytes_SingleTailmatch(self, substr, start, end, direction);
    651 }
    652 
    653 
    654 /////////////// str_tailmatch.proto ///////////////
    655 
    656 static CYTHON_INLINE int __Pyx_PyStr_Tailmatch(PyObject* self, PyObject* arg, Py_ssize_t start,
    657                                                Py_ssize_t end, int direction);
    658 
    659 /////////////// str_tailmatch ///////////////
    660 //@requires: bytes_tailmatch
    661 //@requires: unicode_tailmatch
    662 
    663 static CYTHON_INLINE int __Pyx_PyStr_Tailmatch(PyObject* self, PyObject* arg, Py_ssize_t start,
    664                                                Py_ssize_t end, int direction)
    665 {
    666     // We do not use a C compiler macro here to avoid "unused function"
    667     // warnings for the *_Tailmatch() function that is not being used in
    668     // the specific CPython version.  The C compiler will generate the same
    669     // code anyway, and will usually just remove the unused function.
    670     if (PY_MAJOR_VERSION < 3)
    671         return __Pyx_PyBytes_Tailmatch(self, arg, start, end, direction);
    672     else
    673         return __Pyx_PyUnicode_Tailmatch(self, arg, start, end, direction);
    674 }
    675 
    676 
    677 /////////////// bytes_index.proto ///////////////
    678 
    679 static CYTHON_INLINE char __Pyx_PyBytes_GetItemInt(PyObject* bytes, Py_ssize_t index, int check_bounds) {
    680     if (check_bounds) {
    681         Py_ssize_t size = PyBytes_GET_SIZE(bytes);
    682         if (unlikely(index >= size) | ((index < 0) & unlikely(index < -size))) {
    683             PyErr_SetString(PyExc_IndexError, "string index out of range");
    684             return -1;
    685         }
    686     }
    687     if (index < 0)
    688         index += PyBytes_GET_SIZE(bytes);
    689     return PyBytes_AS_STRING(bytes)[index];
    690 }
    691 
    692 
    693 //////////////////// StringJoin.proto ////////////////////
    694 
    695 #if PY_MAJOR_VERSION < 3
    696 #define __Pyx_PyString_Join __Pyx_PyBytes_Join
    697 #define __Pyx_PyBaseString_Join(s, v) (PyUnicode_CheckExact(s) ? PyUnicode_Join(s, v) : __Pyx_PyBytes_Join(s, v))
    698 #else
    699 #define __Pyx_PyString_Join PyUnicode_Join
    700 #define __Pyx_PyBaseString_Join PyUnicode_Join
    701 #endif
    702 
    703 #if CYTHON_COMPILING_IN_CPYTHON
    704     #if PY_MAJOR_VERSION < 3
    705     #define __Pyx_PyBytes_Join _PyString_Join
    706     #else
    707     #define __Pyx_PyBytes_Join _PyBytes_Join
    708     #endif
    709 #else
    710 static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values); /*proto*/
    711 #endif
    712 
    713 
    714 //////////////////// StringJoin ////////////////////
    715 
    716 #if !CYTHON_COMPILING_IN_CPYTHON
    717 static CYTHON_INLINE PyObject* __Pyx_PyBytes_Join(PyObject* sep, PyObject* values) {
    718     return PyObject_CallMethodObjArgs(sep, PYIDENT("join"), values, NULL);
    719 }
    720 #endif
    721 
    722 
    723 //////////////////// ByteArrayAppendObject.proto ////////////////////
    724 
    725 static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyObject* value);
    726 
    727 //////////////////// ByteArrayAppendObject ////////////////////
    728 //@requires: ByteArrayAppend
    729 
    730 static CYTHON_INLINE int __Pyx_PyByteArray_AppendObject(PyObject* bytearray, PyObject* value) {
    731     Py_ssize_t ival;
    732 #if PY_MAJOR_VERSION < 3
    733     if (unlikely(PyString_Check(value))) {
    734         if (unlikely(PyString_GET_SIZE(value) != 1)) {
    735             PyErr_SetString(PyExc_ValueError, "string must be of size 1");
    736             return -1;
    737         }
    738         ival = (unsigned char) (PyString_AS_STRING(value)[0]);
    739     } else
    740 #endif
    741     {
    742         // CPython calls PyNumber_Index() internally
    743         ival = __Pyx_PyIndex_AsSsize_t(value);
    744         if (unlikely((ival < 0) | (ival > 255))) {
    745             if (ival == -1 && PyErr_Occurred())
    746                 return -1;
    747             PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
    748             return -1;
    749         }
    750     }
    751     return __Pyx_PyByteArray_Append(bytearray, ival);
    752 }
    753 
    754 //////////////////// ByteArrayAppend.proto ////////////////////
    755 
    756 static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value);
    757 
    758 //////////////////// ByteArrayAppend ////////////////////
    759 //@requires: ObjectHandling.c::PyObjectCallMethod
    760 
    761 static CYTHON_INLINE int __Pyx_PyByteArray_Append(PyObject* bytearray, int value) {
    762     PyObject *pyval, *retval;
    763 #if CYTHON_COMPILING_IN_CPYTHON
    764     if (likely((value >= 0) & (value <= 255))) {
    765         Py_ssize_t n = Py_SIZE(bytearray);
    766         if (likely(n != PY_SSIZE_T_MAX)) {
    767             if (unlikely(PyByteArray_Resize(bytearray, n + 1) < 0))
    768                 return -1;
    769             PyByteArray_AS_STRING(bytearray)[n] = value;
    770             return 0;
    771         }
    772     } else {
    773         PyErr_SetString(PyExc_ValueError, "byte must be in range(0, 256)");
    774         return -1;
    775     }
    776 #endif
    777     pyval = PyInt_FromLong(value);
    778     if (unlikely(!pyval))
    779         return -1;
    780     retval = __Pyx_PyObject_CallMethod1(bytearray, PYIDENT("append"), pyval);
    781     Py_DECREF(pyval);
    782     if (unlikely(!retval))
    783         return -1;
    784     Py_DECREF(retval);
    785     return 0;
    786 }
    787