Skip to content

Commit c08ec9f

Browse files
author
Victor Stinner
committed
Create a subfunction for PySys_SetArgvEx()
Create sys_update_path() static function. Do nothing if argc==0.
1 parent 7980eaa commit c08ec9f

1 file changed

Lines changed: 94 additions & 78 deletions

File tree

Python/sysmodule.c

Lines changed: 94 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,106 +1685,122 @@ _wrealpath(const wchar_t *path, wchar_t *resolved_path)
16851685
#define _HAVE_SCRIPT_ARGUMENT(argc, argv) \
16861686
(argc > 0 && argv0 != NULL && \
16871687
wcscmp(argv0, L"-c") != 0 && wcscmp(argv0, L"-m") != 0)
1688-
1689-
void
1690-
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
1688+
1689+
static void
1690+
sys_update_path(int argc, wchar_t **argv)
16911691
{
1692+
wchar_t *argv0;
1693+
wchar_t *p = NULL;
1694+
Py_ssize_t n = 0;
1695+
PyObject *a;
1696+
PyObject *path;
1697+
#ifdef HAVE_READLINK
1698+
extern int _Py_wreadlink(const wchar_t *, wchar_t *, size_t);
1699+
wchar_t link[MAXPATHLEN+1];
1700+
wchar_t argv0copy[2*MAXPATHLEN+1];
1701+
int nr = 0;
1702+
#endif
16921703
#if defined(HAVE_REALPATH)
16931704
wchar_t fullpath[MAXPATHLEN];
16941705
#elif defined(MS_WINDOWS) && !defined(MS_WINCE)
16951706
wchar_t fullpath[MAX_PATH];
16961707
#endif
1697-
PyObject *av = makeargvobject(argc, argv);
1698-
PyObject *path = PySys_GetObject("path");
1699-
if (av == NULL)
1700-
Py_FatalError("no mem for sys.argv");
1701-
if (PySys_SetObject("argv", av) != 0)
1702-
Py_FatalError("can't assign sys.argv");
1703-
if (updatepath && path != NULL) {
1704-
wchar_t *argv0 = argv[0];
1705-
wchar_t *p = NULL;
1706-
Py_ssize_t n = 0;
1707-
PyObject *a;
1708-
extern int _Py_wreadlink(const wchar_t *, wchar_t *, size_t);
1708+
1709+
path = PySys_GetObject("path");
1710+
if (path == NULL)
1711+
return;
1712+
1713+
if (argc == 0)
1714+
return;
1715+
argv0 = argv[0];
1716+
17091717
#ifdef HAVE_READLINK
1710-
wchar_t link[MAXPATHLEN+1];
1711-
wchar_t argv0copy[2*MAXPATHLEN+1];
1712-
int nr = 0;
1713-
if (_HAVE_SCRIPT_ARGUMENT(argc, argv))
1714-
nr = _Py_wreadlink(argv0, link, MAXPATHLEN);
1715-
if (nr > 0) {
1716-
/* It's a symlink */
1717-
link[nr] = '\0';
1718-
if (link[0] == SEP)
1719-
argv0 = link; /* Link to absolute path */
1720-
else if (wcschr(link, SEP) == NULL)
1721-
; /* Link without path */
1718+
if (_HAVE_SCRIPT_ARGUMENT(argc, argv))
1719+
nr = _Py_wreadlink(argv0, link, MAXPATHLEN);
1720+
if (nr > 0) {
1721+
/* It's a symlink */
1722+
link[nr] = '\0';
1723+
if (link[0] == SEP)
1724+
argv0 = link; /* Link to absolute path */
1725+
else if (wcschr(link, SEP) == NULL)
1726+
; /* Link without path */
1727+
else {
1728+
/* Must join(dirname(argv0), link) */
1729+
wchar_t *q = wcsrchr(argv0, SEP);
1730+
if (q == NULL)
1731+
argv0 = link; /* argv0 without path */
17221732
else {
1723-
/* Must join(dirname(argv0), link) */
1724-
wchar_t *q = wcsrchr(argv0, SEP);
1725-
if (q == NULL)
1726-
argv0 = link; /* argv0 without path */
1727-
else {
1728-
/* Must make a copy */
1729-
wcscpy(argv0copy, argv0);
1730-
q = wcsrchr(argv0copy, SEP);
1731-
wcscpy(q+1, link);
1732-
argv0 = argv0copy;
1733-
}
1733+
/* Must make a copy */
1734+
wcscpy(argv0copy, argv0);
1735+
q = wcsrchr(argv0copy, SEP);
1736+
wcscpy(q+1, link);
1737+
argv0 = argv0copy;
17341738
}
17351739
}
1740+
}
17361741
#endif /* HAVE_READLINK */
17371742
#if SEP == '\\' /* Special case for MS filename syntax */
1738-
if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) {
1739-
wchar_t *q;
1743+
if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) {
1744+
wchar_t *q;
17401745
#if defined(MS_WINDOWS) && !defined(MS_WINCE)
1741-
/* This code here replaces the first element in argv with the full
1742-
path that it represents. Under CE, there are no relative paths so
1743-
the argument must be the full path anyway. */
1744-
wchar_t *ptemp;
1745-
if (GetFullPathNameW(argv0,
1746-
sizeof(fullpath)/sizeof(fullpath[0]),
1747-
fullpath,
1748-
&ptemp)) {
1749-
argv0 = fullpath;
1750-
}
1746+
/* This code here replaces the first element in argv with the full
1747+
path that it represents. Under CE, there are no relative paths so
1748+
the argument must be the full path anyway. */
1749+
wchar_t *ptemp;
1750+
if (GetFullPathNameW(argv0,
1751+
sizeof(fullpath)/sizeof(fullpath[0]),
1752+
fullpath,
1753+
&ptemp)) {
1754+
argv0 = fullpath;
1755+
}
17511756
#endif
1752-
p = wcsrchr(argv0, SEP);
1753-
/* Test for alternate separator */
1754-
q = wcsrchr(p ? p : argv0, '/');
1755-
if (q != NULL)
1756-
p = q;
1757-
if (p != NULL) {
1758-
n = p + 1 - argv0;
1759-
if (n > 1 && p[-1] != ':')
1760-
n--; /* Drop trailing separator */
1761-
}
1757+
p = wcsrchr(argv0, SEP);
1758+
/* Test for alternate separator */
1759+
q = wcsrchr(p ? p : argv0, '/');
1760+
if (q != NULL)
1761+
p = q;
1762+
if (p != NULL) {
1763+
n = p + 1 - argv0;
1764+
if (n > 1 && p[-1] != ':')
1765+
n--; /* Drop trailing separator */
17621766
}
1767+
}
17631768
#else /* All other filename syntaxes */
1764-
if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) {
1769+
if (_HAVE_SCRIPT_ARGUMENT(argc, argv)) {
17651770
#if defined(HAVE_REALPATH)
1766-
if (_wrealpath(argv0, fullpath)) {
1767-
argv0 = fullpath;
1768-
}
1769-
#endif
1770-
p = wcsrchr(argv0, SEP);
1771+
if (_wrealpath(argv0, fullpath)) {
1772+
argv0 = fullpath;
17711773
}
1772-
if (p != NULL) {
1773-
n = p + 1 - argv0;
1774+
#endif
1775+
p = wcsrchr(argv0, SEP);
1776+
}
1777+
if (p != NULL) {
1778+
n = p + 1 - argv0;
17741779
#if SEP == '/' /* Special case for Unix filename syntax */
1775-
if (n > 1)
1776-
n--; /* Drop trailing separator */
1780+
if (n > 1)
1781+
n--; /* Drop trailing separator */
17771782
#endif /* Unix */
1778-
}
1779-
#endif /* All others */
1780-
a = PyUnicode_FromWideChar(argv0, n);
1781-
if (a == NULL)
1782-
Py_FatalError("no mem for sys.path insertion");
1783-
if (PyList_Insert(path, 0, a) < 0)
1784-
Py_FatalError("sys.path.insert(0) failed");
1785-
Py_DECREF(a);
17861783
}
1784+
#endif /* All others */
1785+
a = PyUnicode_FromWideChar(argv0, n);
1786+
if (a == NULL)
1787+
Py_FatalError("no mem for sys.path insertion");
1788+
if (PyList_Insert(path, 0, a) < 0)
1789+
Py_FatalError("sys.path.insert(0) failed");
1790+
Py_DECREF(a);
1791+
}
1792+
1793+
void
1794+
PySys_SetArgvEx(int argc, wchar_t **argv, int updatepath)
1795+
{
1796+
PyObject *av = makeargvobject(argc, argv);
1797+
if (av == NULL)
1798+
Py_FatalError("no mem for sys.argv");
1799+
if (PySys_SetObject("argv", av) != 0)
1800+
Py_FatalError("can't assign sys.argv");
17871801
Py_DECREF(av);
1802+
if (updatepath)
1803+
sys_update_path(argc, argv);
17881804
}
17891805

17901806
void

0 commit comments

Comments
 (0)