mirror of
https://github.com/python/cpython.git
synced 2025-08-31 14:07:50 +00:00
parent
b9279bc88f
commit
790465fd90
21 changed files with 642 additions and 414 deletions
|
@ -161,7 +161,7 @@ Initialization, Finalization, and Threads
|
||||||
haven't been explicitly destroyed at that point.
|
haven't been explicitly destroyed at that point.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: void Py_SetProgramName(char *name)
|
.. cfunction:: void Py_SetProgramName(wchar_t *name)
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
single: Py_Initialize()
|
single: Py_Initialize()
|
||||||
|
@ -170,11 +170,12 @@ Initialization, Finalization, and Threads
|
||||||
|
|
||||||
This function should be called before :cfunc:`Py_Initialize` is called for
|
This function should be called before :cfunc:`Py_Initialize` is called for
|
||||||
the first time, if it is called at all. It tells the interpreter the value
|
the first time, if it is called at all. It tells the interpreter the value
|
||||||
of the ``argv[0]`` argument to the :cfunc:`main` function of the program.
|
of the ``argv[0]`` argument to the :cfunc:`main` function of the program
|
||||||
|
(converted to wide characters).
|
||||||
This is used by :cfunc:`Py_GetPath` and some other functions below to find
|
This is used by :cfunc:`Py_GetPath` and some other functions below to find
|
||||||
the Python run-time libraries relative to the interpreter executable. The
|
the Python run-time libraries relative to the interpreter executable. The
|
||||||
default value is ``'python'``. The argument should point to a
|
default value is ``'python'``. The argument should point to a
|
||||||
zero-terminated character string in static storage whose contents will not
|
zero-terminated wide character string in static storage whose contents will not
|
||||||
change for the duration of the program's execution. No code in the Python
|
change for the duration of the program's execution. No code in the Python
|
||||||
interpreter will change the contents of this storage.
|
interpreter will change the contents of this storage.
|
||||||
|
|
||||||
|
@ -188,7 +189,7 @@ Initialization, Finalization, and Threads
|
||||||
value.
|
value.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: char* Py_GetPrefix()
|
.. cfunction:: wchar_t* Py_GetPrefix()
|
||||||
|
|
||||||
Return the *prefix* for installed platform-independent files. This is derived
|
Return the *prefix* for installed platform-independent files. This is derived
|
||||||
through a number of complicated rules from the program name set with
|
through a number of complicated rules from the program name set with
|
||||||
|
@ -201,7 +202,7 @@ Initialization, Finalization, and Threads
|
||||||
It is only useful on Unix. See also the next function.
|
It is only useful on Unix. See also the next function.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: char* Py_GetExecPrefix()
|
.. cfunction:: wchar_t* Py_GetExecPrefix()
|
||||||
|
|
||||||
Return the *exec-prefix* for installed platform-*dependent* files. This is
|
Return the *exec-prefix* for installed platform-*dependent* files. This is
|
||||||
derived through a number of complicated rules from the program name set with
|
derived through a number of complicated rules from the program name set with
|
||||||
|
@ -236,7 +237,7 @@ Initialization, Finalization, and Threads
|
||||||
platform.
|
platform.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: char* Py_GetProgramFullPath()
|
.. cfunction:: wchar_t* Py_GetProgramFullPath()
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
single: Py_SetProgramName()
|
single: Py_SetProgramName()
|
||||||
|
@ -249,7 +250,7 @@ Initialization, Finalization, and Threads
|
||||||
to Python code as ``sys.executable``.
|
to Python code as ``sys.executable``.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: char* Py_GetPath()
|
.. cfunction:: wchar_t* Py_GetPath()
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
triple: module; search; path
|
triple: module; search; path
|
||||||
|
@ -342,7 +343,7 @@ Initialization, Finalization, and Threads
|
||||||
``sys.version``.
|
``sys.version``.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: void PySys_SetArgv(int argc, char **argv)
|
.. cfunction:: void PySys_SetArgv(int argc, wchar_t **argv)
|
||||||
|
|
||||||
.. index::
|
.. index::
|
||||||
single: main()
|
single: main()
|
||||||
|
|
|
@ -84,11 +84,11 @@ accessible to C code. They all work with the current interpreter thread's
|
||||||
|
|
||||||
Reset :data:`sys.warnoptions` to an empty list.
|
Reset :data:`sys.warnoptions` to an empty list.
|
||||||
|
|
||||||
.. cfunction:: void PySys_AddWarnOption(char *s)
|
.. cfunction:: void PySys_AddWarnOption(wchar_t *s)
|
||||||
|
|
||||||
Append *s* to :data:`sys.warnoptions`.
|
Append *s* to :data:`sys.warnoptions`.
|
||||||
|
|
||||||
.. cfunction:: void PySys_SetPath(char *path)
|
.. cfunction:: void PySys_SetPath(wchar_t *path)
|
||||||
|
|
||||||
Set :data:`sys.path` to a list object of paths found in *path* which should
|
Set :data:`sys.path` to a list object of paths found in *path* which should
|
||||||
be a list of paths separated with the platform's search path delimiter
|
be a list of paths separated with the platform's search path delimiter
|
||||||
|
|
|
@ -336,6 +336,8 @@ the system's :ctype:`wchar_t`.
|
||||||
.. cfunction:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size)
|
.. cfunction:: PyObject* PyUnicode_FromWideChar(const wchar_t *w, Py_ssize_t size)
|
||||||
|
|
||||||
Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given size.
|
Create a Unicode object from the :ctype:`wchar_t` buffer *w* of the given size.
|
||||||
|
Passing -1 as the size indicates that the function must itself compute the length,
|
||||||
|
using wcslen.
|
||||||
Return *NULL* on failure.
|
Return *NULL* on failure.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -25,16 +25,18 @@ are only passed to these functions if it is certain that they were created by
|
||||||
the same library that the Python runtime is using.
|
the same library that the Python runtime is using.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: int Py_Main(int argc, char **argv)
|
.. cfunction:: int Py_Main(int argc, wchar_t **argv)
|
||||||
|
|
||||||
The main program for the standard interpreter. This is made available for
|
The main program for the standard interpreter. This is made
|
||||||
programs which embed Python. The *argc* and *argv* parameters should be
|
available for programs which embed Python. The *argc* and *argv*
|
||||||
prepared exactly as those which are passed to a C program's :cfunc:`main`
|
parameters should be prepared exactly as those which are passed to
|
||||||
function. It is important to note that the argument list may be modified (but
|
a C program's :cfunc:`main` function (converted to wchar_t
|
||||||
the contents of the strings pointed to by the argument list are not). The return
|
according to the user's locale). It is important to note that the
|
||||||
value will be the integer passed to the :func:`sys.exit` function, ``1`` if the
|
argument list may be modified (but the contents of the strings
|
||||||
interpreter exits due to an exception, or ``2`` if the parameter list does not
|
pointed to by the argument list are not). The return value will be
|
||||||
represent a valid Python command line.
|
the integer passed to the :func:`sys.exit` function, ``1`` if the
|
||||||
|
interpreter exits due to an exception, or ``2`` if the parameter
|
||||||
|
list does not represent a valid Python command line.
|
||||||
|
|
||||||
|
|
||||||
.. cfunction:: int PyRun_AnyFile(FILE *fp, const char *filename)
|
.. cfunction:: int PyRun_AnyFile(FILE *fp, const char *filename)
|
||||||
|
|
|
@ -12,20 +12,20 @@ extern "C" {
|
||||||
#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)
|
#if defined(MS_WINDOWS) || defined(__BORLANDC__) || defined(__WATCOMC__) || defined(__DJGPP__) || defined(PYOS_OS2)
|
||||||
#if defined(PYOS_OS2) && defined(PYCC_GCC)
|
#if defined(PYOS_OS2) && defined(PYCC_GCC)
|
||||||
#define MAXPATHLEN 260
|
#define MAXPATHLEN 260
|
||||||
#define SEP '/'
|
#define SEP L'/'
|
||||||
#define ALTSEP '\\'
|
#define ALTSEP L'\\'
|
||||||
#else
|
#else
|
||||||
#define SEP '\\'
|
#define SEP L'\\'
|
||||||
#define ALTSEP '/'
|
#define ALTSEP L'/'
|
||||||
#define MAXPATHLEN 256
|
#define MAXPATHLEN 256
|
||||||
#endif
|
#endif
|
||||||
#define DELIM ';'
|
#define DELIM L';'
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Filename separator */
|
/* Filename separator */
|
||||||
#ifndef SEP
|
#ifndef SEP
|
||||||
#define SEP '/'
|
#define SEP L'/'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Max pathname length */
|
/* Max pathname length */
|
||||||
|
@ -39,7 +39,7 @@ extern "C" {
|
||||||
|
|
||||||
/* Search path entry delimiter */
|
/* Search path entry delimiter */
|
||||||
#ifndef DELIM
|
#ifndef DELIM
|
||||||
#define DELIM ':'
|
#define DELIM L':'
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
|
@ -7,9 +7,9 @@ extern "C" {
|
||||||
|
|
||||||
PyAPI_DATA(int) _PyOS_opterr;
|
PyAPI_DATA(int) _PyOS_opterr;
|
||||||
PyAPI_DATA(int) _PyOS_optind;
|
PyAPI_DATA(int) _PyOS_optind;
|
||||||
PyAPI_DATA(char *) _PyOS_optarg;
|
PyAPI_DATA(wchar_t *) _PyOS_optarg;
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyOS_GetOpt(int argc, char **argv, char *optstring);
|
PyAPI_FUNC(int) _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,11 +17,11 @@ typedef struct {
|
||||||
int cf_flags; /* bitmask of CO_xxx flags relevant to future */
|
int cf_flags; /* bitmask of CO_xxx flags relevant to future */
|
||||||
} PyCompilerFlags;
|
} PyCompilerFlags;
|
||||||
|
|
||||||
PyAPI_FUNC(void) Py_SetProgramName(char *);
|
PyAPI_FUNC(void) Py_SetProgramName(wchar_t *);
|
||||||
PyAPI_FUNC(char *) Py_GetProgramName(void);
|
PyAPI_FUNC(wchar_t *) Py_GetProgramName(void);
|
||||||
|
|
||||||
PyAPI_FUNC(void) Py_SetPythonHome(char *);
|
PyAPI_FUNC(void) Py_SetPythonHome(wchar_t *);
|
||||||
PyAPI_FUNC(char *) Py_GetPythonHome(void);
|
PyAPI_FUNC(wchar_t *) Py_GetPythonHome(void);
|
||||||
|
|
||||||
PyAPI_FUNC(void) Py_Initialize(void);
|
PyAPI_FUNC(void) Py_Initialize(void);
|
||||||
PyAPI_FUNC(void) Py_InitializeEx(int);
|
PyAPI_FUNC(void) Py_InitializeEx(int);
|
||||||
|
@ -81,7 +81,7 @@ PyAPI_FUNC(void) Py_Exit(int);
|
||||||
PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
|
PyAPI_FUNC(int) Py_FdIsInteractive(FILE *, const char *);
|
||||||
|
|
||||||
/* Bootstrap */
|
/* Bootstrap */
|
||||||
PyAPI_FUNC(int) Py_Main(int argc, char **argv);
|
PyAPI_FUNC(int) Py_Main(int argc, wchar_t **argv);
|
||||||
|
|
||||||
/* Use macros for a bunch of old variants */
|
/* Use macros for a bunch of old variants */
|
||||||
#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL)
|
#define PyRun_String(str, s, g, l) PyRun_StringFlags(str, s, g, l, NULL)
|
||||||
|
@ -103,10 +103,10 @@ PyAPI_FUNC(int) Py_Main(int argc, char **argv);
|
||||||
PyRun_FileExFlags(fp, p, s, g, l, 0, flags)
|
PyRun_FileExFlags(fp, p, s, g, l, 0, flags)
|
||||||
|
|
||||||
/* In getpath.c */
|
/* In getpath.c */
|
||||||
PyAPI_FUNC(char *) Py_GetProgramFullPath(void);
|
PyAPI_FUNC(wchar_t *) Py_GetProgramFullPath(void);
|
||||||
PyAPI_FUNC(char *) Py_GetPrefix(void);
|
PyAPI_FUNC(wchar_t *) Py_GetPrefix(void);
|
||||||
PyAPI_FUNC(char *) Py_GetExecPrefix(void);
|
PyAPI_FUNC(wchar_t *) Py_GetExecPrefix(void);
|
||||||
PyAPI_FUNC(char *) Py_GetPath(void);
|
PyAPI_FUNC(wchar_t *) Py_GetPath(void);
|
||||||
|
|
||||||
/* In their own files */
|
/* In their own files */
|
||||||
PyAPI_FUNC(const char *) Py_GetVersion(void);
|
PyAPI_FUNC(const char *) Py_GetVersion(void);
|
||||||
|
|
|
@ -9,8 +9,8 @@ extern "C" {
|
||||||
|
|
||||||
PyAPI_FUNC(PyObject *) PySys_GetObject(const char *);
|
PyAPI_FUNC(PyObject *) PySys_GetObject(const char *);
|
||||||
PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *);
|
PyAPI_FUNC(int) PySys_SetObject(const char *, PyObject *);
|
||||||
PyAPI_FUNC(void) PySys_SetArgv(int, char **);
|
PyAPI_FUNC(void) PySys_SetArgv(int, wchar_t **);
|
||||||
PyAPI_FUNC(void) PySys_SetPath(const char *);
|
PyAPI_FUNC(void) PySys_SetPath(const wchar_t *);
|
||||||
|
|
||||||
PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
|
PyAPI_FUNC(void) PySys_WriteStdout(const char *format, ...)
|
||||||
Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
|
Py_GCC_ATTRIBUTE((format(printf, 1, 2)));
|
||||||
|
@ -21,7 +21,7 @@ PyAPI_DATA(PyObject *) _PySys_TraceFunc, *_PySys_ProfileFunc;
|
||||||
PyAPI_DATA(int) _PySys_CheckInterval;
|
PyAPI_DATA(int) _PySys_CheckInterval;
|
||||||
|
|
||||||
PyAPI_FUNC(void) PySys_ResetWarnOptions(void);
|
PyAPI_FUNC(void) PySys_ResetWarnOptions(void);
|
||||||
PyAPI_FUNC(void) PySys_AddWarnOption(const char *);
|
PyAPI_FUNC(void) PySys_AddWarnOption(const wchar_t *);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,10 @@ What's New in Python 3.0a5?
|
||||||
Core and Builtins
|
Core and Builtins
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
- The command line processing was converted to pass Unicode strings
|
||||||
|
through as unmodified as possible; as a consequence, the C API
|
||||||
|
related to command line arguments was changed to use wchar_t.
|
||||||
|
|
||||||
Extension Modules
|
Extension Modules
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
|
@ -3012,7 +3012,7 @@ ins_string(PyObject *d, char *name, char *val)
|
||||||
PyMODINIT_FUNC
|
PyMODINIT_FUNC
|
||||||
init_tkinter(void)
|
init_tkinter(void)
|
||||||
{
|
{
|
||||||
PyObject *m, *d;
|
PyObject *m, *d, *uexe, *cexe;
|
||||||
|
|
||||||
Py_TYPE(&Tkapp_Type) = &PyType_Type;
|
Py_TYPE(&Tkapp_Type) = &PyType_Type;
|
||||||
|
|
||||||
|
@ -3065,7 +3065,16 @@ init_tkinter(void)
|
||||||
|
|
||||||
/* This helps the dynamic loader; in Unicode aware Tcl versions
|
/* This helps the dynamic loader; in Unicode aware Tcl versions
|
||||||
it also helps Tcl find its encodings. */
|
it also helps Tcl find its encodings. */
|
||||||
Tcl_FindExecutable(Py_GetProgramName());
|
uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1);
|
||||||
|
if (uexe) {
|
||||||
|
cexe = PyUnicode_AsEncodedString(uexe,
|
||||||
|
Py_FileSystemDefaultEncoding,
|
||||||
|
NULL);
|
||||||
|
if (cexe)
|
||||||
|
Tcl_FindExecutable(PyString_AsString(cexe));
|
||||||
|
Py_XDECREF(cexe);
|
||||||
|
Py_DECREF(uexe);
|
||||||
|
}
|
||||||
|
|
||||||
if (PyErr_Occurred())
|
if (PyErr_Occurred())
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -122,19 +122,81 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef LANDMARK
|
#ifndef LANDMARK
|
||||||
#define LANDMARK "os.py"
|
#define LANDMARK L"os.py"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char prefix[MAXPATHLEN+1];
|
static wchar_t prefix[MAXPATHLEN+1];
|
||||||
static char exec_prefix[MAXPATHLEN+1];
|
static wchar_t exec_prefix[MAXPATHLEN+1];
|
||||||
static char progpath[MAXPATHLEN+1];
|
static wchar_t progpath[MAXPATHLEN+1];
|
||||||
static char *module_search_path = NULL;
|
static wchar_t *module_search_path = NULL;
|
||||||
static char lib_python[] = "lib/python" VERSION;
|
static wchar_t lib_python[] = L"lib/python" VERSION;
|
||||||
|
|
||||||
|
/* In principle, this should use HAVE__WSTAT, and _wstat
|
||||||
|
should be detected by autoconf. However, no current
|
||||||
|
POSIX system provides that function, so testing for
|
||||||
|
it is pointless. */
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
|
static int
|
||||||
|
_wstat(const wchar_t* path, struct stat *buf)
|
||||||
|
{
|
||||||
|
char fname[PATH_MAX];
|
||||||
|
size_t res = wcstombs(fname, path, sizeof(fname));
|
||||||
|
if (res == (size_t)-1) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return stat(fname, buf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
|
static wchar_t*
|
||||||
|
_wgetcwd(wchar_t *buf, size_t size)
|
||||||
|
{
|
||||||
|
char fname[PATH_MAX];
|
||||||
|
if (getcwd(fname, PATH_MAX) == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (mbstowcs(buf, fname, size) >= size) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_READLINK
|
||||||
|
int
|
||||||
|
_Py_wreadlink(const wchar_t *path, wchar_t *buf, size_t bufsiz)
|
||||||
|
{
|
||||||
|
char cbuf[PATH_MAX];
|
||||||
|
char cpath[PATH_MAX];
|
||||||
|
int res;
|
||||||
|
size_t r1 = wcstombs(cpath, path, PATH_MAX);
|
||||||
|
if (r1 == (size_t)-1 || r1 >= PATH_MAX) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
res = (int)readlink(cpath, cbuf, PATH_MAX);
|
||||||
|
if (res == -1)
|
||||||
|
return -1;
|
||||||
|
if (res == PATH_MAX) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
r1 = mbstowcs(buf, cbuf, bufsiz);
|
||||||
|
if (r1 == -1) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return (int)r1;
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reduce(char *dir)
|
reduce(wchar_t *dir)
|
||||||
{
|
{
|
||||||
size_t i = strlen(dir);
|
size_t i = wcslen(dir);
|
||||||
while (i > 0 && dir[i] != SEP)
|
while (i > 0 && dir[i] != SEP)
|
||||||
--i;
|
--i;
|
||||||
dir[i] = '\0';
|
dir[i] = '\0';
|
||||||
|
@ -142,10 +204,10 @@ reduce(char *dir)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
isfile(char *filename) /* Is file, not directory */
|
isfile(wchar_t *filename) /* Is file, not directory */
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
if (stat(filename, &buf) != 0)
|
if (_wstat(filename, &buf) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (!S_ISREG(buf.st_mode))
|
if (!S_ISREG(buf.st_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -154,14 +216,14 @@ isfile(char *filename) /* Is file, not directory */
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
|
ismodule(wchar_t *filename) /* Is module -- check for .pyc/.pyo too */
|
||||||
{
|
{
|
||||||
if (isfile(filename))
|
if (isfile(filename))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Check for the compiled version of prefix. */
|
/* Check for the compiled version of prefix. */
|
||||||
if (strlen(filename) < MAXPATHLEN) {
|
if (wcslen(filename) < MAXPATHLEN) {
|
||||||
strcat(filename, Py_OptimizeFlag ? "o" : "c");
|
wcscat(filename, Py_OptimizeFlag ? L"o" : L"c");
|
||||||
if (isfile(filename))
|
if (isfile(filename))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -170,10 +232,10 @@ ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
isxfile(char *filename) /* Is executable file */
|
isxfile(wchar_t *filename) /* Is executable file */
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
if (stat(filename, &buf) != 0)
|
if (_wstat(filename, &buf) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (!S_ISREG(buf.st_mode))
|
if (!S_ISREG(buf.st_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -184,10 +246,10 @@ isxfile(char *filename) /* Is executable file */
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
isdir(char *filename) /* Is directory */
|
isdir(wchar_t *filename) /* Is directory */
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct stat buf;
|
||||||
if (stat(filename, &buf) != 0)
|
if (_wstat(filename, &buf) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
if (!S_ISDIR(buf.st_mode))
|
if (!S_ISDIR(buf.st_mode))
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -205,34 +267,34 @@ isdir(char *filename) /* Is directory */
|
||||||
stuff as fits will be appended.
|
stuff as fits will be appended.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
joinpath(char *buffer, char *stuff)
|
joinpath(wchar_t *buffer, wchar_t *stuff)
|
||||||
{
|
{
|
||||||
size_t n, k;
|
size_t n, k;
|
||||||
if (stuff[0] == SEP)
|
if (stuff[0] == SEP)
|
||||||
n = 0;
|
n = 0;
|
||||||
else {
|
else {
|
||||||
n = strlen(buffer);
|
n = wcslen(buffer);
|
||||||
if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
|
if (n > 0 && buffer[n-1] != SEP && n < MAXPATHLEN)
|
||||||
buffer[n++] = SEP;
|
buffer[n++] = SEP;
|
||||||
}
|
}
|
||||||
if (n > MAXPATHLEN)
|
if (n > MAXPATHLEN)
|
||||||
Py_FatalError("buffer overflow in getpath.c's joinpath()");
|
Py_FatalError("buffer overflow in getpath.c's joinpath()");
|
||||||
k = strlen(stuff);
|
k = wcslen(stuff);
|
||||||
if (n + k > MAXPATHLEN)
|
if (n + k > MAXPATHLEN)
|
||||||
k = MAXPATHLEN - n;
|
k = MAXPATHLEN - n;
|
||||||
strncpy(buffer+n, stuff, k);
|
wcsncpy(buffer+n, stuff, k);
|
||||||
buffer[n+k] = '\0';
|
buffer[n+k] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* copy_absolute requires that path be allocated at least
|
/* copy_absolute requires that path be allocated at least
|
||||||
MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
|
MAXPATHLEN + 1 bytes and that p be no more than MAXPATHLEN bytes. */
|
||||||
static void
|
static void
|
||||||
copy_absolute(char *path, char *p)
|
copy_absolute(wchar_t *path, wchar_t *p)
|
||||||
{
|
{
|
||||||
if (p[0] == SEP)
|
if (p[0] == SEP)
|
||||||
strcpy(path, p);
|
wcscpy(path, p);
|
||||||
else {
|
else {
|
||||||
getcwd(path, MAXPATHLEN);
|
_wgetcwd(path, MAXPATHLEN);
|
||||||
if (p[0] == '.' && p[1] == SEP)
|
if (p[0] == '.' && p[1] == SEP)
|
||||||
p += 2;
|
p += 2;
|
||||||
joinpath(path, p);
|
joinpath(path, p);
|
||||||
|
@ -241,46 +303,46 @@ copy_absolute(char *path, char *p)
|
||||||
|
|
||||||
/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
|
/* absolutize() requires that path be allocated at least MAXPATHLEN+1 bytes. */
|
||||||
static void
|
static void
|
||||||
absolutize(char *path)
|
absolutize(wchar_t *path)
|
||||||
{
|
{
|
||||||
char buffer[MAXPATHLEN + 1];
|
wchar_t buffer[MAXPATHLEN + 1];
|
||||||
|
|
||||||
if (path[0] == SEP)
|
if (path[0] == SEP)
|
||||||
return;
|
return;
|
||||||
copy_absolute(buffer, path);
|
copy_absolute(buffer, path);
|
||||||
strcpy(path, buffer);
|
wcscpy(path, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
|
/* search_for_prefix requires that argv0_path be no more than MAXPATHLEN
|
||||||
bytes long.
|
bytes long.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
search_for_prefix(char *argv0_path, char *home)
|
search_for_prefix(wchar_t *argv0_path, wchar_t *home)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
char *vpath;
|
wchar_t *vpath;
|
||||||
|
|
||||||
/* If PYTHONHOME is set, we believe it unconditionally */
|
/* If PYTHONHOME is set, we believe it unconditionally */
|
||||||
if (home) {
|
if (home) {
|
||||||
char *delim;
|
wchar_t *delim;
|
||||||
strncpy(prefix, home, MAXPATHLEN);
|
wcsncpy(prefix, home, MAXPATHLEN);
|
||||||
delim = strchr(prefix, DELIM);
|
delim = wcschr(prefix, DELIM);
|
||||||
if (delim)
|
if (delim)
|
||||||
*delim = '\0';
|
*delim = L'\0';
|
||||||
joinpath(prefix, lib_python);
|
joinpath(prefix, lib_python);
|
||||||
joinpath(prefix, LANDMARK);
|
joinpath(prefix, LANDMARK);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if argv[0] is in the build directory */
|
/* Check to see if argv[0] is in the build directory */
|
||||||
strcpy(prefix, argv0_path);
|
wcscpy(prefix, argv0_path);
|
||||||
joinpath(prefix, "Modules/Setup");
|
joinpath(prefix, L"Modules/Setup");
|
||||||
if (isfile(prefix)) {
|
if (isfile(prefix)) {
|
||||||
/* Check VPATH to see if argv0_path is in the build directory. */
|
/* Check VPATH to see if argv0_path is in the build directory. */
|
||||||
vpath = VPATH;
|
vpath = L"" VPATH;
|
||||||
strcpy(prefix, argv0_path);
|
wcscpy(prefix, argv0_path);
|
||||||
joinpath(prefix, vpath);
|
joinpath(prefix, vpath);
|
||||||
joinpath(prefix, "Lib");
|
joinpath(prefix, L"Lib");
|
||||||
joinpath(prefix, LANDMARK);
|
joinpath(prefix, LANDMARK);
|
||||||
if (ismodule(prefix))
|
if (ismodule(prefix))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -289,17 +351,17 @@ search_for_prefix(char *argv0_path, char *home)
|
||||||
/* Search from argv0_path, until root is found */
|
/* Search from argv0_path, until root is found */
|
||||||
copy_absolute(prefix, argv0_path);
|
copy_absolute(prefix, argv0_path);
|
||||||
do {
|
do {
|
||||||
n = strlen(prefix);
|
n = wcslen(prefix);
|
||||||
joinpath(prefix, lib_python);
|
joinpath(prefix, lib_python);
|
||||||
joinpath(prefix, LANDMARK);
|
joinpath(prefix, LANDMARK);
|
||||||
if (ismodule(prefix))
|
if (ismodule(prefix))
|
||||||
return 1;
|
return 1;
|
||||||
prefix[n] = '\0';
|
prefix[n] = L'\0';
|
||||||
reduce(prefix);
|
reduce(prefix);
|
||||||
} while (prefix[0]);
|
} while (prefix[0]);
|
||||||
|
|
||||||
/* Look at configure's PREFIX */
|
/* Look at configure's PREFIX */
|
||||||
strncpy(prefix, PREFIX, MAXPATHLEN);
|
wcsncpy(prefix, L"" PREFIX, MAXPATHLEN);
|
||||||
joinpath(prefix, lib_python);
|
joinpath(prefix, lib_python);
|
||||||
joinpath(prefix, LANDMARK);
|
joinpath(prefix, LANDMARK);
|
||||||
if (ismodule(prefix))
|
if (ismodule(prefix))
|
||||||
|
@ -314,26 +376,26 @@ search_for_prefix(char *argv0_path, char *home)
|
||||||
MAXPATHLEN bytes long.
|
MAXPATHLEN bytes long.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
search_for_exec_prefix(char *argv0_path, char *home)
|
search_for_exec_prefix(wchar_t *argv0_path, wchar_t *home)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
/* If PYTHONHOME is set, we believe it unconditionally */
|
/* If PYTHONHOME is set, we believe it unconditionally */
|
||||||
if (home) {
|
if (home) {
|
||||||
char *delim;
|
wchar_t *delim;
|
||||||
delim = strchr(home, DELIM);
|
delim = wcschr(home, DELIM);
|
||||||
if (delim)
|
if (delim)
|
||||||
strncpy(exec_prefix, delim+1, MAXPATHLEN);
|
wcsncpy(exec_prefix, delim+1, MAXPATHLEN);
|
||||||
else
|
else
|
||||||
strncpy(exec_prefix, home, MAXPATHLEN);
|
wcsncpy(exec_prefix, home, MAXPATHLEN);
|
||||||
joinpath(exec_prefix, lib_python);
|
joinpath(exec_prefix, lib_python);
|
||||||
joinpath(exec_prefix, "lib-dynload");
|
joinpath(exec_prefix, L"lib-dynload");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check to see if argv[0] is in the build directory */
|
/* Check to see if argv[0] is in the build directory */
|
||||||
strcpy(exec_prefix, argv0_path);
|
wcscpy(exec_prefix, argv0_path);
|
||||||
joinpath(exec_prefix, "Modules/Setup");
|
joinpath(exec_prefix, L"Modules/Setup");
|
||||||
if (isfile(exec_prefix)) {
|
if (isfile(exec_prefix)) {
|
||||||
reduce(exec_prefix);
|
reduce(exec_prefix);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -342,19 +404,19 @@ search_for_exec_prefix(char *argv0_path, char *home)
|
||||||
/* Search from argv0_path, until root is found */
|
/* Search from argv0_path, until root is found */
|
||||||
copy_absolute(exec_prefix, argv0_path);
|
copy_absolute(exec_prefix, argv0_path);
|
||||||
do {
|
do {
|
||||||
n = strlen(exec_prefix);
|
n = wcslen(exec_prefix);
|
||||||
joinpath(exec_prefix, lib_python);
|
joinpath(exec_prefix, lib_python);
|
||||||
joinpath(exec_prefix, "lib-dynload");
|
joinpath(exec_prefix, L"lib-dynload");
|
||||||
if (isdir(exec_prefix))
|
if (isdir(exec_prefix))
|
||||||
return 1;
|
return 1;
|
||||||
exec_prefix[n] = '\0';
|
exec_prefix[n] = L'\0';
|
||||||
reduce(exec_prefix);
|
reduce(exec_prefix);
|
||||||
} while (exec_prefix[0]);
|
} while (exec_prefix[0]);
|
||||||
|
|
||||||
/* Look at configure's EXEC_PREFIX */
|
/* Look at configure's EXEC_PREFIX */
|
||||||
strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
|
wcsncpy(exec_prefix, L"" EXEC_PREFIX, MAXPATHLEN);
|
||||||
joinpath(exec_prefix, lib_python);
|
joinpath(exec_prefix, lib_python);
|
||||||
joinpath(exec_prefix, "lib-dynload");
|
joinpath(exec_prefix, L"lib-dynload");
|
||||||
if (isdir(exec_prefix))
|
if (isdir(exec_prefix))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
@ -366,22 +428,25 @@ search_for_exec_prefix(char *argv0_path, char *home)
|
||||||
static void
|
static void
|
||||||
calculate_path(void)
|
calculate_path(void)
|
||||||
{
|
{
|
||||||
extern char *Py_GetProgramName(void);
|
extern wchar_t *Py_GetProgramName(void);
|
||||||
|
|
||||||
static char delimiter[2] = {DELIM, '\0'};
|
static wchar_t delimiter[2] = {DELIM, '\0'};
|
||||||
static char separator[2] = {SEP, '\0'};
|
static wchar_t separator[2] = {SEP, '\0'};
|
||||||
char *pythonpath = PYTHONPATH;
|
wchar_t *pythonpath = L"" PYTHONPATH;
|
||||||
char *rtpypath = Py_GETENV("PYTHONPATH");
|
char *_rtpypath = Py_GETENV("PYTHONPATH"); /* XXX use wide version on Windows */
|
||||||
char *home = Py_GetPythonHome();
|
wchar_t rtpypath[MAXPATHLEN+1];
|
||||||
char *path = getenv("PATH");
|
wchar_t *home = Py_GetPythonHome();
|
||||||
char *prog = Py_GetProgramName();
|
char *_path = getenv("PATH");
|
||||||
char argv0_path[MAXPATHLEN+1];
|
wchar_t wpath[MAXPATHLEN+1];
|
||||||
char zip_path[MAXPATHLEN+1];
|
wchar_t *path = NULL;
|
||||||
|
wchar_t *prog = Py_GetProgramName();
|
||||||
|
wchar_t argv0_path[MAXPATHLEN+1];
|
||||||
|
wchar_t zip_path[MAXPATHLEN+1];
|
||||||
int pfound, efound; /* 1 if found; -1 if found build directory */
|
int pfound, efound; /* 1 if found; -1 if found build directory */
|
||||||
char *buf;
|
wchar_t *buf;
|
||||||
size_t bufsz;
|
size_t bufsz;
|
||||||
size_t prefixsz;
|
size_t prefixsz;
|
||||||
char *defpath = pythonpath;
|
wchar_t *defpath = pythonpath;
|
||||||
#ifdef WITH_NEXT_FRAMEWORK
|
#ifdef WITH_NEXT_FRAMEWORK
|
||||||
NSModule pythonModule;
|
NSModule pythonModule;
|
||||||
#endif
|
#endif
|
||||||
|
@ -393,13 +458,22 @@ calculate_path(void)
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (_path) {
|
||||||
|
size_t r = mbstowcs(wpath, _path, MAXPATHLEN+1);
|
||||||
|
path = wpath;
|
||||||
|
if (r == (size_t)-1 || r > MAXPATHLEN) {
|
||||||
|
/* Could not convert PATH, or it's too long. */
|
||||||
|
path = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* If there is no slash in the argv0 path, then we have to
|
/* If there is no slash in the argv0 path, then we have to
|
||||||
* assume python is on the user's $PATH, since there's no
|
* assume python is on the user's $PATH, since there's no
|
||||||
* other way to find a directory to start the search from. If
|
* other way to find a directory to start the search from. If
|
||||||
* $PATH isn't exported, you lose.
|
* $PATH isn't exported, you lose.
|
||||||
*/
|
*/
|
||||||
if (strchr(prog, SEP))
|
if (wcschr(prog, SEP))
|
||||||
strncpy(progpath, prog, MAXPATHLEN);
|
wcsncpy(progpath, prog, MAXPATHLEN);
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
/* On Mac OS X, if a script uses an interpreter of the form
|
/* On Mac OS X, if a script uses an interpreter of the form
|
||||||
* "#!/opt/python2.3/bin/python", the kernel only passes "python"
|
* "#!/opt/python2.3/bin/python", the kernel only passes "python"
|
||||||
|
@ -416,24 +490,24 @@ calculate_path(void)
|
||||||
#endif /* __APPLE__ */
|
#endif /* __APPLE__ */
|
||||||
else if (path) {
|
else if (path) {
|
||||||
while (1) {
|
while (1) {
|
||||||
char *delim = strchr(path, DELIM);
|
wchar_t *delim = wcschr(path, DELIM);
|
||||||
|
|
||||||
if (delim) {
|
if (delim) {
|
||||||
size_t len = delim - path;
|
size_t len = delim - path;
|
||||||
if (len > MAXPATHLEN)
|
if (len > MAXPATHLEN)
|
||||||
len = MAXPATHLEN;
|
len = MAXPATHLEN;
|
||||||
strncpy(progpath, path, len);
|
wcsncpy(progpath, path, len);
|
||||||
*(progpath + len) = '\0';
|
*(progpath + len) = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strncpy(progpath, path, MAXPATHLEN);
|
wcsncpy(progpath, path, MAXPATHLEN);
|
||||||
|
|
||||||
joinpath(progpath, prog);
|
joinpath(progpath, prog);
|
||||||
if (isxfile(progpath))
|
if (isxfile(progpath))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!delim) {
|
if (!delim) {
|
||||||
progpath[0] = '\0';
|
progpath[0] = L'\0';
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
path = delim + 1;
|
path = delim + 1;
|
||||||
|
@ -443,7 +517,7 @@ calculate_path(void)
|
||||||
progpath[0] = '\0';
|
progpath[0] = '\0';
|
||||||
if (progpath[0] != SEP)
|
if (progpath[0] != SEP)
|
||||||
absolutize(progpath);
|
absolutize(progpath);
|
||||||
strncpy(argv0_path, progpath, MAXPATHLEN);
|
wcsncpy(argv0_path, progpath, MAXPATHLEN);
|
||||||
argv0_path[MAXPATHLEN] = '\0';
|
argv0_path[MAXPATHLEN] = '\0';
|
||||||
|
|
||||||
#ifdef WITH_NEXT_FRAMEWORK
|
#ifdef WITH_NEXT_FRAMEWORK
|
||||||
|
@ -454,7 +528,7 @@ calculate_path(void)
|
||||||
*/
|
*/
|
||||||
pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
|
pythonModule = NSModuleForSymbol(NSLookupAndBindSymbol("_Py_Initialize"));
|
||||||
/* Use dylib functions to find out where the framework was loaded from */
|
/* Use dylib functions to find out where the framework was loaded from */
|
||||||
buf = (char *)NSLibraryNameForModule(pythonModule);
|
buf = (wchar_t *)NSLibraryNameForModule(pythonModule);
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
/* We're in a framework. */
|
/* We're in a framework. */
|
||||||
/* See if we might be in the build directory. The framework in the
|
/* See if we might be in the build directory. The framework in the
|
||||||
|
@ -464,39 +538,39 @@ calculate_path(void)
|
||||||
** be running the interpreter in the build directory, so we use the
|
** be running the interpreter in the build directory, so we use the
|
||||||
** build-directory-specific logic to find Lib and such.
|
** build-directory-specific logic to find Lib and such.
|
||||||
*/
|
*/
|
||||||
strncpy(argv0_path, buf, MAXPATHLEN);
|
wcsncpy(argv0_path, buf, MAXPATHLEN);
|
||||||
reduce(argv0_path);
|
reduce(argv0_path);
|
||||||
joinpath(argv0_path, lib_python);
|
joinpath(argv0_path, lib_python);
|
||||||
joinpath(argv0_path, LANDMARK);
|
joinpath(argv0_path, LANDMARK);
|
||||||
if (!ismodule(argv0_path)) {
|
if (!ismodule(argv0_path)) {
|
||||||
/* We are in the build directory so use the name of the
|
/* We are in the build directory so use the name of the
|
||||||
executable - we know that the absolute path is passed */
|
executable - we know that the absolute path is passed */
|
||||||
strncpy(argv0_path, prog, MAXPATHLEN);
|
wcsncpy(argv0_path, prog, MAXPATHLEN);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Use the location of the library as the progpath */
|
/* Use the location of the library as the progpath */
|
||||||
strncpy(argv0_path, buf, MAXPATHLEN);
|
wcsncpy(argv0_path, buf, MAXPATHLEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if HAVE_READLINK
|
#if HAVE_READLINK
|
||||||
{
|
{
|
||||||
char tmpbuffer[MAXPATHLEN+1];
|
wchar_t tmpbuffer[MAXPATHLEN+1];
|
||||||
int linklen = readlink(progpath, tmpbuffer, MAXPATHLEN);
|
int linklen = _Py_wreadlink(progpath, tmpbuffer, MAXPATHLEN);
|
||||||
while (linklen != -1) {
|
while (linklen != -1) {
|
||||||
/* It's not null terminated! */
|
/* It's not null terminated! */
|
||||||
tmpbuffer[linklen] = '\0';
|
tmpbuffer[linklen] = '\0';
|
||||||
if (tmpbuffer[0] == SEP)
|
if (tmpbuffer[0] == SEP)
|
||||||
/* tmpbuffer should never be longer than MAXPATHLEN,
|
/* tmpbuffer should never be longer than MAXPATHLEN,
|
||||||
but extra check does not hurt */
|
but extra check does not hurt */
|
||||||
strncpy(argv0_path, tmpbuffer, MAXPATHLEN);
|
wcsncpy(argv0_path, tmpbuffer, MAXPATHLEN);
|
||||||
else {
|
else {
|
||||||
/* Interpret relative to progpath */
|
/* Interpret relative to progpath */
|
||||||
reduce(argv0_path);
|
reduce(argv0_path);
|
||||||
joinpath(argv0_path, tmpbuffer);
|
joinpath(argv0_path, tmpbuffer);
|
||||||
}
|
}
|
||||||
linklen = readlink(argv0_path, tmpbuffer, MAXPATHLEN);
|
linklen = _Py_wreadlink(argv0_path, tmpbuffer, MAXPATHLEN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_READLINK */
|
#endif /* HAVE_READLINK */
|
||||||
|
@ -510,22 +584,22 @@ calculate_path(void)
|
||||||
if (!Py_FrozenFlag)
|
if (!Py_FrozenFlag)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Could not find platform independent libraries <prefix>\n");
|
"Could not find platform independent libraries <prefix>\n");
|
||||||
strncpy(prefix, PREFIX, MAXPATHLEN);
|
wcsncpy(prefix, L"" PREFIX, MAXPATHLEN);
|
||||||
joinpath(prefix, lib_python);
|
joinpath(prefix, lib_python);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
reduce(prefix);
|
reduce(prefix);
|
||||||
|
|
||||||
strncpy(zip_path, prefix, MAXPATHLEN);
|
wcsncpy(zip_path, prefix, MAXPATHLEN);
|
||||||
zip_path[MAXPATHLEN] = '\0';
|
zip_path[MAXPATHLEN] = L'\0';
|
||||||
if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
|
if (pfound > 0) { /* Use the reduced prefix returned by Py_GetPrefix() */
|
||||||
reduce(zip_path);
|
reduce(zip_path);
|
||||||
reduce(zip_path);
|
reduce(zip_path);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strncpy(zip_path, PREFIX, MAXPATHLEN);
|
wcsncpy(zip_path, L"" PREFIX, MAXPATHLEN);
|
||||||
joinpath(zip_path, "lib/python00.zip");
|
joinpath(zip_path, L"lib/python00.zip");
|
||||||
bufsz = strlen(zip_path); /* Replace "00" with version */
|
bufsz = wcslen(zip_path); /* Replace "00" with version */
|
||||||
zip_path[bufsz - 6] = VERSION[0];
|
zip_path[bufsz - 6] = VERSION[0];
|
||||||
zip_path[bufsz - 5] = VERSION[2];
|
zip_path[bufsz - 5] = VERSION[2];
|
||||||
|
|
||||||
|
@ -533,8 +607,8 @@ calculate_path(void)
|
||||||
if (!Py_FrozenFlag)
|
if (!Py_FrozenFlag)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Could not find platform dependent libraries <exec_prefix>\n");
|
"Could not find platform dependent libraries <exec_prefix>\n");
|
||||||
strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
|
wcsncpy(exec_prefix, L"" EXEC_PREFIX, MAXPATHLEN);
|
||||||
joinpath(exec_prefix, "lib/lib-dynload");
|
joinpath(exec_prefix, L"lib/lib-dynload");
|
||||||
}
|
}
|
||||||
/* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
|
/* If we found EXEC_PREFIX do *not* reduce it! (Yet.) */
|
||||||
|
|
||||||
|
@ -546,13 +620,19 @@ calculate_path(void)
|
||||||
*/
|
*/
|
||||||
bufsz = 0;
|
bufsz = 0;
|
||||||
|
|
||||||
if (rtpypath)
|
if (_rtpypath) {
|
||||||
bufsz += strlen(rtpypath) + 1;
|
size_t s = mbstowcs(rtpypath, _rtpypath, sizeof(rtpypath)/sizeof(wchar_t));
|
||||||
|
if (s == (size_t)-1 || s >=sizeof(rtpypath))
|
||||||
|
/* XXX deal with errors more gracefully */
|
||||||
|
_rtpypath = NULL;
|
||||||
|
if (_rtpypath)
|
||||||
|
bufsz += wcslen(rtpypath) + 1;
|
||||||
|
}
|
||||||
|
|
||||||
prefixsz = strlen(prefix) + 1;
|
prefixsz = wcslen(prefix) + 1;
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
char *delim = strchr(defpath, DELIM);
|
wchar_t *delim = wcschr(defpath, DELIM);
|
||||||
|
|
||||||
if (defpath[0] != SEP)
|
if (defpath[0] != SEP)
|
||||||
/* Paths are relative to prefix */
|
/* Paths are relative to prefix */
|
||||||
|
@ -561,65 +641,65 @@ calculate_path(void)
|
||||||
if (delim)
|
if (delim)
|
||||||
bufsz += delim - defpath + 1;
|
bufsz += delim - defpath + 1;
|
||||||
else {
|
else {
|
||||||
bufsz += strlen(defpath) + 1;
|
bufsz += wcslen(defpath) + 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
defpath = delim + 1;
|
defpath = delim + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bufsz += strlen(zip_path) + 1;
|
bufsz += wcslen(zip_path) + 1;
|
||||||
bufsz += strlen(exec_prefix) + 1;
|
bufsz += wcslen(exec_prefix) + 1;
|
||||||
|
|
||||||
/* This is the only malloc call in this file */
|
/* This is the only malloc call in this file */
|
||||||
buf = (char *)PyMem_Malloc(bufsz);
|
buf = (wchar_t *)PyMem_Malloc(bufsz*sizeof(wchar_t));
|
||||||
|
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
/* We can't exit, so print a warning and limp along */
|
/* We can't exit, so print a warning and limp along */
|
||||||
fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
|
fprintf(stderr, "Not enough memory for dynamic PYTHONPATH.\n");
|
||||||
fprintf(stderr, "Using default static PYTHONPATH.\n");
|
fprintf(stderr, "Using default static PYTHONPATH.\n");
|
||||||
module_search_path = PYTHONPATH;
|
module_search_path = L"" PYTHONPATH;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Run-time value of $PYTHONPATH goes first */
|
/* Run-time value of $PYTHONPATH goes first */
|
||||||
if (rtpypath) {
|
if (_rtpypath) {
|
||||||
strcpy(buf, rtpypath);
|
wcscpy(buf, rtpypath);
|
||||||
strcat(buf, delimiter);
|
wcscat(buf, delimiter);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
buf[0] = '\0';
|
buf[0] = '\0';
|
||||||
|
|
||||||
/* Next is the default zip path */
|
/* Next is the default zip path */
|
||||||
strcat(buf, zip_path);
|
wcscat(buf, zip_path);
|
||||||
strcat(buf, delimiter);
|
wcscat(buf, delimiter);
|
||||||
|
|
||||||
/* Next goes merge of compile-time $PYTHONPATH with
|
/* Next goes merge of compile-time $PYTHONPATH with
|
||||||
* dynamically located prefix.
|
* dynamically located prefix.
|
||||||
*/
|
*/
|
||||||
defpath = pythonpath;
|
defpath = pythonpath;
|
||||||
while (1) {
|
while (1) {
|
||||||
char *delim = strchr(defpath, DELIM);
|
wchar_t *delim = wcschr(defpath, DELIM);
|
||||||
|
|
||||||
if (defpath[0] != SEP) {
|
if (defpath[0] != SEP) {
|
||||||
strcat(buf, prefix);
|
wcscat(buf, prefix);
|
||||||
strcat(buf, separator);
|
wcscat(buf, separator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (delim) {
|
if (delim) {
|
||||||
size_t len = delim - defpath + 1;
|
size_t len = delim - defpath + 1;
|
||||||
size_t end = strlen(buf) + len;
|
size_t end = wcslen(buf) + len;
|
||||||
strncat(buf, defpath, len);
|
wcsncat(buf, defpath, len);
|
||||||
*(buf + end) = '\0';
|
*(buf + end) = '\0';
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
strcat(buf, defpath);
|
wcscat(buf, defpath);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
defpath = delim + 1;
|
defpath = delim + 1;
|
||||||
}
|
}
|
||||||
strcat(buf, delimiter);
|
wcscat(buf, delimiter);
|
||||||
|
|
||||||
/* Finally, on goes the directory for dynamic-load modules */
|
/* Finally, on goes the directory for dynamic-load modules */
|
||||||
strcat(buf, exec_prefix);
|
wcscat(buf, exec_prefix);
|
||||||
|
|
||||||
/* And publish the results */
|
/* And publish the results */
|
||||||
module_search_path = buf;
|
module_search_path = buf;
|
||||||
|
@ -636,26 +716,26 @@ calculate_path(void)
|
||||||
/* The prefix is the root directory, but reduce() chopped
|
/* The prefix is the root directory, but reduce() chopped
|
||||||
* off the "/". */
|
* off the "/". */
|
||||||
if (!prefix[0])
|
if (!prefix[0])
|
||||||
strcpy(prefix, separator);
|
wcscpy(prefix, separator);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strncpy(prefix, PREFIX, MAXPATHLEN);
|
wcsncpy(prefix, L"" PREFIX, MAXPATHLEN);
|
||||||
|
|
||||||
if (efound > 0) {
|
if (efound > 0) {
|
||||||
reduce(exec_prefix);
|
reduce(exec_prefix);
|
||||||
reduce(exec_prefix);
|
reduce(exec_prefix);
|
||||||
reduce(exec_prefix);
|
reduce(exec_prefix);
|
||||||
if (!exec_prefix[0])
|
if (!exec_prefix[0])
|
||||||
strcpy(exec_prefix, separator);
|
wcscpy(exec_prefix, separator);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strncpy(exec_prefix, EXEC_PREFIX, MAXPATHLEN);
|
wcsncpy(exec_prefix, L"" EXEC_PREFIX, MAXPATHLEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* External interface */
|
/* External interface */
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetPath(void)
|
Py_GetPath(void)
|
||||||
{
|
{
|
||||||
if (!module_search_path)
|
if (!module_search_path)
|
||||||
|
@ -663,7 +743,7 @@ Py_GetPath(void)
|
||||||
return module_search_path;
|
return module_search_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetPrefix(void)
|
Py_GetPrefix(void)
|
||||||
{
|
{
|
||||||
if (!module_search_path)
|
if (!module_search_path)
|
||||||
|
@ -671,7 +751,7 @@ Py_GetPrefix(void)
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetExecPrefix(void)
|
Py_GetExecPrefix(void)
|
||||||
{
|
{
|
||||||
if (!module_search_path)
|
if (!module_search_path)
|
||||||
|
@ -679,7 +759,7 @@ Py_GetExecPrefix(void)
|
||||||
return exec_prefix;
|
return exec_prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetProgramFullPath(void)
|
Py_GetProgramFullPath(void)
|
||||||
{
|
{
|
||||||
if (!module_search_path)
|
if (!module_search_path)
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#ifdef HAVE_FCNTL_H
|
#ifdef HAVE_FCNTL_H
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#define PATH_MAX MAXPATHLEN
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -40,17 +41,17 @@ extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* For Py_GetArgcArgv(); set by main() */
|
/* For Py_GetArgcArgv(); set by main() */
|
||||||
static char **orig_argv;
|
static wchar_t **orig_argv;
|
||||||
static int orig_argc;
|
static int orig_argc;
|
||||||
|
|
||||||
/* command line options */
|
/* command line options */
|
||||||
#define BASE_OPTS "bBc:dEhim:OStuvVW:xX?"
|
#define BASE_OPTS L"bBc:dEhim:OStuvVW:xX?"
|
||||||
|
|
||||||
#define PROGRAM_OPTS BASE_OPTS
|
#define PROGRAM_OPTS BASE_OPTS
|
||||||
|
|
||||||
/* Short usage message (with %s for argv0) */
|
/* Short usage message (with %s for argv0) */
|
||||||
static char *usage_line =
|
static char *usage_line =
|
||||||
"usage: %s [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
|
"usage: %ls [option] ... [-c cmd | -m mod | file | -] [arg] ...\n";
|
||||||
|
|
||||||
/* Long usage message, split into parts < 512 bytes */
|
/* Long usage message, split into parts < 512 bytes */
|
||||||
static char *usage_1 = "\
|
static char *usage_1 = "\
|
||||||
|
@ -96,9 +97,30 @@ PYTHONHOME : alternate <prefix> directory (or <prefix>%c<exec_prefix>).\n\
|
||||||
PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
|
PYTHONCASEOK : ignore case in 'import' statements (Windows).\n\
|
||||||
";
|
";
|
||||||
|
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
|
static FILE*
|
||||||
|
_wfopen(const wchar_t *path, const wchar_t *mode)
|
||||||
|
{
|
||||||
|
char cpath[PATH_MAX];
|
||||||
|
char cmode[10];
|
||||||
|
size_t r;
|
||||||
|
r = wcstombs(cpath, path, PATH_MAX);
|
||||||
|
if (r == (size_t)-1 || r >= PATH_MAX) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
r = wcstombs(cmode, mode, 10);
|
||||||
|
if (r == (size_t)-1 || r >= 10) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return fopen(cpath, cmode);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
usage(int exitcode, char* program)
|
usage(int exitcode, wchar_t* program)
|
||||||
{
|
{
|
||||||
FILE *f = exitcode ? stderr : stdout;
|
FILE *f = exitcode ? stderr : stdout;
|
||||||
|
|
||||||
|
@ -187,11 +209,11 @@ static int RunModule(char *module, int set_argv0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int RunMainFromImporter(char *filename)
|
static int RunMainFromImporter(wchar_t *filename)
|
||||||
{
|
{
|
||||||
PyObject *argv0 = NULL, *importer = NULL;
|
PyObject *argv0 = NULL, *importer = NULL;
|
||||||
|
|
||||||
if ((argv0 = PyUnicode_DecodeFSDefault(filename)) &&
|
if ((argv0 = PyUnicode_FromWideChar(filename,wcslen(filename))) &&
|
||||||
(importer = PyImport_GetImporter(argv0)) &&
|
(importer = PyImport_GetImporter(argv0)) &&
|
||||||
(importer->ob_type != &PyNullImporter_Type))
|
(importer->ob_type != &PyNullImporter_Type))
|
||||||
{
|
{
|
||||||
|
@ -249,12 +271,12 @@ WaitForThreadShutdown(void)
|
||||||
/* Main program */
|
/* Main program */
|
||||||
|
|
||||||
int
|
int
|
||||||
Py_Main(int argc, char **argv)
|
Py_Main(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
int sts;
|
int sts;
|
||||||
char *command = NULL;
|
char *command = NULL;
|
||||||
char *filename = NULL;
|
wchar_t *filename = NULL;
|
||||||
char *module = NULL;
|
char *module = NULL;
|
||||||
FILE *fp = stdin;
|
FILE *fp = stdin;
|
||||||
char *p;
|
char *p;
|
||||||
|
@ -275,14 +297,19 @@ Py_Main(int argc, char **argv)
|
||||||
|
|
||||||
while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
|
while ((c = _PyOS_GetOpt(argc, argv, PROGRAM_OPTS)) != EOF) {
|
||||||
if (c == 'c') {
|
if (c == 'c') {
|
||||||
|
size_t r1 = wcslen(_PyOS_optarg) + 2;
|
||||||
|
size_t r2;
|
||||||
/* -c is the last option; following arguments
|
/* -c is the last option; following arguments
|
||||||
that look like options are left for the
|
that look like options are left for the
|
||||||
command to interpret. */
|
command to interpret. */
|
||||||
command = (char *)malloc(strlen(_PyOS_optarg) + 2);
|
command = (char *)malloc(r1);
|
||||||
if (command == NULL)
|
if (command == NULL)
|
||||||
Py_FatalError(
|
Py_FatalError(
|
||||||
"not enough memory to copy -c argument");
|
"not enough memory to copy -c argument");
|
||||||
strcpy(command, _PyOS_optarg);
|
r2 = wcstombs(command, _PyOS_optarg, r1);
|
||||||
|
if (r2 > r1-2)
|
||||||
|
Py_FatalError(
|
||||||
|
"not enough memory to copy -c argument");
|
||||||
strcat(command, "\n");
|
strcat(command, "\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -291,11 +318,16 @@ Py_Main(int argc, char **argv)
|
||||||
/* -m is the last option; following arguments
|
/* -m is the last option; following arguments
|
||||||
that look like options are left for the
|
that look like options are left for the
|
||||||
module to interpret. */
|
module to interpret. */
|
||||||
module = (char *)malloc(strlen(_PyOS_optarg) + 2);
|
size_t r1 = wcslen(_PyOS_optarg) + 1;
|
||||||
|
size_t r2;
|
||||||
|
module = (char *)malloc(r1);
|
||||||
if (module == NULL)
|
if (module == NULL)
|
||||||
Py_FatalError(
|
Py_FatalError(
|
||||||
"not enough memory to copy -m argument");
|
"not enough memory to copy -m argument");
|
||||||
strcpy(module, _PyOS_optarg);
|
r2 = wcstombs(module, _PyOS_optarg, r1);
|
||||||
|
if (r2 >= r1)
|
||||||
|
Py_FatalError(
|
||||||
|
"not enough memory to copy -m argument");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -384,7 +416,7 @@ Py_Main(int argc, char **argv)
|
||||||
unbuffered = 1;
|
unbuffered = 1;
|
||||||
|
|
||||||
if (command == NULL && module == NULL && _PyOS_optind < argc &&
|
if (command == NULL && module == NULL && _PyOS_optind < argc &&
|
||||||
strcmp(argv[_PyOS_optind], "-") != 0)
|
wcscmp(argv[_PyOS_optind], L"-") != 0)
|
||||||
{
|
{
|
||||||
#ifdef __VMS
|
#ifdef __VMS
|
||||||
filename = decc$translate_vms(argv[_PyOS_optind]);
|
filename = decc$translate_vms(argv[_PyOS_optind]);
|
||||||
|
@ -462,14 +494,14 @@ Py_Main(int argc, char **argv)
|
||||||
if (command != NULL) {
|
if (command != NULL) {
|
||||||
/* Backup _PyOS_optind and force sys.argv[0] = '-c' */
|
/* Backup _PyOS_optind and force sys.argv[0] = '-c' */
|
||||||
_PyOS_optind--;
|
_PyOS_optind--;
|
||||||
argv[_PyOS_optind] = "-c";
|
argv[_PyOS_optind] = L"-c";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module != NULL) {
|
if (module != NULL) {
|
||||||
/* Backup _PyOS_optind and force sys.argv[0] = '-c'
|
/* Backup _PyOS_optind and force sys.argv[0] = '-c'
|
||||||
so that PySys_SetArgv correctly sets sys.path[0] to ''*/
|
so that PySys_SetArgv correctly sets sys.path[0] to ''*/
|
||||||
_PyOS_optind--;
|
_PyOS_optind--;
|
||||||
argv[_PyOS_optind] = "-c";
|
argv[_PyOS_optind] = L"-c";
|
||||||
}
|
}
|
||||||
|
|
||||||
PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
|
PySys_SetArgv(argc-_PyOS_optind, argv+_PyOS_optind);
|
||||||
|
@ -506,8 +538,8 @@ Py_Main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sts==-1 && filename!=NULL) {
|
if (sts==-1 && filename!=NULL) {
|
||||||
if ((fp = fopen(filename, "r")) == NULL) {
|
if ((fp = _wfopen(filename, L"r")) == NULL) {
|
||||||
fprintf(stderr, "%s: can't open file '%s': [Errno %d] %s\n",
|
fprintf(stderr, "%s: can't open file '%ls': [Errno %d] %s\n",
|
||||||
argv[0], filename, errno, strerror(errno));
|
argv[0], filename, errno, strerror(errno));
|
||||||
|
|
||||||
return 2;
|
return 2;
|
||||||
|
@ -528,7 +560,7 @@ Py_Main(int argc, char **argv)
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
if (fstat(fileno(fp), &sb) == 0 &&
|
if (fstat(fileno(fp), &sb) == 0 &&
|
||||||
S_ISDIR(sb.st_mode)) {
|
S_ISDIR(sb.st_mode)) {
|
||||||
fprintf(stderr, "%s: '%s' is a directory, cannot continue\n", argv[0], filename);
|
fprintf(stderr, "%ls: '%ls' is a directory, cannot continue\n", argv[0], filename);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -536,9 +568,17 @@ Py_Main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sts==-1) {
|
if (sts==-1) {
|
||||||
|
char cfilename[PATH_MAX];
|
||||||
|
char *p_cfilename = "<stdin>";
|
||||||
|
if (filename) {
|
||||||
|
size_t r = wcstombs(cfilename, filename, PATH_MAX);
|
||||||
|
p_cfilename = cfilename;
|
||||||
|
if (r == (size_t)-1 || r >= PATH_MAX)
|
||||||
|
p_cfilename = "<decoding error>";
|
||||||
|
}
|
||||||
sts = PyRun_AnyFileExFlags(
|
sts = PyRun_AnyFileExFlags(
|
||||||
fp,
|
fp,
|
||||||
filename == NULL ? "<stdin>" : filename,
|
p_cfilename,
|
||||||
filename != NULL, &cf) != 0;
|
filename != NULL, &cf) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -589,7 +629,7 @@ Py_Main(int argc, char **argv)
|
||||||
This is rare, but it is needed by the secureware extension. */
|
This is rare, but it is needed by the secureware extension. */
|
||||||
|
|
||||||
void
|
void
|
||||||
Py_GetArgcArgv(int *argc, char ***argv)
|
Py_GetArgcArgv(int *argc, wchar_t ***argv)
|
||||||
{
|
{
|
||||||
*argc = orig_argc;
|
*argc = orig_argc;
|
||||||
*argv = orig_argv;
|
*argv = orig_argv;
|
||||||
|
|
|
@ -1,14 +1,27 @@
|
||||||
/* Minimal main program -- everything is loaded from the library */
|
/* Minimal main program -- everything is loaded from the library */
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#ifdef __FreeBSD__
|
#ifdef __FreeBSD__
|
||||||
#include <floatingpoint.h>
|
#include <floatingpoint.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
int
|
||||||
|
wmain(int argc, wchar_t **argv)
|
||||||
|
{
|
||||||
|
return Py_Main(argc, argv);
|
||||||
|
}
|
||||||
|
#else
|
||||||
int
|
int
|
||||||
main(int argc, char **argv)
|
main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
|
wchar_t **argv_copy = PyMem_Malloc(sizeof(wchar_t*)*argc);
|
||||||
|
/* We need a second copies, as Python might modify the first one. */
|
||||||
|
wchar_t **argv_copy2 = PyMem_Malloc(sizeof(wchar_t*)*argc);
|
||||||
|
int i, res;
|
||||||
|
char *oldloc;
|
||||||
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
/* 754 requires that FP exceptions run in "no stop" mode by default,
|
||||||
* and until C vendors implement C99's ways to control FP exceptions,
|
* and until C vendors implement C99's ways to control FP exceptions,
|
||||||
* Python requires non-stop mode. Alas, some platforms enable FP
|
* Python requires non-stop mode. Alas, some platforms enable FP
|
||||||
|
@ -20,5 +33,33 @@ main(int argc, char **argv)
|
||||||
m = fpgetmask();
|
m = fpgetmask();
|
||||||
fpsetmask(m & ~FP_X_OFL);
|
fpsetmask(m & ~FP_X_OFL);
|
||||||
#endif
|
#endif
|
||||||
return Py_Main(argc, argv);
|
if (!argv_copy || !argv_copy2) {
|
||||||
|
fprintf(stderr, "out of memory");
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
oldloc = setlocale(LC_ALL, NULL);
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
size_t argsize = mbstowcs(NULL, argv[i], 0);
|
||||||
|
if (argsize == (size_t)-1) {
|
||||||
|
fprintf(stderr, "Could not convert argument %d to string", i);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
argv_copy[i] = PyMem_Malloc((argsize+1)*sizeof(wchar_t));
|
||||||
|
argv_copy2[i] = argv_copy[i];
|
||||||
|
if (!argv_copy[i]) {
|
||||||
|
fprintf(stderr, "out of memory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
mbstowcs(argv_copy[i], argv[i], argsize+1);
|
||||||
|
}
|
||||||
|
setlocale(LC_ALL, oldloc);
|
||||||
|
res = Py_Main(argc, argv_copy);
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
PyMem_Free(argv_copy2[i]);
|
||||||
|
}
|
||||||
|
PyMem_Free(argv_copy);
|
||||||
|
PyMem_Free(argv_copy2);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -553,10 +553,16 @@ PyObject *PyUnicode_FromWideChar(register const wchar_t *w,
|
||||||
PyUnicodeObject *unicode;
|
PyUnicodeObject *unicode;
|
||||||
|
|
||||||
if (w == NULL) {
|
if (w == NULL) {
|
||||||
|
if (size == 0)
|
||||||
|
return PyUnicode_FromStringAndSize(NULL, 0);
|
||||||
PyErr_BadInternalCall();
|
PyErr_BadInternalCall();
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (size == -1) {
|
||||||
|
size = wcslen(w);
|
||||||
|
}
|
||||||
|
|
||||||
unicode = _PyUnicode_New(size);
|
unicode = _PyUnicode_New(size);
|
||||||
if (!unicode)
|
if (!unicode)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
|
@ -12,5 +12,5 @@ int WINAPI WinMain(
|
||||||
int nCmdShow /* show state of window */
|
int nCmdShow /* show state of window */
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
return Py_Main(__argc, __argv);
|
return Py_Main(__argc, __wargv);
|
||||||
}
|
}
|
||||||
|
|
279
PC/getpathp.c
279
PC/getpathp.c
|
@ -56,10 +56,10 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "osdefs.h"
|
#include "osdefs.h"
|
||||||
|
#include <wchar.h>
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <tchar.h>
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SYS_TYPES_H
|
#ifdef HAVE_SYS_TYPES_H
|
||||||
|
@ -82,17 +82,17 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef LANDMARK
|
#ifndef LANDMARK
|
||||||
#define LANDMARK "lib\\os.py"
|
#define LANDMARK L"lib\\os.py"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static char prefix[MAXPATHLEN+1];
|
static wchar_t prefix[MAXPATHLEN+1];
|
||||||
static char progpath[MAXPATHLEN+1];
|
static wchar_t progpath[MAXPATHLEN+1];
|
||||||
static char dllpath[MAXPATHLEN+1];
|
static wchar_t dllpath[MAXPATHLEN+1];
|
||||||
static char *module_search_path = NULL;
|
static wchar_t *module_search_path = NULL;
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
is_sep(char ch) /* determine if "ch" is a separator character */
|
is_sep(wchar_t ch) /* determine if "ch" is a separator character */
|
||||||
{
|
{
|
||||||
#ifdef ALTSEP
|
#ifdef ALTSEP
|
||||||
return ch == SEP || ch == ALTSEP;
|
return ch == SEP || ch == ALTSEP;
|
||||||
|
@ -105,9 +105,9 @@ is_sep(char ch) /* determine if "ch" is a separator character */
|
||||||
beyond existing terminator.
|
beyond existing terminator.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
reduce(char *dir)
|
reduce(wchar_t *dir)
|
||||||
{
|
{
|
||||||
size_t i = strlen(dir);
|
size_t i = wcslen(dir);
|
||||||
while (i > 0 && !is_sep(dir[i]))
|
while (i > 0 && !is_sep(dir[i]))
|
||||||
--i;
|
--i;
|
||||||
dir[i] = '\0';
|
dir[i] = '\0';
|
||||||
|
@ -115,24 +115,24 @@ reduce(char *dir)
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
exists(char *filename)
|
exists(wchar_t *filename)
|
||||||
{
|
{
|
||||||
struct stat buf;
|
struct _stat64 buf;
|
||||||
return stat(filename, &buf) == 0;
|
return _wstat64(filename, &buf) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Assumes 'filename' MAXPATHLEN+1 bytes long -
|
/* Assumes 'filename' MAXPATHLEN+1 bytes long -
|
||||||
may extend 'filename' by one character.
|
may extend 'filename' by one character.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
|
ismodule(wchar_t *filename) /* Is module -- check for .pyc/.pyo too */
|
||||||
{
|
{
|
||||||
if (exists(filename))
|
if (exists(filename))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
/* Check for the compiled version of prefix. */
|
/* Check for the compiled version of prefix. */
|
||||||
if (strlen(filename) < MAXPATHLEN) {
|
if (wcslen(filename) < MAXPATHLEN) {
|
||||||
strcat(filename, Py_OptimizeFlag ? "o" : "c");
|
wcscat(filename, Py_OptimizeFlag ? L"o" : L"c");
|
||||||
if (exists(filename))
|
if (exists(filename))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -149,22 +149,22 @@ ismodule(char *filename) /* Is module -- check for .pyc/.pyo too */
|
||||||
stuff as fits will be appended.
|
stuff as fits will be appended.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
join(char *buffer, char *stuff)
|
join(wchar_t *buffer, wchar_t *stuff)
|
||||||
{
|
{
|
||||||
size_t n, k;
|
size_t n, k;
|
||||||
if (is_sep(stuff[0]))
|
if (is_sep(stuff[0]))
|
||||||
n = 0;
|
n = 0;
|
||||||
else {
|
else {
|
||||||
n = strlen(buffer);
|
n = wcslen(buffer);
|
||||||
if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
|
if (n > 0 && !is_sep(buffer[n-1]) && n < MAXPATHLEN)
|
||||||
buffer[n++] = SEP;
|
buffer[n++] = SEP;
|
||||||
}
|
}
|
||||||
if (n > MAXPATHLEN)
|
if (n > MAXPATHLEN)
|
||||||
Py_FatalError("buffer overflow in getpathp.c's joinpath()");
|
Py_FatalError("buffer overflow in getpathp.c's joinpath()");
|
||||||
k = strlen(stuff);
|
k = wcslen(stuff);
|
||||||
if (n + k > MAXPATHLEN)
|
if (n + k > MAXPATHLEN)
|
||||||
k = MAXPATHLEN - n;
|
k = MAXPATHLEN - n;
|
||||||
strncpy(buffer+n, stuff, k);
|
wcsncpy(buffer+n, stuff, k);
|
||||||
buffer[n+k] = '\0';
|
buffer[n+k] = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,12 +173,12 @@ join(char *buffer, char *stuff)
|
||||||
'landmark' can not overflow prefix if too long.
|
'landmark' can not overflow prefix if too long.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
gotlandmark(char *landmark)
|
gotlandmark(wchar_t *landmark)
|
||||||
{
|
{
|
||||||
int ok;
|
int ok;
|
||||||
Py_ssize_t n;
|
Py_ssize_t n;
|
||||||
|
|
||||||
n = strlen(prefix);
|
n = wcslen(prefix);
|
||||||
join(prefix, landmark);
|
join(prefix, landmark);
|
||||||
ok = ismodule(prefix);
|
ok = ismodule(prefix);
|
||||||
prefix[n] = '\0';
|
prefix[n] = '\0';
|
||||||
|
@ -188,10 +188,10 @@ gotlandmark(char *landmark)
|
||||||
/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
|
/* assumes argv0_path is MAXPATHLEN+1 bytes long, already \0 term'd.
|
||||||
assumption provided by only caller, calculate_path() */
|
assumption provided by only caller, calculate_path() */
|
||||||
static int
|
static int
|
||||||
search_for_prefix(char *argv0_path, char *landmark)
|
search_for_prefix(wchar_t *argv0_path, wchar_t *landmark)
|
||||||
{
|
{
|
||||||
/* Search from argv0_path, until landmark is found */
|
/* Search from argv0_path, until landmark is found */
|
||||||
strcpy(prefix, argv0_path);
|
wcscpy(prefix, argv0_path);
|
||||||
do {
|
do {
|
||||||
if (gotlandmark(landmark))
|
if (gotlandmark(landmark))
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -219,39 +219,39 @@ extern const char *PyWin_DLLVersionString;
|
||||||
in advance. It could be simplied now Win16/Win32s is dead!
|
in advance. It could be simplied now Win16/Win32s is dead!
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static char *
|
static wchar_t *
|
||||||
getpythonregpath(HKEY keyBase, int skipcore)
|
getpythonregpath(HKEY keyBase, int skipcore)
|
||||||
{
|
{
|
||||||
HKEY newKey = 0;
|
HKEY newKey = 0;
|
||||||
DWORD dataSize = 0;
|
DWORD dataSize = 0;
|
||||||
DWORD numKeys = 0;
|
DWORD numKeys = 0;
|
||||||
LONG rc;
|
LONG rc;
|
||||||
char *retval = NULL;
|
wchar_t *retval = NULL;
|
||||||
TCHAR *dataBuf = NULL;
|
WCHAR *dataBuf = NULL;
|
||||||
static const TCHAR keyPrefix[] = _T("Software\\Python\\PythonCore\\");
|
static const WCHAR keyPrefix[] = L"Software\\Python\\PythonCore\\";
|
||||||
static const TCHAR keySuffix[] = _T("\\PythonPath");
|
static const WCHAR keySuffix[] = L"\\PythonPath";
|
||||||
size_t versionLen;
|
size_t versionLen;
|
||||||
DWORD index;
|
DWORD index;
|
||||||
TCHAR *keyBuf = NULL;
|
WCHAR *keyBuf = NULL;
|
||||||
TCHAR *keyBufPtr;
|
WCHAR *keyBufPtr;
|
||||||
TCHAR **ppPaths = NULL;
|
WCHAR **ppPaths = NULL;
|
||||||
|
|
||||||
/* Tried to use sysget("winver") but here is too early :-( */
|
/* Tried to use sysget("winver") but here is too early :-( */
|
||||||
versionLen = _tcslen(PyWin_DLLVersionString);
|
versionLen = strlen(PyWin_DLLVersionString);
|
||||||
/* Space for all the chars, plus one \0 */
|
/* Space for all the chars, plus one \0 */
|
||||||
keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) +
|
keyBuf = keyBufPtr = malloc(sizeof(keyPrefix) +
|
||||||
sizeof(TCHAR)*(versionLen-1) +
|
sizeof(WCHAR)*(versionLen-1) +
|
||||||
sizeof(keySuffix));
|
sizeof(keySuffix));
|
||||||
if (keyBuf==NULL) goto done;
|
if (keyBuf==NULL) goto done;
|
||||||
|
|
||||||
memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(TCHAR));
|
memcpy(keyBufPtr, keyPrefix, sizeof(keyPrefix)-sizeof(WCHAR));
|
||||||
keyBufPtr += sizeof(keyPrefix)/sizeof(TCHAR) - 1;
|
keyBufPtr += sizeof(keyPrefix)/sizeof(WCHAR) - 1;
|
||||||
memcpy(keyBufPtr, PyWin_DLLVersionString, versionLen * sizeof(TCHAR));
|
mbstowcs(keyBufPtr, PyWin_DLLVersionString, versionLen);
|
||||||
keyBufPtr += versionLen;
|
keyBufPtr += versionLen;
|
||||||
/* NULL comes with this one! */
|
/* NULL comes with this one! */
|
||||||
memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
|
memcpy(keyBufPtr, keySuffix, sizeof(keySuffix));
|
||||||
/* Open the root Python key */
|
/* Open the root Python key */
|
||||||
rc=RegOpenKeyEx(keyBase,
|
rc=RegOpenKeyExW(keyBase,
|
||||||
keyBuf, /* subkey */
|
keyBuf, /* subkey */
|
||||||
0, /* reserved */
|
0, /* reserved */
|
||||||
KEY_READ,
|
KEY_READ,
|
||||||
|
@ -265,31 +265,31 @@ getpythonregpath(HKEY keyBase, int skipcore)
|
||||||
/* Allocate a temp array of char buffers, so we only need to loop
|
/* Allocate a temp array of char buffers, so we only need to loop
|
||||||
reading the registry once
|
reading the registry once
|
||||||
*/
|
*/
|
||||||
ppPaths = malloc( sizeof(TCHAR *) * numKeys );
|
ppPaths = malloc( sizeof(WCHAR *) * numKeys );
|
||||||
if (ppPaths==NULL) goto done;
|
if (ppPaths==NULL) goto done;
|
||||||
memset(ppPaths, 0, sizeof(TCHAR *) * numKeys);
|
memset(ppPaths, 0, sizeof(WCHAR *) * numKeys);
|
||||||
/* Loop over all subkeys, allocating a temp sub-buffer. */
|
/* Loop over all subkeys, allocating a temp sub-buffer. */
|
||||||
for(index=0;index<numKeys;index++) {
|
for(index=0;index<numKeys;index++) {
|
||||||
TCHAR keyBuf[MAX_PATH+1];
|
WCHAR keyBuf[MAX_PATH+1];
|
||||||
HKEY subKey = 0;
|
HKEY subKey = 0;
|
||||||
DWORD reqdSize = MAX_PATH+1;
|
DWORD reqdSize = MAX_PATH+1;
|
||||||
/* Get the sub-key name */
|
/* Get the sub-key name */
|
||||||
DWORD rc = RegEnumKeyEx(newKey, index, keyBuf, &reqdSize,
|
DWORD rc = RegEnumKeyExW(newKey, index, keyBuf, &reqdSize,
|
||||||
NULL, NULL, NULL, NULL );
|
NULL, NULL, NULL, NULL );
|
||||||
if (rc!=ERROR_SUCCESS) goto done;
|
if (rc!=ERROR_SUCCESS) goto done;
|
||||||
/* Open the sub-key */
|
/* Open the sub-key */
|
||||||
rc=RegOpenKeyEx(newKey,
|
rc=RegOpenKeyExW(newKey,
|
||||||
keyBuf, /* subkey */
|
keyBuf, /* subkey */
|
||||||
0, /* reserved */
|
0, /* reserved */
|
||||||
KEY_READ,
|
KEY_READ,
|
||||||
&subKey);
|
&subKey);
|
||||||
if (rc!=ERROR_SUCCESS) goto done;
|
if (rc!=ERROR_SUCCESS) goto done;
|
||||||
/* Find the value of the buffer size, malloc, then read it */
|
/* Find the value of the buffer size, malloc, then read it */
|
||||||
RegQueryValueEx(subKey, NULL, 0, NULL, NULL, &reqdSize);
|
RegQueryValueExW(subKey, NULL, 0, NULL, NULL, &reqdSize);
|
||||||
if (reqdSize) {
|
if (reqdSize) {
|
||||||
ppPaths[index] = malloc(reqdSize);
|
ppPaths[index] = malloc(reqdSize);
|
||||||
if (ppPaths[index]) {
|
if (ppPaths[index]) {
|
||||||
RegQueryValueEx(subKey, NULL, 0, NULL,
|
RegQueryValueExW(subKey, NULL, 0, NULL,
|
||||||
(LPBYTE)ppPaths[index],
|
(LPBYTE)ppPaths[index],
|
||||||
&reqdSize);
|
&reqdSize);
|
||||||
dataSize += reqdSize + 1; /* 1 for the ";" */
|
dataSize += reqdSize + 1; /* 1 for the ";" */
|
||||||
|
@ -302,19 +302,19 @@ getpythonregpath(HKEY keyBase, int skipcore)
|
||||||
if (dataSize == 0) goto done;
|
if (dataSize == 0) goto done;
|
||||||
|
|
||||||
/* original datasize from RegQueryInfo doesn't include the \0 */
|
/* original datasize from RegQueryInfo doesn't include the \0 */
|
||||||
dataBuf = malloc((dataSize+1) * sizeof(TCHAR));
|
dataBuf = malloc((dataSize+1) * sizeof(WCHAR));
|
||||||
if (dataBuf) {
|
if (dataBuf) {
|
||||||
TCHAR *szCur = dataBuf;
|
WCHAR *szCur = dataBuf;
|
||||||
DWORD reqdSize = dataSize;
|
DWORD reqdSize = dataSize;
|
||||||
/* Copy our collected strings */
|
/* Copy our collected strings */
|
||||||
for (index=0;index<numKeys;index++) {
|
for (index=0;index<numKeys;index++) {
|
||||||
if (index > 0) {
|
if (index > 0) {
|
||||||
*(szCur++) = _T(';');
|
*(szCur++) = L';';
|
||||||
dataSize--;
|
dataSize--;
|
||||||
}
|
}
|
||||||
if (ppPaths[index]) {
|
if (ppPaths[index]) {
|
||||||
Py_ssize_t len = _tcslen(ppPaths[index]);
|
Py_ssize_t len = wcslen(ppPaths[index]);
|
||||||
_tcsncpy(szCur, ppPaths[index], len);
|
wcsncpy(szCur, ppPaths[index], len);
|
||||||
szCur += len;
|
szCur += len;
|
||||||
assert(dataSize > (DWORD)len);
|
assert(dataSize > (DWORD)len);
|
||||||
dataSize -= (DWORD)len;
|
dataSize -= (DWORD)len;
|
||||||
|
@ -325,30 +325,17 @@ getpythonregpath(HKEY keyBase, int skipcore)
|
||||||
else {
|
else {
|
||||||
/* If we have no values, we dont need a ';' */
|
/* If we have no values, we dont need a ';' */
|
||||||
if (numKeys) {
|
if (numKeys) {
|
||||||
*(szCur++) = _T(';');
|
*(szCur++) = L';';
|
||||||
dataSize--;
|
dataSize--;
|
||||||
}
|
}
|
||||||
/* Now append the core path entries -
|
/* Now append the core path entries -
|
||||||
this will include the NULL
|
this will include the NULL
|
||||||
*/
|
*/
|
||||||
rc = RegQueryValueEx(newKey, NULL, 0, NULL,
|
rc = RegQueryValueExW(newKey, NULL, 0, NULL,
|
||||||
(LPBYTE)szCur, &dataSize);
|
(LPBYTE)szCur, &dataSize);
|
||||||
}
|
}
|
||||||
/* And set the result - caller must free
|
/* And set the result - caller must free */
|
||||||
If MBCS, it is fine as is. If Unicode, allocate new
|
|
||||||
buffer and convert.
|
|
||||||
*/
|
|
||||||
#ifdef UNICODE
|
|
||||||
retval = (char *)malloc(reqdSize+1);
|
|
||||||
if (retval)
|
|
||||||
WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
dataBuf, -1, /* source */
|
|
||||||
retval, reqdSize+1, /* dest */
|
|
||||||
NULL, NULL);
|
|
||||||
free(dataBuf);
|
|
||||||
#else
|
|
||||||
retval = dataBuf;
|
retval = dataBuf;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
/* Loop freeing my temp buffers */
|
/* Loop freeing my temp buffers */
|
||||||
|
@ -368,45 +355,21 @@ done:
|
||||||
static void
|
static void
|
||||||
get_progpath(void)
|
get_progpath(void)
|
||||||
{
|
{
|
||||||
extern char *Py_GetProgramName(void);
|
extern wchar_t *Py_GetProgramName(void);
|
||||||
char *path = getenv("PATH");
|
wchar_t *path = _wgetenv(L"PATH");
|
||||||
char *prog = Py_GetProgramName();
|
wchar_t *prog = Py_GetProgramName();
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
extern HANDLE PyWin_DLLhModule;
|
extern HANDLE PyWin_DLLhModule;
|
||||||
#ifdef UNICODE
|
|
||||||
WCHAR wprogpath[MAXPATHLEN+1];
|
|
||||||
/* Windows documents that GetModuleFileName() will "truncate",
|
|
||||||
but makes no mention of the null terminator. Play it safe.
|
|
||||||
PLUS Windows itself defines MAX_PATH as the same, but anyway...
|
|
||||||
*/
|
|
||||||
wprogpath[MAXPATHLEN]=_T('\0');
|
|
||||||
if (PyWin_DLLhModule &&
|
|
||||||
GetModuleFileName(PyWin_DLLhModule, wprogpath, MAXPATHLEN)) {
|
|
||||||
WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
wprogpath, -1,
|
|
||||||
dllpath, MAXPATHLEN+1,
|
|
||||||
NULL, NULL);
|
|
||||||
}
|
|
||||||
wprogpath[MAXPATHLEN]=_T('\0');
|
|
||||||
if (GetModuleFileName(NULL, wprogpath, MAXPATHLEN)) {
|
|
||||||
WideCharToMultiByte(CP_ACP, 0,
|
|
||||||
wprogpath, -1,
|
|
||||||
progpath, MAXPATHLEN+1,
|
|
||||||
NULL, NULL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
/* static init of progpath ensures final char remains \0 */
|
/* static init of progpath ensures final char remains \0 */
|
||||||
if (PyWin_DLLhModule)
|
if (PyWin_DLLhModule)
|
||||||
if (!GetModuleFileName(PyWin_DLLhModule, dllpath, MAXPATHLEN))
|
if (!GetModuleFileNameW(PyWin_DLLhModule, dllpath, MAXPATHLEN))
|
||||||
dllpath[0] = 0;
|
dllpath[0] = 0;
|
||||||
if (GetModuleFileName(NULL, progpath, MAXPATHLEN))
|
if (GetModuleFileNameW(NULL, progpath, MAXPATHLEN))
|
||||||
return;
|
return;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
if (prog == NULL || *prog == '\0')
|
if (prog == NULL || *prog == '\0')
|
||||||
prog = "python";
|
prog = L"python";
|
||||||
|
|
||||||
/* If there is no slash in the argv0 path, then we have to
|
/* If there is no slash in the argv0 path, then we have to
|
||||||
* assume python is on the user's $PATH, since there's no
|
* assume python is on the user's $PATH, since there's no
|
||||||
|
@ -414,24 +377,24 @@ get_progpath(void)
|
||||||
* $PATH isn't exported, you lose.
|
* $PATH isn't exported, you lose.
|
||||||
*/
|
*/
|
||||||
#ifdef ALTSEP
|
#ifdef ALTSEP
|
||||||
if (strchr(prog, SEP) || strchr(prog, ALTSEP))
|
if (wcschr(prog, SEP) || wcschr(prog, ALTSEP))
|
||||||
#else
|
#else
|
||||||
if (strchr(prog, SEP))
|
if (wcschr(prog, SEP))
|
||||||
#endif
|
#endif
|
||||||
strncpy(progpath, prog, MAXPATHLEN);
|
wcsncpy(progpath, prog, MAXPATHLEN);
|
||||||
else if (path) {
|
else if (path) {
|
||||||
while (1) {
|
while (1) {
|
||||||
char *delim = strchr(path, DELIM);
|
wchar_t *delim = wcschr(path, DELIM);
|
||||||
|
|
||||||
if (delim) {
|
if (delim) {
|
||||||
size_t len = delim - path;
|
size_t len = delim - path;
|
||||||
/* ensure we can't overwrite buffer */
|
/* ensure we can't overwrite buffer */
|
||||||
len = min(MAXPATHLEN,len);
|
len = min(MAXPATHLEN,len);
|
||||||
strncpy(progpath, path, len);
|
wcsncpy(progpath, path, len);
|
||||||
*(progpath + len) = '\0';
|
*(progpath + len) = '\0';
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strncpy(progpath, path, MAXPATHLEN);
|
wcsncpy(progpath, path, MAXPATHLEN);
|
||||||
|
|
||||||
/* join() is safe for MAXPATHLEN+1 size buffer */
|
/* join() is safe for MAXPATHLEN+1 size buffer */
|
||||||
join(progpath, prog);
|
join(progpath, prog);
|
||||||
|
@ -452,23 +415,31 @@ get_progpath(void)
|
||||||
static void
|
static void
|
||||||
calculate_path(void)
|
calculate_path(void)
|
||||||
{
|
{
|
||||||
char argv0_path[MAXPATHLEN+1];
|
wchar_t argv0_path[MAXPATHLEN+1];
|
||||||
char *buf;
|
wchar_t *buf;
|
||||||
size_t bufsz;
|
size_t bufsz;
|
||||||
char *pythonhome = Py_GetPythonHome();
|
wchar_t *pythonhome = Py_GetPythonHome();
|
||||||
char *envpath = Py_GETENV("PYTHONPATH");
|
char *_envpath = Py_GETENV("PYTHONPATH");
|
||||||
|
wchar_t wenvpath[MAXPATHLEN+1];
|
||||||
|
wchar_t *envpath = NULL;
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
int skiphome, skipdefault;
|
int skiphome, skipdefault;
|
||||||
char *machinepath = NULL;
|
wchar_t *machinepath = NULL;
|
||||||
char *userpath = NULL;
|
wchar_t *userpath = NULL;
|
||||||
char zip_path[MAXPATHLEN+1];
|
wchar_t zip_path[MAXPATHLEN+1];
|
||||||
size_t len;
|
size_t len;
|
||||||
#endif
|
#endif
|
||||||
|
if (_envpath) {
|
||||||
|
size_t r = mbstowcs(wenvpath, _envpath, MAXPATHLEN+1);
|
||||||
|
envpath = wenvpath;
|
||||||
|
if (r == (size_t)-1 || r >= MAXPATHLEN)
|
||||||
|
envpath = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
get_progpath();
|
get_progpath();
|
||||||
/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
|
/* progpath guaranteed \0 terminated in MAXPATH+1 bytes. */
|
||||||
strcpy(argv0_path, progpath);
|
wcscpy(argv0_path, progpath);
|
||||||
reduce(argv0_path);
|
reduce(argv0_path);
|
||||||
if (pythonhome == NULL || *pythonhome == '\0') {
|
if (pythonhome == NULL || *pythonhome == '\0') {
|
||||||
if (search_for_prefix(argv0_path, LANDMARK))
|
if (search_for_prefix(argv0_path, LANDMARK))
|
||||||
|
@ -477,7 +448,7 @@ calculate_path(void)
|
||||||
pythonhome = NULL;
|
pythonhome = NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
strncpy(prefix, pythonhome, MAXPATHLEN);
|
wcsncpy(prefix, pythonhome, MAXPATHLEN);
|
||||||
|
|
||||||
if (envpath && *envpath == '\0')
|
if (envpath && *envpath == '\0')
|
||||||
envpath = NULL;
|
envpath = NULL;
|
||||||
|
@ -486,11 +457,11 @@ calculate_path(void)
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
/* Calculate zip archive path */
|
/* Calculate zip archive path */
|
||||||
if (dllpath[0]) /* use name of python DLL */
|
if (dllpath[0]) /* use name of python DLL */
|
||||||
strncpy(zip_path, dllpath, MAXPATHLEN);
|
wcsncpy(zip_path, dllpath, MAXPATHLEN);
|
||||||
else /* use name of executable program */
|
else /* use name of executable program */
|
||||||
strncpy(zip_path, progpath, MAXPATHLEN);
|
wcsncpy(zip_path, progpath, MAXPATHLEN);
|
||||||
zip_path[MAXPATHLEN] = '\0';
|
zip_path[MAXPATHLEN] = '\0';
|
||||||
len = strlen(zip_path);
|
len = wcslen(zip_path);
|
||||||
if (len > 4) {
|
if (len > 4) {
|
||||||
zip_path[len-3] = 'z'; /* change ending to "zip" */
|
zip_path[len-3] = 'z'; /* change ending to "zip" */
|
||||||
zip_path[len-2] = 'i';
|
zip_path[len-2] = 'i';
|
||||||
|
@ -524,29 +495,29 @@ calculate_path(void)
|
||||||
|
|
||||||
/* Calculate size of return buffer */
|
/* Calculate size of return buffer */
|
||||||
if (pythonhome != NULL) {
|
if (pythonhome != NULL) {
|
||||||
char *p;
|
wchar_t *p;
|
||||||
bufsz = 1;
|
bufsz = 1;
|
||||||
for (p = PYTHONPATH; *p; p++) {
|
for (p = PYTHONPATH; *p; p++) {
|
||||||
if (*p == DELIM)
|
if (*p == DELIM)
|
||||||
bufsz++; /* number of DELIM plus one */
|
bufsz++; /* number of DELIM plus one */
|
||||||
}
|
}
|
||||||
bufsz *= strlen(pythonhome);
|
bufsz *= wcslen(pythonhome);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
bufsz = 0;
|
bufsz = 0;
|
||||||
bufsz += strlen(PYTHONPATH) + 1;
|
bufsz += wcslen(PYTHONPATH) + 1;
|
||||||
bufsz += strlen(argv0_path) + 1;
|
bufsz += wcslen(argv0_path) + 1;
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
if (userpath)
|
if (userpath)
|
||||||
bufsz += strlen(userpath) + 1;
|
bufsz += wcslen(userpath) + 1;
|
||||||
if (machinepath)
|
if (machinepath)
|
||||||
bufsz += strlen(machinepath) + 1;
|
bufsz += wcslen(machinepath) + 1;
|
||||||
bufsz += strlen(zip_path) + 1;
|
bufsz += wcslen(zip_path) + 1;
|
||||||
#endif
|
#endif
|
||||||
if (envpath != NULL)
|
if (envpath != NULL)
|
||||||
bufsz += strlen(envpath) + 1;
|
bufsz += wcslen(envpath) + 1;
|
||||||
|
|
||||||
module_search_path = buf = malloc(bufsz);
|
module_search_path = buf = malloc(bufsz*sizeof(wchar_t));
|
||||||
if (buf == NULL) {
|
if (buf == NULL) {
|
||||||
/* We can't exit, so print a warning and limp along */
|
/* We can't exit, so print a warning and limp along */
|
||||||
fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
|
fprintf(stderr, "Can't malloc dynamic PYTHONPATH.\n");
|
||||||
|
@ -568,57 +539,57 @@ calculate_path(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (envpath) {
|
if (envpath) {
|
||||||
strcpy(buf, envpath);
|
wcscpy(buf, envpath);
|
||||||
buf = strchr(buf, '\0');
|
buf = wcschr(buf, L'\0');
|
||||||
*buf++ = DELIM;
|
*buf++ = DELIM;
|
||||||
}
|
}
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
if (zip_path[0]) {
|
if (zip_path[0]) {
|
||||||
strcpy(buf, zip_path);
|
wcscpy(buf, zip_path);
|
||||||
buf = strchr(buf, '\0');
|
buf = wcschr(buf, L'\0');
|
||||||
*buf++ = DELIM;
|
*buf++ = DELIM;
|
||||||
}
|
}
|
||||||
if (userpath) {
|
if (userpath) {
|
||||||
strcpy(buf, userpath);
|
wcscpy(buf, userpath);
|
||||||
buf = strchr(buf, '\0');
|
buf = wcschr(buf, L'\0');
|
||||||
*buf++ = DELIM;
|
*buf++ = DELIM;
|
||||||
free(userpath);
|
free(userpath);
|
||||||
}
|
}
|
||||||
if (machinepath) {
|
if (machinepath) {
|
||||||
strcpy(buf, machinepath);
|
wcscpy(buf, machinepath);
|
||||||
buf = strchr(buf, '\0');
|
buf = wcschr(buf, L'\0');
|
||||||
*buf++ = DELIM;
|
*buf++ = DELIM;
|
||||||
free(machinepath);
|
free(machinepath);
|
||||||
}
|
}
|
||||||
if (pythonhome == NULL) {
|
if (pythonhome == NULL) {
|
||||||
if (!skipdefault) {
|
if (!skipdefault) {
|
||||||
strcpy(buf, PYTHONPATH);
|
wcscpy(buf, PYTHONPATH);
|
||||||
buf = strchr(buf, '\0');
|
buf = wcschr(buf, L'\0');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (pythonhome == NULL) {
|
if (pythonhome == NULL) {
|
||||||
strcpy(buf, PYTHONPATH);
|
wcscpy(buf, PYTHONPATH);
|
||||||
buf = strchr(buf, '\0');
|
buf = wcschr(buf, L'\0');
|
||||||
}
|
}
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
else {
|
else {
|
||||||
char *p = PYTHONPATH;
|
wchar_t *p = PYTHONPATH;
|
||||||
char *q;
|
wchar_t *q;
|
||||||
size_t n;
|
size_t n;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
q = strchr(p, DELIM);
|
q = wcschr(p, DELIM);
|
||||||
if (q == NULL)
|
if (q == NULL)
|
||||||
n = strlen(p);
|
n = wcslen(p);
|
||||||
else
|
else
|
||||||
n = q-p;
|
n = q-p;
|
||||||
if (p[0] == '.' && is_sep(p[1])) {
|
if (p[0] == '.' && is_sep(p[1])) {
|
||||||
strcpy(buf, pythonhome);
|
wcscpy(buf, pythonhome);
|
||||||
buf = strchr(buf, '\0');
|
buf = wcschr(buf, L'\0');
|
||||||
p++;
|
p++;
|
||||||
n--;
|
n--;
|
||||||
}
|
}
|
||||||
strncpy(buf, p, n);
|
wcsncpy(buf, p, n);
|
||||||
buf += n;
|
buf += n;
|
||||||
if (q == NULL)
|
if (q == NULL)
|
||||||
break;
|
break;
|
||||||
|
@ -628,10 +599,10 @@ calculate_path(void)
|
||||||
}
|
}
|
||||||
if (argv0_path) {
|
if (argv0_path) {
|
||||||
*buf++ = DELIM;
|
*buf++ = DELIM;
|
||||||
strcpy(buf, argv0_path);
|
wcscpy(buf, argv0_path);
|
||||||
buf = strchr(buf, '\0');
|
buf = wcschr(buf, L'\0');
|
||||||
}
|
}
|
||||||
*buf = '\0';
|
*buf = L'\0';
|
||||||
/* Now to pull one last hack/trick. If sys.prefix is
|
/* Now to pull one last hack/trick. If sys.prefix is
|
||||||
empty, then try and find it somewhere on the paths
|
empty, then try and find it somewhere on the paths
|
||||||
we calculated. We scan backwards, as our general policy
|
we calculated. We scan backwards, as our general policy
|
||||||
|
@ -640,12 +611,12 @@ calculate_path(void)
|
||||||
on the path, and that our 'prefix' directory is
|
on the path, and that our 'prefix' directory is
|
||||||
the parent of that.
|
the parent of that.
|
||||||
*/
|
*/
|
||||||
if (*prefix=='\0') {
|
if (*prefix==L'\0') {
|
||||||
char lookBuf[MAXPATHLEN+1];
|
wchar_t lookBuf[MAXPATHLEN+1];
|
||||||
char *look = buf - 1; /* 'buf' is at the end of the buffer */
|
wchar_t *look = buf - 1; /* 'buf' is at the end of the buffer */
|
||||||
while (1) {
|
while (1) {
|
||||||
Py_ssize_t nchars;
|
Py_ssize_t nchars;
|
||||||
char *lookEnd = look;
|
wchar_t *lookEnd = look;
|
||||||
/* 'look' will end up one character before the
|
/* 'look' will end up one character before the
|
||||||
start of the path in question - even if this
|
start of the path in question - even if this
|
||||||
is one character before the start of the buffer
|
is one character before the start of the buffer
|
||||||
|
@ -653,8 +624,8 @@ calculate_path(void)
|
||||||
while (look >= module_search_path && *look != DELIM)
|
while (look >= module_search_path && *look != DELIM)
|
||||||
look--;
|
look--;
|
||||||
nchars = lookEnd-look;
|
nchars = lookEnd-look;
|
||||||
strncpy(lookBuf, look+1, nchars);
|
wcsncpy(lookBuf, look+1, nchars);
|
||||||
lookBuf[nchars] = '\0';
|
lookBuf[nchars] = L'\0';
|
||||||
/* Up one level to the parent */
|
/* Up one level to the parent */
|
||||||
reduce(lookBuf);
|
reduce(lookBuf);
|
||||||
if (search_for_prefix(lookBuf, LANDMARK)) {
|
if (search_for_prefix(lookBuf, LANDMARK)) {
|
||||||
|
@ -671,7 +642,7 @@ calculate_path(void)
|
||||||
|
|
||||||
/* External interface */
|
/* External interface */
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetPath(void)
|
Py_GetPath(void)
|
||||||
{
|
{
|
||||||
if (!module_search_path)
|
if (!module_search_path)
|
||||||
|
@ -679,7 +650,7 @@ Py_GetPath(void)
|
||||||
return module_search_path;
|
return module_search_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetPrefix(void)
|
Py_GetPrefix(void)
|
||||||
{
|
{
|
||||||
if (!module_search_path)
|
if (!module_search_path)
|
||||||
|
@ -687,13 +658,13 @@ Py_GetPrefix(void)
|
||||||
return prefix;
|
return prefix;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetExecPrefix(void)
|
Py_GetExecPrefix(void)
|
||||||
{
|
{
|
||||||
return Py_GetPrefix();
|
return Py_GetPrefix();
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetProgramFullPath(void)
|
Py_GetProgramFullPath(void)
|
||||||
{
|
{
|
||||||
if (!module_search_path)
|
if (!module_search_path)
|
||||||
|
|
|
@ -80,7 +80,7 @@ WIN32 is still required for the locale module.
|
||||||
#define MS_WIN32 /* only support win32 and greater. */
|
#define MS_WIN32 /* only support win32 and greater. */
|
||||||
#define MS_WINDOWS
|
#define MS_WINDOWS
|
||||||
#ifndef PYTHONPATH
|
#ifndef PYTHONPATH
|
||||||
# define PYTHONPATH ".\\DLLs;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk"
|
# define PYTHONPATH L".\\DLLs;.\\lib;.\\lib\\plat-win;.\\lib\\lib-tk"
|
||||||
#endif
|
#endif
|
||||||
#define NT_THREADS
|
#define NT_THREADS
|
||||||
#define WITH_THREAD
|
#define WITH_THREAD
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
/* Python interpreter main program for frozen scripts */
|
/* Python interpreter main program for frozen scripts */
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
extern void PyWinFreeze_ExeInit(void);
|
extern void PyWinFreeze_ExeInit(void);
|
||||||
|
@ -15,9 +16,13 @@ int
|
||||||
Py_FrozenMain(int argc, char **argv)
|
Py_FrozenMain(int argc, char **argv)
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
int n, sts;
|
int i, n, sts;
|
||||||
int inspect = 0;
|
int inspect = 0;
|
||||||
int unbuffered = 0;
|
int unbuffered = 0;
|
||||||
|
char *oldloc;
|
||||||
|
wchar_t **argv_copy = PyMem_Malloc(sizeof(wchar_t*)*argc);
|
||||||
|
/* We need a second copies, as Python might modify the first one. */
|
||||||
|
wchar_t **argv_copy2 = PyMem_Malloc(sizeof(wchar_t*)*argc);
|
||||||
|
|
||||||
Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
|
Py_FrozenFlag = 1; /* Suppress errors from getpath.c */
|
||||||
|
|
||||||
|
@ -32,10 +37,33 @@ Py_FrozenMain(int argc, char **argv)
|
||||||
setbuf(stderr, (char *)NULL);
|
setbuf(stderr, (char *)NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!argv_copy) {
|
||||||
|
fprintf(stderr, "out of memory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
oldloc = setlocale(LC_ALL, NULL);
|
||||||
|
setlocale(LC_ALL, "");
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
size_t argsize = mbstowcs(NULL, argv[i], 0);
|
||||||
|
if (argsize == (size_t)-1) {
|
||||||
|
fprintf(stderr, "Could not convert argument %d to string", i);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
argv_copy[i] = PyMem_Malloc((argsize+1)*sizeof(wchar_t));
|
||||||
|
argv_copy2[i] = argv_copy[i];
|
||||||
|
if (!argv_copy[i]) {
|
||||||
|
fprintf(stderr, "out of memory");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
mbstowcs(argv_copy[i], argv[i], argsize+1);
|
||||||
|
}
|
||||||
|
setlocale(LC_ALL, oldloc);
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
PyInitFrozenExtensions();
|
PyInitFrozenExtensions();
|
||||||
#endif /* MS_WINDOWS */
|
#endif /* MS_WINDOWS */
|
||||||
Py_SetProgramName(argv[0]);
|
Py_SetProgramName(argv_copy[0]);
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
PyWinFreeze_ExeInit();
|
PyWinFreeze_ExeInit();
|
||||||
|
@ -45,7 +73,7 @@ Py_FrozenMain(int argc, char **argv)
|
||||||
fprintf(stderr, "Python %s\n%s\n",
|
fprintf(stderr, "Python %s\n%s\n",
|
||||||
Py_GetVersion(), Py_GetCopyright());
|
Py_GetVersion(), Py_GetCopyright());
|
||||||
|
|
||||||
PySys_SetArgv(argc, argv);
|
PySys_SetArgv(argc, argv_copy);
|
||||||
|
|
||||||
n = PyImport_ImportFrozenModule("__main__");
|
n = PyImport_ImportFrozenModule("__main__");
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
|
@ -64,5 +92,10 @@ Py_FrozenMain(int argc, char **argv)
|
||||||
PyWinFreeze_ExeTerm();
|
PyWinFreeze_ExeTerm();
|
||||||
#endif
|
#endif
|
||||||
Py_Finalize();
|
Py_Finalize();
|
||||||
|
for (i = 0; i < argc; i++) {
|
||||||
|
PyMem_Free(argv_copy2[i]);
|
||||||
|
}
|
||||||
|
PyMem_Free(argv_copy);
|
||||||
|
PyMem_Free(argv_copy2);
|
||||||
return sts;
|
return sts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,11 @@
|
||||||
/* Modified to support --help and --version, as well as /? on Windows
|
/* Modified to support --help and --version, as well as /? on Windows
|
||||||
* by Georg Brandl. */
|
* by Georg Brandl. */
|
||||||
|
|
||||||
|
#include <Python.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <pygetopt.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -36,40 +39,40 @@ extern "C" {
|
||||||
|
|
||||||
int _PyOS_opterr = 1; /* generate error messages */
|
int _PyOS_opterr = 1; /* generate error messages */
|
||||||
int _PyOS_optind = 1; /* index into argv array */
|
int _PyOS_optind = 1; /* index into argv array */
|
||||||
char *_PyOS_optarg = NULL; /* optional argument */
|
wchar_t *_PyOS_optarg = NULL; /* optional argument */
|
||||||
|
|
||||||
int _PyOS_GetOpt(int argc, char **argv, char *optstring)
|
int _PyOS_GetOpt(int argc, wchar_t **argv, wchar_t *optstring)
|
||||||
{
|
{
|
||||||
static char *opt_ptr = "";
|
static wchar_t *opt_ptr = L"";
|
||||||
char *ptr;
|
wchar_t *ptr;
|
||||||
int option;
|
wchar_t option;
|
||||||
|
|
||||||
if (*opt_ptr == '\0') {
|
if (*opt_ptr == '\0') {
|
||||||
|
|
||||||
if (_PyOS_optind >= argc)
|
if (_PyOS_optind >= argc)
|
||||||
return -1;
|
return -1;
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
else if (strcmp(argv[_PyOS_optind], "/?") == 0) {
|
else if (wcscmp(argv[_PyOS_optind], L"/?") == 0) {
|
||||||
++_PyOS_optind;
|
++_PyOS_optind;
|
||||||
return 'h';
|
return 'h';
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
else if (argv[_PyOS_optind][0] != '-' ||
|
else if (argv[_PyOS_optind][0] != L'-' ||
|
||||||
argv[_PyOS_optind][1] == '\0' /* lone dash */ )
|
argv[_PyOS_optind][1] == L'\0' /* lone dash */ )
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
else if (strcmp(argv[_PyOS_optind], "--") == 0) {
|
else if (wcscmp(argv[_PyOS_optind], L"--") == 0) {
|
||||||
++_PyOS_optind;
|
++_PyOS_optind;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(argv[_PyOS_optind], "--help") == 0) {
|
else if (wcscmp(argv[_PyOS_optind], L"--help") == 0) {
|
||||||
++_PyOS_optind;
|
++_PyOS_optind;
|
||||||
return 'h';
|
return 'h';
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (strcmp(argv[_PyOS_optind], "--version") == 0) {
|
else if (wcscmp(argv[_PyOS_optind], L"--version") == 0) {
|
||||||
++_PyOS_optind;
|
++_PyOS_optind;
|
||||||
return 'V';
|
return 'V';
|
||||||
}
|
}
|
||||||
|
@ -78,27 +81,27 @@ int _PyOS_GetOpt(int argc, char **argv, char *optstring)
|
||||||
opt_ptr = &argv[_PyOS_optind++][1];
|
opt_ptr = &argv[_PyOS_optind++][1];
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( (option = *opt_ptr++) == '\0')
|
if ( (option = *opt_ptr++) == L'\0')
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if ((ptr = strchr(optstring, option)) == NULL) {
|
if ((ptr = wcschr(optstring, option)) == NULL) {
|
||||||
if (_PyOS_opterr)
|
if (_PyOS_opterr)
|
||||||
fprintf(stderr, "Unknown option: -%c\n", option);
|
fprintf(stderr, "Unknown option: -%c\n", (char)option);
|
||||||
|
|
||||||
return '_';
|
return '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(ptr + 1) == ':') {
|
if (*(ptr + 1) == L':') {
|
||||||
if (*opt_ptr != '\0') {
|
if (*opt_ptr != L'\0') {
|
||||||
_PyOS_optarg = opt_ptr;
|
_PyOS_optarg = opt_ptr;
|
||||||
opt_ptr = "";
|
opt_ptr = L"";
|
||||||
}
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
if (_PyOS_optind >= argc) {
|
if (_PyOS_optind >= argc) {
|
||||||
if (_PyOS_opterr)
|
if (_PyOS_opterr)
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Argument expected for the -%c option\n", option);
|
"Argument expected for the -%c option\n", (char)option);
|
||||||
return '_';
|
return '_';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "ast.h"
|
#include "ast.h"
|
||||||
#include "eval.h"
|
#include "eval.h"
|
||||||
#include "marshal.h"
|
#include "marshal.h"
|
||||||
|
#include "osdefs.h"
|
||||||
|
|
||||||
#ifdef HAVE_SIGNAL_H
|
#ifdef HAVE_SIGNAL_H
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
@ -30,6 +31,7 @@
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
#undef BYTE
|
#undef BYTE
|
||||||
#include "windows.h"
|
#include "windows.h"
|
||||||
|
#define PATH_MAX MAXPATHLEN
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef Py_REF_DEBUG
|
#ifndef Py_REF_DEBUG
|
||||||
|
@ -44,7 +46,7 @@
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern char *Py_GetPath(void);
|
extern wchar_t *Py_GetPath(void);
|
||||||
|
|
||||||
extern grammar _PyParser_Grammar; /* From graminit.c */
|
extern grammar _PyParser_Grammar; /* From graminit.c */
|
||||||
|
|
||||||
|
@ -646,35 +648,43 @@ Py_EndInterpreter(PyThreadState *tstate)
|
||||||
PyInterpreterState_Delete(interp);
|
PyInterpreterState_Delete(interp);
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *progname = "python";
|
static wchar_t *progname = L"python";
|
||||||
|
|
||||||
void
|
void
|
||||||
Py_SetProgramName(char *pn)
|
Py_SetProgramName(wchar_t *pn)
|
||||||
{
|
{
|
||||||
if (pn && *pn)
|
if (pn && *pn)
|
||||||
progname = pn;
|
progname = pn;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetProgramName(void)
|
Py_GetProgramName(void)
|
||||||
{
|
{
|
||||||
return progname;
|
return progname;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *default_home = NULL;
|
static wchar_t *default_home = NULL;
|
||||||
|
static wchar_t env_home[PATH_MAX+1];
|
||||||
|
|
||||||
void
|
void
|
||||||
Py_SetPythonHome(char *home)
|
Py_SetPythonHome(wchar_t *home)
|
||||||
{
|
{
|
||||||
default_home = home;
|
default_home = home;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
wchar_t *
|
||||||
Py_GetPythonHome(void)
|
Py_GetPythonHome(void)
|
||||||
{
|
{
|
||||||
char *home = default_home;
|
wchar_t *home = default_home;
|
||||||
if (home == NULL && !Py_IgnoreEnvironmentFlag)
|
if (home == NULL && !Py_IgnoreEnvironmentFlag) {
|
||||||
home = Py_GETENV("PYTHONHOME");
|
char* chome = Py_GETENV("PYTHONHOME");
|
||||||
|
if (chome) {
|
||||||
|
size_t r = mbstowcs(env_home, chome, PATH_MAX+1);
|
||||||
|
if (r != (size_t)-1 && r <= PATH_MAX)
|
||||||
|
home = env_home;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
return home;
|
return home;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -882,7 +882,7 @@ PySys_ResetWarnOptions(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PySys_AddWarnOption(const char *s)
|
PySys_AddWarnOption(const wchar_t *s)
|
||||||
{
|
{
|
||||||
PyObject *str;
|
PyObject *str;
|
||||||
|
|
||||||
|
@ -892,7 +892,7 @@ PySys_AddWarnOption(const char *s)
|
||||||
if (warnoptions == NULL)
|
if (warnoptions == NULL)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
str = PyUnicode_FromString(s);
|
str = PyUnicode_FromWideChar(s, -1);
|
||||||
if (str != NULL) {
|
if (str != NULL) {
|
||||||
PyList_Append(warnoptions, str);
|
PyList_Append(warnoptions, str);
|
||||||
Py_DECREF(str);
|
Py_DECREF(str);
|
||||||
|
@ -1222,12 +1222,12 @@ _PySys_Init(void)
|
||||||
SET_SYS_FROM_STRING("platform",
|
SET_SYS_FROM_STRING("platform",
|
||||||
PyUnicode_FromString(Py_GetPlatform()));
|
PyUnicode_FromString(Py_GetPlatform()));
|
||||||
SET_SYS_FROM_STRING("executable",
|
SET_SYS_FROM_STRING("executable",
|
||||||
PyUnicode_DecodeFSDefault(
|
PyUnicode_FromWideChar(
|
||||||
Py_GetProgramFullPath()));
|
Py_GetProgramFullPath(), -1));
|
||||||
SET_SYS_FROM_STRING("prefix",
|
SET_SYS_FROM_STRING("prefix",
|
||||||
PyUnicode_DecodeFSDefault(Py_GetPrefix()));
|
PyUnicode_FromWideChar(Py_GetPrefix(), -1));
|
||||||
SET_SYS_FROM_STRING("exec_prefix",
|
SET_SYS_FROM_STRING("exec_prefix",
|
||||||
PyUnicode_DecodeFSDefault(Py_GetExecPrefix()));
|
PyUnicode_FromWideChar(Py_GetExecPrefix(), -1));
|
||||||
SET_SYS_FROM_STRING("maxsize",
|
SET_SYS_FROM_STRING("maxsize",
|
||||||
PyLong_FromSsize_t(PY_SSIZE_T_MAX));
|
PyLong_FromSsize_t(PY_SSIZE_T_MAX));
|
||||||
SET_SYS_FROM_STRING("float_info",
|
SET_SYS_FROM_STRING("float_info",
|
||||||
|
@ -1280,15 +1280,15 @@ _PySys_Init(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
makepathobject(const char *path, int delim)
|
makepathobject(const wchar_t *path, wchar_t delim)
|
||||||
{
|
{
|
||||||
int i, n;
|
int i, n;
|
||||||
const char *p;
|
const wchar_t *p;
|
||||||
PyObject *v, *w;
|
PyObject *v, *w;
|
||||||
|
|
||||||
n = 1;
|
n = 1;
|
||||||
p = path;
|
p = path;
|
||||||
while ((p = strchr(p, delim)) != NULL) {
|
while ((p = wcschr(p, delim)) != NULL) {
|
||||||
n++;
|
n++;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
|
@ -1296,10 +1296,10 @@ makepathobject(const char *path, int delim)
|
||||||
if (v == NULL)
|
if (v == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
for (i = 0; ; i++) {
|
for (i = 0; ; i++) {
|
||||||
p = strchr(path, delim);
|
p = wcschr(path, delim);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
p = strchr(path, '\0'); /* End of string */
|
p = wcschr(path, L'\0'); /* End of string */
|
||||||
w = PyUnicode_DecodeFSDefaultAndSize(path, (Py_ssize_t) (p - path));
|
w = PyUnicode_FromWideChar(path, (Py_ssize_t)(p - path));
|
||||||
if (w == NULL) {
|
if (w == NULL) {
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -1313,7 +1313,7 @@ makepathobject(const char *path, int delim)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
PySys_SetPath(const char *path)
|
PySys_SetPath(const wchar_t *path)
|
||||||
{
|
{
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
if ((v = makepathobject(path, DELIM)) == NULL)
|
if ((v = makepathobject(path, DELIM)) == NULL)
|
||||||
|
@ -1324,12 +1324,12 @@ PySys_SetPath(const char *path)
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *
|
static PyObject *
|
||||||
makeargvobject(int argc, char **argv)
|
makeargvobject(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
PyObject *av;
|
PyObject *av;
|
||||||
if (argc <= 0 || argv == NULL) {
|
if (argc <= 0 || argv == NULL) {
|
||||||
/* Ensure at least one (empty) argument is seen */
|
/* Ensure at least one (empty) argument is seen */
|
||||||
static char *empty_argv[1] = {""};
|
static wchar_t *empty_argv[1] = {L""};
|
||||||
argv = empty_argv;
|
argv = empty_argv;
|
||||||
argc = 1;
|
argc = 1;
|
||||||
}
|
}
|
||||||
|
@ -1351,7 +1351,7 @@ makeargvobject(int argc, char **argv)
|
||||||
} else
|
} else
|
||||||
v = PyUnicode_FromString(argv[i]);
|
v = PyUnicode_FromString(argv[i]);
|
||||||
#else
|
#else
|
||||||
PyObject *v = PyUnicode_FromString(argv[i]);
|
PyObject *v = PyUnicode_FromWideChar(argv[i], -1);
|
||||||
#endif
|
#endif
|
||||||
if (v == NULL) {
|
if (v == NULL) {
|
||||||
Py_DECREF(av);
|
Py_DECREF(av);
|
||||||
|
@ -1364,13 +1364,38 @@ makeargvobject(int argc, char **argv)
|
||||||
return av;
|
return av;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_REALPATH
|
||||||
|
static wchar_t*
|
||||||
|
_wrealpath(const wchar_t *path, wchar_t *resolved_path)
|
||||||
|
{
|
||||||
|
char cpath[PATH_MAX];
|
||||||
|
char cresolved_path[PATH_MAX];
|
||||||
|
char *res;
|
||||||
|
size_t r;
|
||||||
|
r = wcstombs(cpath, path, PATH_MAX);
|
||||||
|
if (r == (size_t)-1 || r >= PATH_MAX) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
res = realpath(cpath, cresolved_path);
|
||||||
|
if (res == NULL)
|
||||||
|
return NULL;
|
||||||
|
r = mbstowcs(resolved_path, cresolved_path, PATH_MAX);
|
||||||
|
if (r == (size_t)-1 || r >= PATH_MAX) {
|
||||||
|
errno = EINVAL;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return resolved_path;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void
|
void
|
||||||
PySys_SetArgv(int argc, char **argv)
|
PySys_SetArgv(int argc, wchar_t **argv)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_REALPATH)
|
#if defined(HAVE_REALPATH)
|
||||||
char fullpath[MAXPATHLEN];
|
wchar_t fullpath[MAXPATHLEN];
|
||||||
#elif defined(MS_WINDOWS)
|
#elif defined(MS_WINDOWS)
|
||||||
char fullpath[MAX_PATH];
|
wchar_t fullpath[MAX_PATH];
|
||||||
#endif
|
#endif
|
||||||
PyObject *av = makeargvobject(argc, argv);
|
PyObject *av = makeargvobject(argc, argv);
|
||||||
PyObject *path = PySys_GetObject("path");
|
PyObject *path = PySys_GetObject("path");
|
||||||
|
@ -1379,53 +1404,54 @@ PySys_SetArgv(int argc, char **argv)
|
||||||
if (PySys_SetObject("argv", av) != 0)
|
if (PySys_SetObject("argv", av) != 0)
|
||||||
Py_FatalError("can't assign sys.argv");
|
Py_FatalError("can't assign sys.argv");
|
||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
char *argv0 = argv[0];
|
wchar_t *argv0 = argv[0];
|
||||||
char *p = NULL;
|
wchar_t *p = NULL;
|
||||||
Py_ssize_t n = 0;
|
Py_ssize_t n = 0;
|
||||||
PyObject *a;
|
PyObject *a;
|
||||||
|
extern int _Py_wreadlink(const wchar_t *, wchar_t *, size_t);
|
||||||
#ifdef HAVE_READLINK
|
#ifdef HAVE_READLINK
|
||||||
char link[MAXPATHLEN+1];
|
wchar_t link[MAXPATHLEN+1];
|
||||||
char argv0copy[2*MAXPATHLEN+1];
|
wchar_t argv0copy[2*MAXPATHLEN+1];
|
||||||
int nr = 0;
|
int nr = 0;
|
||||||
if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0)
|
if (argc > 0 && argv0 != NULL && wcscmp(argv0, L"-c") != 0)
|
||||||
nr = readlink(argv0, link, MAXPATHLEN);
|
nr = _Py_wreadlink(argv0, link, MAXPATHLEN);
|
||||||
if (nr > 0) {
|
if (nr > 0) {
|
||||||
/* It's a symlink */
|
/* It's a symlink */
|
||||||
link[nr] = '\0';
|
link[nr] = '\0';
|
||||||
if (link[0] == SEP)
|
if (link[0] == SEP)
|
||||||
argv0 = link; /* Link to absolute path */
|
argv0 = link; /* Link to absolute path */
|
||||||
else if (strchr(link, SEP) == NULL)
|
else if (wcschr(link, SEP) == NULL)
|
||||||
; /* Link without path */
|
; /* Link without path */
|
||||||
else {
|
else {
|
||||||
/* Must join(dirname(argv0), link) */
|
/* Must join(dirname(argv0), link) */
|
||||||
char *q = strrchr(argv0, SEP);
|
wchar_t *q = wcsrchr(argv0, SEP);
|
||||||
if (q == NULL)
|
if (q == NULL)
|
||||||
argv0 = link; /* argv0 without path */
|
argv0 = link; /* argv0 without path */
|
||||||
else {
|
else {
|
||||||
/* Must make a copy */
|
/* Must make a copy */
|
||||||
strcpy(argv0copy, argv0);
|
wcscpy(argv0copy, argv0);
|
||||||
q = strrchr(argv0copy, SEP);
|
q = wcsrchr(argv0copy, SEP);
|
||||||
strcpy(q+1, link);
|
wcscpy(q+1, link);
|
||||||
argv0 = argv0copy;
|
argv0 = argv0copy;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* HAVE_READLINK */
|
#endif /* HAVE_READLINK */
|
||||||
#if SEP == '\\' /* Special case for MS filename syntax */
|
#if SEP == '\\' /* Special case for MS filename syntax */
|
||||||
if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {
|
if (argc > 0 && argv0 != NULL && wcscmp(argv0, L"-c") != 0) {
|
||||||
char *q;
|
wchar_t *q;
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
char *ptemp;
|
wchar_t *ptemp;
|
||||||
if (GetFullPathName(argv0,
|
if (GetFullPathNameW(argv0,
|
||||||
sizeof(fullpath),
|
sizeof(fullpath)/sizeof(fullpath[0]),
|
||||||
fullpath,
|
fullpath,
|
||||||
&ptemp)) {
|
&ptemp)) {
|
||||||
argv0 = fullpath;
|
argv0 = fullpath;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
p = strrchr(argv0, SEP);
|
p = wcsrchr(argv0, SEP);
|
||||||
/* Test for alternate separator */
|
/* Test for alternate separator */
|
||||||
q = strrchr(p ? p : argv0, '/');
|
q = wcsrchr(p ? p : argv0, '/');
|
||||||
if (q != NULL)
|
if (q != NULL)
|
||||||
p = q;
|
p = q;
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
|
@ -1435,13 +1461,13 @@ PySys_SetArgv(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else /* All other filename syntaxes */
|
#else /* All other filename syntaxes */
|
||||||
if (argc > 0 && argv0 != NULL && strcmp(argv0, "-c") != 0) {
|
if (argc > 0 && argv0 != NULL && wcscmp(argv0, L"-c") != 0) {
|
||||||
#if defined(HAVE_REALPATH)
|
#if defined(HAVE_REALPATH)
|
||||||
if (realpath(argv0, fullpath)) {
|
if (_wrealpath(argv0, fullpath)) {
|
||||||
argv0 = fullpath;
|
argv0 = fullpath;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
p = strrchr(argv0, SEP);
|
p = wcsrchr(argv0, SEP);
|
||||||
}
|
}
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
n = p + 1 - argv0;
|
n = p + 1 - argv0;
|
||||||
|
@ -1451,7 +1477,7 @@ PySys_SetArgv(int argc, char **argv)
|
||||||
#endif /* Unix */
|
#endif /* Unix */
|
||||||
}
|
}
|
||||||
#endif /* All others */
|
#endif /* All others */
|
||||||
a = PyUnicode_FromStringAndSize(argv0, n);
|
a = PyUnicode_FromWideChar(argv0, n);
|
||||||
if (a == NULL)
|
if (a == NULL)
|
||||||
Py_FatalError("no mem for sys.path insertion");
|
Py_FatalError("no mem for sys.path insertion");
|
||||||
if (PyList_Insert(path, 0, a) < 0)
|
if (PyList_Insert(path, 0, a) < 0)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue