Home | History | Annotate | Download | only in stringlib
      1 /* stringlib: partition implementation */
      2 
      3 #ifndef STRINGLIB_PARTITION_H
      4 #define STRINGLIB_PARTITION_H
      5 
      6 #ifndef STRINGLIB_FASTSEARCH_H
      7 #error must include "stringlib/fastsearch.h" before including this module
      8 #endif
      9 
     10 Py_LOCAL_INLINE(PyObject*)
     11 stringlib_partition(PyObject* str_obj,
     12                     const STRINGLIB_CHAR* str, Py_ssize_t str_len,
     13                     PyObject* sep_obj,
     14                     const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
     15 {
     16     PyObject* out;
     17     Py_ssize_t pos;
     18 
     19     if (sep_len == 0) {
     20         PyErr_SetString(PyExc_ValueError, "empty separator");
     21         return NULL;
     22     }
     23 
     24     out = PyTuple_New(3);
     25     if (!out)
     26         return NULL;
     27 
     28     pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_SEARCH);
     29 
     30     if (pos < 0) {
     31 #if STRINGLIB_MUTABLE
     32         PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, str_len));
     33         PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
     34         PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(NULL, 0));
     35 #else
     36         Py_INCREF(str_obj);
     37         PyTuple_SET_ITEM(out, 0, (PyObject*) str_obj);
     38         Py_INCREF(STRINGLIB_EMPTY);
     39         PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
     40         Py_INCREF(STRINGLIB_EMPTY);
     41         PyTuple_SET_ITEM(out, 2, (PyObject*) STRINGLIB_EMPTY);
     42 #endif
     43         return out;
     44     }
     45 
     46     PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
     47     Py_INCREF(sep_obj);
     48     PyTuple_SET_ITEM(out, 1, sep_obj);
     49     pos += sep_len;
     50     PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
     51 
     52     if (PyErr_Occurred()) {
     53         Py_DECREF(out);
     54         return NULL;
     55     }
     56 
     57     return out;
     58 }
     59 
     60 Py_LOCAL_INLINE(PyObject*)
     61 stringlib_rpartition(PyObject* str_obj,
     62                      const STRINGLIB_CHAR* str, Py_ssize_t str_len,
     63                      PyObject* sep_obj,
     64                      const STRINGLIB_CHAR* sep, Py_ssize_t sep_len)
     65 {
     66     PyObject* out;
     67     Py_ssize_t pos;
     68 
     69     if (sep_len == 0) {
     70         PyErr_SetString(PyExc_ValueError, "empty separator");
     71         return NULL;
     72     }
     73 
     74     out = PyTuple_New(3);
     75     if (!out)
     76         return NULL;
     77 
     78     pos = fastsearch(str, str_len, sep, sep_len, -1, FAST_RSEARCH);
     79 
     80     if (pos < 0) {
     81 #if STRINGLIB_MUTABLE
     82         PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(NULL, 0));
     83         PyTuple_SET_ITEM(out, 1, STRINGLIB_NEW(NULL, 0));
     84         PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str, str_len));
     85 #else
     86         Py_INCREF(STRINGLIB_EMPTY);
     87         PyTuple_SET_ITEM(out, 0, (PyObject*) STRINGLIB_EMPTY);
     88         Py_INCREF(STRINGLIB_EMPTY);
     89         PyTuple_SET_ITEM(out, 1, (PyObject*) STRINGLIB_EMPTY);
     90         Py_INCREF(str_obj);
     91         PyTuple_SET_ITEM(out, 2, (PyObject*) str_obj);
     92 #endif
     93         return out;
     94     }
     95 
     96     PyTuple_SET_ITEM(out, 0, STRINGLIB_NEW(str, pos));
     97     Py_INCREF(sep_obj);
     98     PyTuple_SET_ITEM(out, 1, sep_obj);
     99     pos += sep_len;
    100     PyTuple_SET_ITEM(out, 2, STRINGLIB_NEW(str + pos, str_len - pos));
    101 
    102     if (PyErr_Occurred()) {
    103         Py_DECREF(out);
    104         return NULL;
    105     }
    106 
    107     return out;
    108 }
    109 
    110 #endif
    111