Commit 4945dd64 authored by Kevin Modzelewski's avatar Kevin Modzelewski

str.expandtabs

parent 82dd179e
......@@ -2142,6 +2142,82 @@ extern "C" void PyString_ConcatAndDel(register PyObject** pv, register PyObject*
PyString_Concat(pv, w);
}
static PyObject* string_expandtabs(PyStringObject* self, PyObject* args) noexcept {
const char* e, *p, *qe;
char* q;
Py_ssize_t i, j, incr;
PyObject* u;
int tabsize = 8;
if (!PyArg_ParseTuple(args, "|i:expandtabs", &tabsize))
return NULL;
/* First pass: determine size of output string */
i = 0; /* chars up to and including most recent \n or \r */
j = 0; /* chars since most recent \n or \r (use in tab calculations) */
e = PyString_AS_STRING(self) + PyString_GET_SIZE(self); /* end of input */
for (p = PyString_AS_STRING(self); p < e; p++) {
if (*p == '\t') {
if (tabsize > 0) {
incr = tabsize - (j % tabsize);
if (j > PY_SSIZE_T_MAX - incr)
goto overflow1;
j += incr;
}
} else {
if (j > PY_SSIZE_T_MAX - 1)
goto overflow1;
j++;
if (*p == '\n' || *p == '\r') {
if (i > PY_SSIZE_T_MAX - j)
goto overflow1;
i += j;
j = 0;
}
}
}
if (i > PY_SSIZE_T_MAX - j)
goto overflow1;
/* Second pass: create output string and fill it */
u = PyString_FromStringAndSize(NULL, i + j);
if (!u)
return NULL;
j = 0; /* same as in first pass */
q = PyString_AS_STRING(u); /* next output char */
qe = PyString_AS_STRING(u) + PyString_GET_SIZE(u); /* end of output */
for (p = PyString_AS_STRING(self); p < e; p++) {
if (*p == '\t') {
if (tabsize > 0) {
i = tabsize - (j % tabsize);
j += i;
while (i--) {
if (q >= qe)
goto overflow2;
*q++ = ' ';
}
}
} else {
if (q >= qe)
goto overflow2;
*q++ = *p;
j++;
if (*p == '\n' || *p == '\r')
j = 0;
}
}
return u;
overflow2:
Py_DECREF(u);
overflow1:
PyErr_SetString(PyExc_OverflowError, "new string is too long");
return NULL;
}
static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, const void** ptr) noexcept {
RELEASE_ASSERT(index == 0, "");
......@@ -2194,6 +2270,7 @@ static PyMethodDef string_methods[] = {
{ "rsplit", (PyCFunction)string_rsplit, METH_VARARGS, NULL },
{ "find", (PyCFunction)string_find, METH_VARARGS, NULL },
{ "rfind", (PyCFunction)string_rfind, METH_VARARGS, NULL },
{ "expandtabs", (PyCFunction)string_expandtabs, METH_VARARGS, NULL },
};
void setupStr() {
......
......@@ -136,3 +136,6 @@ try:
print "hello world".index("goodbye")
except:
print "threw exception"
print repr("hello\tworld\t".expandtabs())
print repr("hello\tworld\t".expandtabs(12))
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment