test('startswith', 'helloworld', 1, 'lowo', 3, 7)
test('startswith', 'helloworld', 0, 'lowo', 3, 6)
+ # test negative indices in startswith
+ test('startswith', 'hello', 1, 'he', 0, -1)
+ test('startswith', 'hello', 1, 'he', -53, -1)
+ test('startswith', 'hello', 0, 'hello', 0, -1)
+ test('startswith', 'hello', 0, 'hello world', -1, -10)
+ test('startswith', 'hello', 0, 'ello', -5)
+ test('startswith', 'hello', 1, 'ello', -4)
+ test('startswith', 'hello', 0, 'o', -2)
+ test('startswith', 'hello', 1, 'o', -1)
+ test('startswith', 'hello', 1, '', -3, -3)
+ test('startswith', 'hello', 0, 'lo', -9)
+
test('endswith', 'hello', 1, 'lo')
test('endswith', 'hello', 0, 'he')
test('endswith', 'hello', 1, '')
test('endswith', 'ab', 0, 'ab', 0, 1)
test('endswith', 'ab', 0, 'ab', 0, 0)
+ # test negative indices in endswith
+ test('endswith', 'hello', 1, 'lo', -2)
+ test('endswith', 'hello', 0, 'he', -2)
+ test('endswith', 'hello', 1, '', -3, -3)
+ test('endswith', 'hello', 0, 'hello world', -10, -2)
+ test('endswith', 'helloworld', 0, 'worl', -6)
+ test('endswith', 'helloworld', 1, 'worl', -5, -1)
+ test('endswith', 'helloworld', 1, 'worl', -5, 9)
+ test('endswith', 'helloworld', 1, 'world', -7, 12)
+ test('endswith', 'helloworld', 1, 'lowo', -99, -3)
+ test('endswith', 'helloworld', 1, 'lowo', -8, -3)
+ test('endswith', 'helloworld', 1, 'lowo', -7, -3)
+ test('endswith', 'helloworld', 0, 'lowo', 3, -4)
+ test('endswith', 'helloworld', 0, 'lowo', -8, -2)
+
test('zfill', '123', '123', 2)
test('zfill', '123', '123', 3)
test('zfill', '123', '0123', 4)
return string_join((PyStringObject *)sep, x);
}
+static void
+string_adjust_indices(int *start, int *end, int len)
+{
+ if (*end > len)
+ *end = len;
+ else if (*end < 0)
+ *end += len;
+ if (*end < 0)
+ *end = 0;
+ if (*start < 0)
+ *start += len;
+ if (*start < 0)
+ *start = 0;
+}
+
static long
string_find_internal(PyStringObject *self, PyObject *args, int dir)
{
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
return -2;
- if (last > len)
- last = len;
- if (last < 0)
- last += len;
- if (last < 0)
- last = 0;
- if (i < 0)
- i += len;
- if (i < 0)
- i = 0;
+ string_adjust_indices(&i, &last, len);
if (dir > 0) {
if (n == 0 && i <= last)
else if (PyObject_AsCharBuffer(subobj, &sub, &n))
return NULL;
- if (last > len)
- last = len;
- if (last < 0)
- last += len;
- if (last < 0)
- last = 0;
- if (i < 0)
- i += len;
- if (i < 0)
- i = 0;
+ string_adjust_indices(&i, &last, len);
+
m = last + 1 - n;
if (n == 0)
return PyInt_FromLong((long) (m-i));
const char* prefix;
int plen;
int start = 0;
- int end = -1;
+ int end = INT_MAX;
PyObject *subobj;
if (!PyArg_ParseTuple(args, "O|O&O&:startswith", &subobj,
else if (PyObject_AsCharBuffer(subobj, &prefix, &plen))
return NULL;
- /* adopt Java semantics for index out of range. it is legal for
- * offset to be == plen, but this only returns true if prefix is
- * the empty string.
- */
- if (start < 0 || start+plen > len)
+ string_adjust_indices(&start, &end, len);
+
+ if (start+plen > len)
return PyBool_FromLong(0);
- if (!memcmp(str+start, prefix, plen)) {
- /* did the match end after the specified end? */
- if (end < 0)
- return PyBool_FromLong(1);
- else if (end - start < plen)
- return PyBool_FromLong(0);
- else
- return PyBool_FromLong(1);
- }
- else return PyBool_FromLong(0);
+ if (end-start >= plen)
+ return PyBool_FromLong(!memcmp(str+start, prefix, plen));
+ else
+ return PyBool_FromLong(0);
}
const char* suffix;
int slen;
int start = 0;
- int end = -1;
- int lower, upper;
+ int end = INT_MAX;
PyObject *subobj;
if (!PyArg_ParseTuple(args, "O|O&O&:endswith", &subobj,
else if (PyObject_AsCharBuffer(subobj, &suffix, &slen))
return NULL;
- if (start < 0 || start > len || slen > len)
- return PyBool_FromLong(0);
+ string_adjust_indices(&start, &end, len);
- upper = (end >= 0 && end <= len) ? end : len;
- lower = (upper - slen) > start ? (upper - slen) : start;
+ if (end-start < slen || start > len)
+ return PyBool_FromLong(0);
- if (upper-lower >= slen && !memcmp(str+lower, suffix, slen))
- return PyBool_FromLong(1);
- else return PyBool_FromLong(0);
+ if (end-slen > start)
+ start = end - slen;
+ if (end-start >= slen)
+ return PyBool_FromLong(!memcmp(str+start, suffix, slen));
+ else
+ return PyBool_FromLong(0);
}