mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Renovate display of non-ASCII messages on Windows.
GNU gettext selects a default encoding for the messages it emits in a platform-specific manner; it uses the Windows ANSI code page on Windows and follows LC_CTYPE on other platforms. This is inconvenient for PostgreSQL server processes, so realize consistent cross-platform behavior by calling bind_textdomain_codeset() on Windows each time we permanently change LC_CTYPE. This primarily affects SQL_ASCII databases and processes like the postmaster that do not attach to a database, making their behavior consistent with PostgreSQL on non-Windows platforms. Messages from SQL_ASCII databases use the encoding implied by the database LC_CTYPE, and messages from non-database processes use LC_CTYPE from the postmaster system environment. PlatformEncoding becomes unused, so remove it. Make write_console() prefer WriteConsoleW() to write() regardless of the encodings in use. In this situation, write() will invariably mishandle non-ASCII characters. elog.c has assumed that messages conform to the database encoding. While usually true, this does not hold for SQL_ASCII and MULE_INTERNAL. Introduce MessageEncoding to track the actual encoding of message text. The present consumers are Windows-specific code for converting messages to UTF16 for use in system interfaces. This fixes the appearance in Windows event logs and consoles of translated messages from SQL_ASCII processes like the postmaster. Note that SQL_ASCII inherently disclaims a strong notion of encoding, so non-ASCII byte sequences interpolated into messages by %s may yet yield a nonsensical message. MULE_INTERNAL has similar problems at present, albeit for a different reason: its lack of libiconv support or a conversion to UTF8. Consequently, one need no longer restart Windows with a different Windows ANSI code page to broadly test backend logging under a given language. Changing the user's locale ("Format") is enough. Several accounts can simultaneously run postmasters under different locales, all correctly logging localized messages to Windows event logs and consoles. Alexander Law and Noah Misch
This commit is contained in:
@ -131,14 +131,16 @@ static char *IsoLocaleName(const char *); /* MSVC specific */
|
||||
/*
|
||||
* pg_perm_setlocale
|
||||
*
|
||||
* This is identical to the libc function setlocale(), with the addition
|
||||
* that if the operation is successful, the corresponding LC_XXX environment
|
||||
* variable is set to match. By setting the environment variable, we ensure
|
||||
* that any subsequent use of setlocale(..., "") will preserve the settings
|
||||
* made through this routine. Of course, LC_ALL must also be unset to fully
|
||||
* ensure that, but that has to be done elsewhere after all the individual
|
||||
* LC_XXX variables have been set correctly. (Thank you Perl for making this
|
||||
* kluge necessary.)
|
||||
* This wraps the libc function setlocale(), with two additions. First, when
|
||||
* changing LC_CTYPE, update gettext's encoding for the current message
|
||||
* domain. GNU gettext automatically tracks LC_CTYPE on most platforms, but
|
||||
* not on Windows. Second, if the operation is successful, the corresponding
|
||||
* LC_XXX environment variable is set to match. By setting the environment
|
||||
* variable, we ensure that any subsequent use of setlocale(..., "") will
|
||||
* preserve the settings made through this routine. Of course, LC_ALL must
|
||||
* also be unset to fully ensure that, but that has to be done elsewhere after
|
||||
* all the individual LC_XXX variables have been set correctly. (Thank you
|
||||
* Perl for making this kluge necessary.)
|
||||
*/
|
||||
char *
|
||||
pg_perm_setlocale(int category, const char *locale)
|
||||
@ -172,6 +174,22 @@ pg_perm_setlocale(int category, const char *locale)
|
||||
if (result == NULL)
|
||||
return result; /* fall out immediately on failure */
|
||||
|
||||
/*
|
||||
* Use the right encoding in translated messages. Under ENABLE_NLS, let
|
||||
* pg_bind_textdomain_codeset() figure it out. Under !ENABLE_NLS, message
|
||||
* format strings are ASCII, but database-encoding strings may enter the
|
||||
* message via %s. This makes the overall message encoding equal to the
|
||||
* database encoding.
|
||||
*/
|
||||
if (category == LC_CTYPE)
|
||||
{
|
||||
#ifdef ENABLE_NLS
|
||||
SetMessageEncoding(pg_bind_textdomain_codeset(textdomain(NULL)));
|
||||
#else
|
||||
SetMessageEncoding(GetDatabaseEncoding());
|
||||
#endif
|
||||
}
|
||||
|
||||
switch (category)
|
||||
{
|
||||
case LC_COLLATE:
|
||||
|
Reference in New Issue
Block a user