summaryrefslogtreecommitdiffstats
path: root/Objects/stringobject.c
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2001-09-12 02:18:30 (GMT)
committerTim Peters <tim.peters@gmail.com>2001-09-12 02:18:30 (GMT)
commit8fa5dd0601ed48c534be96e6f1f3fe54d023d0a0 (patch)
tree1cbc102532b6b71ed909390912cd806741a0444b /Objects/stringobject.c
parentee0fe0b7433a20ab52d033363179d966ef789aef (diff)
downloadcpython-8fa5dd0601ed48c534be96e6f1f3fe54d023d0a0.zip
cpython-8fa5dd0601ed48c534be96e6f1f3fe54d023d0a0.tar.gz
cpython-8fa5dd0601ed48c534be96e6f1f3fe54d023d0a0.tar.bz2
More bug 460020: lots of string optimizations inhibited for string
subclasses, all "the usual" ones (slicing etc), plus replace, translate, ljust, rjust, center and strip. I don't know how to be sure they've all been caught. Question: Should we complain if someone tries to intern an instance of a string subclass? I hate to slow any code on those paths.
Diffstat (limited to 'Objects/stringobject.c')
-rw-r--r--Objects/stringobject.c125
1 files changed, 46 insertions, 79 deletions
diff --git a/Objects/stringobject.c b/Objects/stringobject.c
index 9c873ec..b220859 100644
--- a/Objects/stringobject.c
+++ b/Objects/stringobject.c
@@ -673,11 +673,12 @@ string_concat(register PyStringObject *a, register PyObject *bb)
}
#define b ((PyStringObject *)bb)
/* Optimize cases with empty left or right operand */
- if (a->ob_size == 0) {
- Py_INCREF(bb);
- return bb;
- }
- if (b->ob_size == 0) {
+ if ((a->ob_size == 0 || b->ob_size == 0) &&
+ PyString_CheckExact(a) && PyString_CheckExact(b)) {
+ if (a->ob_size == 0) {
+ Py_INCREF(bb);
+ return bb;
+ }
Py_INCREF(a);
return (PyObject *)a;
}
@@ -719,7 +720,7 @@ string_repeat(register PyStringObject *a, register int n)
"repeated string is too long");
return NULL;
}
- if (size == a->ob_size) {
+ if (size == a->ob_size && PyString_CheckExact(a)) {
Py_INCREF(a);
return (PyObject *)a;
}
@@ -759,7 +760,8 @@ string_slice(register PyStringObject *a, register int i, register int j)
j = 0; /* Avoid signed/unsigned bug in next line */
if (j > a->ob_size)
j = a->ob_size;
- if (i == 0 && j == a->ob_size) { /* It's the same as a */
+ if (i == 0 && j == a->ob_size && PyString_CheckExact(a)) {
+ /* It's the same as a */
Py_INCREF(a);
return (PyObject *)a;
}
@@ -1378,7 +1380,7 @@ do_strip(PyStringObject *self, int striptype)
j++;
}
- if (i == 0 && j == len) {
+ if (i == 0 && j == len && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*)self;
}
@@ -1735,7 +1737,7 @@ string_translate(PyStringObject *self, PyObject *args)
if (Py_CHARMASK((*output++ = table[c])) != c)
changed = 1;
}
- if (changed)
+ if (changed || !PyString_CheckExact(input_obj))
return result;
Py_DECREF(result);
Py_INCREF(input_obj);
@@ -1755,7 +1757,7 @@ string_translate(PyStringObject *self, PyObject *args)
continue;
changed = 1;
}
- if (!changed) {
+ if (!changed && PyString_CheckExact(input_obj)) {
Py_DECREF(result);
Py_INCREF(input_obj);
return input_obj;
@@ -1917,7 +1919,8 @@ string_replace(PyStringObject *self, PyObject *args)
{
const char *str = PyString_AS_STRING(self), *sub, *repl;
char *new_s;
- int len = PyString_GET_SIZE(self), sub_len, repl_len, out_len;
+ const int len = PyString_GET_SIZE(self);
+ int sub_len, repl_len, out_len;
int count = -1;
PyObject *new;
PyObject *subobj, *replobj;
@@ -1960,9 +1963,16 @@ string_replace(PyStringObject *self, PyObject *args)
return NULL;
}
if (out_len == -1) {
- /* we're returning another reference to self */
- new = (PyObject*)self;
- Py_INCREF(new);
+ if (PyString_CheckExact(self)) {
+ /* we're returning another reference to self */
+ new = (PyObject*)self;
+ Py_INCREF(new);
+ }
+ else {
+ new = PyString_FromStringAndSize(str, len);
+ if (new == NULL)
+ return NULL;
+ }
}
else {
new = PyString_FromStringAndSize(new_s, out_len);
@@ -2182,11 +2192,8 @@ string_expandtabs(PyStringObject *self, PyObject *args)
return u;
}
-static
-PyObject *pad(PyStringObject *self,
- int left,
- int right,
- char fill)
+static PyObject *
+pad(PyStringObject *self, int left, int right, char fill)
{
PyObject *u;
@@ -2195,7 +2202,7 @@ PyObject *pad(PyStringObject *self,
if (right < 0)
right = 0;
- if (left == 0 && right == 0) {
+ if (left == 0 && right == 0 && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject *)self;
}
@@ -2217,10 +2224,10 @@ PyObject *pad(PyStringObject *self,
}
static char ljust__doc__[] =
-"S.ljust(width) -> string\n\
-\n\
-Return S left justified in a string of length width. Padding is\n\
-done using spaces.";
+"S.ljust(width) -> string\n"
+"\n"
+"Return S left justified in a string of length width. Padding is\n"
+"done using spaces.";
static PyObject *
string_ljust(PyStringObject *self, PyObject *args)
@@ -2229,7 +2236,7 @@ string_ljust(PyStringObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i:ljust", &width))
return NULL;
- if (PyString_GET_SIZE(self) >= width) {
+ if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*) self;
}
@@ -2239,10 +2246,10 @@ string_ljust(PyStringObject *self, PyObject *args)
static char rjust__doc__[] =
-"S.rjust(width) -> string\n\
-\n\
-Return S right justified in a string of length width. Padding is\n\
-done using spaces.";
+"S.rjust(width) -> string\n"
+"\n"
+"Return S right justified in a string of length width. Padding is\n"
+"done using spaces.";
static PyObject *
string_rjust(PyStringObject *self, PyObject *args)
@@ -2251,7 +2258,7 @@ string_rjust(PyStringObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i:rjust", &width))
return NULL;
- if (PyString_GET_SIZE(self) >= width) {
+ if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*) self;
}
@@ -2261,10 +2268,10 @@ string_rjust(PyStringObject *self, PyObject *args)
static char center__doc__[] =
-"S.center(width) -> string\n\
-\n\
-Return S centered in a string of length width. Padding is done\n\
-using spaces.";
+"S.center(width) -> string\n"
+"\n"
+"Return S centered in a string of length width. Padding is done\n"
+"using spaces.";
static PyObject *
string_center(PyStringObject *self, PyObject *args)
@@ -2275,7 +2282,7 @@ string_center(PyStringObject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "i:center", &width))
return NULL;
- if (PyString_GET_SIZE(self) >= width) {
+ if (PyString_GET_SIZE(self) >= width && PyString_CheckExact(self)) {
Py_INCREF(self);
return (PyObject*) self;
}
@@ -2286,51 +2293,11 @@ string_center(PyStringObject *self, PyObject *args)
return pad(self, left, marg - left, ' ');
}
-#if 0
-static char zfill__doc__[] =
-"S.zfill(width) -> string\n\
-\n\
-Pad a numeric string x with zeros on the left, to fill a field\n\
-of the specified width. The string x is never truncated.";
-
-static PyObject *
-string_zfill(PyStringObject *self, PyObject *args)
-{
- int fill;
- PyObject *u;
- char *str;
-
- int width;
- if (!PyArg_ParseTuple(args, "i:zfill", &width))
- return NULL;
-
- if (PyString_GET_SIZE(self) >= width) {
- Py_INCREF(self);
- return (PyObject*) self;
- }
-
- fill = width - PyString_GET_SIZE(self);
-
- u = pad(self, fill, 0, '0');
- if (u == NULL)
- return NULL;
-
- str = PyString_AS_STRING(u);
- if (str[fill] == '+' || str[fill] == '-') {
- /* move sign to beginning of string */
- str[0] = str[fill];
- str[fill] = '0';
- }
-
- return u;
-}
-#endif
-
static char isspace__doc__[] =
-"S.isspace() -> int\n\
-\n\
-Return 1 if there are only whitespace characters in S,\n\
-0 otherwise.";
+"S.isspace() -> int\n"
+"\n"
+"Return 1 if there are only whitespace characters in S,\n"
+"0 otherwise.";
static PyObject*
string_isspace(PyStringObject *self)