Added lstrip() and rstrip().
Extended split() (and hence splitfields(), which is the same function)
to support an optional third parameter giving the maximum number of
delimiters to parse.
diff --git a/Modules/stropmodule.c b/Modules/stropmodule.c
index 7e44e0e..171b712 100644
--- a/Modules/stropmodule.c
+++ b/Modules/stropmodule.c
@@ -33,13 +33,23 @@
#include <errno.h>
+/* The lstrip(), rstrip() and strip() functions are implemented
+ in do_strip(), which uses an additional parameter to indicate what
+ type of strip should occur. */
+
+#define LEFTSTRIP 0
+#define RIGHTSTRIP 1
+#define BOTHSTRIP 2
+
static object *
-split_whitespace(s, len)
+split_whitespace(s, len, maxsplit)
char *s;
int len;
+ int maxsplit;
{
int i, j, err;
+ int countsplit;
object *list, *item;
list = newlistobject(0);
@@ -47,6 +57,8 @@
return NULL;
i = 0;
+ countsplit = 0;
+
while (i < len) {
while (i < len && isspace(Py_CHARMASK(s[i]))) {
i = i+1;
@@ -67,6 +79,23 @@
DECREF(list);
return NULL;
}
+
+ countsplit++;
+ if (maxsplit && (countsplit >= maxsplit)) {
+ item = newsizedstringobject(s+i, (int)(len - i));
+ if (item == NULL) {
+ DECREF(list);
+ return NULL;
+ }
+ err = addlistitem(list, item);
+ DECREF(item);
+ if (err < 0) {
+ DECREF(list);
+ return NULL;
+ }
+ i = len;
+ }
+
}
}
@@ -80,15 +109,18 @@
object *args;
{
int len, n, i, j, err;
+ int splitcount, maxsplit;
char *s, *sub;
object *list, *item;
sub = NULL;
n = 0;
- if (!newgetargs(args, "s#|z#", &s, &len, &sub, &n))
+ splitcount = 0;
+ maxsplit = 0;
+ if (!newgetargs(args, "s#|z#i", &s, &len, &sub, &n, &maxsplit))
return NULL;
if (sub == NULL)
- return split_whitespace(s, len);
+ return split_whitespace(s, len, maxsplit);
if (n == 0) {
err_setstr(ValueError, "empty separator");
return NULL;
@@ -109,6 +141,9 @@
if (err < 0)
goto fail;
i = j = i + n;
+ splitcount++;
+ if (maxsplit && (splitcount >= maxsplit))
+ break;
}
else
i++;
@@ -265,6 +300,42 @@
return newintobject(-1L);
}
+static object *
+do_strip(args, striptype)
+ object *args;
+ int striptype;
+{
+ char *s;
+ int len, i, j;
+
+
+ if (!getargs(args, "s#", &s, &len))
+ return NULL;
+
+ i = 0;
+ if (striptype != RIGHTSTRIP) {
+ while (i < len && isspace(Py_CHARMASK(s[i]))) {
+ i++;
+ }
+ }
+
+
+ j = len;
+ if (striptype != LEFTSTRIP) {
+ do {
+ j--;
+ } while (j >= i && isspace(Py_CHARMASK(s[j])));
+ j++;
+ }
+
+ if (i == 0 && j == len) {
+ INCREF(args);
+ return args;
+ }
+ else
+ return newsizedstringobject(s+i, j-i);
+}
+
static object *
strop_strip(self, args)
@@ -274,26 +345,29 @@
char *s;
int len, i, j;
- if (!getargs(args, "s#", &s, &len))
- return NULL;
+ return do_strip(args, BOTHSTRIP);
+}
- i = 0;
- while (i < len && isspace(Py_CHARMASK(s[i]))) {
- i++;
- }
+static object *
+strop_lstrip(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ char *s;
+ int len, i, j;
- j = len;
- do {
- j--;
- } while (j >= i && isspace(Py_CHARMASK(s[j])));
- j++;
+ return do_strip(args, LEFTSTRIP);
+}
- if (i == 0 && j == len) {
- INCREF(args);
- return args;
- }
- else
- return newsizedstringobject(s+i, j-i);
+static object *
+strop_rstrip(self, args)
+ object *self; /* Not used */
+ object *args;
+{
+ char *s;
+ int len, i, j;
+
+ return do_strip(args, RIGHTSTRIP);
}
@@ -557,7 +631,7 @@
if (PyTuple_Size(args)!=0) {
if (!PyArg_ParseTuple(args, "s#s#", &from, &fromlen,
- &to, &tolen))
+ &to, &tolen))
return NULL;
}
@@ -604,7 +678,7 @@
if (result == NULL)
return NULL;
output_start = output = PyString_AsString(result);
- if (delete!=NULL && dellen!=0) {
+ if (delete!=NULL && dellen!=0) {
for (i = 0; i < inlen; i++) {
int c = Py_CHARMASK(*input++);
if (trans_table[c]!=-1)
@@ -614,11 +688,11 @@
if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
return NULL;
} else {
- /* If no deletions are required, use a faster loop */
+ /* If no deletions are required, use a faster loop */
for (i = 0; i < inlen; i++) {
int c = Py_CHARMASK(*input++);
- *output++ = (char)trans_table[c];
- }
+ *output++ = (char)trans_table[c];
+ }
}
return result;
}
@@ -634,8 +708,10 @@
{"find", strop_find},
{"join", strop_joinfields, 1},
{"joinfields", strop_joinfields, 1},
+ {"lstrip", strop_lstrip},
{"lower", strop_lower},
{"rfind", strop_rfind},
+ {"rstrip", strop_rstrip},
{"split", strop_splitfields, 1},
{"splitfields", strop_splitfields, 1},
{"strip", strop_strip},