Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 59b9634

Browse files
committed
Implement split method
1 parent 62365a8 commit 59b9634

File tree

2 files changed

+108
-1
lines changed

2 files changed

+108
-1
lines changed

src/cstring.c

Lines changed: 96 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,101 @@ PyObject *cstring_rindex(PyObject *self, PyObject *args) {
655655
return PyLong_FromSsize_t(p - CSTRING_VALUE(self));
656656
}
657657

658+
PyObject *_cstring_split_on_chars(PyObject *self, const char seps[], Py_ssize_t maxsplit) {
659+
if(maxsplit < 0)
660+
maxsplit = PY_SSIZE_T_MAX;
661+
662+
const char *start = CSTRING_VALUE(self);
663+
664+
PyObject *list = PyList_New(0);
665+
if(!list)
666+
return NULL;
667+
668+
while(*start) {
669+
const char *end = start;
670+
while(*end && !strchr(seps, *end))
671+
++end;
672+
673+
PyObject *new = _cstring_new(Py_TYPE(self), start, end - start);
674+
if(!new)
675+
goto fail;
676+
PyList_Append(list, new);
677+
Py_DECREF(new);
678+
679+
const char *skip = end + 1;
680+
while(*skip && strchr(seps, *skip))
681+
++skip;
682+
start = skip;
683+
684+
if(PyList_GET_SIZE(list) + 1 > maxsplit) {
685+
PyObject *new = _cstring_new(Py_TYPE(self), start, strlen(start));
686+
if(!new)
687+
goto fail;
688+
PyList_Append(list, new);
689+
Py_DECREF(new);
690+
break;
691+
}
692+
}
693+
694+
return list;
695+
696+
fail:
697+
Py_DECREF(list);
698+
return NULL;
699+
}
700+
701+
PyObject *_cstring_split_on_cstring(PyObject *self, PyObject *sepobj, Py_ssize_t maxsplit) {
702+
if(!_ensure_cstring(sepobj))
703+
return NULL;
704+
705+
if(maxsplit < 0)
706+
maxsplit = PY_SSIZE_T_MAX;
707+
708+
PyObject *list = PyList_New(0);
709+
if(!list)
710+
return NULL;
711+
712+
const char *sep = CSTRING_VALUE(sepobj);
713+
const char *s = CSTRING_VALUE(self);
714+
for(;;) {
715+
const char *e = strstr(s, sep);
716+
if(!e)
717+
break;
718+
PyObject *new = _cstring_new(Py_TYPE(self), s, e - s);
719+
if(!new)
720+
goto fail;
721+
PyList_Append(list, new);
722+
Py_DECREF(new);
723+
s = e + strlen(sep);
724+
if(PyList_GET_SIZE(list) + 1 > maxsplit)
725+
break;
726+
}
727+
728+
PyObject *new = _cstring_new(Py_TYPE(self), s, strlen(s));
729+
if(!new)
730+
goto fail;
731+
PyList_Append(list, new);
732+
733+
return list;
734+
735+
fail:
736+
Py_DECREF(list);
737+
return NULL;
738+
}
739+
740+
PyDoc_STRVAR(split__doc__, "");
741+
PyObject *cstring_split(PyObject *self, PyObject *args, PyObject *kwargs) {
742+
PyObject *sepobj = Py_None;
743+
int maxsplit = -1;
744+
char *kwlist[] = {"sep", "maxsplit", NULL};
745+
if(!PyArg_ParseTupleAndKeywords(args, kwargs, "|Oi", kwlist, &sepobj, &maxsplit))
746+
return NULL;
747+
748+
return (sepobj == Py_None)
749+
? _cstring_split_on_chars(self, WHITESPACE_CHARS, maxsplit)
750+
: _cstring_split_on_cstring(self, sepobj, maxsplit);
751+
}
752+
658753
PyDoc_STRVAR(startswith__doc__, "");
659754
PyObject *cstring_startswith(PyObject *self, PyObject *args) {
660755
struct _substr_params params;
@@ -821,7 +916,7 @@ static PyMethodDef cstring_methods[] = {
821916
{"rpartition", cstring_rpartition, METH_O, rpartition__doc__},
822917
/* TODO: rsplit */
823918
{"rstrip", cstring_rstrip, METH_VARARGS, rstrip__doc__},
824-
/* TODO: split */
919+
{"split", (PyCFunction)cstring_split, METH_VARARGS | METH_KEYWORDS, split__doc__},
825920
/* TODO: splitlines */
826921
{"startswith", cstring_startswith, METH_VARARGS, startswith__doc__},
827922
{"strip", cstring_strip, METH_VARARGS, strip__doc__},

test/test_methods.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,18 @@ def test_rpartition_sep_not_found():
239239
assert target.rpartition(cstring(': ')) == result
240240

241241

242+
def test_split():
243+
assert cstring('hello, world').split(cstring(', ')) == [cstring('hello'), cstring('world')]
244+
assert cstring('1,2,3').split(cstring(',')) == [
245+
cstring('1'), cstring('2'), cstring('3')]
246+
assert cstring('hello, world').split() == [cstring('hello,'), cstring('world')]
247+
assert cstring('hello\t \n world').split() == [cstring('hello'), cstring('world')]
248+
assert cstring('1,2,3').split(cstring(','), maxsplit=1) == [
249+
cstring('1'), cstring('2,3')]
250+
assert cstring('1 2 3').split(maxsplit=1) == [
251+
cstring('1'), cstring('2 3')]
252+
253+
242254
def test_startswith():
243255
target = cstring('hello, world')
244256
assert target.startswith('hello,') is True

0 commit comments

Comments
 (0)