Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 8a0ef78

Browse files
committed
Rewrite make_source_pathname using Unicode API.
1 parent 30260a7 commit 8a0ef78

1 file changed

Lines changed: 41 additions & 38 deletions

File tree

Python/import.c

Lines changed: 41 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -906,11 +906,11 @@ rightmost_sep(Py_UCS4 *s)
906906

907907
/* Like rightmost_sep, but operate on unicode objects. */
908908
static Py_ssize_t
909-
rightmost_sep_obj(PyObject* o)
909+
rightmost_sep_obj(PyObject* o, Py_ssize_t start, Py_ssize_t end)
910910
{
911911
Py_ssize_t found, i;
912912
Py_UCS4 c;
913-
for (found = -1, i = 0; i < PyUnicode_GET_LENGTH(o); i++) {
913+
for (found = -1, i = start; i < end; i++) {
914914
c = PyUnicode_READ_CHAR(o, i);
915915
if (c == SEP
916916
#ifdef ALTSEP
@@ -947,7 +947,7 @@ make_compiled_pathname(PyObject *pathstr, int debug)
947947
len = PyUnicode_GET_LENGTH(pathstr);
948948
/* If there is no separator, this returns -1, so
949949
lastsep will be 0. */
950-
fname = rightmost_sep_obj(pathstr) + 1;
950+
fname = rightmost_sep_obj(pathstr, 0, len) + 1;
951951
ext = fname - 1;
952952
for(i = fname; i < len; i++)
953953
if (PyUnicode_READ_CHAR(pathstr, i) == '.')
@@ -992,63 +992,66 @@ make_compiled_pathname(PyObject *pathstr, int debug)
992992
(...)/__pycache__/foo.<tag>.pyc -> (...)/foo.py */
993993

994994
static PyObject*
995-
make_source_pathname(PyObject *pathobj)
995+
make_source_pathname(PyObject *path)
996996
{
997-
Py_UCS4 buf[MAXPATHLEN];
998-
Py_UCS4 *pathname;
999-
Py_UCS4 *left, *right, *dot0, *dot1, sep;
1000-
size_t i, j;
997+
Py_ssize_t left, right, dot0, dot1, len;
998+
Py_ssize_t i, j;
999+
PyObject *result;
1000+
int kind;
1001+
void *data;
10011002

1002-
if (PyUnicode_GET_LENGTH(pathobj) > MAXPATHLEN)
1003-
return NULL;
1004-
pathname = PyUnicode_AsUCS4Copy(pathobj);
1005-
if (!pathname)
1003+
len = PyUnicode_GET_LENGTH(path);
1004+
if (len > MAXPATHLEN)
10061005
return NULL;
10071006

10081007
/* Look back two slashes from the end. In between these two slashes
10091008
must be the string __pycache__ or this is not a PEP 3147 style
10101009
path. It's possible for there to be only one slash.
10111010
*/
1012-
right = rightmost_sep(pathname);
1013-
if (right == NULL)
1011+
right = rightmost_sep_obj(path, 0, len);
1012+
if (right == -1)
10141013
return NULL;
1015-
sep = *right;
1016-
*right = '\0';
1017-
left = rightmost_sep(pathname);
1018-
*right = sep;
1019-
if (left == NULL)
1020-
left = pathname;
1014+
left = rightmost_sep_obj(path, 0, right);
1015+
if (left == -1)
1016+
left = 0;
10211017
else
10221018
left++;
1023-
if (right-left != Py_UCS4_strlen(CACHEDIR_UNICODE) ||
1024-
Py_UCS4_strncmp(left, CACHEDIR_UNICODE, right-left) != 0)
1025-
goto error;
1019+
if (right-left != sizeof(CACHEDIR)-1)
1020+
return NULL;
1021+
for (i = 0; i < sizeof(CACHEDIR)-1; i++)
1022+
if (PyUnicode_READ_CHAR(path, left+i) != CACHEDIR[i])
1023+
return NULL;
10261024

10271025
/* Now verify that the path component to the right of the last slash
10281026
has two dots in it.
10291027
*/
1030-
if ((dot0 = Py_UCS4_strchr(right + 1, '.')) == NULL)
1031-
goto error;
1032-
if ((dot1 = Py_UCS4_strchr(dot0 + 1, '.')) == NULL)
1033-
goto error;
1028+
dot0 = PyUnicode_FindChar(path, '.', right+1, len, 1);
1029+
if (dot0 < 0)
1030+
return NULL;
1031+
dot1 = PyUnicode_FindChar(path, '.', dot0+1, len, 1);
1032+
if (dot1 < 0)
1033+
return NULL;
10341034
/* Too many dots? */
1035-
if (Py_UCS4_strchr(dot1 + 1, '.') != NULL)
1036-
goto error;
1035+
if (PyUnicode_FindChar(path, '.', dot1+1, len, 1) != -1)
1036+
return NULL;
10371037

10381038
/* This is a PEP 3147 path. Start by copying everything from the
10391039
start of pathname up to and including the leftmost slash. Then
10401040
copy the file's basename, removing the magic tag and adding a .py
10411041
suffix.
10421042
*/
1043-
Py_UCS4_strncpy(buf, pathname, (i=left-pathname));
1044-
Py_UCS4_strncpy(buf+i, right+1, (j=dot0-right));
1045-
buf[i+j] = 'p';
1046-
buf[i+j+1] = 'y';
1047-
PyMem_Free(pathname);
1048-
return PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buf, i+j+2);
1049-
error:
1050-
PyMem_Free(pathname);
1051-
return NULL;
1043+
result = PyUnicode_New(left + (dot0-right) + 2,
1044+
PyUnicode_MAX_CHAR_VALUE(path));
1045+
if (!result)
1046+
return NULL;
1047+
kind = PyUnicode_KIND(result);
1048+
data = PyUnicode_DATA(result);
1049+
PyUnicode_CopyCharacters(result, 0, path, 0, (i = left));
1050+
PyUnicode_CopyCharacters(result, left, path, right+1,
1051+
(j = dot0-right));
1052+
PyUnicode_WRITE(kind, data, i+j, 'p');
1053+
PyUnicode_WRITE(kind, data, i+j+1, 'y');
1054+
return result;
10521055
}
10531056

10541057
/* Given a pathname for a Python source file, its time of last

0 commit comments

Comments
 (0)