Skip to content

Commit 4bbe7cb

Browse files
committed
Refactor substr args functions
1 parent 3b165ef commit 4bbe7cb

File tree

1 file changed

+37
-27
lines changed

1 file changed

+37
-27
lines changed

src/cstring.c

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@ struct cstring {
66
char value[];
77
};
88

9-
#define CSTRING_HASH(self) (((struct cstring *)self)->hash)
10-
#define CSTRING_VALUE(self) (((struct cstring *)self)->value)
9+
#define CSTRING_HASH(self) (((struct cstring *)self)->hash)
10+
#define CSTRING_VALUE(self) (((struct cstring *)self)->value)
11+
#define CSTRING_VALUE_AT(self, i) (&CSTRING_VALUE(self)[(i)])
1112

1213

1314
static PyObject *_cstring_new(PyTypeObject *type, const char *value, size_t len) {
@@ -132,7 +133,7 @@ static Py_ssize_t _ensure_valid_index(PyObject *self, Py_ssize_t i) {
132133
static PyObject *cstring_item(PyObject *self, Py_ssize_t i) {
133134
if(_ensure_valid_index(self, i) < 0)
134135
return NULL;
135-
return _cstring_new(Py_TYPE(self), &CSTRING_VALUE(self)[i], 1);
136+
return _cstring_new(Py_TYPE(self), CSTRING_VALUE_AT(self, i), 1);
136137
}
137138

138139
static int cstring_contains(PyObject *self, PyObject *arg) {
@@ -160,7 +161,7 @@ static PyObject *_cstring_subscript_slice(PyObject *self, PyObject *slice) {
160161
assert(slicelen >= 0);
161162

162163
struct cstring *new = Py_TYPE(self)->tp_alloc(Py_TYPE(self), slicelen + 1);
163-
char *src = &CSTRING_VALUE(self)[start];
164+
char *src = CSTRING_VALUE_AT(self, start);
164165
for(Py_ssize_t i = 0; i < slicelen; ++i) {
165166
new->value[i] = *src;
166167
src += step;
@@ -202,8 +203,14 @@ static Py_ssize_t _fix_index(Py_ssize_t i, Py_ssize_t len) {
202203
return result;
203204
}
204205

205-
PyDoc_STRVAR(count__doc__, "");
206-
static PyObject *cstring_count(PyObject *self, PyObject *args) {
206+
struct _substr_params {
207+
const char *start;
208+
const char *end;
209+
const char *substr;
210+
Py_ssize_t substr_len;
211+
};
212+
213+
static struct _substr_params *_parse_substr_args(PyObject *self, PyObject *args, struct _substr_params *params) {
207214
PyObject *substr_obj;
208215
Py_ssize_t start = 0;
209216
Py_ssize_t end = PY_SSIZE_T_MAX;
@@ -219,12 +226,27 @@ static PyObject *cstring_count(PyObject *self, PyObject *args) {
219226
start = _fix_index(start, cstring_len(self));
220227
end = _fix_index(end, cstring_len(self));
221228

222-
char *p = &CSTRING_VALUE(self)[start];
229+
params->start = CSTRING_VALUE_AT(self, start);
230+
params->end = CSTRING_VALUE_AT(self, end);
231+
params->substr = substr;
232+
params->substr_len = substr_len;
233+
234+
return params;
235+
}
236+
237+
PyDoc_STRVAR(count__doc__, "");
238+
static PyObject *cstring_count(PyObject *self, PyObject *args) {
239+
struct _substr_params params;
240+
241+
if(!_parse_substr_args(self, args, &params))
242+
return NULL;
243+
244+
char *p = params.start;
223245
long result = 0;
224-
while((p = strstr(p, substr)) != NULL) {
246+
while((p = strstr(p, params.substr)) != NULL) {
225247
++result;
226-
p += substr_len;
227-
if(p >= &CSTRING_VALUE(self)[end])
248+
p += params.substr_len;
249+
if(p >= params.end)
228250
break;
229251
}
230252

@@ -233,30 +255,18 @@ static PyObject *cstring_count(PyObject *self, PyObject *args) {
233255

234256
PyDoc_STRVAR(find__doc__, "");
235257
PyObject *cstring_find(PyObject *self, PyObject *args) {
236-
PyObject *substr_obj;
237-
Py_ssize_t start = 0;
238-
Py_ssize_t end = PY_SSIZE_T_MAX;
258+
struct _substr_params params;
239259

240-
if(!PyArg_ParseTuple(args, "O|nn", &substr_obj, &start, &end))
260+
if(!_parse_substr_args(self, args, &params))
241261
return NULL;
242262

243-
Py_ssize_t substr_len;
244-
const char *substr = _obj_to_utf8(substr_obj, &substr_len);
245-
if(!substr)
246-
return NULL;
247-
248-
start = _fix_index(start, cstring_len(self));
249-
end = _fix_index(end, cstring_len(self));
250-
251-
char *p = strstr(&CSTRING_VALUE(self)[start], substr);
263+
char *p = strstr(params.start, params.substr);
252264
if(!p)
253265
return PyLong_FromLong(-1);
254-
255-
Py_ssize_t result = p - CSTRING_VALUE(self);
256-
if(result + substr_len > end)
266+
if(p + params.substr_len > params.end)
257267
return PyLong_FromLong(-1);
258268

259-
return PyLong_FromSsize_t(result);
269+
return PyLong_FromSsize_t(p - CSTRING_VALUE(self));
260270
}
261271

262272
static PySequenceMethods cstring_as_sequence = {

0 commit comments

Comments
 (0)