diff options
author | Guido van Rossum <guido@python.org> | 1997-01-06 16:50:09 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1997-01-06 16:50:09 (GMT) |
commit | e0548b8da7a8f45d0f86d14864914357535e2cb6 (patch) | |
tree | 49ae44a0177445c596bbf8b75888fafe95fa6e5c /Modules | |
parent | 04d2d15b6bd799e79a1d200ddae133531fdaf561 (diff) | |
download | cpython-e0548b8da7a8f45d0f86d14864914357535e2cb6.zip cpython-e0548b8da7a8f45d0f86d14864914357535e2cb6.tar.gz cpython-e0548b8da7a8f45d0f86d14864914357535e2cb6.tar.bz2 |
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')
-rw-r--r-- | Modules/stropmodule.c | 80 |
1 files changed, 52 insertions, 28 deletions
diff --git a/Modules/stropmodule.c b/Modules/stropmodule.c index d84b55f..9251b03 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; } |