Tell gettext which codeset to use by calling bind_textdomain_codeset(). We
authorHeikki Linnakangas <heikki@enterprisedb.com>
Wed, 8 Apr 2009 09:50:48 +0000 (09:50 +0000)
committerHeikki Linnakangas <heikki@enterprisedb.com>
Wed, 8 Apr 2009 09:50:48 +0000 (09:50 +0000)
already did that on Windows, but it's needed on other platforms too when
LC_CTYPE=C. With other locales, we enforce (or trust) that the codeset of
the locale matches the server encoding so we don't need to bind it
explicitly. It should do no harm in that case either, but I don't have
full faith in the PG encoding -> OS codeset mapping table yet. Per recent
discussion on pgsql-hackers.

src/backend/utils/init/miscinit.c
src/backend/utils/init/postinit.c
src/backend/utils/mb/mbutils.c
src/include/mb/pg_wchar.h

index 03d86ca5f948b1d99412af6fe7a38c22609ddf61..669186ef9aeb03d7a8183db6088cb4bc0edb75a2 100644 (file)
@@ -1242,7 +1242,7 @@ pg_bindtextdomain(const char *domain)
 
                get_locale_path(my_exec_path, locale_path);
                bindtextdomain(domain, locale_path);
-               pg_bind_textdomain_codeset(domain, GetDatabaseEncoding());
+               pg_bind_textdomain_codeset(domain);
        }
 #endif
 }
index b35939556f17f32966f13628d636ee632ac10a6b..a73833a1e632fc87c51191fd7f7aa9c39a286da0 100644 (file)
@@ -265,6 +265,9 @@ CheckMyDatabase(const char *name, bool am_superuser)
        SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE);
        SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE);
 
+       /* Use the right encoding in translated messages */
+       pg_bind_textdomain_codeset(textdomain(NULL));
+
        /*
         * Lastly, set up any database-specific configuration variables.
         */
index cb05b3f934560879d0e0bb49155fdb4d09dfdace..e06500ee91c18c55fc7358274f86f07edbf00e88 100644 (file)
@@ -890,7 +890,7 @@ cliplen(const char *str, int len, int limit)
        return l;
 }
 
-#if defined(ENABLE_NLS) && defined(WIN32)
+#if defined(ENABLE_NLS)
 static const struct codeset_map {
        int     encoding;
        const char *codeset;
@@ -929,7 +929,7 @@ static const struct codeset_map {
        {PG_EUC_TW, "EUC-TW"},
        {PG_EUC_JIS_2004, "EUC-JP"}
 };
-#endif /* WIN32 */
+#endif /* ENABLE_NLS */
 
 void
 SetDatabaseEncoding(int encoding)
@@ -939,22 +939,36 @@ SetDatabaseEncoding(int encoding)
 
        DatabaseEncoding = &pg_enc2name_tbl[encoding];
        Assert(DatabaseEncoding->encoding == encoding);
-
-#ifdef ENABLE_NLS
-       pg_bind_textdomain_codeset(textdomain(NULL), encoding);
-#endif
 }
 
 /*
- * On Windows, we need to explicitly bind gettext to the correct
- * encoding, because gettext() tends to get confused.
+ * Bind gettext to the codeset equivalent with the database encoding.
  */
 void
-pg_bind_textdomain_codeset(const char *domainname, int encoding)
+pg_bind_textdomain_codeset(const char *domainname)
 {
-#if defined(ENABLE_NLS) && defined(WIN32)
+#if defined(ENABLE_NLS)
+       int             encoding = GetDatabaseEncoding();
        int     i;
 
+       /*
+        * gettext() uses the codeset specified by LC_CTYPE by default,
+        * so if that matches the database encoding we don't need to do
+        * anything. In CREATE DATABASE, we enforce or trust that the
+        * locale's codeset matches database encoding, except for the C
+        * locale. In C locale, we bind gettext() explicitly to the right
+        * codeset.
+        *
+        * On Windows, though, gettext() tends to get confused so we always
+        * bind it.
+        */
+#ifndef WIN32
+       const char *ctype = setlocale(LC_CTYPE, NULL);
+
+       if (pg_strcasecmp(ctype, "C") != 0 && pg_strcasecmp(ctype, "POSIX") != 0)
+               return;
+#endif
+
        for (i = 0; i < lengthof(codeset_map_array); i++)
        {
                if (codeset_map_array[i].encoding == encoding)
index 3525299b2a3548c0cfbb2588637860012916a552..fd8557c5d9c4e554218c5e7ae8e8c58580347b51 100644 (file)
@@ -391,7 +391,7 @@ extern const char *pg_get_client_encoding_name(void);
 extern void SetDatabaseEncoding(int encoding);
 extern int     GetDatabaseEncoding(void);
 extern const char *GetDatabaseEncodingName(void);
-extern void pg_bind_textdomain_codeset(const char *domainname, int encoding);
+extern void pg_bind_textdomain_codeset(const char *domainname);
 
 extern int     pg_valid_client_encoding(const char *name);
 extern int     pg_valid_server_encoding(const char *name);