PageRenderTime 52ms CodeModel.GetById 20ms app.highlight 11ms RepoModel.GetById 19ms app.codeStats 0ms

/Objects/stringlib/find.h

http://unladen-swallow.googlecode.com/
C++ Header | 162 lines | 113 code | 25 blank | 24 comment | 31 complexity | 9dd168a0a3f8facd5a817cbc0148f295 MD5 | raw file
  1/* stringlib: find/index implementation */
  2
  3#ifndef STRINGLIB_FIND_H
  4#define STRINGLIB_FIND_H
  5
  6#ifndef STRINGLIB_FASTSEARCH_H
  7#error must include "stringlib/fastsearch.h" before including this module
  8#endif
  9
 10Py_LOCAL_INLINE(Py_ssize_t)
 11stringlib_find(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
 12               const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
 13               Py_ssize_t offset)
 14{
 15    Py_ssize_t pos;
 16
 17    if (str_len < 0)
 18        return -1;
 19    if (sub_len == 0)
 20        return offset;
 21
 22    pos = fastsearch(str, str_len, sub, sub_len, FAST_SEARCH);
 23
 24    if (pos >= 0)
 25        pos += offset;
 26
 27    return pos;
 28}
 29
 30Py_LOCAL_INLINE(Py_ssize_t)
 31stringlib_rfind(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
 32                const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
 33                Py_ssize_t offset)
 34{
 35    /* XXX - create reversefastsearch helper! */
 36    if (sub_len == 0) {
 37        if (str_len < 0)
 38            return -1;
 39	return str_len + offset;
 40    } else {
 41	Py_ssize_t j, pos = -1;
 42	for (j = str_len - sub_len; j >= 0; --j)
 43            if (STRINGLIB_CMP(str+j, sub, sub_len) == 0) {
 44                pos = j + offset;
 45                break;
 46            }
 47        return pos;
 48    }
 49}
 50
 51Py_LOCAL_INLINE(Py_ssize_t)
 52stringlib_find_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
 53                     const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
 54                     Py_ssize_t start, Py_ssize_t end)
 55{
 56    if (start < 0)
 57        start += str_len;
 58    if (start < 0)
 59        start = 0;
 60    if (end > str_len)
 61        end = str_len;
 62    if (end < 0)
 63        end += str_len;
 64    if (end < 0)
 65        end = 0;
 66
 67    return stringlib_find(
 68        str + start, end - start,
 69        sub, sub_len, start
 70        );
 71}
 72
 73Py_LOCAL_INLINE(Py_ssize_t)
 74stringlib_rfind_slice(const STRINGLIB_CHAR* str, Py_ssize_t str_len,
 75                      const STRINGLIB_CHAR* sub, Py_ssize_t sub_len,
 76                      Py_ssize_t start, Py_ssize_t end)
 77{
 78    if (start < 0)
 79        start += str_len;
 80    if (start < 0)
 81        start = 0;
 82    if (end > str_len)
 83        end = str_len;
 84    if (end < 0)
 85        end += str_len;
 86    if (end < 0)
 87        end = 0;
 88
 89    return stringlib_rfind(str + start, end - start, sub, sub_len, start);
 90}
 91
 92#if defined(STRINGLIB_STR) && !defined(FROM_BYTEARRAY)
 93
 94Py_LOCAL_INLINE(int)
 95stringlib_contains_obj(PyObject* str, PyObject* sub)
 96{
 97    return stringlib_find(
 98        STRINGLIB_STR(str), STRINGLIB_LEN(str),
 99        STRINGLIB_STR(sub), STRINGLIB_LEN(sub), 0
100        ) != -1;
101}
102
103#endif /* STRINGLIB_STR */
104
105#ifdef FROM_UNICODE
106
107/*
108This function is a helper for the "find" family (find, rfind, index,
109rindex) of unicodeobject.c file, because they all have the same 
110behaviour for the arguments.
111
112It does not touch the variables received until it knows everything 
113is ok.
114
115Note that we receive a pointer to the pointer of the substring object,
116so when we create that object in this function we don't DECREF it,
117because it continues living in the caller functions (those functions, 
118after finishing using the substring, must DECREF it).
119*/
120
121Py_LOCAL_INLINE(int)
122_ParseTupleFinds (PyObject *args, PyObject **substring, 
123                  Py_ssize_t *start, Py_ssize_t *end) {
124    PyObject *tmp_substring;
125    Py_ssize_t tmp_start = 0;
126    Py_ssize_t tmp_end = PY_SSIZE_T_MAX;
127    PyObject *obj_start=Py_None, *obj_end=Py_None;
128
129    if (!PyArg_ParseTuple(args, "O|OO:find", &tmp_substring,
130         &obj_start, &obj_end))
131        return 0;
132
133    /* To support None in "start" and "end" arguments, meaning
134       the same as if they were not passed.
135    */
136    if (obj_start != Py_None)
137        if (!_PyEval_SliceIndex(obj_start, &tmp_start))
138            return 0;
139    if (obj_end != Py_None)
140        if (!_PyEval_SliceIndex(obj_end, &tmp_end))
141            return 0;
142
143    tmp_substring = PyUnicode_FromObject(tmp_substring);
144    if (!tmp_substring)
145        return 0;
146
147    *start = tmp_start;
148    *end = tmp_end;
149    *substring = tmp_substring;
150    return 1;
151}
152
153#endif /* FROM_UNICODE */
154
155#endif /* STRINGLIB_FIND_H */
156
157/*
158Local variables:
159c-basic-offset: 4
160indent-tabs-mode: nil
161End:
162*/