Patch #1075: Use wide API to format error messages.
This commit is contained in:
parent
c76473d887
commit
5d12abe0b1
|
@ -10,8 +10,8 @@ extern char *strerror(int);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef MS_WINDOWS
|
#ifdef MS_WINDOWS
|
||||||
#include "windows.h"
|
#include <windows.h>
|
||||||
#include "winbase.h"
|
#include <winbase.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -270,30 +270,38 @@ PyErr_NoMemory(void)
|
||||||
PyObject *
|
PyObject *
|
||||||
PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
|
PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
|
||||||
{
|
{
|
||||||
|
PyObject *message;
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
char *s;
|
|
||||||
int i = errno;
|
int i = errno;
|
||||||
#ifdef PLAN9
|
#ifdef PLAN9
|
||||||
char errbuf[ERRMAX];
|
char errbuf[ERRMAX];
|
||||||
#endif
|
#else
|
||||||
#ifdef MS_WINDOWS
|
#ifndef MS_WINDOWS
|
||||||
char *s_buf = NULL;
|
char *s;
|
||||||
char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */
|
#else
|
||||||
#endif
|
WCHAR *s_buf = NULL;
|
||||||
|
#endif /* Unix/Windows */
|
||||||
|
#endif /* PLAN 9*/
|
||||||
|
|
||||||
#ifdef EINTR
|
#ifdef EINTR
|
||||||
if (i == EINTR && PyErr_CheckSignals())
|
if (i == EINTR && PyErr_CheckSignals())
|
||||||
return NULL;
|
return NULL;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef PLAN9
|
#ifdef PLAN9
|
||||||
rerrstr(errbuf, sizeof errbuf);
|
rerrstr(errbuf, sizeof errbuf);
|
||||||
s = errbuf;
|
message = PyUnicode_DecodeUTF8(errbuf, strlen(errbuf), "ignore");
|
||||||
#else
|
#else
|
||||||
|
#ifndef MS_WINDOWS
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
s = "Error"; /* Sometimes errno didn't get set */
|
s = "Error"; /* Sometimes errno didn't get set */
|
||||||
else
|
else
|
||||||
#ifndef MS_WINDOWS
|
|
||||||
s = strerror(i);
|
s = strerror(i);
|
||||||
|
message = PyUnicode_DecodeUTF8(s, strlen(s), "ignore");
|
||||||
#else
|
#else
|
||||||
|
if (i == 0)
|
||||||
|
message = PyUnicode_FromString("Error"); /* Sometimes errno didn't get set */
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* Note that the Win32 errors do not lineup with the
|
/* Note that the Win32 errors do not lineup with the
|
||||||
errno error. So if the error is in the MSVC error
|
errno error. So if the error is in the MSVC error
|
||||||
|
@ -301,10 +309,10 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
|
||||||
a Win32 error code
|
a Win32 error code
|
||||||
*/
|
*/
|
||||||
if (i > 0 && i < _sys_nerr) {
|
if (i > 0 && i < _sys_nerr) {
|
||||||
s = _sys_errlist[i];
|
message = PyUnicode_FromString(_sys_errlist[i]);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int len = FormatMessage(
|
int len = FormatMessageW(
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
|
@ -313,29 +321,39 @@ PyErr_SetFromErrnoWithFilenameObject(PyObject *exc, PyObject *filenameObject)
|
||||||
MAKELANGID(LANG_NEUTRAL,
|
MAKELANGID(LANG_NEUTRAL,
|
||||||
SUBLANG_DEFAULT),
|
SUBLANG_DEFAULT),
|
||||||
/* Default language */
|
/* Default language */
|
||||||
(LPTSTR) &s_buf,
|
(LPWSTR) &s_buf,
|
||||||
0, /* size not used */
|
0, /* size not used */
|
||||||
NULL); /* no args */
|
NULL); /* no args */
|
||||||
if (len==0) {
|
if (len==0) {
|
||||||
/* Only ever seen this in out-of-mem
|
/* Only ever seen this in out-of-mem
|
||||||
situations */
|
situations */
|
||||||
sprintf(s_small_buf, "Windows Error 0x%X", i);
|
|
||||||
s = s_small_buf;
|
|
||||||
s_buf = NULL;
|
s_buf = NULL;
|
||||||
|
message = PyUnicode_FromFormat("Windows Error 0x%X", i);
|
||||||
} else {
|
} else {
|
||||||
s = s_buf;
|
|
||||||
/* remove trailing cr/lf and dots */
|
/* remove trailing cr/lf and dots */
|
||||||
while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
|
while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
|
||||||
s[--len] = '\0';
|
s_buf[--len] = L'\0';
|
||||||
|
message = PyUnicode_FromUnicode(s_buf, len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif /* Unix/Windows */
|
#endif /* Unix/Windows */
|
||||||
#endif /* PLAN 9*/
|
#endif /* PLAN 9*/
|
||||||
|
|
||||||
|
if (message == NULL)
|
||||||
|
{
|
||||||
|
#ifdef MS_WINDOWS
|
||||||
|
LocalFree(s_buf);
|
||||||
|
#endif
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (filenameObject != NULL)
|
if (filenameObject != NULL)
|
||||||
v = Py_BuildValue("(iUO)", i, s, filenameObject);
|
v = Py_BuildValue("(iOO)", i, message, filenameObject);
|
||||||
else
|
else
|
||||||
v = Py_BuildValue("(iU)", i, s);
|
v = Py_BuildValue("(iO)", i, message);
|
||||||
|
Py_DECREF(message);
|
||||||
|
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
PyErr_SetObject(exc, v);
|
PyErr_SetObject(exc, v);
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
|
@ -383,13 +401,12 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||||
PyObject *filenameObject)
|
PyObject *filenameObject)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char *s;
|
WCHAR *s_buf = NULL; /* Free via LocalFree */
|
||||||
char *s_buf = NULL; /* Free via LocalFree */
|
PyObject *message;
|
||||||
char s_small_buf[28]; /* Room for "Windows Error 0xFFFFFFFF" */
|
|
||||||
PyObject *v;
|
PyObject *v;
|
||||||
DWORD err = (DWORD)ierr;
|
DWORD err = (DWORD)ierr;
|
||||||
if (err==0) err = GetLastError();
|
if (err==0) err = GetLastError();
|
||||||
len = FormatMessage(
|
len = FormatMessageW(
|
||||||
/* Error API error */
|
/* Error API error */
|
||||||
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_FROM_SYSTEM |
|
FORMAT_MESSAGE_FROM_SYSTEM |
|
||||||
|
@ -398,24 +415,32 @@ PyObject *PyErr_SetExcFromWindowsErrWithFilenameObject(
|
||||||
err,
|
err,
|
||||||
MAKELANGID(LANG_NEUTRAL,
|
MAKELANGID(LANG_NEUTRAL,
|
||||||
SUBLANG_DEFAULT), /* Default language */
|
SUBLANG_DEFAULT), /* Default language */
|
||||||
(LPTSTR) &s_buf,
|
(LPWSTR) &s_buf,
|
||||||
0, /* size not used */
|
0, /* size not used */
|
||||||
NULL); /* no args */
|
NULL); /* no args */
|
||||||
if (len==0) {
|
if (len==0) {
|
||||||
/* Only seen this in out of mem situations */
|
/* Only seen this in out of mem situations */
|
||||||
sprintf(s_small_buf, "Windows Error 0x%X", err);
|
message = PyUnicode_FromFormat("Windows Error 0x%X", err);
|
||||||
s = s_small_buf;
|
|
||||||
s_buf = NULL;
|
s_buf = NULL;
|
||||||
} else {
|
} else {
|
||||||
s = s_buf;
|
|
||||||
/* remove trailing cr/lf and dots */
|
/* remove trailing cr/lf and dots */
|
||||||
while (len > 0 && (s[len-1] <= ' ' || s[len-1] == '.'))
|
while (len > 0 && (s_buf[len-1] <= L' ' || s_buf[len-1] == L'.'))
|
||||||
s[--len] = '\0';
|
s_buf[--len] = L'\0';
|
||||||
|
message = PyUnicode_FromUnicode(s_buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message == NULL)
|
||||||
|
{
|
||||||
|
LocalFree(s_buf);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (filenameObject != NULL)
|
if (filenameObject != NULL)
|
||||||
v = Py_BuildValue("(iUO)", err, s, filenameObject);
|
v = Py_BuildValue("(iOO)", err, message, filenameObject);
|
||||||
else
|
else
|
||||||
v = Py_BuildValue("(iU)", err, s);
|
v = Py_BuildValue("(iO)", err, message);
|
||||||
|
Py_DECREF(message);
|
||||||
|
|
||||||
if (v != NULL) {
|
if (v != NULL) {
|
||||||
PyErr_SetObject(exc, v);
|
PyErr_SetObject(exc, v);
|
||||||
Py_DECREF(v);
|
Py_DECREF(v);
|
||||||
|
|
Loading…
Reference in New Issue