digitalmars.D.bugs - sysErrorString has problem on multibyte environment
- k2 (2/2) Jul 14 2005 sysErrorString are using "A" function.
- Regan Heath (27/29) Jul 14 2005 This should do the trick, I suspect.
- k2 (39/39) Jul 14 2005 The following sample codes get an error, "Error: 4invalid UTF-8 sequence...
- Regan Heath (9/50) Jul 14 2005 Ahh, of course, FormatMessageA is giving a multibyte result which isn't ...
sysErrorString are using "A" function. If OS environment is multibyte, that result include multibyte string.
Jul 14 2005
On Thu, 14 Jul 2005 08:24:36 +0000 (UTC), k2 <k2_member pathlink.com> wrote:sysErrorString are using "A" function. If OS environment is multibyte, that result include multibyte string.This should do the trick, I suspect. //This code should be considered public domain wchar[] sysErrorStringW(uint errcode) { wchar[] result; wchar* buffer; DWORD r; r = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language cast(LPWSTR)&buffer, 0, null); /* Remove \r\n from error string */ if (r >= 2) r -= 2; result = buffer[0..r].dup; LocalFree(cast(HLOCAL)buffer); return result; } Regan
Jul 14 2005
The following sample codes get an error, "Error: 4invalid UTF-8 sequence", on my PC: import std.file; import std.utf; import std.c.windows.windows; extern(Windows) export int MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); void main() { try{ std.file.isdir("notexist"); }catch(Object o){ MessageBoxW(null, toUTF16z(o.toString()), null, MB_OK); } } isdir, etc are using sysErrorString. So, I think this is better: char[] sysErrorString(uint errcode) { char[] result; wchar* buffer; DWORD r; r = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language cast(LPWSTR)&buffer, 0, null); /* Remove \r\n from error string */ if (r >= 2) r -= 2; result = std.utf.toUTF8(buffer[0..r]); LocalFree(cast(HLOCAL)buffer); return result; }
Jul 14 2005
On Thu, 14 Jul 2005 09:54:46 +0000 (UTC), k2 <k2_member pathlink.com> wrote:The following sample codes get an error, "Error: 4invalid UTF-8 sequence", on my PC: import std.file; import std.utf; import std.c.windows.windows; extern(Windows) export int MessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType); void main() { try{ std.file.isdir("notexist"); }catch(Object o){ MessageBoxW(null, toUTF16z(o.toString()), null, MB_OK); } } isdir, etc are using sysErrorString. So, I think this is better: char[] sysErrorString(uint errcode) { char[] result; wchar* buffer; DWORD r; r = FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, null, errcode, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language cast(LPWSTR)&buffer, 0, null); /* Remove \r\n from error string */ if (r >= 2) r -= 2; result = std.utf.toUTF8(buffer[0..r]); LocalFree(cast(HLOCAL)buffer); return result; }Ahh, of course, FormatMessageA is giving a multibyte result which isn't UTF8. FormatMessageW gives a unicode result AKA UTF-16. Does it bother anyone else that we do UTF conversions all the time? Here we go from UTF-16 to UTF-8. I noticed in particular doFormat uses a delegate taking a dchar so each and every character formatted gets converted to/from dchar. It just seems inefficient in some way. Regan
Jul 14 2005