Re: msvcrt: Implement _wperror
On 06/21/16 10:09, Hugh McMaster wrote:
dlls/msvcrt/msvcrt.spec | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) Please also update other msvc*/ucrtbase spec files as well.
/********************************************************************* + * _wperror (MSVCRT.@) + */ +void CDECL MSVCRT__wperror(const MSVCRT_wchar_t* str) +{ + int err, size, len; + static const WCHAR colon_spaceW[] = {':',' ',0}; + static const WCHAR newlineW[] = {'\n',0}; + MSVCRT_wchar_t *buffer = NULL; + + err = *MSVCRT__errno(); + if (err < 0 || err > MSVCRT__sys_nerr) err = MSVCRT__sys_nerr; + + size = MultiByteToWideChar(CP_ACP, 0, MSVCRT__sys_errlist[err], -1, NULL, 0) + 1 /* add \n */; + + if (str && *str) + size += lstrlenW(str) + 2; /* add str length, colon and space */ + + buffer = MSVCRT_malloc(size * sizeof(MSVCRT_wchar_t)); + if (!buffer) return; + + if (str && *str) + { + lstrcpyW(buffer, str); + lstrcatW(buffer, colon_spaceW); + } + else buffer[0] = 0; + + len = lstrlenW(buffer); + MultiByteToWideChar(CP_ACP, 0, MSVCRT__sys_errlist[err], -1, buffer + len, size - len); + lstrcatW(buffer, newlineW); + MSVCRT__write(2, buffer, lstrlenW(buffer) * sizeof(MSVCRT_wchar_t)); + MSVCRT_free(buffer); +} This is not how the function works. It shouldn't print wchar_t string to stderr. Probably the simplest implementation is to convert input parameter and call _perror (CP_ACP is not the correct encoding, you can use MSVCRT_wcstombs).
Thanks, Piotr
On Tuesday, 21 June 2016 7:04 PM UTC+10, Piotr Caban wrote:
On 06/21/16 10:09, Hugh McMaster wrote:
dlls/msvcrt/msvcrt.spec | 2 +- 2 files changed, 36 insertions(+), 1 deletion(-) Please also update other msvc*/ucrtbase spec files as well.
Okay, will do.
/********************************************************************* + * _wperror (MSVCRT.@) + */ +void CDECL MSVCRT__wperror(const MSVCRT_wchar_t* str) +{ + int err, size, len; + static const WCHAR colon_spaceW[] = {':',' ',0}; + static const WCHAR newlineW[] = {'\n',0}; + MSVCRT_wchar_t *buffer = NULL; + + err = *MSVCRT__errno(); + if (err < 0 || err > MSVCRT__sys_nerr) err = MSVCRT__sys_nerr; + + size = MultiByteToWideChar(CP_ACP, 0, MSVCRT__sys_errlist[err], -1, NULL, 0) + 1 /* add \n */; + + if (str && *str) + size += lstrlenW(str) + 2; /* add str length, colon and space */ + + buffer = MSVCRT_malloc(size * sizeof(MSVCRT_wchar_t)); + if (!buffer) return; + + if (str && *str) + { + lstrcpyW(buffer, str); + lstrcatW(buffer, colon_spaceW); + } + else buffer[0] = 0; + + len = lstrlenW(buffer); + MultiByteToWideChar(CP_ACP, 0, MSVCRT__sys_errlist[err], -1, buffer + len, size - len); + lstrcatW(buffer, newlineW); + MSVCRT__write(2, buffer, lstrlenW(buffer) * sizeof(MSVCRT_wchar_t)); + MSVCRT_free(buffer); +} This is not how the function works. It shouldn't print wchar_t string to stderr. Probably the simplest implementation is to convert input parameter and call _perror (CP_ACP is not the correct encoding, you can use MSVCRT_wcstombs).
I don't understand. The MSDN page [1] contradicts your statement. "The perror function prints an error message to stderr. _wperror is a wide-character version of _perror; the string argument to _wperror is a wide-character string. _wperror and _perror behave identically otherwise." There is nothing in that quote to suggest _wperror does operate like my implementation. Also, if we convert the wide string to multibyte, there is a risk any non-Unicode characters supplied as input will not display correctly. So, IMHO converting to a multibyte string is a bad approach. Still, if that's what you want, I'll do it. [1] https://msdn.microsoft.com/en-us/library/9t0e6085.aspx
On Tuesday, 21 June 2016 8:37 PM, Hugh McMaster wrote:
On Tuesday, 21 June 2016 7:04 PM UTC+10, Piotr Caban wrote:
This is not how the function works. It shouldn't print wchar_t string to stderr. Probably the simplest implementation is to convert input parameter and call _perror (CP_ACP is not the correct encoding, you can use MSVCRT_wcstombs).
I don't understand. The MSDN page [1] contradicts your statement. "The perror function prints an error message to stderr. _wperror is a wide-character version of _perror; the string argument to _wperror is a wide-character string. _wperror and _perror behave identically otherwise."
There is nothing in that quote to suggest _wperror does operate like my implementation.
Bad typo. This should say: "There is nothing in that quote to suggest _wperror does not operate like my implementation."
Also, if we convert the wide string to multibyte, there is a risk any non-Unicode characters supplied as input will not display correctly. So, IMHO converting to a multibyte string is a bad approach.
Still, if that's what you want, I'll do it.
On 06/21/16 12:37, Hugh McMaster wrote:
On Tuesday, 21 June 2016 7:04 PM UTC+10, Piotr Caban wrote:
This is not how the function works. It shouldn't print wchar_t string to stderr. Probably the simplest implementation is to convert input parameter and call _perror (CP_ACP is not the correct encoding, you can use MSVCRT_wcstombs).
I don't understand. The MSDN page [1] contradicts your statement. "The perror function prints an error message to stderr. _wperror is a wide-character version of _perror; the string argument to _wperror is a wide-character string. _wperror and _perror behave identically otherwise." The function is not writing wide-characters to stderr. It can be easily tested, e.g. do something like this: freopen("test.txt", "wb", stderr); errno = 3; _wperror(L"test"); and see what's in the file when run on Windows/with your implementation. It will also display incorrectly when _wperror is run inside wine's cmd window.
Also, if we convert the wide string to multibyte, there is a risk any non-Unicode characters supplied as input will not display correctly. So, IMHO converting to a multibyte string is a bad approach. This is something that is worth testing. Anyway the conversion needs to be done.
Still, if that's what you want, I'll do it. I want the function to be implemented correctly.
Thanks, Piotr
participants (2)
-
Hugh McMaster -
Piotr Caban