summaryrefslogtreecommitdiff
path: root/Modules/stropmodule.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1997-01-06 16:50:09 +0000
committerGuido van Rossum <guido@python.org>1997-01-06 16:50:09 +0000
commitb9d24de03b2198a536e57840cb0850f62f5d29b3 (patch)
tree0cd822193a35496d6befb1e012be88d5219b6184 /Modules/stropmodule.c
parent61f544690ff9f39f17a1b5edba4957aff3ee65d8 (diff)
downloadcpython-b9d24de03b2198a536e57840cb0850f62f5d29b3.tar.gz
Rewrote translate() as follows:
- 'delete' is a C++ keyword; use 'del_table' instead - apply Py_CHARMASK() to del_table[i] before using it as an index *** this fixes a bug that was just reported on the list *** - if the translation didn't make any changes, INCREF and return the original string - when del_table is empty or omitted, don't copy the translation table to a table of ints (should be a bit faster) Rewrote maketrans() to avoid copying the table (2-3% faster).
Diffstat (limited to 'Modules/stropmodule.c')
-rw-r--r--Modules/stropmodule.c80
1 files changed, 52 insertions, 28 deletions
diff --git a/Modules/stropmodule.c b/Modules/stropmodule.c
index d84b55f55c..9251b034b6 100644
--- a/Modules/stropmodule.c
+++ b/Modules/stropmodule.c
@@ -661,8 +661,9 @@ strop_maketrans(self, args)
PyObject *self; /* Not used */
PyObject *args;
{
- unsigned char c[256], *from=NULL, *to=NULL;
+ unsigned char *c, *from=NULL, *to=NULL;
int i, fromlen=0, tolen=0;
+ PyObject *result;
if (!PyArg_ParseTuple(args, "s#s#", &from, &fromlen, &to, &tolen))
return NULL;
@@ -672,12 +673,17 @@ strop_maketrans(self, args)
"maketrans arguments must have same length");
return NULL;
}
+
+ result = PyString_FromStringAndSize((char *)NULL, 256);
+ if (result == NULL)
+ return NULL;
+ c = (unsigned char *) PyString_AS_STRING((PyStringObject *)result);
for (i = 0; i < 256; i++)
c[i]=(unsigned char)i;
for (i = 0; i < fromlen; i++)
c[from[i]]=to[i];
- return PyString_FromStringAndSize((char *)c, 256);
+ return result;
}
@@ -686,48 +692,66 @@ strop_translate(self, args)
PyObject *self;
PyObject *args;
{
- char *input, *table, *output, *output_start, *delete=NULL;
+ register char *input, *table, *output;
+ register int i, c, changed = 0;
+ PyObject *input_obj;
+ char *table1, *output_start, *del_table=NULL;
int inlen, tablen, dellen = 0;
PyObject *result;
- int i, trans_table[256];
+ int trans_table[256];
- if (!PyArg_ParseTuple(args, "s#s#|s#", &input, &inlen,
- &table, &tablen, &delete, &dellen))
+ if (!PyArg_ParseTuple(args, "Ss#|s#", &input_obj,
+ &table1, &tablen, &del_table, &dellen))
return NULL;
if (tablen != 256) {
PyErr_SetString(PyExc_ValueError,
"translation table must be 256 characters long");
return NULL;
}
- for (i = 0; i < 256; i++)
- trans_table[i] = Py_CHARMASK(table[i]);
-
- if (delete != NULL) {
- for (i = 0; i < dellen; i++)
- trans_table[(int)delete[i]] = -1;
- }
+ table = table1;
+ inlen = PyString_Size(input_obj);
result = PyString_FromStringAndSize((char *)NULL, inlen);
if (result == NULL)
return NULL;
output_start = output = PyString_AsString(result);
-
- if (delete != NULL && dellen != 0) {
- for (i = 0; i < inlen; i++) {
- int c = Py_CHARMASK(*input++);
- if (trans_table[c] != -1)
- *output++ = (char)trans_table[c];
- }
- /* Fix the size of the resulting string */
- if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
- return NULL;
- } else {
- /* 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];
+ input = PyString_AsString(input_obj);
+
+ if (dellen == 0) {
+ /* If no deletions are required, use faster code */
+ for (i = inlen; --i >= 0; ) {
+ c = Py_CHARMASK(*input++);
+ if (Py_CHARMASK((*output++ = table[c])) != c)
+ changed = 1;
}
+ if (changed)
+ return result;
+ Py_DECREF(result);
+ Py_INCREF(input_obj);
+ return input_obj;
+ }
+
+ for (i = 0; i < 256; i++)
+ trans_table[i] = Py_CHARMASK(table[i]);
+
+ for (i = 0; i < dellen; i++)
+ trans_table[Py_CHARMASK(del_table[i])] = -1;
+
+ for (i = inlen; --i >= 0; ) {
+ c = Py_CHARMASK(*input++);
+ if (trans_table[c] != -1)
+ if (Py_CHARMASK(*output++ = (char)trans_table[c]) == c)
+ continue;
+ changed = 1;
+ }
+ if (!changed) {
+ Py_DECREF(result);
+ Py_INCREF(input_obj);
+ return input_obj;
}
+ /* Fix the size of the resulting string */
+ if (inlen > 0 &&_PyString_Resize(&result, output-output_start))
+ return NULL;
return result;
}