505 lines
17 KiB
Diff
505 lines
17 KiB
Diff
From d395585e2ae03e557dc30ad03bd4e8aa59443952 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?=D0=90=D0=BB=D0=B5=D0=BA=D1=81=D0=B5=D0=B9?=
|
|
<alexey.pawlow@gmail.com>
|
|
Date: Thu, 17 Jun 2021 18:51:47 +0530
|
|
Subject: [PATCH 032/N] mingw use posix getpath
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Co-authored-by: Алексей <alexey.pawlow@gmail.com>
|
|
Co-authored-by: Christoph Reiter <reiter.christoph@gmail.com>
|
|
---
|
|
Include/cpython/fileutils.h | 3 +-
|
|
Include/pylifecycle.h | 2 +-
|
|
Modules/getpath.c | 130 +++++++++++++++++++++++++++++++++---
|
|
Modules/posixmodule.c | 2 +-
|
|
Python/dynload_win.c | 2 +
|
|
Python/fileutils.c | 22 +++++-
|
|
6 files changed, 145 insertions(+), 16 deletions(-)
|
|
|
|
diff --git a/Include/cpython/fileutils.h b/Include/cpython/fileutils.h
|
|
index ccf37e9..c287ab3 100644
|
|
--- a/Include/cpython/fileutils.h
|
|
+++ b/Include/cpython/fileutils.h
|
|
@@ -135,9 +135,8 @@ PyAPI_FUNC(wchar_t*) _Py_wrealpath(
|
|
size_t resolved_path_len);
|
|
#endif
|
|
|
|
-#ifndef MS_WINDOWS
|
|
PyAPI_FUNC(int) _Py_isabs(const wchar_t *path);
|
|
-#endif
|
|
+PyAPI_FUNC(int) _Py_issep(const wchar_t ch);
|
|
|
|
PyAPI_FUNC(int) _Py_abspath(const wchar_t *path, wchar_t **abspath_p);
|
|
|
|
diff --git a/Include/pylifecycle.h b/Include/pylifecycle.h
|
|
index 17d403c..ce3f411 100644
|
|
--- a/Include/pylifecycle.h
|
|
+++ b/Include/pylifecycle.h
|
|
@@ -52,7 +52,7 @@ PyAPI_FUNC(wchar_t *) Py_GetPrefix(void);
|
|
PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
|
|
PyAPI_FUNC(wchar_t *) Py_GetPath(void);
|
|
PyAPI_FUNC(void) Py_SetPath(const wchar_t *);
|
|
-#ifdef MS_WINDOWS
|
|
+#ifdef _MSC_VER
|
|
int _Py_CheckPython3(void);
|
|
#endif
|
|
|
|
diff --git a/Modules/getpath.c b/Modules/getpath.c
|
|
index ef6dd59..4cb6738 100644
|
|
--- a/Modules/getpath.c
|
|
+++ b/Modules/getpath.c
|
|
@@ -13,6 +13,11 @@
|
|
# include <mach-o/dyld.h>
|
|
#endif
|
|
|
|
+#ifdef MS_WINDOWS
|
|
+#include <windows.h>
|
|
+#include <shlwapi.h>
|
|
+#endif
|
|
+
|
|
/* Search in some common locations for the associated Python libraries.
|
|
*
|
|
* Two directories must be found, the platform independent directory
|
|
@@ -129,6 +134,7 @@ typedef struct {
|
|
wchar_t *prefix_macro; /* PREFIX macro */
|
|
wchar_t *exec_prefix_macro; /* EXEC_PREFIX macro */
|
|
wchar_t *vpath_macro; /* VPATH macro */
|
|
+ wchar_t *dll_path; /* DLL Path */
|
|
|
|
wchar_t *lib_python; /* <platlibdir> / "pythonX.Y" */
|
|
|
|
@@ -146,7 +152,7 @@ typedef struct {
|
|
} PyCalculatePath;
|
|
|
|
static const wchar_t delimiter[2] = {DELIM, '\0'};
|
|
-static const wchar_t separator[2] = {SEP, '\0'};
|
|
+static wchar_t separator[2] = {SEP, '\0'};
|
|
|
|
|
|
/* Get file status. Encode the path to the locale encoding. */
|
|
@@ -170,7 +176,7 @@ static void
|
|
reduce(wchar_t *dir)
|
|
{
|
|
size_t i = wcslen(dir);
|
|
- while (i > 0 && dir[i] != SEP) {
|
|
+ while (i > 0 && !_Py_issep(dir[i])) {
|
|
--i;
|
|
}
|
|
dir[i] = '\0';
|
|
@@ -224,6 +230,9 @@ isdir(const wchar_t *filename)
|
|
return 1;
|
|
}
|
|
|
|
+/*
|
|
+x86_64-w64-mingw32-gcc -c -Wno-unused-result -Wsign-compare -DNDEBUG -march=x86-64 -mtune=generic -O2 -pipe -fwrapv -D__USE_MINGW_ANSI_STDIO=1 -D_WIN32_WINNT=0x0601 -DNDEBUG -DMS_DLL_ID="\"3.9\"" -flto -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -g -std=c99 -Wextra -Wno-unused-result -Wno-unused-parameter -Wno-missing-field-initializers -Wstrict-prototypes -Werror=implicit-function-declaration -fvisibility=hidden -fprofile-generate -I../Python-3.9.4/Include/internal -IObjects -IInclude -IPython -I. -I../Python-3.9.4/Include -I../Python-3.9.4/PC -D__USE_MINGW_ANSI_STDIO=1 -IC:/msys64/mingw64/include/ncurses -I. -DPy_BUILD_CORE -DPYTHONPATH='""' -DPREFIX='"/mingw64"' -DEXEC_PREFIX='"/mingw64"' -DVERSION='"3.9"' -DVPATH='"../Python-3.9.4"' -o Modules/getpath.o ../Python-3.9.4/Modules/getpath.c
|
|
+*/
|
|
|
|
/* Add a path component, by appending stuff to buffer.
|
|
buflen: 'buffer' length in characters including trailing NUL.
|
|
@@ -242,8 +251,8 @@ joinpath(wchar_t *path, const wchar_t *path2, size_t path_len)
|
|
return PATHLEN_ERR();
|
|
}
|
|
|
|
- if (n > 0 && path[n-1] != SEP) {
|
|
- path[n++] = SEP;
|
|
+ if (n > 0 && !_Py_issep(path[n-1])) {
|
|
+ path[n++] = Py_GetSepW(path);
|
|
}
|
|
}
|
|
else {
|
|
@@ -285,7 +294,7 @@ joinpath2(const wchar_t *path, const wchar_t *path2)
|
|
}
|
|
|
|
size_t len = wcslen(path);
|
|
- int add_sep = (len > 0 && path[len - 1] != SEP);
|
|
+ int add_sep = (len > 0 && !_Py_issep(path[len - 1]));
|
|
len += add_sep;
|
|
len += wcslen(path2);
|
|
|
|
@@ -334,7 +343,7 @@ copy_absolute(wchar_t *abs_path, const wchar_t *path, size_t abs_path_len)
|
|
}
|
|
return _PyStatus_OK();
|
|
}
|
|
- if (path[0] == '.' && path[1] == SEP) {
|
|
+ if (path[0] == '.' && _Py_issep(path[1])) {
|
|
path += 2;
|
|
}
|
|
PyStatus status = joinpath(abs_path, path, abs_path_len);
|
|
@@ -478,6 +487,7 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
|
return _PyStatus_NO_MEMORY();
|
|
}
|
|
|
|
+ Py_NormalizeSepsW(path);
|
|
int is_build_dir = isfile(path);
|
|
PyMem_RawFree(path);
|
|
|
|
@@ -502,6 +512,7 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
|
}
|
|
|
|
int module;
|
|
+ Py_NormalizeSepsW(prefix);
|
|
status = ismodule(prefix, &module);
|
|
if (_PyStatus_EXCEPTION(status)) {
|
|
return status;
|
|
@@ -528,6 +539,7 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
|
}
|
|
|
|
int module;
|
|
+ Py_NormalizeSepsW(prefix);
|
|
status = ismodule(prefix, &module);
|
|
if (_PyStatus_EXCEPTION(status)) {
|
|
return status;
|
|
@@ -551,6 +563,7 @@ search_for_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
|
}
|
|
|
|
int module;
|
|
+ Py_NormalizeSepsW(prefix);
|
|
status = ismodule(prefix, &module);
|
|
if (_PyStatus_EXCEPTION(status)) {
|
|
return status;
|
|
@@ -610,6 +623,11 @@ calculate_set_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
* return the compiled-in defaults instead.
|
|
*/
|
|
if (calculate->prefix_found > 0) {
|
|
+#ifdef MS_WINDOWS
|
|
+ wchar_t drive_root[3];
|
|
+ memset(drive_root, 0, sizeof(drive_root));
|
|
+ wcsncpy(drive_root, calculate->prefix, 3);
|
|
+#endif
|
|
wchar_t *prefix = _PyMem_RawWcsdup(calculate->prefix);
|
|
if (prefix == NULL) {
|
|
return _PyStatus_NO_MEMORY();
|
|
@@ -625,7 +643,11 @@ calculate_set_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
|
|
/* The prefix is the root directory, but reduce() chopped
|
|
off the "/". */
|
|
+#ifdef MS_WINDOWS
|
|
+ pathconfig->prefix = _PyMem_RawWcsdup(drive_root);
|
|
+#else
|
|
pathconfig->prefix = _PyMem_RawWcsdup(separator);
|
|
+#endif
|
|
if (pathconfig->prefix == NULL) {
|
|
return _PyStatus_NO_MEMORY();
|
|
}
|
|
@@ -682,6 +704,7 @@ calculate_pybuilddir(const wchar_t *argv0_path,
|
|
return PATHLEN_ERR();
|
|
}
|
|
status = joinpath(exec_prefix, pybuilddir, exec_prefix_len);
|
|
+ Py_NormalizeSepsW(exec_prefix);
|
|
PyMem_RawFree(pybuilddir);
|
|
if (_PyStatus_EXCEPTION(status)) {
|
|
return status;
|
|
@@ -730,6 +753,7 @@ search_for_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig,
|
|
|
|
/* Check for pybuilddir.txt */
|
|
assert(*found == 0);
|
|
+ Py_NormalizeSepsW(exec_prefix);
|
|
status = calculate_pybuilddir(calculate->argv0_path,
|
|
exec_prefix, exec_prefix_len, found);
|
|
if (_PyStatus_EXCEPTION(status)) {
|
|
@@ -804,6 +828,7 @@ calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
return status;
|
|
}
|
|
|
|
+ Py_NormalizeSepsW(exec_prefix);
|
|
if (!calculate->exec_prefix_found) {
|
|
if (calculate->warnings) {
|
|
fprintf(stderr,
|
|
@@ -836,6 +861,47 @@ calculate_exec_prefix(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
}
|
|
|
|
|
|
+#ifdef MS_WINDOWS
|
|
+wchar_t *
|
|
+GetWindowsModulePaths(void)
|
|
+{
|
|
+ int result = 0;
|
|
+ wchar_t program_full_path[MAXPATHLEN+1];
|
|
+ memset(program_full_path, 0, sizeof(program_full_path));
|
|
+
|
|
+ if (GetModuleFileNameW(NULL, program_full_path, MAXPATHLEN)) {
|
|
+ result = 1;
|
|
+ Py_NormalizeSepsW(program_full_path);
|
|
+ }
|
|
+
|
|
+ return _PyMem_RawWcsdup(program_full_path);
|
|
+}
|
|
+
|
|
+
|
|
+wchar_t*
|
|
+_Py_GetDLLPath(void)
|
|
+{
|
|
+ wchar_t dll_path[MAXPATHLEN+1];
|
|
+ memset(dll_path, 0, sizeof(dll_path));
|
|
+
|
|
+#ifdef Py_ENABLE_SHARED
|
|
+ extern HANDLE PyWin_DLLhModule;
|
|
+ if (PyWin_DLLhModule) {
|
|
+ if (GetModuleFileNameW(PyWin_DLLhModule, dll_path, MAXPATHLEN)) {
|
|
+ Py_NormalizeSepsW(dll_path);
|
|
+ } else {
|
|
+ dll_path[0] = 0;
|
|
+ }
|
|
+ }
|
|
+#else
|
|
+ dll_path[0] = 0;
|
|
+#endif
|
|
+
|
|
+ return _PyMem_RawWcsdup(dll_path);
|
|
+}
|
|
+#endif /* MS_WINDOWS */
|
|
+
|
|
+
|
|
static PyStatus
|
|
calculate_set_exec_prefix(PyCalculatePath *calculate,
|
|
_PyPathConfig *pathconfig)
|
|
@@ -846,6 +912,12 @@ calculate_set_exec_prefix(PyCalculatePath *calculate,
|
|
return _PyStatus_NO_MEMORY();
|
|
}
|
|
|
|
+#ifdef MS_WINDOWS
|
|
+ wchar_t drive_root[3];
|
|
+ memset(drive_root, 0, sizeof(drive_root));
|
|
+ wcsncpy(drive_root, calculate->exec_prefix, 3);
|
|
+#endif
|
|
+
|
|
reduce(exec_prefix);
|
|
reduce(exec_prefix);
|
|
reduce(exec_prefix);
|
|
@@ -859,7 +931,11 @@ calculate_set_exec_prefix(PyCalculatePath *calculate,
|
|
|
|
/* The exec_prefix is the root directory, but reduce() chopped
|
|
off the "/". */
|
|
+#ifdef MS_WINDOWS
|
|
+ pathconfig->exec_prefix = _PyMem_RawWcsdup(drive_root);
|
|
+#else
|
|
pathconfig->exec_prefix = _PyMem_RawWcsdup(separator);
|
|
+#endif
|
|
if (pathconfig->exec_prefix == NULL) {
|
|
return _PyStatus_NO_MEMORY();
|
|
}
|
|
@@ -964,13 +1040,22 @@ calculate_program_impl(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
* other way to find a directory to start the search from. If
|
|
* $PATH isn't exported, you lose.
|
|
*/
|
|
- if (wcschr(pathconfig->program_name, SEP)) {
|
|
+ if (wcschr(pathconfig->program_name, Py_GetSepW(pathconfig->program_name))) {
|
|
pathconfig->program_full_path = _PyMem_RawWcsdup(pathconfig->program_name);
|
|
if (pathconfig->program_full_path == NULL) {
|
|
return _PyStatus_NO_MEMORY();
|
|
}
|
|
return _PyStatus_OK();
|
|
}
|
|
+#ifdef MS_WINDOWS
|
|
+ else if(pathconfig->program_full_path == NULL) {
|
|
+ pathconfig->program_full_path = GetWindowsModulePaths();
|
|
+ if (pathconfig->program_full_path == NULL) {
|
|
+ return _PyStatus_NO_MEMORY();
|
|
+ }
|
|
+ return _PyStatus_OK();
|
|
+ }
|
|
+#endif /* MS_WINDOWS */
|
|
|
|
#ifdef __APPLE__
|
|
wchar_t *abs_path = NULL;
|
|
@@ -1007,7 +1092,7 @@ calculate_program_impl(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
|
|
|
|
/* Calculate pathconfig->program_full_path */
|
|
-static PyStatus
|
|
+PyStatus
|
|
calculate_program(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
{
|
|
PyStatus status;
|
|
@@ -1173,7 +1258,7 @@ done:
|
|
#endif
|
|
|
|
|
|
-static PyStatus
|
|
+PyStatus
|
|
calculate_argv0_path(PyCalculatePath *calculate,
|
|
_PyPathConfig *pathconfig)
|
|
{
|
|
@@ -1191,10 +1276,12 @@ calculate_argv0_path(PyCalculatePath *calculate,
|
|
}
|
|
#endif
|
|
|
|
+#if defined(HAVE_READLINK)
|
|
status = resolve_symlinks(&calculate->argv0_path);
|
|
if (_PyStatus_EXCEPTION(status)) {
|
|
return status;
|
|
}
|
|
+#endif
|
|
|
|
reduce(calculate->argv0_path);
|
|
|
|
@@ -1324,6 +1411,7 @@ calculate_zip_path(PyCalculatePath *calculate)
|
|
goto done;
|
|
}
|
|
|
|
+ Py_NormalizeSepsW(calculate->zip_path);
|
|
res = _PyStatus_OK();
|
|
|
|
done:
|
|
@@ -1363,7 +1451,14 @@ calculate_module_search_path(PyCalculatePath *calculate,
|
|
}
|
|
|
|
bufsz += wcslen(calculate->zip_path) + 1;
|
|
+/* TODO :: The MS_WINDOWS bit may be unnecessary. */
|
|
+#ifdef MS_WINDOWS
|
|
+ if (_Py_isabs(calculate->exec_prefix)) {
|
|
+ bufsz += wcslen(calculate->exec_prefix) + 1;
|
|
+ }
|
|
+#else
|
|
bufsz += wcslen(calculate->exec_prefix) + 1;
|
|
+#endif
|
|
|
|
/* Allocate the buffer */
|
|
wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
|
|
@@ -1391,7 +1486,7 @@ calculate_module_search_path(PyCalculatePath *calculate,
|
|
|
|
if (!_Py_isabs(defpath)) {
|
|
wcscat(buf, calculate->prefix);
|
|
- if (prefixsz >= 2 && calculate->prefix[prefixsz - 2] != SEP &&
|
|
+ if (prefixsz >= 2 && !_Py_issep(calculate->prefix[prefixsz - 2]) &&
|
|
defpath[0] != (delim ? DELIM : L'\0'))
|
|
{
|
|
/* not empty */
|
|
@@ -1413,8 +1508,15 @@ calculate_module_search_path(PyCalculatePath *calculate,
|
|
}
|
|
wcscat(buf, delimiter);
|
|
|
|
+#ifdef MS_WINDOWS
|
|
+ if (_Py_isabs(calculate->exec_prefix)) {
|
|
+ wcscat(buf, calculate->exec_prefix);
|
|
+ wcscat(buf, delimiter);
|
|
+ }
|
|
+#else
|
|
/* Finally, on goes the directory for dynamic-load modules */
|
|
wcscat(buf, calculate->exec_prefix);
|
|
+#endif
|
|
|
|
pathconfig->module_search_path = buf;
|
|
return _PyStatus_OK();
|
|
@@ -1443,14 +1545,17 @@ calculate_init(PyCalculatePath *calculate, const PyConfig *config)
|
|
if (!calculate->pythonpath_macro) {
|
|
return DECODE_LOCALE_ERR("PYTHONPATH macro", len);
|
|
}
|
|
+ Py_NormalizeSepsW(calculate->pythonpath_macro);
|
|
calculate->prefix_macro = Py_DecodeLocale(PREFIX, &len);
|
|
if (!calculate->prefix_macro) {
|
|
return DECODE_LOCALE_ERR("PREFIX macro", len);
|
|
}
|
|
+ Py_NormalizeSepsW(calculate->prefix_macro);
|
|
calculate->exec_prefix_macro = Py_DecodeLocale(EXEC_PREFIX, &len);
|
|
if (!calculate->exec_prefix_macro) {
|
|
return DECODE_LOCALE_ERR("EXEC_PREFIX macro", len);
|
|
}
|
|
+ Py_NormalizeSepsW(calculate->exec_prefix_macro);
|
|
calculate->vpath_macro = Py_DecodeLocale(VPATH, &len);
|
|
if (!calculate->vpath_macro) {
|
|
return DECODE_LOCALE_ERR("VPATH macro", len);
|
|
@@ -1461,6 +1566,7 @@ calculate_init(PyCalculatePath *calculate, const PyConfig *config)
|
|
if (!pyversion) {
|
|
return DECODE_LOCALE_ERR("VERSION macro", len);
|
|
}
|
|
+
|
|
calculate->lib_python = joinpath2(config->platlibdir, pyversion);
|
|
PyMem_RawFree(pyversion);
|
|
if (calculate->lib_python == NULL) {
|
|
@@ -1477,6 +1583,7 @@ calculate_free(PyCalculatePath *calculate)
|
|
PyMem_RawFree(calculate->pythonpath_macro);
|
|
PyMem_RawFree(calculate->prefix_macro);
|
|
PyMem_RawFree(calculate->exec_prefix_macro);
|
|
+ PyMem_RawFree(calculate->dll_path);
|
|
PyMem_RawFree(calculate->vpath_macro);
|
|
PyMem_RawFree(calculate->lib_python);
|
|
PyMem_RawFree(calculate->path_env);
|
|
@@ -1492,6 +1599,8 @@ calculate_path(PyCalculatePath *calculate, _PyPathConfig *pathconfig)
|
|
{
|
|
PyStatus status;
|
|
|
|
+ calculate->dll_path = _Py_GetDLLPath();
|
|
+
|
|
if (pathconfig->program_full_path == NULL) {
|
|
status = calculate_program(calculate, pathconfig);
|
|
if (_PyStatus_EXCEPTION(status)) {
|
|
@@ -1592,6 +1701,7 @@ _PyPathConfig_Calculate(_PyPathConfig *pathconfig, const PyConfig *config)
|
|
{
|
|
PyStatus status;
|
|
PyCalculatePath calculate;
|
|
+ separator[0] = Py_GetSepW(NULL);
|
|
memset(&calculate, 0, sizeof(calculate));
|
|
|
|
status = calculate_init(&calculate, config);
|
|
diff --git a/Modules/posixmodule.c b/Modules/posixmodule.c
|
|
index b40c0fe..545fd4c 100644
|
|
--- a/Modules/posixmodule.c
|
|
+++ b/Modules/posixmodule.c
|
|
@@ -4107,7 +4107,7 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list)
|
|
Py_END_ALLOW_THREADS
|
|
/* FindNextFile sets error to ERROR_NO_MORE_FILES if
|
|
it got to the end of the directory. */
|
|
- if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
|
|
+ if (!result && GetLastError() != 0 && GetLastError() != ERROR_NO_MORE_FILES) {
|
|
Py_DECREF(list);
|
|
list = path_error(path);
|
|
goto exit;
|
|
diff --git a/Python/dynload_win.c b/Python/dynload_win.c
|
|
index 6b53780..1083fe8 100644
|
|
--- a/Python/dynload_win.c
|
|
+++ b/Python/dynload_win.c
|
|
@@ -173,7 +173,9 @@ dl_funcptr _PyImport_FindSharedFuncptrWindows(const char *prefix,
|
|
dl_funcptr p;
|
|
char funcname[258], *import_python;
|
|
|
|
+#if defined(_MSC_VER)
|
|
_Py_CheckPython3();
|
|
+#endif
|
|
|
|
#if USE_UNICODE_WCHAR_CACHE
|
|
const wchar_t *wpathname = _PyUnicode_AsUnicode(pathname);
|
|
diff --git a/Python/fileutils.c b/Python/fileutils.c
|
|
index 3b53baa..1ee5476 100644
|
|
--- a/Python/fileutils.c
|
|
+++ b/Python/fileutils.c
|
|
@@ -1976,13 +1976,31 @@ _Py_wrealpath(const wchar_t *path,
|
|
#endif
|
|
|
|
|
|
-#ifndef MS_WINDOWS
|
|
int
|
|
_Py_isabs(const wchar_t *path)
|
|
{
|
|
- return (path[0] == SEP);
|
|
+#ifdef MS_WINDOWS
|
|
+ size_t i = wcslen(path);
|
|
+ if (i >= 3) {
|
|
+ if (iswalpha(path[0]) && path[1] == L':' && _Py_issep(path[2])) {
|
|
+ return 1;
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+#else
|
|
+ return _Py_issep(path[0]);
|
|
+#endif
|
|
}
|
|
+
|
|
+int
|
|
+_Py_issep(const wchar_t ch)
|
|
+{
|
|
+#ifdef MS_WINDOWS
|
|
+ return ch == SEP || ch == ALTSEP;
|
|
+#else
|
|
+ return ch == SEP;
|
|
#endif
|
|
+}
|
|
|
|
|
|
/* Get an absolute path.
|
|
--
|
|
2.36.1
|
|
|