mirror of
https://github.com/python/cpython.git
synced 2025-09-19 15:10:58 +00:00
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).
This commit is contained in:
parent
04d2d15b6b
commit
e0548b8da7
1 changed files with 51 additions and 27 deletions
|
@ -661,8 +661,9 @@ strop_maketrans(self, args)
|
||||||
PyObject *self; /* Not used */
|
PyObject *self; /* Not used */
|
||||||
PyObject *args;
|
PyObject *args;
|
||||||
{
|
{
|
||||||
unsigned char c[256], *from=NULL, *to=NULL;
|
unsigned char *c, *from=NULL, *to=NULL;
|
||||||
int i, fromlen=0, tolen=0;
|
int i, fromlen=0, tolen=0;
|
||||||
|
PyObject *result;
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#s#", &from, &fromlen, &to, &tolen))
|
if (!PyArg_ParseTuple(args, "s#s#", &from, &fromlen, &to, &tolen))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -672,12 +673,17 @@ strop_maketrans(self, args)
|
||||||
"maketrans arguments must have same length");
|
"maketrans arguments must have same length");
|
||||||
return NULL;
|
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++)
|
for (i = 0; i < 256; i++)
|
||||||
c[i]=(unsigned char)i;
|
c[i]=(unsigned char)i;
|
||||||
for (i = 0; i < fromlen; i++)
|
for (i = 0; i < fromlen; i++)
|
||||||
c[from[i]]=to[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 *self;
|
||||||
PyObject *args;
|
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;
|
int inlen, tablen, dellen = 0;
|
||||||
PyObject *result;
|
PyObject *result;
|
||||||
int i, trans_table[256];
|
int trans_table[256];
|
||||||
|
|
||||||
if (!PyArg_ParseTuple(args, "s#s#|s#", &input, &inlen,
|
if (!PyArg_ParseTuple(args, "Ss#|s#", &input_obj,
|
||||||
&table, &tablen, &delete, &dellen))
|
&table1, &tablen, &del_table, &dellen))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (tablen != 256) {
|
if (tablen != 256) {
|
||||||
PyErr_SetString(PyExc_ValueError,
|
PyErr_SetString(PyExc_ValueError,
|
||||||
"translation table must be 256 characters long");
|
"translation table must be 256 characters long");
|
||||||
return NULL;
|
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);
|
result = PyString_FromStringAndSize((char *)NULL, inlen);
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
output_start = output = PyString_AsString(result);
|
output_start = output = PyString_AsString(result);
|
||||||
|
input = PyString_AsString(input_obj);
|
||||||
|
|
||||||
if (delete != NULL && dellen != 0) {
|
if (dellen == 0) {
|
||||||
for (i = 0; i < inlen; i++) {
|
/* If no deletions are required, use faster code */
|
||||||
int c = Py_CHARMASK(*input++);
|
for (i = inlen; --i >= 0; ) {
|
||||||
if (trans_table[c] != -1)
|
c = Py_CHARMASK(*input++);
|
||||||
*output++ = (char)trans_table[c];
|
if (Py_CHARMASK((*output++ = table[c])) != c)
|
||||||
}
|
changed = 1;
|
||||||
/* 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];
|
|
||||||
}
|
}
|
||||||
|
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;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue